"use client" import { useMemo, useState } from "react" import { Users, Clock, UserPlus, Merge, Upload, Trash2, Plus, Tag, Menu, ChevronDown, } from "lucide-react" import { Button } from "@/components/ui/button" import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, } from "@/components/ui/dropdown-menu" import { cn } from "@/lib/utils" import { CONTACTS_CREATE_BTN_CLASS, CONTACTS_FIELD_CLASS, CONTACTS_MUTED_TEXT, CONTACTS_NAV_ACTIVE_CLASS, CONTACTS_NAV_ICON_MUTED, CONTACTS_NAV_ITEM_CLASS, CONTACTS_CREATE_BTN_LABEL_CLASS, CONTACTS_SIDEBAR_CLASS, } from "@/lib/contacts-chrome-classes" import { MAIL_SIDEBAR_MENU_SURFACE_CLASS } from "@/lib/mail-chrome-classes" import { useContactsList } from "@/lib/contacts/use-contacts-list" import { useContactsStore } from "@/lib/contacts/contacts-store" import { findDuplicatePairs } from "@/lib/contacts/duplicate-detection" import { useNavStore } from "@/lib/stores/nav-store" import type { ContactsPageView } from "./contacts-app-shell" interface ContactsSidebarProps { open: boolean overlay: boolean onToggle: () => void onClose: () => void currentView: ContactsPageView activeLabelId?: string | null onNavigate: (view: ContactsPageView) => void onHome?: () => void onCreateContact: () => void onBulkCreate?: () => void onSelectLabel?: (id: string) => void } export function ContactsSidebar({ open, overlay, onToggle, onClose, currentView, activeLabelId, onNavigate, onHome, onCreateContact, onBulkCreate, onSelectLabel, }: ContactsSidebarProps) { const { contacts } = useContactsList() const ignoredMergePairs = useContactsStore((s) => s.ignoredMergePairs) const mergeSuggestionCount = useMemo( () => findDuplicatePairs(contacts, new Set(ignoredMergePairs)).length, [contacts, ignoredMergePairs] ) const labelRows = useNavStore((s) => s.labelRows) const addLabelRowFromSidebar = useNavStore((s) => s.addLabelRowFromSidebar) const [labelInput, setLabelInput] = useState("") const [showLabelInput, setShowLabelInput] = useState(false) const labelsByContactCount = useMemo(() => { return labelRows .filter((r) => r.enabled !== false) .map((label) => ({ label, count: contacts.filter((c) => c.labels?.includes(label.id)).length, })) .sort( (a, b) => b.count - a.count || a.label.label.localeCompare(b.label.label, "fr") ) }, [labelRows, contacts]) function handleAddLabel() { const trimmed = labelInput.trim() if (trimmed) { addLabelRowFromSidebar(trimmed) setLabelInput("") setShowLabelInput(false) } } function handleMenuClick() { if (overlay && open) { onClose() } else { onToggle() } } if (!overlay && !open) { return null } return ( ) } function NavItem({ icon, label, count, badge, active, onClick, }: { icon: React.ReactNode label: string count?: number badge?: number active: boolean onClick: () => void }) { return ( {icon} {label} {badge !== undefined && ( {badge} )} {count !== undefined && ( {count} )} ) }