Skip to content

Commit 28b83b6

Browse files
committed
Fix nav to work with ssg agent store (but also introduce on-load jump)
1 parent 877b451 commit 28b83b6

File tree

2 files changed

+145
-59
lines changed

2 files changed

+145
-59
lines changed
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
'use client'
2+
3+
import { useSession } from 'next-auth/react'
4+
import Link from 'next/link'
5+
import { LogIn, BarChart2 } from 'lucide-react'
6+
import { UserDropdown } from './user-dropdown'
7+
import { Button } from '../ui/button'
8+
import { cn } from '@/lib/utils'
9+
import { DropdownMenuItem } from '../ui/dropdown-menu'
10+
11+
interface ClientAuthNavProps {
12+
className?: string
13+
isMobile?: boolean
14+
}
15+
16+
export function ClientAuthNav({
17+
className,
18+
isMobile = false,
19+
}: ClientAuthNavProps) {
20+
const { data: session, status } = useSession()
21+
22+
// Server container handles spacing, no need for placeholder here
23+
if (status === 'loading') {
24+
return null
25+
}
26+
27+
if (isMobile) {
28+
// Mobile dropdown item
29+
if (!session) {
30+
return (
31+
<DropdownMenuItem asChild>
32+
<Link href="/login" className="flex items-center">
33+
<LogIn className="mr-2 h-4 w-4" />
34+
Log in
35+
</Link>
36+
</DropdownMenuItem>
37+
)
38+
}
39+
return null // Usage link is handled separately in mobile menu
40+
}
41+
42+
// Desktop version
43+
if (session) {
44+
return <UserDropdown session={session} />
45+
}
46+
47+
return (
48+
<Link href="/login" className="relative group">
49+
<div className="absolute inset-0 bg-[rgb(255,110,11)] translate-x-0.5 -translate-y-0.5" />
50+
<Button
51+
className={cn(
52+
'relative',
53+
'bg-white text-black hover:bg-white',
54+
'border border-white/50',
55+
'transition-all duration-300',
56+
'group-hover:-translate-x-0.5 group-hover:translate-y-0.5'
57+
)}
58+
>
59+
Log in
60+
</Button>
61+
</Link>
62+
)
63+
}
64+
65+
export function ClientUsageLink() {
66+
const { data: session, status } = useSession()
67+
68+
// Server container handles spacing, just return null when not logged in
69+
if (!session) {
70+
return null
71+
}
72+
73+
return (
74+
<Link
75+
href="/usage"
76+
className="hover:text-blue-400 transition-colors font-medium px-2 py-1 rounded-md hover:bg-blue-50 dark:hover:bg-blue-900/20"
77+
>
78+
Usage
79+
</Link>
80+
)
81+
}
82+
83+
export function ClientMobileUsageLink() {
84+
const { data: session } = useSession()
85+
86+
if (!session) return null
87+
88+
return (
89+
<DropdownMenuItem asChild>
90+
<Link href="/usage" className="flex items-center">
91+
<BarChart2 className="mr-2 h-4 w-4" />
92+
Usage
93+
</Link>
94+
</DropdownMenuItem>
95+
)
96+
}

web/src/components/navbar/navbar.tsx

Lines changed: 49 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,8 @@
1-
import {
2-
Menu,
3-
DollarSign,
4-
LogIn,
5-
BarChart2,
6-
BookHeart,
7-
User,
8-
Bot,
9-
} from 'lucide-react'
1+
import { Menu, DollarSign, BookHeart, Bot } from 'lucide-react'
102
import Image from 'next/image'
113
import Link from 'next/link'
12-
import { getServerSession } from 'next-auth'
4+
import dynamic from 'next/dynamic'
135

14-
import { UserDropdown } from './user-dropdown'
156
import { Button } from '../ui/button'
167
import {
178
DropdownMenu,
@@ -21,12 +12,47 @@ import {
2112
} from '../ui/dropdown-menu'
2213
import { Icons } from '../icons'
2314

24-
import { authOptions } from '@/app/api/auth/[...nextauth]/auth-options'
25-
import { cn } from '@/lib/utils'
15+
// TODO: This dynamic pattern might not be the best way to handle the navbar. Reconsider from first principles.
16+
17+
// Dynamically import client auth components to prevent SSR and enable SSG
18+
const ClientAuthNav = dynamic(
19+
() =>
20+
import('./client-auth-nav').then((mod) => ({ default: mod.ClientAuthNav })),
21+
{
22+
ssr: false,
23+
loading: () => <div className="w-[50px] h-[40px]" />, // Placeholder to prevent layout shift
24+
}
25+
)
26+
27+
const ClientUsageLink = dynamic(
28+
() =>
29+
import('./client-auth-nav').then((mod) => ({
30+
default: mod.ClientUsageLink,
31+
})),
32+
{
33+
ssr: false,
34+
}
35+
)
36+
37+
const ClientMobileUsageLink = dynamic(
38+
() =>
39+
import('./client-auth-nav').then((mod) => ({
40+
default: mod.ClientMobileUsageLink,
41+
})),
42+
{
43+
ssr: false,
44+
}
45+
)
2646

27-
export const Navbar = async () => {
28-
const session = await getServerSession(authOptions)
47+
const ClientMobileAuthNav = dynamic(
48+
() =>
49+
import('./client-auth-nav').then((mod) => ({ default: mod.ClientAuthNav })),
50+
{
51+
ssr: false,
52+
}
53+
)
2954

55+
export const Navbar = () => {
3056
return (
3157
<header className="container mx-auto p-4 flex justify-between items-center relative z-10">
3258
<Link
@@ -71,15 +97,9 @@ export const Navbar = async () => {
7197
<Bot className="h-4 w-4" />
7298
Agent Store
7399
</Link>
74-
75-
{session && (
76-
<Link
77-
href="/usage"
78-
className="hover:text-blue-400 transition-colors font-medium px-2 py-1 rounded-md hover:bg-blue-50 dark:hover:bg-blue-900/20"
79-
>
80-
Usage
81-
</Link>
82-
)}
100+
<div className="min-w-[50px] flex items-center">
101+
<ClientUsageLink />
102+
</div>
83103
</nav>
84104
<div className="flex items-center space-x-3">
85105
<DropdownMenu>
@@ -119,43 +139,13 @@ export const Navbar = async () => {
119139
Agent Store
120140
</Link>
121141
</DropdownMenuItem>
122-
123-
{session && (
124-
<DropdownMenuItem asChild>
125-
<Link href="/usage" className="flex items-center">
126-
<BarChart2 className="mr-2 h-4 w-4" />
127-
Usage
128-
</Link>
129-
</DropdownMenuItem>
130-
)}
131-
{!session && (
132-
<DropdownMenuItem asChild>
133-
<Link href="/login" className="flex items-center">
134-
<LogIn className="mr-2 h-4 w-4" />
135-
Log in
136-
</Link>
137-
</DropdownMenuItem>
138-
)}
142+
<ClientMobileUsageLink />
143+
<ClientMobileAuthNav isMobile />
139144
</DropdownMenuContent>
140145
</DropdownMenu>
141-
{session ? (
142-
<UserDropdown session={session} />
143-
) : (
144-
<Link href="/login" className="hidden md:inline-block relative group">
145-
<div className="absolute inset-0 bg-[rgb(255,110,11)] translate-x-0.5 -translate-y-0.5" />
146-
<Button
147-
className={cn(
148-
'relative',
149-
'bg-white text-black hover:bg-white',
150-
'border border-white/50',
151-
'transition-all duration-300',
152-
'group-hover:-translate-x-0.5 group-hover:translate-y-0.5'
153-
)}
154-
>
155-
Log in
156-
</Button>
157-
</Link>
158-
)}
146+
<div className="min-w-[50px] h-[44px] flex items-center justify-end -ml-3">
147+
<ClientAuthNav />
148+
</div>
159149
{/* <ThemeSwitcher /> */}
160150
</div>
161151
</header>

0 commit comments

Comments
 (0)