'use client'; import { useState } from 'react'; import { Pencil, RefreshCw } from 'lucide-react'; import { useQueryClient } from '@tanstack/react-query'; import { toast } from 'sonner'; import { useForm } from 'react-hook-form'; import { zodResolver } from '@hookform/resolvers/zod'; import { Button } from '@/components/ui/button'; import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter, } from '@/components/ui/dialog'; import { Label } from '@/components/ui/label'; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from '@/components/ui/select'; import { Textarea } from '@/components/ui/textarea'; import { DetailHeaderStrip } from '@/components/shared/detail-header-strip'; import { PermissionGate } from '@/components/shared/permission-gate'; import { BerthForm } from './berth-form'; import { apiFetch } from '@/lib/api/client'; import { updateBerthStatusSchema, type UpdateBerthStatusInput } from '@/lib/validators/berths'; import { BERTH_STATUSES } from '@/lib/constants'; type BerthDetailData = { id: string; mooringNumber: string; area: string | null; status: string; portId: string; lengthFt: string | null; lengthM: string | null; widthFt: string | null; widthM: string | null; draftFt: string | null; draftM: string | null; widthIsMinimum: boolean | null; price: string | null; priceCurrency: string; tenureType: string; tenureYears: number | null; tenureStartDate: string | null; tenureEndDate: string | null; powerCapacity: string | null; voltage: string | null; mooringType: string | null; access: string | null; berthApproved: boolean | null; tags: Array<{ id: string; name: string; color: string }>; }; interface BerthDetailHeaderProps { berth: BerthDetailData; } const STATUS_COLORS: Record = { available: 'bg-green-100 text-green-800 border-green-300', under_offer: 'bg-yellow-100 text-yellow-800 border-yellow-300', sold: 'bg-red-100 text-red-800 border-red-300', }; const STATUS_LABELS: Record = { available: 'Available', under_offer: 'Under Offer', sold: 'Sold', }; function StatusChangeDialog({ berthId, currentStatus, open, onOpenChange, }: { berthId: string; currentStatus: string; open: boolean; onOpenChange: (open: boolean) => void; }) { const queryClient = useQueryClient(); const { register, handleSubmit, setValue, watch, reset, formState: { isSubmitting }, } = useForm({ resolver: zodResolver(updateBerthStatusSchema), defaultValues: { status: currentStatus as (typeof BERTH_STATUSES)[number], reason: '' }, }); const status = watch('status'); async function onSubmit(data: UpdateBerthStatusInput) { try { await apiFetch(`/api/v1/berths/${berthId}/status`, { method: 'PATCH', body: data, }); queryClient.invalidateQueries({ queryKey: ['berths'] }); queryClient.invalidateQueries({ queryKey: ['berth', berthId] }); toast.success('Status updated'); reset(); onOpenChange(false); } catch (err: unknown) { const message = err instanceof Error ? err.message : 'Failed to update status'; toast.error(message); } } return ( Change Status