Alexis Bruneteau 14eff8d0da feat: Rebuild frontend with Next.js and shadcn/ui components
- 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>
2025-11-06 17:02:14 +01:00

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