'use client'; import { useState } from 'react'; import Link from 'next/link'; import { useParams, useRouter } from 'next/navigation'; import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'; import { Pencil, Archive, ArrowRightLeft } from 'lucide-react'; import { toast } from 'sonner'; import { Button } from '@/components/ui/button'; import { Badge } from '@/components/ui/badge'; import { ArchiveConfirmDialog } from '@/components/shared/archive-confirm-dialog'; import { PermissionGate } from '@/components/shared/permission-gate'; import { YachtForm } from '@/components/yachts/yacht-form'; import { YachtTransferDialog } from '@/components/yachts/yacht-transfer-dialog'; import { apiFetch } from '@/lib/api/client'; interface YachtDetailHeaderYacht { id: string; name: string; hullNumber: string | null; registration: string | null; flag: string | null; yearBuilt: number | null; builder: string | null; model: string | null; hullMaterial: string | null; lengthFt: string | null; widthFt: string | null; draftFt: string | null; lengthM: string | null; widthM: string | null; draftM: string | null; currentOwnerType: 'client' | 'company'; currentOwnerId: string; status: string; notes: string | null; archivedAt: string | null; } interface YachtDetailHeaderProps { yacht: YachtDetailHeaderYacht; } const STATUS_COLORS: Record = { active: 'bg-green-100 text-green-800 border-green-300', retired: 'bg-gray-100 text-gray-800 border-gray-300', sold_away: 'bg-amber-100 text-amber-800 border-amber-300', }; const STATUS_LABELS: Record = { active: 'Active', retired: 'Retired', sold_away: 'Sold Away', }; export function OwnerLink({ portSlug, type, id, }: { portSlug: string; type: 'client' | 'company'; id: string; }) { const { data } = useQuery<{ fullName?: string; name?: string }>({ queryKey: [type === 'client' ? 'clients' : 'companies', id, 'name-only'], queryFn: () => apiFetch<{ data: { fullName?: string; name?: string } }>( type === 'client' ? `/api/v1/clients/${id}` : `/api/v1/companies/${id}`, ).then((r) => r.data), }); const label = type === 'client' ? data?.fullName : data?.name; const href = type === 'client' ? `/${portSlug}/clients/${id}` : `/${portSlug}/companies/${id}`; return ( {label ?? `${type === 'client' ? 'Client' : 'Company'} ${id.slice(0, 8)}`} ); } function formatDimensions(yacht: YachtDetailHeaderYacht): string | null { const parts: string[] = []; if (yacht.lengthFt) parts.push(`${yacht.lengthFt} ft`); if (yacht.widthFt) parts.push(`${yacht.widthFt} ft`); let summary: string | null = null; if (parts.length > 0) { summary = parts.join(' × '); } if (yacht.draftFt) { summary = summary ? `${summary} (draft ${yacht.draftFt} ft)` : `draft ${yacht.draftFt} ft`; } return summary; } export function YachtDetailHeader({ yacht }: YachtDetailHeaderProps) { const queryClient = useQueryClient(); const router = useRouter(); const params = useParams<{ portSlug: string }>(); const portSlug = params?.portSlug ?? ''; const [editOpen, setEditOpen] = useState(false); const [archiveOpen, setArchiveOpen] = useState(false); const [transferOpen, setTransferOpen] = useState(false); const isArchived = !!yacht.archivedAt; const archiveMutation = useMutation({ mutationFn: () => apiFetch(`/api/v1/yachts/${yacht.id}`, { method: 'DELETE' }), onSuccess: () => { queryClient.invalidateQueries({ queryKey: ['yachts', yacht.id] }); queryClient.invalidateQueries({ queryKey: ['yachts'] }); toast.success('Yacht archived'); setArchiveOpen(false); // eslint-disable-next-line @typescript-eslint/no-explicit-any router.push(`/${portSlug}/yachts` as any); }, onError: (err: Error) => { toast.error(err.message || 'Failed to archive yacht'); }, }); const dimensions = formatDimensions(yacht); const statusLabel = STATUS_LABELS[yacht.status] ?? yacht.status; const statusColor = STATUS_COLORS[yacht.status] ?? 'bg-muted text-muted-foreground border-muted'; return ( <>

{yacht.name}

{statusLabel} {isArchived && ( Archived )}
{dimensions &&

{dimensions}

}
Owner:
{/* Actions */}
{ archiveMutation.mutate(); }} isLoading={archiveMutation.isPending} /> ); }