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}
);
}