1
1
'use client' ;
2
+
2
3
import { ChevronUp } from 'lucide-react' ;
3
4
import Image from 'next/image' ;
4
5
import type { User } from 'next-auth' ;
5
- import { signOut } from 'next-auth/react' ;
6
+ import { signOut , useSession } from 'next-auth/react' ;
6
7
import { useTheme } from 'next-themes' ;
7
8
8
9
import {
@@ -17,26 +18,50 @@ import {
17
18
SidebarMenuButton ,
18
19
SidebarMenuItem ,
19
20
} from '@/components/ui/sidebar' ;
21
+ import { anonymousRegex } from '@/lib/constants' ;
22
+ import { useRouter } from 'next/navigation' ;
23
+ import { toast } from './toast' ;
24
+ import { LoaderIcon } from './icons' ;
20
25
21
26
export function SidebarUserNav ( { user } : { user : User } ) {
27
+ const router = useRouter ( ) ;
28
+ const { data, status } = useSession ( ) ;
22
29
const { setTheme, theme } = useTheme ( ) ;
23
30
31
+ const isGuest = anonymousRegex . test ( data ?. user ?. email ?? '' ) ;
32
+
24
33
return (
25
34
< SidebarMenu >
26
35
< SidebarMenuItem >
27
36
< DropdownMenu >
28
37
< DropdownMenuTrigger asChild >
29
- < SidebarMenuButton className = "data-[state=open]:bg-sidebar-accent bg-background data-[state=open]:text-sidebar-accent-foreground h-10" >
30
- < Image
31
- src = { `https://avatar.vercel.sh/${ user . email } ` }
32
- alt = { user . email ?? 'User Avatar' }
33
- width = { 24 }
34
- height = { 24 }
35
- className = "rounded-full"
36
- />
37
- < span className = "truncate" > { user ?. email } </ span >
38
- < ChevronUp className = "ml-auto" />
39
- </ SidebarMenuButton >
38
+ { status === 'loading' ? (
39
+ < SidebarMenuButton className = "data-[state=open]:bg-sidebar-accent bg-background data-[state=open]:text-sidebar-accent-foreground h-10 justify-between" >
40
+ < div className = "flex flex-row gap-2" >
41
+ < div className = "size-6 bg-zinc-500/30 rounded-full animate-pulse" />
42
+ < span className = "bg-zinc-500/30 text-transparent rounded-md animate-pulse" >
43
+ Loading auth status
44
+ </ span >
45
+ </ div >
46
+ < div className = "animate-spin text-zinc-500/30" >
47
+ < LoaderIcon />
48
+ </ div >
49
+ </ SidebarMenuButton >
50
+ ) : (
51
+ < SidebarMenuButton className = "data-[state=open]:bg-sidebar-accent bg-background data-[state=open]:text-sidebar-accent-foreground h-10" >
52
+ < Image
53
+ src = { `https://avatar.vercel.sh/${ user . email } ` }
54
+ alt = { user . email ?? 'User Avatar' }
55
+ width = { 24 }
56
+ height = { 24 }
57
+ className = "rounded-full"
58
+ />
59
+ < span className = "truncate" >
60
+ { isGuest ? 'Guest' : user ?. email }
61
+ </ span >
62
+ < ChevronUp className = "ml-auto" />
63
+ </ SidebarMenuButton >
64
+ ) }
40
65
</ DropdownMenuTrigger >
41
66
< DropdownMenuContent
42
67
side = "top"
@@ -54,12 +79,26 @@ export function SidebarUserNav({ user }: { user: User }) {
54
79
type = "button"
55
80
className = "w-full cursor-pointer"
56
81
onClick = { ( ) => {
57
- signOut ( {
58
- redirectTo : '/' ,
59
- } ) ;
82
+ if ( status === 'loading' ) {
83
+ toast ( {
84
+ type : 'error' ,
85
+ description :
86
+ 'Checking authentication status, please try again!' ,
87
+ } ) ;
88
+
89
+ return ;
90
+ }
91
+
92
+ if ( isGuest ) {
93
+ router . push ( '/login' ) ;
94
+ } else {
95
+ signOut ( {
96
+ redirectTo : '/' ,
97
+ } ) ;
98
+ }
60
99
} }
61
100
>
62
- Sign out
101
+ { isGuest ? 'Login to your account' : ' Sign out' }
63
102
</ button >
64
103
</ DropdownMenuItem >
65
104
</ DropdownMenuContent >
0 commit comments