Core Integration: - Create API client with TypeScript types for all endpoints - Implement authentication context provider for user state management - Add protected route component for dashboard access control - Connect login/register pages to backend authentication endpoints - Implement user session persistence with localStorage tokens Authentication: - Login page now connects to /api/auth/login endpoint - Register page connects to /api/auth/register with validation - Password strength requirements (min 8 chars) - Form validation and error handling - Automatic redirect to dashboard on successful auth - Logout functionality with session cleanup Protected Routes: - Dashboard pages require authentication - Non-authenticated users redirected to login - Loading spinner during auth verification - User name displayed in dashboard header - Proper session management Election/Vote APIs: - Dashboard fetches active elections from /api/elections/active - Display real election data with candidates count - Handle loading and error states - Skeleton loaders for better UX Type Safety: - Full TypeScript interfaces for all API responses - Proper error handling with try-catch blocks - API response types: AuthToken, VoterProfile, Election, Candidate, Vote, VoteHistory Environment: - API URL configurable via NEXT_PUBLIC_API_URL env variable - Default to http://localhost:8000 for local development 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
39 lines
1011 B
TypeScript
39 lines
1011 B
TypeScript
/**
|
|
* Protected Route Component
|
|
* Redirects to login if user is not authenticated
|
|
*/
|
|
|
|
"use client"
|
|
|
|
import { useAuth } from "@/lib/auth-context"
|
|
import { useRouter } from "next/navigation"
|
|
import { useEffect } from "react"
|
|
|
|
export function ProtectedRoute({ children }: { children: React.ReactNode }) {
|
|
const { isAuthenticated, isLoading } = useAuth()
|
|
const router = useRouter()
|
|
|
|
useEffect(() => {
|
|
if (!isLoading && !isAuthenticated) {
|
|
router.replace("/auth/login")
|
|
}
|
|
}, [isAuthenticated, isLoading, router])
|
|
|
|
if (isLoading) {
|
|
return (
|
|
<div className="min-h-screen flex items-center justify-center bg-background">
|
|
<div className="text-center space-y-4">
|
|
<div className="w-8 h-8 border-4 border-muted border-t-accent rounded-full animate-spin mx-auto" />
|
|
<p className="text-muted-foreground">Vérification de l'authentification...</p>
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|
|
|
|
if (!isAuthenticated) {
|
|
return null
|
|
}
|
|
|
|
return <>{children}</>
|
|
}
|