1
0
Fork 0
polaris-task-force/src/components/frontend/logistics/ShipmentsList.tsx
Z8MB1E f8ce3f3dcc feat(logistics): timestamp shipment lifecycle with client relay
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-09-20 02:43:29 -04:00

106 lines
3.2 KiB
TypeScript

"use client";
import { useMemo, useState } from "react";
import type { Shipment } from "@/payload-types";
import { ShipmentCard } from "@/components/frontend/logistics/ShipmentCard";
import { Button } from "@/components/ui/button";
import { usePageCommands } from "@/components/command-palette/CommandPaletteContext";
import { CheckCircleIcon, ClockIcon, ListFilterIcon, TruckIcon, XCircleIcon } from "lucide-react";
import { isShipmentActive } from "@/lib/shipping/client";
const statusFilters = [
{ label: "All", value: null },
{ label: "Active", value: "active" },
{ label: "Completed", value: "completed" },
{ label: "Cancelled", value: "cancelled" },
{ label: "Stranded", value: "stranded" },
];
interface ShipmentsListProps {
shipments: Shipment[];
}
export function ShipmentsList({ shipments }: ShipmentsListProps) {
const [filter, setFilter] = useState<string | null>(null);
usePageCommands([
{
id: "shipments:filter-all",
group: "Shipments",
label: "Filter: All Shipments",
icon: ListFilterIcon,
keywords: ["filter", "all", "shipments"],
onSelect: () => setFilter(null),
},
{
id: "shipments:filter-active",
group: "Shipments",
label: "Filter: Active Shipments",
icon: ClockIcon,
keywords: ["filter", "active", "in transit", "pending"],
onSelect: () => setFilter("active"),
},
{
id: "shipments:filter-completed",
group: "Shipments",
label: "Filter: Completed Shipments",
icon: CheckCircleIcon,
keywords: ["filter", "completed", "arrived", "done"],
onSelect: () => setFilter("completed"),
},
{
id: "shipments:filter-cancelled",
group: "Shipments",
label: "Filter: Cancelled Shipments",
icon: XCircleIcon,
keywords: ["filter", "cancelled", "failed"],
onSelect: () => setFilter("cancelled"),
},
{
id: "shipments:filter-stranded",
group: "Shipments",
label: "Filter: Stranded Shipments",
icon: TruckIcon,
keywords: ["filter", "stranded", "stuck"],
onSelect: () => setFilter("stranded"),
},
]);
const filtered = useMemo(() => {
if (!filter) return shipments;
if (filter === "active") {
return shipments.filter((s) => isShipmentActive(s));
}
return shipments.filter((s) => s.status === filter);
}, [shipments, filter]);
return (
<div className="flex flex-col gap-4">
<div className="flex flex-wrap gap-1.5">
{statusFilters.map((f) => (
<Button
key={f.value ?? "all"}
variant={filter === f.value ? "default" : "outline"}
size="sm"
className="h-7 text-xs"
onClick={() => setFilter(f.value)}
>
{f.label}
</Button>
))}
</div>
{filtered.length === 0 ? (
<div className="flex flex-col items-center justify-center py-12 text-muted-foreground">
<p className="text-sm">No shipments found.</p>
</div>
) : (
<div className="flex flex-col gap-2">
{filtered.map((shipment) => (
<ShipmentCard key={shipment.id} shipment={shipment} />
))}
</div>
)}
</div>
);
}