import { useMemo, useState } from "react"; import { ArrowRight, Building2, Package } from "lucide-react"; import { Accordion, Badge, Button, Checkbox, Group, Paper, Stack, Text, Title, } from "@mantine/core"; import { BookingPriorityBadge } from "@/components/bookings/BookingPriorityBadge"; import { canAllocateBooking } from "@/features/bookings/booking-actions.config"; import type { BookingListRow } from "@/types/booking"; import { groupBookingsForOperationsQueue } from "@/utils/groupBookingsForOperationsQueue"; function BookingQueueRow({ booking, selected, disabled, onToggle, }: { booking: BookingListRow; selected: boolean; disabled: boolean; onToggle: () => void; }) { return ( {booking.reference} {booking.isGovernment ? ( }> Government ) : null} {booking.freightType} {booking.schedulingStatus ? ( {booking.schedulingStatus} ) : null} {booking.customerLabel} {booking.originLabel} {booking.destinationLabel} {booking.serviceTypeLabel ? ( {booking.serviceTypeLabel} {booking.serviceTypeBonus ? ` (+${booking.serviceTypeBonus} bonus)` : ""} ) : null} ); } export function OperationsBookingQueue({ bookings, isLoading, onAllocate, }: { bookings: BookingListRow[]; isLoading?: boolean; onAllocate: (bookingIds: string[]) => void; }) { const { government, commercial } = useMemo( () => groupBookingsForOperationsQueue(bookings), [bookings], ); const [govSelected, setGovSelected] = useState([]); const [selectedByBucket, setSelectedByBucket] = useState>({}); const allocatable = (row: BookingListRow) => row.status === "PAID" && canAllocateBooking({ status: row.status, schedulingStatus: row.schedulingStatus }); const govSelection = govSelected.length ? govSelected : government.filter(allocatable).map((b) => b.id); const bucketSelection = (bucketKey: string, bucketBookings: BookingListRow[]) => { const existing = selectedByBucket[bucketKey]; if (existing) return existing; return bucketBookings.filter(allocatable).map((b) => b.id); }; const toggleGov = (bookingId: string) => { setGovSelected((prev) => { const base = prev.length ? prev : government.filter(allocatable).map((b) => b.id); return base.includes(bookingId) ? base.filter((id) => id !== bookingId) : [...base, bookingId]; }); }; const toggleBucket = (bucketKey: string, bookingId: string) => { setSelectedByBucket((prev) => { const current = prev[bucketKey] ?? []; const next = current.includes(bookingId) ? current.filter((id) => id !== bookingId) : [...current, bookingId]; return { ...prev, [bucketKey]: next }; }); }; if (isLoading) { return Loading operations queue…; } if (!government.length && !commercial.length) { return ( No PAID bookings ready to allocate. ); } return ( {government.length > 0 ? ( Government priority Served first — not grouped by 3-hour window {govSelection.length} selected {government.map((booking) => ( toggleGov(booking.id)} /> ))} ) : null} {commercial.length > 0 ? ( {commercial.map((bucket) => { const selected = bucketSelection(bucket.key, bucket.bookings); return ( {bucket.label} {bucket.bookings.length} commercial booking {bucket.bookings.length === 1 ? "" : "s"} {selected.length} selected {bucket.bookings.map((booking) => ( toggleBucket(bucket.key, booking.id)} /> ))} ); })} ) : null} ); }