import { Link, useNavigate } from "@tanstack/react-router"; import { useQueryClient } from "@tanstack/react-query"; import { useEffect, useRef, useState } from "react"; import { IoDesktopOutline, IoLogOutOutline, IoMoonOutline, IoSettingsOutline, IoSunnyOutline, } from "react-icons/io5"; import type { SessionUser } from "@/lib/api"; import type { Theme } from "@/lib/theme"; import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"; import { api } from "@/lib/api"; import { useTheme } from "@/lib/theme"; import { cn } from "@/lib/utils"; const THEME_OPTIONS: Array<{ value: Theme; label: string; icon: typeof IoSunnyOutline }> = [ { value: "light", label: "Light", icon: IoSunnyOutline }, { value: "dark", label: "Dark", icon: IoMoonOutline }, { value: "system", label: "System", icon: IoDesktopOutline }, ]; interface SidebarUserMenuProps { user: SessionUser; showSettingsLink?: boolean; } export function SidebarUserMenu({ user, showSettingsLink = false }: SidebarUserMenuProps) { const qc = useQueryClient(); const navigate = useNavigate(); const { theme, setTheme } = useTheme(); const [open, setOpen] = useState(false); const ref = useRef(null); useEffect(() => { if (!open) return; const onClickOutside = (e: MouseEvent) => { if (ref.current && !ref.current.contains(e.target as Node)) setOpen(false); }; const onKey = (e: KeyboardEvent) => { if (e.key === "Escape") setOpen(false); }; document.addEventListener("mousedown", onClickOutside); document.addEventListener("keydown", onKey); return () => { document.removeEventListener("mousedown", onClickOutside); document.removeEventListener("keydown", onKey); }; }, [open]); const onLogout = async () => { setOpen(false); await api.logout(); qc.setQueryData(["session"], null); navigate({ to: "/login" }); }; const initials = (user.login || "?").slice(0, 2).toUpperCase(); return (
{open && (
Theme
{THEME_OPTIONS.map((option) => { const Icon = option.icon; const active = theme === option.value; return ( ); })}
{showSettingsLink && ( setOpen(false)} className="flex w-full items-center gap-2 rounded-sm px-2 py-1.5 text-xs/relaxed hover:bg-muted" > Dashboard settings )}
)}
); }