From a849e391055cba3901230ad2fa562caa57c1884f Mon Sep 17 00:00:00 2001 From: NotII <46204250+NotII@users.noreply.github.com> Date: Wed, 2 Apr 2025 00:29:37 +0100 Subject: [PATCH] Update page.tsx --- app/dashboard/storefront/customers/page.tsx | 377 ++++++++++++++------ 1 file changed, 263 insertions(+), 114 deletions(-) diff --git a/app/dashboard/storefront/customers/page.tsx b/app/dashboard/storefront/customers/page.tsx index 6675435..48b59ec 100644 --- a/app/dashboard/storefront/customers/page.tsx +++ b/app/dashboard/storefront/customers/page.tsx @@ -21,8 +21,24 @@ import { SelectTrigger, SelectValue, } from "@/components/ui/select"; +import { + Dialog, + DialogContent, + DialogHeader, + DialogTitle, + DialogDescription, +} from "@/components/ui/dialog"; import { Button } from "@/components/ui/button"; -import { ChevronLeft, ChevronRight, Loader2, Users } from "lucide-react"; +import { + ChevronLeft, + ChevronRight, + Loader2, + Users, + ArrowUpDown, + MessageCircle +} from "lucide-react"; +import { Badge } from "@/components/ui/badge"; +import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; export default function CustomerManagementPage() { const router = useRouter(); @@ -32,12 +48,36 @@ export default function CustomerManagementPage() { const [totalPages, setTotalPages] = useState(1); const [itemsPerPage, setItemsPerPage] = useState(25); const [selectedCustomer, setSelectedCustomer] = useState(null); + const [sortConfig, setSortConfig] = useState<{ + column: "totalOrders" | "totalSpent" | "lastOrderDate"; + direction: "asc" | "desc"; + }>({ column: "totalSpent", direction: "desc" }); const fetchCustomers = useCallback(async () => { try { setLoading(true); const response = await getCustomers(page, itemsPerPage); - setCustomers(response.customers); + + // Sort customers based on current sort config + let sortedCustomers = [...response.customers]; + sortedCustomers.sort((a, b) => { + if (sortConfig.column === "totalOrders") { + return sortConfig.direction === "asc" + ? a.totalOrders - b.totalOrders + : b.totalOrders - a.totalOrders; + } else if (sortConfig.column === "totalSpent") { + return sortConfig.direction === "asc" + ? a.totalSpent - b.totalSpent + : b.totalSpent - a.totalSpent; + } else if (sortConfig.column === "lastOrderDate") { + return sortConfig.direction === "asc" + ? new Date(a.lastOrderDate).getTime() - new Date(b.lastOrderDate).getTime() + : new Date(b.lastOrderDate).getTime() - new Date(a.lastOrderDate).getTime(); + } + return 0; + }); + + setCustomers(sortedCustomers); setTotalPages(Math.ceil(response.total / itemsPerPage)); } catch (err) { toast.error("Failed to fetch customers"); @@ -45,7 +85,7 @@ export default function CustomerManagementPage() { } finally { setLoading(false); } - }, [page, itemsPerPage]); + }, [page, itemsPerPage, sortConfig]); useEffect(() => { fetchCustomers(); @@ -71,6 +111,23 @@ export default function CustomerManagementPage() { setPage(1); // Reset to first page when changing items per page }; + const handleSort = (column: "totalOrders" | "totalSpent" | "lastOrderDate") => { + setSortConfig(prev => ({ + column, + direction: prev.column === column && prev.direction === "asc" ? "desc" : "asc" + })); + }; + + // Format date without time + const formatDate = (dateString: string) => { + const date = new Date(dateString); + return new Intl.DateTimeFormat('en-GB', { + day: '2-digit', + month: 'short', + year: 'numeric' + }).format(date); + }; + return (
@@ -81,69 +138,117 @@ export default function CustomerManagementPage() {
-
+
-
-
Show:
- +
+
+
Show:
+ +
+
+ +
+ {loading + ? "Loading..." + : `Showing ${customers.length} of ${totalPages * itemsPerPage} customers`}
{loading ? (
- +
) : customers.length === 0 ? (
-

No customers found

+ +

No customers found

+

+ Once you have customers placing orders, they will appear here. +

) : ( - - - - Customer - Total Orders - Total Spent - Order Status - Last Order - - - - {customers.map((customer) => ( - setSelectedCustomer(customer)} - > - -
@{customer.telegramUsername}
-
ID: {customer.telegramUserId}
-
- {customer.totalOrders} - {formatCurrency(customer.totalSpent)} - -
- Paid: {customer.ordersByStatus.paid} | - Completed: {customer.ordersByStatus.completed} | - Shipped: {customer.ordersByStatus.shipped} +
+
+ + + Customer + handleSort("totalOrders")} + > +
+ Total Orders +
- - - {new Date(customer.lastOrderDate).toLocaleDateString()} - +
+ handleSort("totalSpent")} + > +
+ Total Spent + +
+
+ Status Breakdown + handleSort("lastOrderDate")} + > +
+ Last Order Date + +
+
- ))} - -
+ + + {customers.map((customer) => ( + setSelectedCustomer(customer)} + > + +
@{customer.telegramUsername || "Unknown"}
+
ID: {customer.telegramUserId}
+
+ + {customer.totalOrders} + + + {formatCurrency(customer.totalSpent)} + + +
+ + Paid: {customer.ordersByStatus.paid} + + + Completed: {customer.ordersByStatus.completed} + + + Shipped: {customer.ordersByStatus.shipped} + +
+
+ + {formatDate(customer.lastOrderDate)} + +
+ ))} +
+ +
)}
@@ -155,83 +260,127 @@ export default function CustomerManagementPage() { variant="outline" size="sm" onClick={() => handlePageChange(Math.max(1, page - 1))} - disabled={page === 1} + disabled={page === 1 || loading} > - - Previous + + Previous
- {/* Customer Details Modal */} - {selectedCustomer && ( -
-
-
-

Customer Details

- -
+ {/* Customer Details Dialog */} + !open && setSelectedCustomer(null)}> + + + + + Customer Details + + + Details and order statistics for this customer + + + + {selectedCustomer && (
-
-
-

Customer Information

-
-

Telegram Username: @{selectedCustomer.telegramUsername}

-

Telegram User ID: {selectedCustomer.telegramUserId}

-

Chat ID: {selectedCustomer.chatId}

-
-
-
-

Order Statistics

-
-

Total Orders: {selectedCustomer.totalOrders}

-

Total Spent: {formatCurrency(selectedCustomer.totalSpent)}

-

First Order: {new Date(selectedCustomer.firstOrderDate).toLocaleDateString()}

-

Last Order: {new Date(selectedCustomer.lastOrderDate).toLocaleDateString()}

-
-
+
+ + + Customer Information + + +
+
Username:
+
@{selectedCustomer.telegramUsername || "Unknown"}
+
+
+
Telegram ID:
+
{selectedCustomer.telegramUserId}
+
+
+
Chat ID:
+
{selectedCustomer.chatId}
+
+
+ +
+
+
+ + + + Order Statistics + + +
+
Total Orders:
+
{selectedCustomer.totalOrders}
+
+
+
Total Spent:
+
{formatCurrency(selectedCustomer.totalSpent)}
+
+
+
First Order:
+
{formatDate(selectedCustomer.firstOrderDate)}
+
+
+
Last Order:
+
{formatDate(selectedCustomer.lastOrderDate)}
+
+
+
-
-

Order Status Breakdown

-
-
-

Paid

-

{selectedCustomer.ordersByStatus.paid}

+ + + + Order Status Breakdown + + +
+
+

Paid

+

{selectedCustomer.ordersByStatus.paid}

+
+
+

Acknowledged

+

{selectedCustomer.ordersByStatus.acknowledged}

+
+
+

Shipped

+

{selectedCustomer.ordersByStatus.shipped}

+
+
+

Completed

+

{selectedCustomer.ordersByStatus.completed}

+
-
-

Completed

-

{selectedCustomer.ordersByStatus.completed}

-
-
-

Acknowledged

-

{selectedCustomer.ordersByStatus.acknowledged}

-
-
-

Shipped

-

{selectedCustomer.ordersByStatus.shipped}

-
-
-
+ +
-
-
- )} + )} +
+
);