forked from
slices.network/slices
Highly ambitious ATProtocol AppView service and sdks
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}