import { useEffect, useMemo, useState } from 'react'; import { BrandMark } from '../../../shared/components/BrandMark'; import { useViewport } from '../../../shared/hooks/useViewport'; import { getCurrentUser, getCurrentUserDisplay } from '../../auth/services/sessionService'; import { listContactProfiles, saveContactProfile } from '../../chat/services/contactProfileService'; import { HomeSidebar } from '../components/HomeSidebar'; import { sidebarItems } from '../services/homeMocks'; const inputStyle = { width: '100%', border: '1px solid var(--color-border)', borderRadius: 14, padding: '0.85rem 0.9rem', background: '#fff', color: 'var(--color-text)', fontWeight: 600, }; function getUserId(user) { const value = user?.databaseId || user?.id; const numeric = Number(value); return Number.isFinite(numeric) ? numeric : null; } function onlyDigits(value) { return String(value || '').replace(/\D/g, ''); } function buildChatId(phone) { const digits = onlyDigits(phone); return digits ? `${digits}@c.us` : ''; } function normalizeContact(contact) { return { chatId: contact.chat_id || buildChatId(contact.phone), name: contact.name || contact.phone || 'Contato sem nome', whatsappPhone: contact.phone || '', callSmsPhone: contact.call_sms_phone || contact.callSmsPhone || '', email: contact.email || '', tag: contact.company || '', note: contact.note || '', updatedAt: contact.updated_at || contact.created_at || null, }; } function emptyDraft() { return { chatId: '', name: '', whatsappPhone: '', callSmsPhone: '', email: '', tag: '', note: '', }; } export function ContactsPanel({ embedded = false }) { const { isDesktop, isMobile } = useViewport(); const currentUser = getCurrentUser(); const currentUserId = getUserId(currentUser); const userDisplay = getCurrentUserDisplay(); const [contacts, setContacts] = useState([]); const [search, setSearch] = useState(''); const [draft, setDraft] = useState(emptyDraft()); const [selectedChatId, setSelectedChatId] = useState(''); const [status, setStatus] = useState(''); const [isLoading, setIsLoading] = useState(false); const [isSaving, setIsSaving] = useState(false); async function loadContacts() { setIsLoading(true); try { const data = await listContactProfiles(); setContacts(Array.isArray(data) ? data.map(normalizeContact) : []); setStatus(''); } catch (error) { setStatus(error.message); } finally { setIsLoading(false); } } useEffect(() => { loadContacts(); }, []); const sidebarWithCount = useMemo( () => sidebarItems.map((item) => (item.id === 'contacts' ? { ...item, count: contacts.length } : item)), [contacts.length], ); const filteredContacts = useMemo(() => { const value = search.trim().toLowerCase(); if (!value) return contacts; return contacts.filter((contact) => `${contact.name} ${contact.whatsappPhone} ${contact.callSmsPhone} ${contact.email} ${contact.tag} ${contact.note}` .toLowerCase() .includes(value), ); }, [contacts, search]); function selectContact(contact) { setSelectedChatId(contact.chatId); setDraft({ ...contact }); setStatus(''); } function startNewContact() { setSelectedChatId(''); setDraft(emptyDraft()); setStatus(''); } async function handleSave(event) { event.preventDefault(); const whatsappPhone = onlyDigits(draft.whatsappPhone); const chatId = selectedChatId || draft.chatId || buildChatId(whatsappPhone); if (!chatId || !whatsappPhone) { setStatus('Informe o número de WhatsApp para salvar o contato.'); return; } setIsSaving(true); try { await saveContactProfile(chatId, { phone: whatsappPhone, whatsappPhone, callSmsPhone: onlyDigits(draft.callSmsPhone), email: draft.email, name: draft.name, company: draft.tag, note: draft.note, userId: currentUserId, }); setStatus('Contato salvo com sucesso.'); await loadContacts(); setSelectedChatId(chatId); setDraft((current) => ({ ...current, chatId, whatsappPhone })); } catch (error) { setStatus(error.message); } finally { setIsSaving(false); } } const content = ( {selectedChatId ? 'Editar contato' : 'Novo contato'} O WhatsApp é usado para vincular o contato à conversa. Nome setDraft((current) => ({ ...current, name: event.target.value }))} style={inputStyle} /> Etiqueta de identificação setDraft((current) => ({ ...current, tag: event.target.value }))} placeholder="Ex: Departamento, vaga ou conta vinculada" style={inputStyle} /> Número WhatsApp setDraft((current) => ({ ...current, whatsappPhone: event.target.value }))} placeholder="5511988267544" style={inputStyle} /> Ligação/SMS setDraft((current) => ({ ...current, callSmsPhone: event.target.value }))} placeholder="5511988267544" style={inputStyle} /> E-mail setDraft((current) => ({ ...current, email: event.target.value }))} placeholder="nome@empresa.com" style={inputStyle} /> Observação setDraft((current) => ({ ...current, note: event.target.value }))} style={{ ...inputStyle, resize: 'vertical', lineHeight: 1.5 }} /> {status ? {status} : null} {isLoading ? Carregando agenda... : null} {isSaving ? 'Salvando...' : 'Salvar contato'} ); if (embedded) { return content; } return ( Contatos Agenda geral com WhatsApp, telefone para ligação/SMS, e-mail, etiqueta e observação. {userDisplay.name} Atendimento omnichannel {userDisplay.initials} {content} ); } export function ContactsPage() { return ; }
Agenda geral com WhatsApp, telefone para ligação/SMS, e-mail, etiqueta e observação.