'use client'; import Link from 'next/link'; import { format } from 'date-fns'; import { MoreHorizontal, Pencil, Archive } from 'lucide-react'; import type { ColumnDef } from '@tanstack/react-table'; import { Button } from '@/components/ui/button'; import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, } from '@/components/ui/dropdown-menu'; import { Badge } from '@/components/ui/badge'; import { getCountryName } from '@/lib/i18n/countries'; export interface ClientRow { id: string; fullName: string; nationalityIso: string | null; source: string | null; archivedAt: string | null; createdAt: string; primaryEmail?: string | null; primaryPhone?: string | null; yachtCount?: number; companyCount?: number; interestCount?: number; latestInterest?: { stage: string; mooringNumber: string | null } | null; tags?: Array<{ id: string; name: string; color: string }>; } const STAGE_LABELS: Record = { open: 'Open', qualified: 'Qualified', eoi_sent: 'EOI sent', eoi_signed: 'EOI signed', deposit: 'Deposit', contract: 'Contract', signed: 'Signed', closed_won: 'Won', closed_lost: 'Lost', }; const SOURCE_LABELS: Record = { website: 'Website', manual: 'Manual', referral: 'Referral', broker: 'Broker', }; interface GetColumnsOptions { portSlug: string; onEdit: (client: ClientRow) => void; onArchive: (client: ClientRow) => void; } export function getClientColumns({ portSlug, onEdit, onArchive, }: GetColumnsOptions): ColumnDef[] { return [ { id: 'fullName', accessorKey: 'fullName', header: 'Name', cell: ({ row }) => ( e.stopPropagation()} > {row.original.fullName} ), }, { id: 'email', header: 'Email', enableSorting: false, cell: ({ row }) => { const value = row.original.primaryEmail; if (!value) return -; return {value}; }, }, { id: 'phone', header: 'Phone', enableSorting: false, cell: ({ row }) => { const value = row.original.primaryPhone; if (!value) return -; return {value}; }, }, { id: 'country', accessorKey: 'nationalityIso', header: 'Country', cell: ({ getValue }) => { const iso = getValue() as string | null; return ( {iso ? getCountryName(iso, 'en') : '-'} ); }, }, { id: 'source', accessorKey: 'source', header: 'Source', cell: ({ getValue }) => { const source = getValue() as string | null; if (!source) return -; return ( {SOURCE_LABELS[source] ?? source} ); }, }, { id: 'latestStage', header: 'Latest stage', enableSorting: false, cell: ({ row }) => { const latest = row.original.latestInterest; if (!latest) return -; const stageLabel = STAGE_LABELS[latest.stage] ?? latest.stage; return (
{stageLabel} {latest.mooringNumber && ( {latest.mooringNumber} )}
); }, }, { id: 'createdAt', accessorKey: 'createdAt', header: 'Created', cell: ({ getValue }) => ( {format(new Date(getValue() as string), 'MMM d, yyyy')} ), }, { id: 'actions', header: '', enableSorting: false, size: 48, cell: ({ row }) => ( onEdit(row.original)}> Edit onArchive(row.original)}> Archive ), }, ]; }