import { Button, Divider, Group, Modal, Stack, Table, Text, } from '@mantine/core'; import { DateTimePicker } from '@mantine/dates'; import { useMutation, useQueryClient } from '@tanstack/react-query'; import { useEffect, useState } from 'react'; import { useToast } from '@/hooks/use-toast'; import { lastMileService, type LastMileRecord } from '@/services/last-mile.service'; interface WarehouseGateTimesModalProps { opened: boolean; onClose: () => void; record: LastMileRecord | null; } const plateOf = (a: NonNullable[number]) => [a.vehicle?.code, a.vehicle?.plateNumber].filter(Boolean).join(' ยท ') || a.vehicleId; export function WarehouseGateTimesModal({ opened, onClose, record }: WarehouseGateTimesModalProps) { const { toast } = useToast(); const qc = useQueryClient(); const id = record?.id ?? null; const assignments = record?.vehicleAssignments ?? []; interface TruckRow { vehicleId: string; label: string; arrivedAt: Date | null; departedAt: Date | null; } const [rows, setRows] = useState>([]); const [saving, setSaving] = useState(false); useEffect(() => { if (assignments.length > 0) { setRows( assignments.map((a) => ({ vehicleId: a.vehicleId, label: plateOf(a), arrivedAt: a.arrivedAt ? new Date(a.arrivedAt) : null, departedAt: a.departedAt ? new Date(a.departedAt) : null, })), ); } }, [assignments, opened]); const updateMutation = useMutation({ mutationFn: () => { if (!id) return Promise.resolve(null); return lastMileService.setWarehouseGateTimes(id, rows.map(r => ({ vehicleId: r.vehicleId, arrivedAt: r.arrivedAt?.toISOString() ?? null, departedAt: r.departedAt?.toISOString() ?? null, }))); }, onSuccess: () => { toast({ title: 'Warehouse gate times updated', }); qc.invalidateQueries({ queryKey: ['last-mile-record-import-trucks', id] }); onClose(); }, onError: (error: any) => { toast({ variant: 'destructive', title: 'Failed to update warehouse gate times', description: error?.response?.data?.message || error?.message, }); }, onSettled: () => { setSaving(false); }, }); const handleSave = async () => { setSaving(true); await updateMutation.mutateAsync(); }; return ( Set arrival (gate-in) and departure (gate-out) times for each truck. {/* @ts-ignore - DateTimePicker type inference issue with row state */} Plate Arrived At (Gate-In) Departed At (Gate-Out) {rows.map((row: TruckRow, idx: number) => ( {row.label} { const newRows = [...rows]; newRows[idx] = { ...row, arrivedAt: date }; setRows(newRows); }} clearable size="sm" /> { const newRows = [...rows]; newRows[idx] = { ...row, departedAt: date }; setRows(newRows); }} clearable size="sm" /> ))}
); }