diff --git a/client/src/pages/admin/dashboard.tsx b/client/src/pages/admin/dashboard.tsx new file mode 100644 index 0000000..097406f --- /dev/null +++ b/client/src/pages/admin/dashboard.tsx @@ -0,0 +1,125 @@ +import { useQuery } from "@tanstack/react-query"; +import { Link, useLocation } from "wouter"; +import { ShoppingBag, Users, Package, DollarSign, LayoutDashboard, Tag, LogOut } from "lucide-react"; +import { apiRequest, queryClient } from "../../lib/queryClient"; + +function AdminNav({ active }: { active: string }) { + const [, setLocation] = useLocation(); + const navItems = [ + { href: "/admin", label: "Dashboard", icon: LayoutDashboard }, + { href: "/admin/orders", label: "Orders", icon: ShoppingBag }, + { href: "/admin/products", label: "Products", icon: Package }, + { href: "/admin/customers", label: "Customers", icon: Users }, + { href: "/admin/discounts", label: "Discounts", icon: Tag }, + ]; + + const handleLogout = async () => { + await apiRequest("POST", "/api/admin/logout"); + await queryClient.invalidateQueries(); + setLocation("/admin/login"); + }; + + return ( + + ); +} + +interface Stats { + totalOrders: number; + totalRevenue: number; + totalCustomers: number; + activeProducts: number; + recentOrders: Array<{ id: number; orderNumber: string; email: string; total: string; status: string; createdAt: string }>; +} + +export default function AdminDashboard() { + const { data: stats, isLoading } = useQuery({ + queryKey: ["/api/admin/stats"], + queryFn: async () => { const r = await fetch("/api/admin/stats", { credentials: "include" }); if (r.status === 401) window.location.href = "/admin/login"; return r.json(); }, + }); + + return ( +
+ +
+

Dashboard

+ {isLoading ? ( +
+ {[1, 2, 3, 4].map((i) =>
)} +
+ ) : ( + <> +
+ {[ + { label: "Total Revenue", value: `$${(stats?.totalRevenue || 0).toLocaleString("en-US", { minimumFractionDigits: 2 })}`, icon: DollarSign, color: "text-green-600 bg-green-100" }, + { label: "Total Orders", value: stats?.totalOrders || 0, icon: ShoppingBag, color: "text-blue-600 bg-blue-100" }, + { label: "Customers", value: stats?.totalCustomers || 0, icon: Users, color: "text-purple-600 bg-purple-100" }, + { label: "Active Products", value: stats?.activeProducts || 0, icon: Package, color: "text-orange-600 bg-orange-100" }, + ].map((stat) => { + const Icon = stat.icon; + return ( +
+
+ +
+

{stat.value}

+

{stat.label}

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

Recent Orders

+ View all +
+
+ {stats?.recentOrders.map((order) => ( +
+
+

#{order.orderNumber}

+

{order.email}

+
+
+ {order.status} + ${parseFloat(order.total).toFixed(2)} +
+
+ ))} +
+
+ + )} +
+
+ ); +} + +export { AdminNav };