'use client'; import { useState } from 'react'; import { useMutation, useQueryClient } from '@tanstack/react-query'; import { Archive, Mail, MessageCircle, Phone, RotateCcw } from 'lucide-react'; import { format } from 'date-fns'; import { Button } from '@/components/ui/button'; import { Badge } from '@/components/ui/badge'; import { TagBadge } from '@/components/shared/tag-badge'; import { ArchiveConfirmDialog } from '@/components/shared/archive-confirm-dialog'; import { DetailHeaderStrip } from '@/components/shared/detail-header-strip'; import { PortalInviteButton } from '@/components/clients/portal-invite-button'; import { GdprExportButton } from '@/components/clients/gdpr-export-button'; import { apiFetch } from '@/lib/api/client'; import { cn } from '@/lib/utils'; import { getCountryName } from '@/lib/i18n/countries'; interface ClientDetailHeaderProps { client: { id: string; fullName: string; nationalityIso?: string | null; archivedAt?: string | null; createdAt?: string; contacts?: Array<{ channel: string; value: string; valueE164?: string | null; isPrimary: boolean; label?: string | null; }>; tags?: Array<{ id: string; name: string; color: string }>; clientPortalEnabled?: boolean; }; } export function ClientDetailHeader({ client }: ClientDetailHeaderProps) { const queryClient = useQueryClient(); const [archiveOpen, setArchiveOpen] = useState(false); const isArchived = !!client.archivedAt; const archiveMutation = useMutation({ mutationFn: () => apiFetch(`/api/v1/clients/${client.id}`, { method: 'DELETE' }), onSuccess: () => { queryClient.invalidateQueries({ queryKey: ['clients', client.id] }); queryClient.invalidateQueries({ queryKey: ['clients'] }); setArchiveOpen(false); }, }); const restoreMutation = useMutation({ mutationFn: () => apiFetch(`/api/v1/clients/${client.id}/restore`, { method: 'POST' }), onSuccess: () => { queryClient.invalidateQueries({ queryKey: ['clients', client.id] }); queryClient.invalidateQueries({ queryKey: ['clients'] }); setArchiveOpen(false); }, }); const primaryEmail = client.contacts?.find((c) => c.channel === 'email' && c.isPrimary)?.value ?? client.contacts?.find((c) => c.channel === 'email')?.value; const primaryPhoneContact = client.contacts?.find((c) => c.channel === 'phone' && c.isPrimary) ?? client.contacts?.find((c) => c.channel === 'phone'); const primaryPhone = primaryPhoneContact?.value; // wa.me requires the E.164 number without the leading "+". Strip from the // canonical E.164 form when available; otherwise strip non-digits from the // display value as a best-effort fallback. const whatsappNumber = primaryPhoneContact?.valueE164 ? primaryPhoneContact.valueE164.replace(/^\+/, '') : primaryPhoneContact?.value ? primaryPhoneContact.value.replace(/[^\d]/g, '') : null; const country = client.nationalityIso ? getCountryName(client.nationalityIso, 'en') : null; const addedLabel = client.createdAt ? `Added ${format(new Date(client.createdAt), 'MMM d, yyyy')}` : null; const meta = [country, addedLabel].filter(Boolean) as string[]; return ( <>

{client.fullName}

{isArchived && ( Archived )}
{meta.length > 0 ? (

{meta.join(' ยท ')}

) : null}
{primaryEmail ? ( ) : null} {primaryPhone ? ( ) : null} {whatsappNumber ? ( ) : null} {!isArchived && client.clientPortalEnabled !== false ? (
) : null}
{client.tags && client.tags.length > 0 && (
{client.tags.map((tag) => ( ))}
)}
{/* Top-right: archive/restore as a small icon button - destructive action sits out of the primary action flow. */}
{ if (isArchived) { restoreMutation.mutate(); } else { archiveMutation.mutate(); } }} isLoading={archiveMutation.isPending || restoreMutation.isPending} /> ); }