mhsf-dev/apps/www/src/components/feat/navbar/navbar.tsx

175 lines
6.0 KiB
TypeScript
Raw Normal View History

2025-02-15 17:18:58 -06:00
"use client";
2025-02-22 10:38:19 -06:00
import {
BrandingGenericIcon,
brandingIconClipboard,
} from "@/components/feat/icons/branding-icons";
2025-02-16 21:40:17 -06:00
import { Button } from "@/components/ui/button";
2025-02-16 13:37:40 -06:00
import {
ContextMenu,
ContextMenuContent,
ContextMenuItem,
ContextMenuSeparator,
ContextMenuTrigger,
} from "@/components/ui/context-menu";
2025-02-16 21:40:17 -06:00
import {
DropdownMenu,
DropdownMenuContent,
2025-02-22 10:38:19 -06:00
DropdownMenuSeparator,
2025-02-16 21:40:17 -06:00
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
2025-02-16 13:37:40 -06:00
import Github from "@/components/ui/github";
2025-02-18 18:19:04 -06:00
import { Link } from "@/components/util/link";
2025-02-15 17:18:58 -06:00
import { version } from "@/config/version";
2025-02-15 20:06:35 -06:00
import { useScroll } from "@/lib/hooks/use-scroll";
2025-02-15 17:18:58 -06:00
import { cn } from "@/lib/utils";
2025-02-22 10:38:19 -06:00
import { Home, Image, Menu, ServerCrash } from "lucide-react";
2025-02-16 21:40:17 -06:00
import { MenuDropdown } from "./menu-dropdown";
2025-02-22 10:38:19 -06:00
import useClipboard from "@/lib/useClipboard";
import { toast } from "sonner";
import { SignedIn, SignedOut, useUser } from "@clerk/nextjs";
import NextImage from "next/image";
import { usePathname } from "next/navigation";
const animatedTopbarPages = ["/home"];
2025-02-15 17:18:58 -06:00
export function NavBar() {
2025-02-15 20:06:35 -06:00
const showBorder = useScroll(40);
2025-02-22 10:38:19 -06:00
const clipboard = useClipboard();
const pathname = usePathname();
const { user } = useUser();
2025-02-15 20:06:35 -06:00
2025-02-15 17:18:58 -06:00
return (
<div
className={cn(
2025-02-15 20:06:35 -06:00
"w-screen h-[3rem] grid-cols-3 fixed backdrop-blur-xl z-10 flex",
2025-02-16 13:37:40 -06:00
"items-center justify-self-start me-auto pl-4 flex-1 transition-all justify-between",
2025-02-22 10:38:19 -06:00
showBorder ? "border-b" : "",
pathname !== null && animatedTopbarPages.includes(pathname)
? "[--animation-delay:1000ms] opacity-0 animate-fade-in"
: ""
2025-02-15 17:18:58 -06:00
)}
>
2025-02-16 13:37:40 -06:00
<span>
<ContextMenu>
<ContextMenuTrigger>
<Link className="gap-5 flex items-center " href="/">
<BrandingGenericIcon className="max-w-[32px] max-h-[32px] mt-0.5" />
<span className="gap-2 flex group hover:text-blue-500 hover:underline transition-all">
<strong className="">MHSF</strong>
<span className="text-muted-foreground group-hover:text-blue-500 transition-all">
v{version}
</span>
</span>
</Link>
</ContextMenuTrigger>
<ContextMenuContent className="overflow-hidden min-w-[300px]">
2025-02-22 10:38:19 -06:00
<DropdownMenuSeparator>Platform</DropdownMenuSeparator>
2025-02-18 18:19:04 -06:00
<Link href="Special:Root">
2025-02-16 13:37:40 -06:00
<ContextMenuItem>
<span className="pl-2 flex gap-2 items-center">
2025-02-22 10:38:19 -06:00
<ServerCrash size={16} /> Go to Dynamic Home Page
2025-02-16 13:37:40 -06:00
</span>
</ContextMenuItem>
2025-02-18 18:19:04 -06:00
</Link>
2025-02-22 10:38:19 -06:00
<Link href="/home">
<ContextMenuItem>
<span className="pl-2 flex gap-2 items-center">
<Home size={16} /> Go to Home Page
</span>
</ContextMenuItem>
</Link>
<ContextMenuSeparator />
<ContextMenuItem
onClick={() => {
clipboard.writeText(brandingIconClipboard);
toast.success("Copied icon to clipboard!");
}}
>
<span className="pl-2 flex gap-2 items-center">
<Image size={16} /> Copy Logo as SVG
</span>
</ContextMenuItem>
2025-02-16 13:37:40 -06:00
<ContextMenuSeparator />
2025-02-18 18:19:04 -06:00
<Link href="Special:GitHub">
2025-02-16 13:37:40 -06:00
<ContextMenuItem>
<span className="pl-2 flex gap-2 items-center">
<Github /> Open GitHub
</span>
</ContextMenuItem>
2025-02-18 18:19:04 -06:00
</Link>
<Link href="Special:GitHub/releases">
2025-02-16 21:40:17 -06:00
<ContextMenuItem>
<span className="pl-2 flex gap-2 items-center">
<Github /> Open GitHub Releases
</span>
</ContextMenuItem>
2025-02-18 18:19:04 -06:00
</Link>
2025-02-16 13:37:40 -06:00
</ContextMenuContent>
</ContextMenu>
</span>
2025-02-16 21:40:17 -06:00
<span className="mr-3 flex items-center">
<DropdownMenu>
<DropdownMenuTrigger>
2025-02-22 10:38:19 -06:00
<SignedOut>
<Button
className={cn(
"rounded-full flex items-center",
pathname !== null && animatedTopbarPages.includes(pathname)
? "[--animation-delay:2000ms] opacity-0 animate-fade-in"
: ""
)}
size="square-lg"
variant="secondary"
>
<Menu size={16} />
</Button>
</SignedOut>
<SignedIn>
<Button
size="square-lg"
variant="tertiary"
className={cn(
"rounded-full flex items-center",
pathname !== null && animatedTopbarPages.includes(pathname)
? "[--animation-delay:2000ms] opacity-0 animate-fade-in"
: ""
)}
>
<NextImage
alt="Clerk Image"
src={
user?.imageUrl === undefined
? "https://img.clerk.com/preview.png?size=144&seed=seed&initials=AD&isSquare=true&bgType=marble&bgColor=6c47ff&fgType=silhouette&fgColor=FFFFFF&type=user&w=48&q=75"
: user?.imageUrl
}
width={26}
height={26}
className="rounded-full"
/>
</Button>
</SignedIn>
2025-02-16 21:40:17 -06:00
</DropdownMenuTrigger>
<DropdownMenuContent className="max-w-[280px] w-[280px] mt-2 mr-2">
<MenuDropdown />
</DropdownMenuContent>
</DropdownMenu>
2025-02-22 10:38:19 -06:00
<SignedIn>
<div
className="absolute right-0 -z-10 h-full
overflow-hidden w-full ml-auto"
style={{ borderRadius: "inherit" }}
>
<img
src={user?.imageUrl ?? ""}
className="blur-2xl -z-10 object-cover w-48 h-48 opacity-20 dark:opacity-50 ml-auto"
alt=""
/>
</div>
</SignedIn>
2025-02-16 13:37:40 -06:00
</span>
2025-02-15 17:18:58 -06:00
</div>
);
}