From b7b08b1961367d411f1b1f0b44fe5e8dccd10783 Mon Sep 17 00:00:00 2001 From: soufiane Date: Wed, 3 Dec 2025 14:34:29 +0100 Subject: [PATCH] feat: improve admin dashboard design and add new charts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add gradient backgrounds and modern styling to all admin pages - Add Statut des Tickets donut chart - Add Types d'Utilisateurs donut chart - Update headers and card containers with consistent design 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- app/admin/dashboard/page.tsx | 226 ++++++++++++++++++++++-------- app/admin/lots/page.tsx | 16 ++- app/admin/marketing-data/page.tsx | 9 +- app/admin/tickets/page.tsx | 10 +- app/admin/tirages/page.tsx | 7 +- app/admin/utilisateurs/page.tsx | 11 +- 6 files changed, 202 insertions(+), 77 deletions(-) diff --git a/app/admin/dashboard/page.tsx b/app/admin/dashboard/page.tsx index 4cea927..3afdb70 100644 --- a/app/admin/dashboard/page.tsx +++ b/app/admin/dashboard/page.tsx @@ -172,6 +172,21 @@ export default function AdminDashboardAdvanced() { (city) => city.city && city.city.trim() !== "" && !city.city.toLowerCase().includes("non spécifié") && city.count > 0 ); + // Données pour le graphique des statuts de tickets + const ticketStatusData = [ + { name: "Distribués", value: stats.tickets.distributed || 0, color: "#10b981" }, + { name: "En attente", value: stats.tickets.pending || 0, color: "#f59e0b" }, + { name: "Réclamés", value: stats.tickets.claimed || 0, color: "#3b82f6" }, + { name: "Rejetés", value: stats.tickets.rejected || 0, color: "#ef4444" }, + ].filter(item => item.value > 0); + + // Données pour le graphique des utilisateurs par type + const userTypeData = [ + { name: "Clients", value: stats.users.clients || 0, color: "#10b981" }, + { name: "Employés", value: stats.users.employees || 0, color: "#8b5cf6" }, + { name: "Admins", value: stats.users.admins || 0, color: "#3b82f6" }, + ].filter(item => item.value > 0); + const ticketDistributedPercent = stats.tickets.total > 0 ? ((stats.tickets.distributed / stats.tickets.total) * 100).toFixed(1) : 0; @@ -180,33 +195,35 @@ export default function AdminDashboardAdvanced() { : 0; return ( -
+
{/* Header avec contrĂ´les */}
-

Dashboard Administrateur Avancé

-

+

+ Dashboard Administrateur +

+

Statistiques complètes et analyses en temps réel

{/* Auto-refresh toggle */} -
{/* Filter period */} -
- - Période: - {["all", "week", "month", "year"].map((period) => ( - - ))} +
+
+ + Période: +
+
+ {["all", "week", "month", "year"].map((period) => ( + + ))} +
@@ -288,9 +309,11 @@ export default function AdminDashboardAdvanced() {
{/* Graphique répartition des lots */} {prizeChartData.length > 0 && ( -
-

- +
+

+
+ +
Répartition des Lots

@@ -315,11 +338,82 @@ export default function AdminDashboardAdvanced() {
)} + {/* Graphique Statut des Tickets */} + {ticketStatusData.length > 0 && ( +
+

+
+ +
+ Statut des Tickets +

+ + + `${name}: ${value}`} + outerRadius={80} + innerRadius={40} + fill="#8884d8" + dataKey="value" + > + {ticketStatusData.map((entry, index) => ( + + ))} + + + + + +
+ )} +

+ + {/* Deuxième ligne de graphiques */} +
+ {/* Graphique Types d'Utilisateurs */} + {userTypeData.length > 0 && ( +
+

+
+ +
+ Types d'Utilisateurs +

+ + + `${name}: ${value}`} + outerRadius={80} + innerRadius={40} + fill="#8884d8" + dataKey="value" + > + {userTypeData.map((entry, index) => ( + + ))} + + + + + +
+ )} + {/* Graphique répartition par genre */} {genderChartData.length > 0 && ( -
-

- +
+

+
+ +
Répartition par Genre

@@ -331,6 +425,7 @@ export default function AdminDashboardAdvanced() { labelLine={false} label={({ name, value }) => `${name}: ${value}`} outerRadius={80} + innerRadius={40} fill="#8884d8" dataKey="value" > @@ -339,6 +434,7 @@ export default function AdminDashboardAdvanced() { ))} +
@@ -347,9 +443,11 @@ export default function AdminDashboardAdvanced() { {/* Graphique tranches d'âge */} {ageChartData.length > 0 && ( -
-

- +
+

+
+ +
Répartition par Âge

@@ -368,15 +466,17 @@ export default function AdminDashboardAdvanced() { {/* Section détaillée existante */}
{/* Statistiques Tickets détaillées */} -
-
-

- +
+
+

+
+ +
Statistiques des Tickets

Voir tout → @@ -402,15 +502,17 @@ export default function AdminDashboardAdvanced() {
{/* Utilisateurs */} -
-
-

- +
+
+

+
+ +
Utilisateurs

Voir tout → @@ -426,9 +528,11 @@ export default function AdminDashboardAdvanced() { {/* Top Villes - affiché uniquement s'il y a des vraies données de villes */} {topCitiesData.length > 0 && ( -
-

- +
+

+
+ +
Top 10 Villes des Participants

@@ -460,7 +564,7 @@ interface StatCardProps { } function StatCard({ title, value, subtitle, icon, color, link, trend }: StatCardProps) { - const colors = { + const iconColors = { blue: "bg-blue-100 text-blue-600", green: "bg-green-100 text-green-600", yellow: "bg-yellow-100 text-yellow-600", @@ -468,23 +572,31 @@ function StatCard({ title, value, subtitle, icon, color, link, trend }: StatCard red: "bg-red-100 text-red-600", }; + const valueColors = { + blue: "text-blue-600", + green: "text-green-600", + yellow: "text-yellow-500", + purple: "text-purple-600", + red: "text-red-600", + }; + return (
-
{icon}
+
{icon}
{trend && ( -
- +
+ {trend}
)}
-

{title}

-

{(value || 0).toLocaleString("fr-FR")}

- {subtitle &&

{subtitle}

} +

{title}

+

{(value || 0).toLocaleString("fr-FR")}

+ {subtitle &&

{subtitle}

} ); } diff --git a/app/admin/lots/page.tsx b/app/admin/lots/page.tsx index 25ab92a..205e8d0 100644 --- a/app/admin/lots/page.tsx +++ b/app/admin/lots/page.tsx @@ -3,5 +3,19 @@ import PrizeManagement from '@/components/admin/PrizeManagement'; export default function LotsPage() { - return ; + return ( +
+
+

+ Gestion des Lots & Prix +

+

+ Gérez les lots et prix du jeu-concours +

+
+
+ +
+
+ ); } diff --git a/app/admin/marketing-data/page.tsx b/app/admin/marketing-data/page.tsx index 08fb45a..d6ebab6 100644 --- a/app/admin/marketing-data/page.tsx +++ b/app/admin/marketing-data/page.tsx @@ -225,14 +225,13 @@ export default function MarketingPage() { const hasDemographicData = filteredGenderData.length > 0 || filteredAgeData.length > 0 || filteredCityData.length > 0; return ( -
+
{/* En-tĂŞte */} -
-

- +
+

Données Marketing

-

+

Statistiques et export des données pour vos campagnes d'emailing

diff --git a/app/admin/tickets/page.tsx b/app/admin/tickets/page.tsx index 92e790a..fe9a031 100644 --- a/app/admin/tickets/page.tsx +++ b/app/admin/tickets/page.tsx @@ -4,16 +4,16 @@ import TicketManagement from "@/components/admin/TicketManagement"; export default function AdminTicketsPage() { return ( -
-
-

+
+
+

Gestion des tickets

-

+

Consultez et gérez tous les tickets du jeu-concours

-
+
diff --git a/app/admin/tirages/page.tsx b/app/admin/tirages/page.tsx index 19da1c3..715d22d 100644 --- a/app/admin/tirages/page.tsx +++ b/app/admin/tirages/page.tsx @@ -364,11 +364,10 @@ ${report.draw.notifiedAt ? `📧 Gagnant notifié le: ${new Date(report.draw.not }; return ( -
+
{/* En-tĂŞte avec titre du prix */} -
-

- +
+

Tirage au Sort - {prizeName}

diff --git a/app/admin/utilisateurs/page.tsx b/app/admin/utilisateurs/page.tsx index f866077..195c591 100644 --- a/app/admin/utilisateurs/page.tsx +++ b/app/admin/utilisateurs/page.tsx @@ -1,19 +1,20 @@ "use client"; import UserManagement from "@/components/admin/UserManagement"; +import { Users } from "lucide-react"; export default function AdminUtilisateursPage() { return ( -

-
-

+
+
+

Gestion des utilisateurs

-

+

Gérez tous les comptes utilisateurs de la plateforme

-
+