Files
wr.do/components/layout/mobile-nav.tsx
2024-07-26 22:08:57 +08:00

143 lines
4.1 KiB
TypeScript

"use client";
import { useEffect, useState } from "react";
import Link from "next/link";
import { useSelectedLayoutSegment } from "next/navigation";
import { Menu, X } from "lucide-react";
import { useSession } from "next-auth/react";
import { docsConfig } from "@/config/docs";
import { marketingConfig } from "@/config/marketing";
import { siteConfig } from "@/config/site";
import { cn } from "@/lib/utils";
import { DocsSidebarNav } from "@/components/docs/sidebar-nav";
import { Icons } from "@/components/shared/icons";
import { ModeToggle } from "./mode-toggle";
export function NavMobile() {
const { data: session } = useSession();
const [open, setOpen] = useState(false);
const selectedLayout = useSelectedLayoutSegment();
const documentation = selectedLayout === "docs";
const configMap = {
docs: docsConfig.mainNav,
};
const links =
(selectedLayout && configMap[selectedLayout]) || marketingConfig.mainNav;
// prevent body scroll when modal is open
useEffect(() => {
if (open) {
document.body.style.overflow = "hidden";
} else {
document.body.style.overflow = "auto";
}
}, [open]);
return (
<>
<button
onClick={() => setOpen(!open)}
className={cn(
"fixed right-2 top-2.5 z-50 rounded-full p-2 transition-colors duration-200 hover:bg-muted focus:outline-none active:bg-muted md:hidden",
open && "hover:bg-muted active:bg-muted",
)}
>
{open ? (
<X className="size-5 text-muted-foreground" />
) : (
<Menu className="size-5 text-muted-foreground" />
)}
</button>
<nav
className={cn(
"fixed inset-0 z-20 hidden w-full overflow-auto bg-background px-5 py-16 lg:hidden",
open && "block",
)}
>
<ul className="grid divide-y divide-muted">
{links &&
links.length > 0 &&
links.map(({ title, href }) => (
<li key={href} className="py-3">
<Link
href={href}
onClick={() => setOpen(false)}
className="flex w-full font-medium capitalize"
>
{title}
</Link>
</li>
))}
{session ? (
<>
{session.user.role === "ADMIN" ? (
<li className="py-3">
<Link
href="/admin"
onClick={() => setOpen(false)}
className="flex w-full font-medium capitalize"
>
Admin
</Link>
</li>
) : null}
<li className="py-3">
<Link
href="/dashboard"
onClick={() => setOpen(false)}
className="flex w-full font-medium capitalize"
>
Dashboard
</Link>
</li>
</>
) : (
<>
<li className="py-3">
<Link
href="/login"
onClick={() => setOpen(false)}
className="flex w-full font-medium capitalize"
>
Sign in
</Link>
</li>
<li className="py-3">
<Link
href="/register"
onClick={() => setOpen(false)}
className="flex w-full font-medium capitalize"
>
Sign up
</Link>
</li>
</>
)}
</ul>
{documentation ? (
<div className="mt-8 block md:hidden">
<DocsSidebarNav setOpen={setOpen} />
</div>
) : null}
<div className="mt-5 flex items-center justify-end space-x-4">
<Link href={siteConfig.links.github} target="_blank" rel="noreferrer">
<Icons.gitHub className="size-6" />
<span className="sr-only">GitHub</span>
</Link>
<ModeToggle />
</div>
</nav>
</>
);
}