"use client"; import { useState, useEffect } from "react"; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from "@/components/ui/table"; import { Button } from "@/components/ui/button"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select"; import { Eye, Loader, CheckCircle, XCircle, ChevronLeft, ChevronRight, ArrowUpDown, Truck, } from "lucide-react"; import Link from "next/link"; import { fetchWithAuthClient } from "@/lib/client-utils"; import { toast } from "sonner"; import { Checkbox } from "@/components/ui/checkbox"; interface Order { _id: string; orderId: number; status: string; totalPrice: number; escrowExpiresAt: string; telegramUsername: string; createdAt: string; } export default function OrderTable() { const [orders, setOrders] = useState([]); const [filteredOrders, setFilteredOrders] = useState([]); const [selectedOrders, setSelectedOrders] = useState>(new Set()); const [loading, setLoading] = useState(true); const [statusFilter, setStatusFilter] = useState("all"); const [currentPage, setCurrentPage] = useState(1); const [totalPages, setTotalPages] = useState(1); const [sortColumn, setSortColumn] = useState("createdAt"); const [sortDirection, setSortDirection] = useState<"asc" | "desc">("desc"); const ITEMS_PER_PAGE = 10; // Fetch Orders useEffect(() => { const fetchOrders = async () => { try { setLoading(true); const response = await fetchWithAuthClient("/orders"); if (response.orders) { setOrders(response.orders); setFilteredOrders(response.orders); setTotalPages(Math.ceil(response.orders.length / ITEMS_PER_PAGE)); } else { throw new Error("Invalid API response format"); } } catch (error) { toast.error("Failed to fetch orders."); console.error("Error fetching orders:", error); } finally { setLoading(false); } }; fetchOrders(); }, []); // Filter Orders by Status useEffect(() => { const filtered = orders.filter( (order) => statusFilter === "all" || order.status === statusFilter ); setFilteredOrders(filtered); setTotalPages(Math.ceil(filtered.length / ITEMS_PER_PAGE)); setCurrentPage(1); // Reset to the first page on filter change }, [statusFilter, orders]); // Sort Orders const sortedOrders = filteredOrders.sort((a, b) => { const aValue = a[sortColumn as keyof Order]; const bValue = b[sortColumn as keyof Order]; if (typeof aValue === "number" || typeof aValue === "string") { if (aValue < bValue) return sortDirection === "asc" ? -1 : 1; if (aValue > bValue) return sortDirection === "asc" ? 1 : -1; } return 0; }); // Paginated Orders const paginatedOrders = sortedOrders.slice( (currentPage - 1) * ITEMS_PER_PAGE, currentPage * ITEMS_PER_PAGE ); // Handle Sorting const handleSort = (column: string) => { if (column === sortColumn) { setSortDirection(sortDirection === "asc" ? "desc" : "asc"); } else { setSortColumn(column); setSortDirection("asc"); } }; const toggleOrderSelection = (orderId: string) => { setSelectedOrders((prev) => { const updated = new Set(prev); if (updated.has(orderId)) { updated.delete(orderId); } else { updated.add(orderId); } return updated; }); }; // Handle Bulk Actions const markAsShipped = async () => { try { if (selectedOrders.size === 0) { toast.warning("No orders selected."); return; } const orderIds = Array.from(selectedOrders); const response = await fetchWithAuthClient( "/orders/mark-shipped", "POST", { orderIds } ); if (response.success) { setOrders((prevOrders) => prevOrders.map((order) => selectedOrders.has(order._id) ? { ...order, status: "shipped" } : order ) ); setSelectedOrders(new Set()); toast.success("Orders marked as shipped successfully."); } else { throw new Error("Failed to update orders"); } } catch (error) { toast.error("Failed to update orders."); console.error("Error marking orders as shipped:", error); } }; return (
{/* Filter and Bulk Action */}
{/* Orders Table */} 0 } onCheckedChange={(checked) => setSelectedOrders( checked ? new Set(paginatedOrders.map((o) => o._id)) : new Set() ) } /> handleSort("orderId")} > Order ID handleSort("totalPrice")} > Total (£) handleSort("status")} > Status handleSort("createdAt")} > Date Buyer Action {loading ? ( ) : paginatedOrders.length ? ( paginatedOrders.map((order) => ( toggleOrderSelection(order._id)} /> #{order.orderId} £{order.totalPrice.toFixed(2)} {order.status === "paid" && ( Paid )} {order.status === "unpaid" && ( Unpaid )} {order.status === "confirming" && ( {" "} Confirming )} {order.status === "shipped" && ( Shipped )} {order.status === "completed" && ( Completed )} {order.status === "disputed" && ( Disputed )} {order.status === "cancelled" && ( Cancelled )} {new Date(order.createdAt).toLocaleDateString()} @{order.telegramUsername} )) ) : ( No orders found. )}
{/* Pagination */}
Page {currentPage} of {totalPages}
); }