diff --git a/components/tables/order-table.tsx b/components/tables/order-table.tsx index c176951..4f0b84e 100644 --- a/components/tables/order-table.tsx +++ b/components/tables/order-table.tsx @@ -64,6 +64,46 @@ interface StatusConfig { type OrderStatus = "paid" | "unpaid" | "acknowledged" | "shipped" | "completed" | "cancelled" | "confirming"; +// Create a StatusFilter component to replace the missing component +const StatusFilter = ({ currentStatus, onChange }: { currentStatus: string, onChange: (value: string) => void }) => { + return ( + + ); +}; + +// Create a PageSizeSelector component +const PageSizeSelector = ({ currentSize, onChange, options }: { currentSize: number, onChange: (value: string) => void, options: number[] }) => { + return ( +
+
Show:
+ +
+ ); +}; + export default function OrderTable() { const [orders, setOrders] = useState([]); const [loading, setLoading] = useState(true); @@ -77,7 +117,8 @@ export default function OrderTable() { }>({ column: "orderDate", direction: "desc" }); const [selectedOrders, setSelectedOrders] = useState>(new Set()); const [isShipping, setIsShipping] = useState(false); - const ITEMS_PER_PAGE = 10; + const [itemsPerPage, setItemsPerPage] = useState(20); + const pageSizeOptions = [5, 10, 15, 20, 25, 50, 75, 100]; // Fetch orders with server-side pagination const fetchOrders = useCallback(async () => { @@ -85,7 +126,7 @@ export default function OrderTable() { setLoading(true); const queryParams = new URLSearchParams({ page: currentPage.toString(), - limit: ITEMS_PER_PAGE.toString(), + limit: itemsPerPage.toString(), ...(statusFilter !== "all" && { status: statusFilter }), }); @@ -100,7 +141,7 @@ export default function OrderTable() { } finally { setLoading(false); } - }, [currentPage, statusFilter]); + }, [currentPage, statusFilter, itemsPerPage]); useEffect(() => { fetchOrders(); @@ -115,6 +156,12 @@ export default function OrderTable() { setCurrentPage(newPage); }; + const handleItemsPerPageChange = (e: React.ChangeEvent) => { + const newSize = parseInt(e.target.value, 10); + setItemsPerPage(newSize); + setCurrentPage(1); // Reset to first page when changing items per page + }; + // Derived data calculations const filteredOrders = orders.filter( (order) => statusFilter === "all" || order.status === statusFilter @@ -138,8 +185,8 @@ export default function OrderTable() { }); const paginatedOrders = sortedOrders.slice( - (currentPage - 1) * ITEMS_PER_PAGE, - currentPage * ITEMS_PER_PAGE + (currentPage - 1) * itemsPerPage, + currentPage * itemsPerPage ); // Handlers @@ -249,158 +296,160 @@ export default function OrderTable() { }; return ( -
- {/* Toolbar */} -
-
- -
- Total Orders: {totalOrders} +
+
+ {/* Filters header */} +
+
+
+ + + handleItemsPerPageChange({ target: { value } } as React.ChangeEvent)} + options={pageSizeOptions} + /> +
+ +
+ + + + + + + Mark Orders as Shipped + + Are you sure you want to mark {selectedOrders.size} order{selectedOrders.size !== 1 ? 's' : ''} as shipped? + This action cannot be undone. + + + + Cancel + + Confirm + + + + +
- - - - - - - Mark Orders as Shipped - - Are you sure you want to mark {selectedOrders.size} order{selectedOrders.size !== 1 ? 's' : ''} as shipped? - This action cannot be undone. - - - - Cancel - - Confirm - - - - -
- - {/* Table */} -
- {loading && ( -
- -
- )} - - - - - 0} - onCheckedChange={toggleAll} - /> - - handleSort("orderId")}> - Order ID - - handleSort("totalPrice")}> - Total - - handleSort("status")}> - Status - - handleSort("orderDate")}> - Date - - Buyer - Actions - - - - {orders.map((order) => { - const StatusIcon = statusConfig[order.status as keyof typeof statusConfig]?.icon || XCircle; - - return ( - - + {/* Table */} +
+ {loading && ( +
+ +
+ )} +
+
+ + + toggleSelection(order._id)} - disabled={order.status !== "paid" && order.status !== "acknowledged"} + checked={selectedOrders.size === orders.length && orders.length > 0} + onCheckedChange={toggleAll} /> - - #{order.orderId} - £{order.totalPrice.toFixed(2)} - -
- {React.createElement(statusConfig[order.status as OrderStatus]?.icon || XCircle, { - className: `h-4 w-4 ${statusConfig[order.status as OrderStatus]?.animate || ""}` - })} - {order.status.charAt(0).toUpperCase() + order.status.slice(1)} -
-
- - {new Date(order.orderDate).toLocaleDateString("en-GB")} - - - {order.telegramUsername ? `@${order.telegramUsername}` : "-"} - - - - +
+ handleSort("orderId")}> + Order ID + + handleSort("totalPrice")}> + Total + + handleSort("status")}> + Status + + handleSort("orderDate")}> + Date + + Buyer + Actions
- ); - })} - -
-
+ + + {orders.map((order) => { + const StatusIcon = statusConfig[order.status as keyof typeof statusConfig]?.icon || XCircle; - {/* Pagination */} -
-
- Page {currentPage} of {totalPages} + return ( + + + toggleSelection(order._id)} + disabled={order.status !== "paid" && order.status !== "acknowledged"} + /> + + #{order.orderId} + £{order.totalPrice.toFixed(2)} + +
+ {React.createElement(statusConfig[order.status as OrderStatus]?.icon || XCircle, { + className: `h-4 w-4 ${statusConfig[order.status as OrderStatus]?.animate || ""}` + })} + {order.status.charAt(0).toUpperCase() + order.status.slice(1)} +
+
+ + {new Date(order.orderDate).toLocaleDateString("en-GB")} + + + {order.telegramUsername ? `@${order.telegramUsername}` : "-"} + + + + +
+ ); + })} + + +
-
- - + + {/* Pagination */} +
+
+ Page {currentPage} of {totalPages} ({totalOrders} total) +
+
+ + +
diff --git a/components/ui/table.tsx b/components/ui/table.tsx index 2f38f8c..aab59fc 100644 --- a/components/ui/table.tsx +++ b/components/ui/table.tsx @@ -9,7 +9,7 @@ const Table = React.forwardRef<
@@ -58,7 +58,7 @@ const TableRow = React.forwardRef<