Use a slideout menu on mobile

This commit is contained in:
Austin Chen 2022-03-30 21:57:34 -07:00
parent 00c04e967f
commit 2501b94c65
2 changed files with 93 additions and 28 deletions

View File

@ -1,63 +1,128 @@
import clsx from 'clsx'
import Link from 'next/link' import Link from 'next/link'
import { useUser } from '../../hooks/use-user' import { useUser } from '../../hooks/use-user'
import { firebaseLogin, User } from '../../lib/firebase/users'
import { import {
CollectionIcon,
HomeIcon, HomeIcon,
MenuAlt3Icon,
SearchIcon, SearchIcon,
UserGroupIcon, UserGroupIcon,
XIcon,
} from '@heroicons/react/outline' } from '@heroicons/react/outline'
import { Transition, Dialog } from '@headlessui/react'
import { useState, Fragment } from 'react'
import Sidebar from './sidebar'
// From https://codepen.io/chris__sev/pen/QWGvYbL // From https://codepen.io/chris__sev/pen/QWGvYbL
export function BottomNavBar() { export function BottomNavBar() {
const [sidebarOpen, setSidebarOpen] = useState(false)
const user = useUser() const user = useUser()
if (!user) { if (!user) {
return null return null
} }
return ( return (
<nav className="fixed inset-x-0 bottom-0 z-20 flex justify-between border-t-2 bg-white text-xs text-gray-700 md:hidden"> <nav className="fixed inset-x-0 bottom-0 z-20 flex justify-between border-t-2 bg-white text-xs text-gray-700 lg:hidden">
<Link href="/home"> <Link href="/home">
<a <a className="block w-full py-2 px-3 text-center transition duration-300 hover:bg-indigo-200 hover:text-indigo-700">
href="#"
className="block w-full py-2 px-3 text-center transition duration-300 hover:bg-indigo-200 hover:text-indigo-700"
>
<HomeIcon className="my-1 mx-auto h-6 w-6" aria-hidden="true" /> <HomeIcon className="my-1 mx-auto h-6 w-6" aria-hidden="true" />
{/* Home */} {/* Home */}
</a> </a>
</Link> </Link>
<Link href="/markets"> <Link href="/markets">
<a <a className="block w-full py-2 px-3 text-center hover:bg-indigo-200 hover:text-indigo-700">
href="#"
className="block w-full py-2 px-3 text-center hover:bg-indigo-200 hover:text-indigo-700"
>
<SearchIcon className="my-1 mx-auto h-6 w-6" aria-hidden="true" /> <SearchIcon className="my-1 mx-auto h-6 w-6" aria-hidden="true" />
{/* Explore */} {/* Explore */}
</a> </a>
</Link> </Link>
<Link href="/folds"> <Link href="/folds">
<a <a className="block w-full py-2 px-3 text-center hover:bg-indigo-200 hover:text-indigo-700">
href="#"
className="block w-full py-2 px-3 text-center hover:bg-indigo-200 hover:text-indigo-700"
>
<UserGroupIcon className="my-1 mx-auto h-6 w-6" aria-hidden="true" /> <UserGroupIcon className="my-1 mx-auto h-6 w-6" aria-hidden="true" />
{/* Folds */} {/* Folds */}
</a> </a>
</Link> </Link>
{/* TODO: replace with a link to your own profile */} <span
<Link href="/trades"> className="block w-full py-2 px-3 text-center hover:cursor-pointer hover:bg-indigo-200 hover:text-indigo-700"
<a onClick={() => setSidebarOpen(true)}
href="#"
className="block w-full py-2 px-3 text-center hover:bg-indigo-200 hover:text-indigo-700"
> >
<CollectionIcon className="my-1 mx-auto h-6 w-6" aria-hidden="true" /> <MenuAlt3Icon className="my-1 mx-auto h-6 w-6" aria-hidden="true" />
{/* Your Trades */} {/* Menu */}
</a> </span>
</Link>
<MobileSidebar
sidebarOpen={sidebarOpen}
setSidebarOpen={setSidebarOpen}
/>
</nav> </nav>
) )
} }
// Sidebar that slides out on mobile
export function MobileSidebar(props: {
sidebarOpen: boolean
setSidebarOpen: (open: boolean) => void
}) {
const { sidebarOpen, setSidebarOpen } = props
return (
<div>
<Transition.Root show={sidebarOpen} as={Fragment}>
<Dialog
as="div"
className="fixed inset-0 z-40 flex"
onClose={setSidebarOpen}
>
<Transition.Child
as={Fragment}
enter="transition-opacity ease-linear duration-300"
enterFrom="opacity-0"
enterTo="opacity-100"
leave="transition-opacity ease-linear duration-300"
leaveFrom="opacity-100"
leaveTo="opacity-0"
>
<Dialog.Overlay className="fixed inset-0 bg-gray-600 bg-opacity-75" />
</Transition.Child>
<Transition.Child
as={Fragment}
enter="transition ease-in-out duration-300 transform"
enterFrom="-translate-x-full"
enterTo="translate-x-0"
leave="transition ease-in-out duration-300 transform"
leaveFrom="translate-x-0"
leaveTo="-translate-x-full"
>
<div className="relative flex w-full max-w-xs flex-1 flex-col bg-white pt-5 pb-4">
<Transition.Child
as={Fragment}
enter="ease-in-out duration-300"
enterFrom="opacity-0"
enterTo="opacity-100"
leave="ease-in-out duration-300"
leaveFrom="opacity-100"
leaveTo="opacity-0"
>
<div className="absolute top-0 right-0 -mr-12 pt-2">
<button
type="button"
className="ml-1 flex h-10 w-10 items-center justify-center rounded-full focus:outline-none focus:ring-2 focus:ring-inset focus:ring-white"
onClick={() => setSidebarOpen(false)}
>
<span className="sr-only">Close sidebar</span>
<XIcon className="h-6 w-6 text-white" aria-hidden="true" />
</button>
</div>
</Transition.Child>
<div className="mx-2 mt-5 h-0 flex-1 overflow-y-auto">
<Sidebar />
</div>
</div>
</Transition.Child>
<div className="w-14 flex-shrink-0" aria-hidden="true">
{/* Dummy element to force sidebar to shrink to fit close icon */}
</div>
</Dialog>
</Transition.Root>
</div>
)
}

View File

@ -31,8 +31,8 @@ export function ProfileSummary(props: { user: User | undefined }) {
<Row className="group avatar items-center gap-4 py-6 text-gray-600 group-hover:text-gray-900"> <Row className="group avatar items-center gap-4 py-6 text-gray-600 group-hover:text-gray-900">
<Avatar avatarUrl={user?.avatarUrl} username={user?.username} noLink /> <Avatar avatarUrl={user?.avatarUrl} username={user?.username} noLink />
<div className="truncate text-left sm:w-32"> <div className="truncate text-left">
<div className="hidden sm:flex">{user?.name}</div> <div>{user?.name}</div>
<div className="text-sm"> <div className="text-sm">
{user ? formatMoney(Math.floor(user.balance)) : ' '} {user ? formatMoney(Math.floor(user.balance)) : ' '}
</div> </div>