"use client"; import { Check, ChevronUp, Languages, Laptop, LogOut, Moon, Settings, Sun } from "lucide-react"; import { useTranslations } from "next-intl"; import { useState } from "react"; import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuSeparator, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, } from "@/components/ui/dropdown-menu"; import { Spinner } from "@/components/ui/spinner"; import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip"; import { useLocaleContext } from "@/contexts/LocaleContext"; import { cn } from "@/lib/utils"; import type { User } from "../../types/layout.types"; // Supported languages configuration const LANGUAGES = [ { code: "en" as const, name: "English", flag: "🇺🇸" }, { code: "es" as const, name: "Español", flag: "🇪🇸" }, { code: "pt" as const, name: "Português", flag: "🇧🇷" }, { code: "hi" as const, name: "हिन्दी", flag: "🇮🇳" }, { code: "zh" as const, name: "简体中文", flag: "🇨🇳" }, ]; // Supported themes configuration const THEMES = [ { value: "light" as const, name: "Light", icon: Sun }, { value: "dark" as const, name: "Dark", icon: Moon }, { value: "system" as const, name: "System", icon: Laptop }, ]; interface SidebarUserProfileProps { user: User; onUserSettings?: () => void; onLogout?: () => void; isCollapsed?: boolean; theme?: string; setTheme?: (theme: "light" | "dark" | "system") => void; } /** * Generates a consistent color based on email */ function stringToColor(str: string): string { let hash = 0; for (let i = 0; i < str.length; i++) { hash = str.charCodeAt(i) + ((hash << 5) - hash); } const colors = [ "#6366f1", "#8b5cf6", "#a855f7", "#d946ef", "#ec4899", "#f43f5e", "#ef4444", "#f97316", "#eab308", "#84cc16", "#22c55e", "#14b8a6", "#06b6d4", "#0ea5e9", "#3b82f6", ]; return colors[Math.abs(hash) % colors.length]; } /** * Gets initials from email */ function getInitials(email: string): string { const name = email.split("@")[0]; const parts = name.split(/[._-]/); if (parts.length >= 2) { return (parts[0][0] + parts[1][0]).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 ( User avatar ); } return (
{initials}
); } export function SidebarUserProfile({ user, onUserSettings, onLogout, isCollapsed = false, theme, setTheme, }: SidebarUserProfileProps) { const t = useTranslations("sidebar"); const { locale, setLocale } = useLocaleContext(); const [isLoggingOut, setIsLoggingOut] = useState(false); const bgColor = stringToColor(user.email); const initials = getInitials(user.email); const displayName = user.name || user.email.split("@")[0]; const handleLanguageChange = (newLocale: "en" | "es" | "pt" | "hi" | "zh") => { setLocale(newLocale); }; const handleThemeChange = (newTheme: "light" | "dark" | "system") => { setTheme?.(newTheme); }; const handleLogout = async () => { if (isLoggingOut || !onLogout) return; setIsLoggingOut(true); try { await onLogout(); } finally { setIsLoggingOut(false); } }; // Collapsed view - just show avatar with dropdown if (isCollapsed) { return (
{displayName}

{displayName}

{user.email}

{t("user_settings")} {setTheme && ( {t("theme")} {THEMES.map((themeOption) => { const Icon = themeOption.icon; const isSelected = theme === themeOption.value; return ( handleThemeChange(themeOption.value)} className={cn( "mb-1 last:mb-0 transition-all", "hover:bg-accent/50", isSelected && "text-primary" )} > {t(themeOption.value)} {isSelected && } ); })} )} {t("language")} {LANGUAGES.map((language) => { const isSelected = locale === language.code; return ( handleLanguageChange(language.code)} className={cn( "mb-1 last:mb-0 transition-all", "hover:bg-accent/50", isSelected && "text-primary" )} > {language.flag} {language.name} {isSelected && } ); })} {isLoggingOut ? ( ) : ( )} {isLoggingOut ? t("loggingOut") : t("logout")}
); } // Expanded view return (

{displayName}

{user.email}

{t("user_settings")} {setTheme && ( {t("theme")} {THEMES.map((themeOption) => { const Icon = themeOption.icon; const isSelected = theme === themeOption.value; return ( handleThemeChange(themeOption.value)} className={cn( "mb-1 last:mb-0 transition-all", "hover:bg-accent/50", isSelected && "text-primary" )} > {t(themeOption.value)} {isSelected && } ); })} )} {t("language")} {LANGUAGES.map((language) => { const isSelected = locale === language.code; return ( handleLanguageChange(language.code)} className={cn( "mb-1 last:mb-0 transition-all", "hover:bg-accent/50", isSelected && "text-primary" )} > {language.flag} {language.name} {isSelected && } ); })} {isLoggingOut ? : } {isLoggingOut ? t("loggingOut") : t("logout")}
); }