mirror of
https://github.com/MODSetter/SurfSense.git
synced 2026-05-29 19:35:20 +02:00
show user avatar in sidebar when available
This commit is contained in:
parent
3ad2dbeeaf
commit
9d3c6f0ee1
4 changed files with 40 additions and 26 deletions
|
|
@ -354,7 +354,11 @@ export function LayoutDataProvider({
|
||||||
onChatDelete={handleChatDelete}
|
onChatDelete={handleChatDelete}
|
||||||
onViewAllSharedChats={handleViewAllSharedChats}
|
onViewAllSharedChats={handleViewAllSharedChats}
|
||||||
onViewAllPrivateChats={handleViewAllPrivateChats}
|
onViewAllPrivateChats={handleViewAllPrivateChats}
|
||||||
user={{ email: user?.email || "", name: user?.email?.split("@")[0] }}
|
user={{
|
||||||
|
email: user?.email || "",
|
||||||
|
name: user?.display_name || user?.email?.split("@")[0],
|
||||||
|
avatarUrl: user?.avatar_url || undefined,
|
||||||
|
}}
|
||||||
onSettings={handleSettings}
|
onSettings={handleSettings}
|
||||||
onManageMembers={handleManageMembers}
|
onManageMembers={handleManageMembers}
|
||||||
onUserSettings={handleUserSettings}
|
onUserSettings={handleUserSettings}
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ export interface SearchSpace {
|
||||||
export interface User {
|
export interface User {
|
||||||
email: string;
|
email: string;
|
||||||
name?: string;
|
name?: string;
|
||||||
|
avatarUrl?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface NavItem {
|
export interface NavItem {
|
||||||
|
|
|
||||||
|
|
@ -61,6 +61,34 @@ function getInitials(email: string): string {
|
||||||
return name.slice(0, 2).toUpperCase();
|
return name.slice(0, 2).toUpperCase();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* User avatar component - shows image if available, otherwise falls back to initials
|
||||||
|
*/
|
||||||
|
function UserAvatar({
|
||||||
|
avatarUrl,
|
||||||
|
initials,
|
||||||
|
bgColor,
|
||||||
|
}: {
|
||||||
|
avatarUrl?: string;
|
||||||
|
initials: string;
|
||||||
|
bgColor: string;
|
||||||
|
}) {
|
||||||
|
if (avatarUrl) {
|
||||||
|
return (
|
||||||
|
<img src={avatarUrl} alt="User avatar" className="h-8 w-8 shrink-0 rounded-lg object-cover" />
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className="flex h-8 w-8 shrink-0 items-center justify-center rounded-lg text-xs font-semibold text-white"
|
||||||
|
style={{ backgroundColor: bgColor }}
|
||||||
|
>
|
||||||
|
{initials}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
export function SidebarUserProfile({
|
export function SidebarUserProfile({
|
||||||
user,
|
user,
|
||||||
onUserSettings,
|
onUserSettings,
|
||||||
|
|
@ -88,12 +116,7 @@ export function SidebarUserProfile({
|
||||||
"focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring"
|
"focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring"
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<div
|
<UserAvatar avatarUrl={user.avatarUrl} initials={initials} bgColor={bgColor} />
|
||||||
className="flex h-8 w-8 items-center justify-center rounded-lg text-xs font-semibold text-white"
|
|
||||||
style={{ backgroundColor: bgColor }}
|
|
||||||
>
|
|
||||||
{initials}
|
|
||||||
</div>
|
|
||||||
<span className="sr-only">{displayName}</span>
|
<span className="sr-only">{displayName}</span>
|
||||||
</button>
|
</button>
|
||||||
</DropdownMenuTrigger>
|
</DropdownMenuTrigger>
|
||||||
|
|
@ -104,12 +127,7 @@ export function SidebarUserProfile({
|
||||||
<DropdownMenuContent className="w-56" side="right" align="end" sideOffset={8}>
|
<DropdownMenuContent className="w-56" side="right" align="end" sideOffset={8}>
|
||||||
<DropdownMenuLabel className="font-normal">
|
<DropdownMenuLabel className="font-normal">
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<div
|
<UserAvatar avatarUrl={user.avatarUrl} initials={initials} bgColor={bgColor} />
|
||||||
className="flex h-8 w-8 shrink-0 items-center justify-center rounded-lg text-xs font-semibold text-white"
|
|
||||||
style={{ backgroundColor: bgColor }}
|
|
||||||
>
|
|
||||||
{initials}
|
|
||||||
</div>
|
|
||||||
<div className="flex-1 min-w-0">
|
<div className="flex-1 min-w-0">
|
||||||
<p className="truncate text-sm font-medium">{displayName}</p>
|
<p className="truncate text-sm font-medium">{displayName}</p>
|
||||||
<p className="truncate text-xs text-muted-foreground">{user.email}</p>
|
<p className="truncate text-xs text-muted-foreground">{user.email}</p>
|
||||||
|
|
@ -149,13 +167,7 @@ export function SidebarUserProfile({
|
||||||
"focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring"
|
"focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring"
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
{/* Avatar */}
|
<UserAvatar avatarUrl={user.avatarUrl} initials={initials} bgColor={bgColor} />
|
||||||
<div
|
|
||||||
className="flex h-8 w-8 shrink-0 items-center justify-center rounded-lg text-xs font-semibold text-white"
|
|
||||||
style={{ backgroundColor: bgColor }}
|
|
||||||
>
|
|
||||||
{initials}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Name and email */}
|
{/* Name and email */}
|
||||||
<div className="flex-1 min-w-0">
|
<div className="flex-1 min-w-0">
|
||||||
|
|
@ -171,12 +183,7 @@ export function SidebarUserProfile({
|
||||||
<DropdownMenuContent className="w-56" side="top" align="start" sideOffset={4}>
|
<DropdownMenuContent className="w-56" side="top" align="start" sideOffset={4}>
|
||||||
<DropdownMenuLabel className="font-normal">
|
<DropdownMenuLabel className="font-normal">
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<div
|
<UserAvatar avatarUrl={user.avatarUrl} initials={initials} bgColor={bgColor} />
|
||||||
className="flex h-8 w-8 shrink-0 items-center justify-center rounded-lg text-xs font-semibold text-white"
|
|
||||||
style={{ backgroundColor: bgColor }}
|
|
||||||
>
|
|
||||||
{initials}
|
|
||||||
</div>
|
|
||||||
<div className="flex-1 min-w-0">
|
<div className="flex-1 min-w-0">
|
||||||
<p className="truncate text-sm font-medium">{displayName}</p>
|
<p className="truncate text-sm font-medium">{displayName}</p>
|
||||||
<p className="truncate text-xs text-muted-foreground">{user.email}</p>
|
<p className="truncate text-xs text-muted-foreground">{user.email}</p>
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,8 @@ export const user = z.object({
|
||||||
is_verified: z.boolean(),
|
is_verified: z.boolean(),
|
||||||
pages_limit: z.number(),
|
pages_limit: z.number(),
|
||||||
pages_used: z.number(),
|
pages_used: z.number(),
|
||||||
|
display_name: z.string().nullable().optional(),
|
||||||
|
avatar_url: z.string().nullable().optional(),
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue