- Migrate from React CRA to Next.js 15 with modern architecture - Implement comprehensive shadcn/ui component library - Create complete dashboard system with layouts and navigation - Build authentication pages (login, register) with proper forms - Implement vote management pages (active, upcoming, history, archives) - Add user profile management with security settings - Configure Tailwind CSS with custom dark theme (accent: #e8704b) - Setup TypeScript with strict type checking - Backup old React-based frontend to .backups/frontend-old - All pages compile successfully and build passes linting Pages created: - Home page with hero section and features - Authentication (login/register) - Dashboard with stats and vote cards - Vote management (active, upcoming, history, archives) - User profile with form validation 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
170 lines
5.5 KiB
TypeScript
170 lines
5.5 KiB
TypeScript
"use client"
|
|
|
|
import Link from "next/link"
|
|
import { Button } from "@/components/ui/button"
|
|
import { Card, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"
|
|
import { BarChart3, CheckCircle, Clock, Archive } from "lucide-react"
|
|
|
|
export default function DashboardPage() {
|
|
// Mock data - would come from backend
|
|
const stats = [
|
|
{
|
|
title: "Votes Actifs",
|
|
value: "3",
|
|
icon: CheckCircle,
|
|
color: "text-accent",
|
|
href: "/dashboard/votes/active",
|
|
},
|
|
{
|
|
title: "À Venir",
|
|
value: "5",
|
|
icon: Clock,
|
|
color: "text-blue-500",
|
|
href: "/dashboard/votes/upcoming",
|
|
},
|
|
{
|
|
title: "Votes Passés",
|
|
value: "12",
|
|
icon: BarChart3,
|
|
color: "text-green-500",
|
|
href: "/dashboard/votes/history",
|
|
},
|
|
{
|
|
title: "Archives",
|
|
value: "8",
|
|
icon: Archive,
|
|
color: "text-gray-500",
|
|
href: "/dashboard/votes/archives",
|
|
},
|
|
]
|
|
|
|
const activeVotes = [
|
|
{
|
|
id: 1,
|
|
title: "Election Présidentielle 2025",
|
|
description: "Première manche - Scrutin dimanche",
|
|
progress: 65,
|
|
endDate: "6 Nov 2025 à 20:00",
|
|
},
|
|
{
|
|
id: 2,
|
|
title: "Référendum : Réforme Constitutionnelle",
|
|
description: "Consultez la population",
|
|
progress: 45,
|
|
endDate: "8 Nov 2025 à 18:00",
|
|
},
|
|
{
|
|
id: 3,
|
|
title: "Election Municipale - Île-de-France",
|
|
description: "Élection locale régionale",
|
|
progress: 78,
|
|
endDate: "10 Nov 2025 à 17:00",
|
|
},
|
|
]
|
|
|
|
return (
|
|
<div className="space-y-8">
|
|
{/* Header */}
|
|
<div>
|
|
<h1 className="text-3xl font-bold">Tableau de Bord</h1>
|
|
<p className="text-muted-foreground mt-2">
|
|
Gérez et participez à vos élections en toute sécurité
|
|
</p>
|
|
</div>
|
|
|
|
{/* Stats Grid */}
|
|
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6">
|
|
{stats.map((stat) => {
|
|
const Icon = stat.icon
|
|
return (
|
|
<Link key={stat.href} href={stat.href}>
|
|
<Card className="hover:border-accent transition-colors cursor-pointer h-full">
|
|
<CardHeader>
|
|
<div className="flex items-center justify-between">
|
|
<div>
|
|
<CardDescription className="text-xs">{stat.title}</CardDescription>
|
|
<CardTitle className="text-2xl mt-2">{stat.value}</CardTitle>
|
|
</div>
|
|
<Icon className={`w-8 h-8 ${stat.color}`} />
|
|
</div>
|
|
</CardHeader>
|
|
</Card>
|
|
</Link>
|
|
)
|
|
})}
|
|
</div>
|
|
|
|
{/* Active Votes Section */}
|
|
<div className="space-y-4">
|
|
<div className="flex items-center justify-between">
|
|
<h2 className="text-2xl font-bold">Votes Actifs</h2>
|
|
<Link href="/dashboard/votes/active">
|
|
<Button variant="outline">Voir tous</Button>
|
|
</Link>
|
|
</div>
|
|
|
|
<div className="grid gap-6">
|
|
{activeVotes.map((vote) => (
|
|
<Link key={vote.id} href={`/dashboard/votes/active/${vote.id}`}>
|
|
<Card className="hover:border-accent transition-colors cursor-pointer">
|
|
<CardHeader>
|
|
<div className="space-y-4">
|
|
<div>
|
|
<CardTitle className="text-lg">{vote.title}</CardTitle>
|
|
<CardDescription className="mt-1">{vote.description}</CardDescription>
|
|
</div>
|
|
|
|
{/* Progress Bar */}
|
|
<div className="space-y-2">
|
|
<div className="flex justify-between text-sm">
|
|
<span className="text-muted-foreground">Participation</span>
|
|
<span className="font-medium">{vote.progress}%</span>
|
|
</div>
|
|
<div className="w-full h-2 bg-muted rounded-full overflow-hidden">
|
|
<div
|
|
className="h-full bg-gradient-to-r from-accent to-accent/60 transition-all"
|
|
style={{ width: `${vote.progress}%` }}
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Footer Info */}
|
|
<div className="flex items-center justify-between pt-2 border-t border-border">
|
|
<span className="text-xs text-muted-foreground">
|
|
Ferme le {vote.endDate}
|
|
</span>
|
|
<Button size="sm">Participer</Button>
|
|
</div>
|
|
</div>
|
|
</CardHeader>
|
|
</Card>
|
|
</Link>
|
|
))}
|
|
</div>
|
|
</div>
|
|
|
|
{/* Quick Actions */}
|
|
<div className="bg-card border border-border rounded-lg p-6 space-y-4">
|
|
<h3 className="font-bold text-lg">Actions Rapides</h3>
|
|
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
|
|
<Link href="/dashboard/votes/active">
|
|
<Button variant="outline" className="w-full">
|
|
Voir mes votes actifs
|
|
</Button>
|
|
</Link>
|
|
<Link href="/dashboard/votes/history">
|
|
<Button variant="outline" className="w-full">
|
|
Historique de votes
|
|
</Button>
|
|
</Link>
|
|
<Link href="/dashboard/profile">
|
|
<Button variant="outline" className="w-full">
|
|
Gérer mon profil
|
|
</Button>
|
|
</Link>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|