"use client"; import { useMemo } from "react"; import { useTranslations } from "next-intl"; import { Search, Plus, BookUser, Info, Check, Trash2, Users, Download, X } from "lucide-react"; import { Input } from "@/components/ui/input"; import { Button } from "@/components/ui/button"; import { ContactListItem } from "./contact-list-item"; import { cn } from "@/lib/utils"; import type { ContactCard } from "@/lib/jmap/types"; import { getContactDisplayName } from "@/stores/contact-store"; interface ContactListProps { contacts: ContactCard[]; selectedContactId: string | null; searchQuery: string; onSearchChange: (query: string) => void; onSelectContact: (id: string) => void; onCreateNew: () => void; supportsSync: boolean; className?: string; selectedContactIds: Set; onToggleSelection: (id: string) => void; onSelectAll: (ids: string[]) => void; onClearSelection: () => void; onBulkDelete: () => void; onBulkAddToGroup: () => void; onBulkExport: () => void; } export function ContactList({ contacts, selectedContactId, searchQuery, onSearchChange, onSelectContact, onCreateNew, supportsSync, className, selectedContactIds, onToggleSelection, onSelectAll, onClearSelection, onBulkDelete, onBulkAddToGroup, onBulkExport, }: ContactListProps) { const t = useTranslations("contacts"); const filtered = useMemo(() => { const individuals = contacts.filter(c => c.kind !== "group"); if (!searchQuery) return individuals; const lower = searchQuery.toLowerCase(); return individuals.filter((c) => { const name = getContactDisplayName(c).toLowerCase(); const emails = c.emails ? Object.values(c.emails).map((e) => e.address.toLowerCase()) : []; return ( name.includes(lower) || emails.some((e) => e.includes(lower)) ); }); }, [contacts, searchQuery]); const sorted = useMemo(() => { return [...filtered].sort((a, b) => { const nameA = getContactDisplayName(a).toLowerCase(); const nameB = getContactDisplayName(b).toLowerCase(); return nameA.localeCompare(nameB); }); }, [filtered]); const hasSelection = selectedContactIds.size > 0; const allSelected = sorted.length > 0 && sorted.every(c => selectedContactIds.has(c.id)); return (

{t("title")}

onSearchChange(e.target.value)} className="pl-9" />
{!supportsSync && (
{t("local_mode")}
)}
{hasSelection && (
{t("bulk.selected", { count: selectedContactIds.size })}
)} {sorted.length > 0 && (
)}
{sorted.length === 0 ? (

{searchQuery ? t("empty_search") : t("empty_state")}

) : (
{sorted.map((contact) => (
onSelectContact(contact.id)} />
))}
)}
); }