-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathuser-settings-bar.tsx
130 lines (116 loc) · 3.52 KB
/
user-settings-bar.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
'use client';
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu';
import PullModel from './pull-model';
import {
AvatarFallback,
AvatarImage,
SmallAvatar,
} from '@/components/ui/avatar';
import { GearIcon } from '@radix-ui/react-icons';
import { Button } from '@/components/ui/button';
import { useRouter } from 'next/navigation';
import { useMemo, useState, memo, useEffect } from 'react';
import { EventEnum } from '../const/EventEnum';
import { useAuthContext } from '@/providers/AuthProvider';
import { LogOut } from 'lucide-react';
import { normalizeAvatarUrl } from './avatar-uploader';
interface UserSettingsProps {
isSimple: boolean;
}
/**
* UserSettingsBar component for managing user settings and actions.
*
* @param param0 - Props for UserSettings, including isSimple flag.
* @returns UserSettings JSX element.
*/
export const UserSettingsBar = ({ isSimple }: UserSettingsProps) => {
const { user, isLoading, logout } = useAuthContext();
const [open, setOpen] = useState(false);
const router = useRouter();
const handleLogout = useMemo(() => {
return () => {
router.push('/');
// router.push('/login');
logout();
};
}, [logout, router]);
const avatarFallback = useMemo(() => {
if (!user?.username) return 'US';
return user.username.substring(0, 2).toUpperCase();
}, [user?.username]);
const displayUsername = useMemo(() => {
if (isLoading) return 'Loading...';
return user?.username || 'Anonymous';
}, [isLoading, user?.username]);
// Normalize the avatar URL
const normalizedAvatarUrl = useMemo(() => {
return normalizeAvatarUrl(user?.avatarUrl);
}, [user?.avatarUrl]);
const handleSettingsClick = () => {
// First navigate using Next.js router
router.push('/settings');
// Then dispatch the event
setTimeout(() => {
const event = new Event(EventEnum.SETTING);
window.dispatchEvent(event);
}, 0);
};
const avatarButton = useMemo(() => {
return (
<Button
size="setting"
variant="ghost"
className={`flex justify-start ${
isSimple ? 'w-10 h-12 p-auto' : 'gap-2 w-full h-12 p-1'
}`}
>
<SmallAvatar className="flex items-center justify-center">
{/* Use normalized avatar URL */}
<AvatarImage
src={normalizedAvatarUrl}
alt="User"
key={user?.avatarUrl}
/>
<AvatarFallback>{avatarFallback}</AvatarFallback>
</SmallAvatar>
</Button>
);
}, [
avatarFallback,
displayUsername,
isSimple,
normalizedAvatarUrl,
user?.avatarUrl,
]);
return (
<DropdownMenu>
<DropdownMenuTrigger asChild>{avatarButton}</DropdownMenuTrigger>
<DropdownMenuContent className="w-60">
<DropdownMenuItem onSelect={(e) => e.preventDefault()}>
<div
className="flex w-full gap-2 p-1 items-center cursor-pointer"
onClick={handleSettingsClick}
>
<GearIcon className="w-4 h-4" />
Settings
</div>
</DropdownMenuItem>
<DropdownMenuItem className="">
<div
className="flex w-full gap-2 p-1 items-center cursor-pointer"
onClick={handleLogout}
>
<LogOut className="w-4 h-4" strokeWidth={1.4} />
<span>Logout</span>
</div>
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
);
};
export default memo(UserSettingsBar);