import { useState, useEffect } from 'react'; import { useNavigate } from 'react-router-dom'; import { Modal } from '../../components/Modal'; import { useContacts, useDeleteContact } from '../hooks'; import { ContactFormModal } from './ContactFormModal'; import type { Contact, ContactType, ContactsQueryParams } from '../types'; import styles from './ContactsPage.module.css'; const TYPE_COLORS: Record = { PERSON: { bg: '#dbeafe', color: '#1e40af' }, ORGANIZATION: { bg: '#d1fae5', color: '#065f46' }, }; const TYPE_LABELS: Record = { PERSON: 'Person', ORGANIZATION: 'Organisation', }; const thStyle: React.CSSProperties = { padding: '0.75rem 1rem', textAlign: 'left', fontSize: '0.75rem', textTransform: 'uppercase', color: 'var(--color-text-muted)', }; function contactDisplayName(c: Contact): string { if (c.type === 'ORGANIZATION') return c.companyName ?? '—'; return [c.firstName, c.lastName].filter(Boolean).join(' ') || '—'; } export function ContactsPage() { const navigate = useNavigate(); const [page, setPage] = useState(1); const [searchInput, setSearchInput] = useState(''); const [search, setSearch] = useState(''); const [typeFilter, setTypeFilter] = useState(''); const [isCreateOpen, setCreateOpen] = useState(false); const [editingContact, setEditingContact] = useState(null); const [deletingContact, setDeletingContact] = useState(null); // Debounced search useEffect(() => { const t = setTimeout(() => { setSearch(searchInput); setPage(1); }, 300); return () => clearTimeout(t); }, [searchInput]); const params: ContactsQueryParams = { page, pageSize: 25, ...(search ? { search } : {}), ...(typeFilter ? { type: typeFilter } : {}), sort: 'createdAt', order: 'desc', }; const { data, isLoading, error } = useContacts(params); const deleteMutation = useDeleteContact(); if (isLoading) return

Laden...

; if (error) return (

Fehler beim Laden der Kontakte

); const contacts = data?.data ?? []; const pagination = data?.pagination; return (
{/* Header */}

Kontakte

{pagination?.total ?? 0} Kontakte gesamt
{/* Filterleiste */}
setSearchInput(e.target.value)} className={styles.searchInput} />
{/* Tabelle */}
{contacts.length === 0 && ( )} {contacts.map((contact) => { const typeStyle = TYPE_COLORS[contact.type]; return ( navigate(`/crm/contacts/${contact.id}`)} > ); })}
Name / Firma Typ E-Mail Telefon Stadt Status Aktionen
Keine Kontakte gefunden
{contactDisplayName(contact)} {TYPE_LABELS[contact.type]} {contact.email ?? '—'} {contact.phone ?? contact.mobile ?? '—'} {contact.city ?? '—'} {contact.isActive ? 'Aktiv' : 'Inaktiv'} e.stopPropagation()} >
{/* Paginierung */} {pagination && pagination.totalPages > 1 && (
Seite {pagination.page} von {pagination.totalPages} ({pagination.total}{' '} Einträge)
)}
{/* Modal: Neuen Kontakt anlegen */} setCreateOpen(false)} onSuccess={() => setCreateOpen(false)} /> {/* Modal: Kontakt bearbeiten */} setEditingContact(null)} contact={editingContact} onSuccess={() => setEditingContact(null)} /> {/* Modal: Kontakt löschen — Bestätigung */} setDeletingContact(null)} title="Kontakt löschen" maxWidth="420px" >

Soll der Kontakt{' '} {deletingContact ? contactDisplayName(deletingContact) : ''} {' '} wirklich gelöscht werden?

Alle Aktivitäten dieses Kontakts werden ebenfalls gelöscht. Deals bleiben erhalten, verlieren aber die Kontaktverknüpfung.

); }