diff --git a/app/api/admin/orders-by-timeslot/route.ts b/app/api/admin/orders-by-timeslot/route.ts index aa4be81..ce92a6f 100644 --- a/app/api/admin/orders-by-timeslot/route.ts +++ b/app/api/admin/orders-by-timeslot/route.ts @@ -61,6 +61,28 @@ export async function GET(request: NextRequest) { }); } + // Sort chronologically by date, then start/end time. The Payload query + // only sorts by date, so slots on the same day would otherwise appear in + // an arbitrary order. `date` is "YYYY-MM-DD" and the times are zero-padded + // "HH:MM", so lexicographic comparison is chronological. + const normaliseDate = (value: unknown): string => + typeof value === "string" + ? value.includes("T") + ? value.split("T")[0] + : value + : ""; + timeslots = [...timeslots].sort((a, b) => { + const dateCmp = normaliseDate(a.date).localeCompare( + normaliseDate(b.date), + ); + if (dateCmp !== 0) return dateCmp; + const startCmp = String(a.startTime ?? "").localeCompare( + String(b.startTime ?? ""), + ); + if (startCmp !== 0) return startCmp; + return String(a.endTime ?? "").localeCompare(String(b.endTime ?? "")); + }); + const timeslotIds = timeslots.map((t) => String(t.id)); // ── 2. Fetch orders in two parallel queries ────────────────────── diff --git a/components/admin/OrdersByTimeslotView.tsx b/components/admin/OrdersByTimeslotView.tsx index 67ef1ac..09275d3 100644 --- a/components/admin/OrdersByTimeslotView.tsx +++ b/components/admin/OrdersByTimeslotView.tsx @@ -195,9 +195,15 @@ function OrdersByTimeslotViewInner() { [getFileKey], ); - /** Download all files for all orders in a timeslot group sequentially */ + /** + * Open every downloadable file across the given orders in new tabs. + * + * Shared by the per-timeslot "Download All Files" button and the per-order + * download button, so both behave identically (parallel presign, sequential + * open with a small delay to dodge popup blockers). + */ const downloadingRef = useRef(false); - const handleDownloadAllFiles = useCallback( + const downloadFilesForOrders = useCallback( async (orders: OrderData[]) => { if (downloadingRef.current) return; downloadingRef.current = true; @@ -265,6 +271,18 @@ function OrdersByTimeslotViewInner() { [getFileKey], ); + /** Download all files across every order in a timeslot group. */ + const handleDownloadAllFiles = useCallback( + (orders: OrderData[]) => downloadFilesForOrders(orders), + [downloadFilesForOrders], + ); + + /** Download all files for a single order. */ + const handleDownloadOrderFiles = useCallback( + (order: OrderData) => downloadFilesForOrders([order]), + [downloadFilesForOrders], + ); + return (