Highly ambitious ATProtocol AppView service and sdks
at fix-postgres 128 lines 5.6 kB view raw
1import type { AuthenticatedUser } from "../../routes/middleware.ts"; 2import { Button } from "./Button.tsx"; 3import { Logo } from "./Logo.tsx"; 4 5interface NavigationProps { 6 currentUser?: AuthenticatedUser; 7} 8 9export function Navigation({ currentUser }: NavigationProps) { 10 return ( 11 <nav className="sm:fixed sm:top-0 sm:left-0 sm:right-0 h-14 z-50 bg-zinc-50 dark:bg-zinc-950 border-b border-zinc-200 dark:border-zinc-800"> 12 <div className="mx-auto max-w-5xl h-full flex items-center justify-between px-4"> 13 <div className="flex items-center space-x-4"> 14 <a 15 href="/" 16 className="flex items-center space-x-2 text-xl font-bold text-zinc-900 dark:text-white hover:text-zinc-700 dark:hover:text-zinc-300" 17 > 18 <Logo className="w-8 h-8" /> 19 <span>Slices</span> 20 </a> 21 {currentUser?.isAuthenticated && ( 22 <a 23 href="/docs" 24 className="px-3 py-1.5 text-sm text-zinc-600 dark:text-zinc-400 hover:text-zinc-900 dark:hover:text-white hover:bg-zinc-100 dark:hover:bg-zinc-800 rounded-md transition-colors" 25 > 26 Docs 27 </a> 28 )} 29 </div> 30 <div className="flex items-center space-x-2"> 31 {currentUser?.isAuthenticated 32 ? ( 33 <div className="flex items-center space-x-2"> 34 <a 35 href={`/profile/${currentUser.handle}`} 36 className="px-3 py-1.5 text-sm text-zinc-600 dark:text-zinc-400 hover:text-zinc-900 dark:hover:text-white hover:bg-zinc-100 dark:hover:bg-zinc-800 rounded-md transition-colors" 37 > 38 Dashboard 39 </a> 40 <div className="relative"> 41 <button 42 type="button" 43 className="flex items-center p-1 rounded-full hover:bg-zinc-100 dark:hover:bg-zinc-800 transition-colors" 44 /* @ts-ignore - Hyperscript attribute */ 45 _="on click toggle .hidden on #avatar-dropdown 46 on click from document 47 if not me.contains(event.target) and not #avatar-dropdown.contains(event.target) 48 add .hidden to #avatar-dropdown" 49 > 50 {currentUser.avatar 51 ? ( 52 <img 53 src={currentUser.avatar} 54 alt="Profile avatar" 55 className="w-8 h-8 rounded-full" 56 /> 57 ) 58 : ( 59 <div className="w-8 h-8 bg-zinc-300 dark:bg-zinc-700 rounded-full flex items-center justify-center"> 60 <span className="text-sm text-zinc-600 dark:text-zinc-300 font-medium"> 61 {currentUser.handle?.charAt(0) 62 .toUpperCase() || "U"} 63 </span> 64 </div> 65 )} 66 </button> 67 68 <div 69 id="avatar-dropdown" 70 className="hidden absolute right-0 mt-2 w-64 bg-white dark:bg-zinc-900 border border-zinc-200 dark:border-zinc-800 rounded-md shadow-lg z-50" 71 > 72 <div className="py-1"> 73 <div className="px-4 py-3 border-b border-zinc-100 dark:border-zinc-800"> 74 <div className="text-sm font-medium text-zinc-900 dark:text-white"> 75 {currentUser.displayName || 76 currentUser.handle || "User"} 77 </div> 78 <div className="text-sm text-zinc-500 dark:text-zinc-400"> 79 {currentUser.handle 80 ? `@${currentUser.handle}` 81 : ""} 82 </div> 83 </div> 84 <a 85 href="/settings" 86 className="block px-4 py-2 text-sm text-zinc-700 dark:text-zinc-300 hover:bg-zinc-100 dark:hover:bg-zinc-800 transition-colors" 87 > 88 Settings 89 </a> 90 <form 91 method="post" 92 action="/logout" 93 className="block" 94 > 95 <button 96 type="submit" 97 className="w-full text-left px-4 py-2 text-sm text-zinc-700 dark:text-zinc-300 hover:bg-zinc-100 dark:hover:bg-zinc-800 transition-colors" 98 > 99 Sign out 100 </button> 101 </form> 102 </div> 103 </div> 104 </div> 105 </div> 106 ) 107 : ( 108 <div className="flex items-center space-x-2"> 109 <a 110 href="/waitlist" 111 className="px-3 py-1.5 text-sm text-zinc-600 dark:text-zinc-400 hover:text-zinc-900 dark:hover:text-white hover:bg-zinc-100 dark:hover:bg-zinc-800 rounded-md transition-colors" 112 > 113 Join Waitlist 114 </a> 115 <Button 116 href="/login" 117 variant="blue" 118 size="md" 119 > 120 Sign in 121 </Button> 122 </div> 123 )} 124 </div> 125 </div> 126 </nav> 127 ); 128}