'use client'; import { useState, useEffect, useCallback } from 'react'; import { useStorage } from '@/core/storage'; import { v4 as uuid } from 'uuid'; import type { AddressContact, ContactType } from '../types'; const PREFIX = 'contact:'; export interface ContactFilters { search: string; type: ContactType | 'all'; } export function useContacts() { const storage = useStorage('address-book'); const [contacts, setContacts] = useState([]); const [loading, setLoading] = useState(true); const [filters, setFilters] = useState({ search: '', type: 'all' }); const refresh = useCallback(async () => { setLoading(true); const keys = await storage.list(); const results: AddressContact[] = []; for (const key of keys) { if (key.startsWith(PREFIX)) { const item = await storage.get(key); if (item) results.push(item); } } results.sort((a, b) => a.name.localeCompare(b.name)); setContacts(results); setLoading(false); }, [storage]); // eslint-disable-next-line react-hooks/set-state-in-effect useEffect(() => { refresh(); }, [refresh]); const addContact = useCallback(async (data: Omit) => { const now = new Date().toISOString(); const contact: AddressContact = { ...data, id: uuid(), createdAt: now, updatedAt: now }; await storage.set(`${PREFIX}${contact.id}`, contact); await refresh(); return contact; }, [storage, refresh]); const updateContact = useCallback(async (id: string, updates: Partial) => { const existing = contacts.find((c) => c.id === id); if (!existing) return; const updated: AddressContact = { ...existing, ...updates, id: existing.id, createdAt: existing.createdAt, updatedAt: new Date().toISOString(), }; await storage.set(`${PREFIX}${id}`, updated); await refresh(); }, [storage, refresh, contacts]); const removeContact = useCallback(async (id: string) => { await storage.delete(`${PREFIX}${id}`); await refresh(); }, [storage, refresh]); const updateFilter = useCallback((key: K, value: ContactFilters[K]) => { setFilters((prev) => ({ ...prev, [key]: value })); }, []); const filteredContacts = contacts.filter((c) => { if (filters.type !== 'all' && c.type !== filters.type) return false; if (filters.search) { const q = filters.search.toLowerCase(); return ( c.name.toLowerCase().includes(q) || c.company.toLowerCase().includes(q) || c.email.toLowerCase().includes(q) || c.phone.includes(q) || (c.department ?? '').toLowerCase().includes(q) || (c.role ?? '').toLowerCase().includes(q) ); } return true; }); return { contacts: filteredContacts, allContacts: contacts, loading, filters, updateFilter, addContact, updateContact, removeContact, refresh }; }