diff --git a/attached_assets/image_1752104929215.png b/attached_assets/image_1752104929215.png new file mode 100644 index 0000000..0d052ce Binary files /dev/null and b/attached_assets/image_1752104929215.png differ diff --git a/client/src/pages/Dashboard.tsx b/client/src/pages/Dashboard.tsx index 6fc3945..9b77ebd 100644 --- a/client/src/pages/Dashboard.tsx +++ b/client/src/pages/Dashboard.tsx @@ -2,21 +2,27 @@ import { useState } from "react"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Button } from "@/components/ui/button"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; -import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; import { useAuth } from "@/hooks/useAuth"; import { StoreProvider, useStoreContext } from "@/hooks/useStoreContext"; import NewSaleForm from "@/components/NewSaleForm"; import SalesHistory from "@/components/SalesHistory"; import Administration from "@/components/Administration"; -import { Package, History, Settings, LogOut, User, Building2, Shield } from "lucide-react"; +import { Package, History, Settings, LogOut, User, Building2, Shield, BarChart3, TrendingUp, Users, ShoppingCart } from "lucide-react"; import { useToast } from "@/hooks/use-toast"; +import { useQuery } from "@tanstack/react-query"; function DashboardContent() { const { user, logout } = useAuth(); const { toast } = useToast(); - const [activeTab, setActiveTab] = useState("new-sale"); + const [activeView, setActiveView] = useState("dashboard"); const { selectedStoreId, setSelectedStoreId, stores, selectedStore, isLoadingStores } = useStoreContext(); + // Fetch sales data for dashboard metrics + const { data: sales = [] } = useQuery({ + queryKey: ['/api/sales'], + enabled: !!user + }); + const handleLogout = async () => { try { await logout(); @@ -37,136 +43,306 @@ function DashboardContent() { const canDeleteSales = user?.role === "admin" || user?.role === "manager"; const isAdmin = user?.role === "admin"; + // Calculate dashboard metrics + const todaysSales = sales.filter(sale => { + const saleDate = new Date(sale.timestamp).toDateString(); + const today = new Date().toDateString(); + return saleDate === today; + }); + + const totalSales = sales.length; + const todaysCount = todaysSales.length; + const totalRevenue = sales.reduce((sum, sale) => sum + (sale.quantite * 25), 0); // Estimation + const uniqueCustomers = new Set(sales.map(sale => `${sale.nom}_${sale.prenom}`)).size; + + const menuItems = [ + { id: "dashboard", label: "Tableau de bord", icon: BarChart3 }, + { id: "new-sale", label: "Nouvelle Vente", icon: Package }, + { id: "history", label: "Historique", icon: History }, + ...(canAccessAdmin ? [{ id: "admin", label: "Administration", icon: Settings }] : []) + ]; + return ( -
- {/* Modern Header */} -
-
-
-
-
-
- -
-
-
-
-

RegisFlow

-

Registre des ventes des Feux d'artifice

-
+
+ {/* Sidebar */} +
+ {/* Logo */} +
+
+
+
- -
- {/* Store Selector for Admin */} - {isAdmin && !isLoadingStores && ( -
- - -
- )} - - {/* Current Store Display for Non-Admin */} - {!isAdmin && selectedStore && ( -
- - {selectedStore.name} -
- )} - -
-
-

- {user?.firstName} {user?.lastName} -

-
- {user?.role === 'admin' && } -

{user?.role}

-
-
- -
+
+

RegisFlow

+

Feux d'artifice

-
+ + {/* Navigation */} + + + {/* User Info & Store Selector */} +
+ {/* Store Selector for Admin */} + {isAdmin && !isLoadingStores && ( +
+ +
+ )} + + {/* Current Store Display for Non-Admin */} + {!isAdmin && selectedStore && ( +
+ + {selectedStore.name} +
+ )} + + {/* User Profile */} +
+
+ +
+
+

+ {user?.firstName} {user?.lastName} +

+
+ {user?.role === 'admin' && } +

{user?.role}

+
+
+
+ + +
+
{/* Main Content */} -
-
- - - - - Nouvelle Vente - Vente - - - - Historique - Liste - - {canAccessAdmin && ( - - - Administration - Admin - - )} - - - -
- +
+ {/* Top Header */} +
+
+
+

+ Bonjour {user?.firstName} ! +

+

+ {new Date().toLocaleDateString('fr-FR', { + weekday: 'long', + year: 'numeric', + month: 'long', + day: 'numeric' + })} +

+
+ {selectedStore && ( +
+

Magasin actuel

+

{selectedStore.name}

- - - -
- -
-
- - {canAccessAdmin && ( - -
- -
-
)} - -
-
+ + + + {/* Content Area */} +
+ {activeView === "dashboard" && ( +
+ {/* Metrics Cards */} +
+ + +
+
+

Commandes du jour

+

{todaysCount}

+

+12% vs hier

+
+
+ +
+
+
+
+ + + +
+
+

Ventes totales

+

{totalSales}

+

Toutes les ventes

+
+
+ +
+
+
+
+ + + +
+
+

Clients uniques

+

{uniqueCustomers}

+

Base clients

+
+
+ +
+
+
+
+ + + +
+
+

Revenus estimés

+

{totalRevenue.toLocaleString()}€

+

Estimation

+
+
+ +
+
+
+
+
+ + {/* Recent Activity */} +
+ + + + + Activités récentes + + + +
+ {sales.slice(0, 5).map((sale) => ( +
+
+ +
+
+

+ {sale.nom} {sale.prenom} +

+

{sale.typeArticle} - {sale.quantite} unité(s)

+
+

+ {new Date(sale.timestamp).toLocaleDateString()} +

+
+ ))} +
+
+
+ + + + + + Actions rapides + + + +
+ + + {canAccessAdmin && ( + + )} +
+
+
+
+
+ )} + + {activeView === "new-sale" && ( +
+ +
+ )} + + {activeView === "history" && ( +
+ +
+ )} + + {activeView === "admin" && canAccessAdmin && ( +
+ +
+ )} +
+ ); }