diff --git a/components/tables/order-table.tsx b/components/tables/order-table.tsx index da2b047..862b796 100644 --- a/components/tables/order-table.tsx +++ b/components/tables/order-table.tsx @@ -30,12 +30,18 @@ import { MessageCircle, AlertTriangle, Tag, - Percent + Percent, + TrendingUp, + Users, + DollarSign, + ShoppingCart, + Calendar } from "lucide-react"; import Link from "next/link"; import { clientFetch } from '@/lib/api'; import { toast } from "sonner"; import { Checkbox } from "@/components/ui/checkbox"; +import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"; import { AlertDialog, AlertDialogAction, @@ -69,6 +75,35 @@ interface Order { subtotalBeforeDiscount?: number; } +interface CustomerInsights { + overview: { + totalOrders: number; + completedOrders: number; + cancelledOrders: number; + uniqueCustomers: number; + completionRate: number; + paymentSuccessRate: number; + cancellationRate: number; + }; + financial: { + totalRevenue: number; + averageOrderValue: number; + }; + recent30Days: { + orders: number; + revenue: number; + newCustomers: number; + }; +} + +interface OrdersResponse { + orders: Order[]; + page: number; + totalPages: number; + totalOrders: number; + customerInsights: CustomerInsights; +} + type SortableColumns = "orderId" | "totalPrice" | "status" | "orderDate" | "paidAt"; interface StatusConfig { @@ -120,6 +155,68 @@ const PageSizeSelector = ({ currentSize, onChange, options }: { currentSize: num ); }; +// Customer Insights Display Component +const CustomerInsightsDisplay = ({ insights }: { insights: CustomerInsights }) => { + return ( +
+ {/* Overview Stats */} + + + Total Orders + + + +
{insights.overview.totalOrders}
+

+ {insights.overview.uniqueCustomers} unique customers +

+
+
+ + + + Success Rate + + + +
+ {insights.overview.paymentSuccessRate.toFixed(1)}% +
+

+ {insights.overview.completionRate.toFixed(1)}% completion rate +

+
+
+ + + + Total Revenue + + + +
£{insights.financial.totalRevenue.toFixed(2)}
+

+ £{insights.financial.averageOrderValue.toFixed(2)} avg order +

+
+
+ + + + Last 30 Days + + + +
{insights.recent30Days.orders}
+

+ £{insights.recent30Days.revenue.toFixed(2)} revenue +

+
+
+
+ ); +}; + export default function OrderTable() { const [orders, setOrders] = useState([]); const [loading, setLoading] = useState(true); @@ -127,6 +224,7 @@ export default function OrderTable() { const [currentPage, setCurrentPage] = useState(1); const [totalPages, setTotalPages] = useState(1); const [totalOrders, setTotalOrders] = useState(0); + const [customerInsights, setCustomerInsights] = useState(null); const [sortConfig, setSortConfig] = useState<{ column: SortableColumns; direction: "asc" | "desc"; @@ -159,12 +257,13 @@ export default function OrderTable() { ...(statusFilter !== "all" && { status: statusFilter }), }); - const data = await clientFetch(`/orders?${queryParams}`); + const data: OrdersResponse = await clientFetch(`/orders?${queryParams}`); console.log("Fetched orders with fresh data:", data.orders?.length || 0); setOrders(data.orders || []); setTotalPages(data.totalPages || 1); setTotalOrders(data.totalOrders || 0); + setCustomerInsights(data.customerInsights || null); } catch (error) { toast.error("Failed to fetch orders"); console.error("Fetch error:", error); @@ -365,6 +464,9 @@ export default function OrderTable() { return (
+ {/* Customer Insights */} + {customerInsights && } +
{/* Filters header */}
diff --git a/public/git-info.json b/public/git-info.json index de113eb..9027d99 100644 --- a/public/git-info.json +++ b/public/git-info.json @@ -1,4 +1,4 @@ { - "commitHash": "57502d0", - "buildTime": "2025-08-30T20:06:32.862Z" + "commitHash": "fabc8f2", + "buildTime": "2025-08-30T21:51:03.692Z" } \ No newline at end of file