"use client" import * as React from "react" import Link from "next/link" import { IconCreditCard, IconLogout, IconNotification, IconUserCircle, IconMicrophone, IconMicrophoneOff, IconHeadphones, IconHeadphonesOff, IconSettings, IconChevronUp, } from "@tabler/icons-react" import { logout } from "@/app/actions/profile" import { Avatar, AvatarFallback, AvatarImage, } from "@/components/ui/avatar" import { DropdownMenu, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger, } from "@/components/ui/dropdown-menu" import { SidebarMenu, SidebarMenuButton, SidebarMenuItem, useSidebar, } from "@/components/ui/sidebar" import { Popover, PopoverContent, PopoverTrigger, } from "@/components/ui/popover" import { AccountModal } from "@/components/account-modal" import { DevicePicker } from "@/components/voice/device-picker" import { useVoiceState } from "@/hooks/use-voice-state" import { cn } from "@/lib/utils" import { getInitials } from "@/lib/utils" import type { SidebarUser } from "@/lib/auth" function stopEvent(e: React.MouseEvent | React.PointerEvent): void { e.stopPropagation() e.preventDefault() } export function NavUser({ user, }: { readonly user: SidebarUser | null }): React.ReactElement | null { const { isMobile } = useSidebar() const [accountOpen, setAccountOpen] = React.useState(false) const { isMuted, isDeafened, inputDeviceId, outputDeviceId, inputDevices, outputDevices, toggleMute, toggleDeafen, setInputDevice, setOutputDevice, } = useVoiceState() if (!user) { return null } const initials = getInitials(user.name) async function handleLogout(): Promise { await logout() } return ( {user.avatar && ( )} {initials} {user.name} {/* Voice controls -- replace the old dots icon */}
{ stopEvent(e); toggleMute() }} icon={isMuted ? IconMicrophoneOff : IconMicrophone} label={isMuted ? "Unmute" : "Mute"} dimmed={isMuted} devices={inputDevices} selectedDeviceId={inputDeviceId} onSelectDevice={setInputDevice} deviceLabel="Input Device" /> { stopEvent(e); toggleDeafen() }} icon={isDeafened ? IconHeadphonesOff : IconHeadphones} label={isDeafened ? "Undeafen" : "Deafen"} dimmed={isDeafened} devices={outputDevices} selectedDeviceId={outputDeviceId} onSelectDevice={setOutputDevice} deviceLabel="Output Device" />
{user.avatar && ( )} {initials}
{user.name} {user.email}
setAccountOpen(true)}> Account Billing Notifications Log out
) } /** * Tight icon+chevron pair: toggle button and device picker * as one visual group to save horizontal space. */ function DeviceButtonGroup({ onToggle, icon: Icon, label, dimmed, devices, selectedDeviceId, onSelectDevice, deviceLabel, }: { readonly isMuted: boolean readonly onToggle: (e: React.MouseEvent) => void readonly icon: React.ComponentType<{ className?: string }> readonly label: string readonly dimmed: boolean readonly devices: MediaDeviceInfo[] readonly selectedDeviceId: string | undefined readonly onSelectDevice: (deviceId: string) => void readonly deviceLabel: string }): React.ReactElement { return (
) }