import { useState, useMemo } from "react"; import { useMutation, useQuery } from "@tanstack/react-query"; import { Box, Button, Group, Loader, Select, Stack, Table, Text, Alert, } from "@mantine/core"; import { AlertCircle } from "lucide-react"; import toast from "react-hot-toast"; import { vehiclesService } from "@/services/vehicles.service"; export interface ContainerAllocationRow { id: string; type: string; qty: number; } export interface FirstMileContainerAllocationTableProps { firstMileId: string; containers: ContainerAllocationRow[]; onSave: (allocations: Array<{ containerId: string; vehicleId: string }>) => Promise; } /** * Manual container-to-vehicle allocation table for first-mile pickups. * Displays containers with type/qty, vehicle dropdown per row, and save action. */ export function FirstMileContainerAllocationTable({ firstMileId, containers, onSave, }: FirstMileContainerAllocationTableProps) { const [allocations, setAllocations] = useState>( () => containers.reduce((acc, c) => ({ ...acc, [c.id]: null }), {}), ); const { data: vehicles = [], isLoading: vehiclesLoading } = useQuery({ queryKey: ["vehicles", "active"], queryFn: () => vehiclesService.getAll({ status: "ACTIVE" }), }); const vehicleOptions = useMemo( () => vehicles.map((v) => ({ value: v.id, label: `${v.plateNumber} (${v.vehicleType})`, description: `${v.model} ยท ${v.manufacturer}`, })), [vehicles], ); const saveAllocation = useMutation({ mutationFn: async () => { const mappings = containers .filter((c) => allocations[c.id]) .map((c) => ({ containerId: c.id, vehicleId: allocations[c.id]!, })); if (mappings.length === 0) { throw new Error("No containers allocated to vehicles"); } await onSave(mappings); }, onSuccess: () => { toast.success("Container allocations saved"); setAllocations( containers.reduce((acc, c) => ({ ...acc, [c.id]: null }), {}), ); }, onError: (error) => { toast.error( error instanceof Error ? error.message : "Failed to save allocations", ); }, }); const allocatedCount = Object.values(allocations).filter(Boolean).length; const allAllocated = allocatedCount === containers.length; if (vehiclesLoading) { return ( ); } return ( {vehicles.length === 0 && ( } color="yellow"> No active vehicles available. Add vehicles before allocating containers. )} Container ID Type Qty Assigned Vehicle {containers.map((container) => ( {container.id} {container.type} {container.qty}
{allocatedCount} of {containers.length} containers allocated
); }