The weeb for the next gen discord boat - Wamellow wamellow.com
bot discord
at master 5.8 kB view raw
1"use client"; 2 3import type { User } from "@/common/user"; 4import { userStore } from "@/common/user"; 5import { webStore } from "@/common/webstore"; 6import { LoginButton } from "@/components/login-button"; 7import { Avatar, AvatarImage } from "@/components/ui/avatar"; 8import { 9 DropdownMenu, 10 DropdownMenuContent, 11 DropdownMenuGroup, 12 DropdownMenuItem, 13 DropdownMenuLabel, 14 DropdownMenuSeparator, 15 DropdownMenuTrigger 16} from "@/components/ui/dropdown-menu"; 17import { authorize } from "@/utils/authorize-user"; 18import Link from "next/link"; 19import { useEffect, useState } from "react"; 20import { HiBookOpen, HiChevronDown, HiIdentification, HiLogout, HiSparkles, HiSupport, HiTerminal, HiViewGridAdd } from "react-icons/hi"; 21 22import { Skeleton } from "./ui/skeleton"; 23 24enum State { 25 Idle = 0, 26 Loading = 1, 27 Failure = 2 28} 29 30export function Header() { 31 const [state, setState] = useState<State>(State.Loading); 32 const user = userStore((s) => s); 33 34 useEffect(() => { 35 authorize({ setState }) 36 .then((_user) => { 37 userStore.setState({ 38 ...(_user || {}), 39 __fetched: true 40 }); 41 }); 42 43 webStore.setState({ 44 width: window?.innerWidth 45 }); 46 }, []); 47 48 if (state === State.Failure) { 49 return <LoginButton state={state} className="ml-auto" />; 50 } 51 52 if (state === State.Loading || !user) { 53 return ( 54 <div className="ml-auto flex items-center py-2 px-4"> 55 <Skeleton className="rounded-full mr-2 size-[30px]" /> 56 <Skeleton className="rounded-xl w-20 h-5" /> 57 </div> 58 ); 59 } 60 61 return <Dropdown user={user} />; 62} 63 64function Dropdown({ user }: { user: User; }) { 65 return ( 66 <DropdownMenu> 67 <DropdownMenuTrigger asChild> 68 <button 69 className="ml-auto truncate flex hover:bg-wamellow py-2 px-4 rounded-lg duration-200 items-center data-[state=open]:bg-wamellow outline-none" 70 > 71 <Avatar className="size-[30px] mr-2"> 72 <AvatarImage 73 alt={user.username} 74 src={user.avatar ? `https://cdn.discordapp.com/avatars/${user.id}/${user.avatar}?size=96` : "/discord.webp"} 75 /> 76 </Avatar> 77 78 <p className="mr-1 relative bottom-px truncate block text-primary-foreground font-medium tracking-tight">{user.globalName || user.username}</p> 79 <HiChevronDown /> 80 </button> 81 </DropdownMenuTrigger> 82 <DropdownMenuContent className='w-56 scale-120 relative top-7 right-5' align="end"> 83 <DropdownMenuLabel className='flex items-center gap-3'> 84 <Avatar> 85 <AvatarImage 86 alt={user.username} 87 src={user.avatar ? `https://cdn.discordapp.com/avatars/${user.id}/${user.avatar}?size=96` : "/discord.webp"} 88 /> 89 </Avatar> 90 <div className='flex flex-col pb-0.5 truncate'> 91 <span className='text-popover-foreground truncate'>{user.globalName || user.username}</span> 92 <span className='text-muted-foreground text-xs truncate'>{user.email}</span> 93 </div> 94 </DropdownMenuLabel> 95 <DropdownMenuSeparator /> 96 <DropdownMenuGroup> 97 <DropdownMenuItem asChild> 98 <Link href="/profile"> 99 <HiViewGridAdd /> 100 Dashboard 101 </Link> 102 </DropdownMenuItem> 103 <DropdownMenuItem asChild> 104 <Link href="/profile"> 105 <HiIdentification /> 106 Profile 107 </Link> 108 </DropdownMenuItem> 109 <DropdownMenuItem asChild> 110 <Link href={user.premium ? "/profile/billing" : "/premium"}> 111 <HiSparkles /> 112 {user.premium ? "Billing" : "Premium"} 113 </Link> 114 </DropdownMenuItem> 115 </DropdownMenuGroup> 116 <DropdownMenuSeparator /> 117 <DropdownMenuGroup> 118 <DropdownMenuItem asChild> 119 <Link href="/support"> 120 <HiSupport /> 121 Support 122 </Link> 123 </DropdownMenuItem> 124 <DropdownMenuItem asChild> 125 <Link href="/docs/index"> 126 <HiBookOpen /> 127 Documentation 128 </Link> 129 </DropdownMenuItem> 130 <DropdownMenuItem disabled> 131 <HiTerminal /> 132 Developer API 133 </DropdownMenuItem> 134 </DropdownMenuGroup> 135 <DropdownMenuSeparator /> 136 <DropdownMenuGroup> 137 <DropdownMenuItem 138 asChild 139 className="text-red-400" 140 > 141 <Link href="/login?logout=true" prefetch={false}> 142 <HiLogout /> 143 Logout 144 </Link> 145 </DropdownMenuItem> 146 </DropdownMenuGroup> 147 </DropdownMenuContent> 148 </DropdownMenu> 149 ); 150}