From e5eba12cbeb192d3f55703905420fe1c43c53ea3 Mon Sep 17 00:00:00 2001 From: NotII <46204250+NotII@users.noreply.github.com> Date: Wed, 2 Apr 2025 00:27:27 +0100 Subject: [PATCH] woohoo --- app/dashboard/storefront/customers/page.tsx | 238 ++++++++++++++++++++ components/home-navbar.tsx | 4 +- config/index.ts | 5 + config/sidebar.ts | 3 +- services/customerService.ts | 29 +++ utils/format.ts | 6 + 6 files changed, 282 insertions(+), 3 deletions(-) create mode 100644 app/dashboard/storefront/customers/page.tsx create mode 100644 config/index.ts create mode 100644 services/customerService.ts create mode 100644 utils/format.ts diff --git a/app/dashboard/storefront/customers/page.tsx b/app/dashboard/storefront/customers/page.tsx new file mode 100644 index 0000000..6675435 --- /dev/null +++ b/app/dashboard/storefront/customers/page.tsx @@ -0,0 +1,238 @@ +"use client"; + +import React, { useEffect, useState, useCallback } from "react"; +import { getCustomers, CustomerStats } from "@/services/customerService"; +import { formatCurrency } from "@/utils/format"; +import { useRouter } from "next/navigation"; +import { toast } from "sonner"; +import Layout from "@/components/layout/layout"; +import { + Table, + TableBody, + TableCell, + TableHead, + TableHeader, + TableRow, +} from "@/components/ui/table"; +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from "@/components/ui/select"; +import { Button } from "@/components/ui/button"; +import { ChevronLeft, ChevronRight, Loader2, Users } from "lucide-react"; + +export default function CustomerManagementPage() { + const router = useRouter(); + const [customers, setCustomers] = useState([]); + const [loading, setLoading] = useState(true); + const [page, setPage] = useState(1); + const [totalPages, setTotalPages] = useState(1); + const [itemsPerPage, setItemsPerPage] = useState(25); + const [selectedCustomer, setSelectedCustomer] = useState(null); + + const fetchCustomers = useCallback(async () => { + try { + setLoading(true); + const response = await getCustomers(page, itemsPerPage); + setCustomers(response.customers); + setTotalPages(Math.ceil(response.total / itemsPerPage)); + } catch (err) { + toast.error("Failed to fetch customers"); + console.error(err); + } finally { + setLoading(false); + } + }, [page, itemsPerPage]); + + useEffect(() => { + fetchCustomers(); + }, [fetchCustomers]); + + useEffect(() => { + const authToken = document.cookie + .split("; ") + .find((row) => row.startsWith("Authorization=")) + ?.split("=")[1]; + + if (!authToken) { + router.push("/login"); + } + }, [router]); + + const handlePageChange = (newPage: number) => { + setPage(newPage); + }; + + const handleItemsPerPageChange = (value: string) => { + setItemsPerPage(parseInt(value, 10)); + setPage(1); // Reset to first page when changing items per page + }; + + return ( + +
+
+

+ + Customer Management +

+
+ +
+
+
+
Show:
+ +
+
+ + {loading ? ( +
+ +
+ ) : customers.length === 0 ? ( +
+

No customers found

+
+ ) : ( + + + + 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} +
+
+ + {new Date(customer.lastOrderDate).toLocaleDateString()} + +
+ ))} +
+
+ )} + +
+
+ Page {page} of {totalPages} +
+
+ + +
+
+
+ + {/* Customer Details Modal */} + {selectedCustomer && ( +
+
+
+

Customer Details

+ +
+
+
+
+

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()}

+
+
+
+
+

Order Status Breakdown

+
+
+

Paid

+

{selectedCustomer.ordersByStatus.paid}

+
+
+

Completed

+

{selectedCustomer.ordersByStatus.completed}

+
+
+

Acknowledged

+

{selectedCustomer.ordersByStatus.acknowledged}

+
+
+

Shipped

+

{selectedCustomer.ordersByStatus.shipped}

+
+
+
+
+
+
+ )} +
+
+ ); +} \ No newline at end of file diff --git a/components/home-navbar.tsx b/components/home-navbar.tsx index c57ddfd..5eeb0d9 100644 --- a/components/home-navbar.tsx +++ b/components/home-navbar.tsx @@ -34,9 +34,9 @@ export function HomeNavbar() {