'use client'; import { useSession } from 'next-auth/react'; import { useRouter } from 'next/navigation'; import { useEffect, useState } from 'react'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { Label } from '@/components/ui/label'; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from '@/components/ui/table'; import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, } from '@/components/ui/dialog'; import { toast } from 'sonner'; import { DatePicker } from '@/components/ui/date-picker'; import { format } from 'date-fns'; interface Hour { id: string; date: string; duration: number; reason: string; status: string; userId: string; user: { email: string; firstName?: string; lastName?: string; role: string }; } interface Settings { name: string; logo: string; } export default function AdminPage() { const { data: session, status } = useSession(); const router = useRouter(); const [hours, setHours] = useState([]); const [settings, setSettings] = useState({ name: '', logo: '' }); const [newEmail, setNewEmail] = useState(''); const [newPassword, setNewPassword] = useState(''); const [newRole, setNewRole] = useState('MEMBER'); const [logoFile, setLogoFile] = useState(null); const [date, setDate] = useState(); const [duration, setDuration] = useState(''); const [reason, setReason] = useState(''); const [hoursInput, setHoursInput] = useState(''); const [minutesInput, setMinutesInput] = useState(''); const [newFirstName, setNewFirstName] = useState(''); const [newLastName, setNewLastName] = useState(''); const [showAll, setShowAll] = useState(false); const [dialogOpen, setDialogOpen] = useState(false); const [selectedUser, setSelectedUser] = useState<{ id: string; name: string; } | null>(null); useEffect(() => { if (status === 'loading') return; if ( !session || (session.user.role !== 'ADMIN' && session.user.role !== 'SUPER_ADMIN') ) { router.push('/dashboard'); return; } fetchHours(); fetchSettings(); }, [session, status, router]); const fetchHours = async () => { const res = await fetch('/api/hours'); if (res.ok) { const data = await res.json(); setHours(data); } }; const fetchSettings = async () => { const res = await fetch('/api/settings'); if (res.ok) { const data = await res.json(); setSettings(data); } }; const handleValidate = async (id: number, status: string) => { await fetch(`/api/hours/${id}`, { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ status }), }); fetchHours(); }; const handleUpdateSettings = async (e: React.FormEvent) => { e.preventDefault(); let logoPath = settings.logo; if (logoFile) { const formData = new FormData(); formData.append('file', logoFile); const uploadRes = await fetch('/api/upload', { method: 'POST', body: formData, }); if (uploadRes.ok) { const uploadData = await uploadRes.json(); logoPath = uploadData.path; } else { alert('Erreur upload'); return; } } await fetch('/api/settings', { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ name: settings.name, logo: logoPath }), }); setLogoFile(null); fetchSettings(); }; const handleCreateUser = async (e: React.FormEvent) => { e.preventDefault(); const res = await fetch('/api/auth/signup', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ email: newEmail, password: newPassword, role: newRole, firstName: newFirstName, lastName: newLastName, }), }); if (res.ok) { setNewEmail(''); setNewPassword(''); setNewRole('MEMBER'); setNewFirstName(''); setNewLastName(''); toast.success('Utilisateur créé'); } }; const handleExport = (format: string) => { window.open(`/api/export?format=${format}`, '_blank'); }; const handleAddHour = async (e: React.FormEvent) => { e.preventDefault(); const totalMinutes = parseInt(hoursInput) * 60 + parseInt(minutesInput); const dateString = date ? format(date, 'yyyy-MM-dd') : ''; const res = await fetch('/api/hours', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ date: dateString, duration: totalMinutes, reason, }), }); if (res.ok) { setDate(undefined); setHoursInput(''); setMinutesInput(''); setReason(''); fetchHours(); } }; const handleDelete = async (id: number) => { await fetch(`/api/hours/${id}`, { method: 'DELETE', }); fetchHours(); }; const userDisplayNames = hours.reduce( (acc, hour) => { const name = `${hour.user.firstName || ''} ${hour.user.lastName || ''}`.trim() || hour.user.email; acc[hour.user.email] = name; return acc; }, {} as Record, ); const userMap = {} as Record< string, { name: string; email: string; role: string } >; hours.forEach((hour) => { userMap[hour.userId] = { name: userDisplayNames[hour.user.email], email: hour.user.email, role: hour.user.role, }; }); const userTotals = hours.reduce( (acc, hour) => { if (hour.status === 'VALIDATED') { acc[hour.userId] = (acc[hour.userId] || 0) + hour.duration; } return acc; }, {} as Record, ); const handleDeleteUser = async () => { if (!selectedUser) return; await fetch(`/api/users/${selectedUser.id}`, { method: 'DELETE' }); setDialogOpen(false); setSelectedUser(null); fetchHours(); }; if (status === 'loading') return
Chargement...
; const isSuperAdmin = session?.user?.role === 'SUPER_ADMIN'; const sortedHours = hours.sort( (a, b) => new Date(b.date).getTime() - new Date(a.date).getTime(), ); const displayedHours = showAll ? sortedHours : sortedHours.slice(0, 10); const formatHours = (minutes: number) => { const h = Math.floor(minutes / 60); const m = minutes % 60; return `${h}h ${m}min`; }; return (

Administration

Ajouter des heures
setHoursInput(e.target.value)} required />
setMinutesInput(e.target.value)} required />
setReason(e.target.value)} required />
Gestion des heures Date Durée Raison Statut Utilisateur Actions {displayedHours.map((hour) => ( {new Date(hour.date).toLocaleDateString()} {hour.duration} min {hour.reason} {hour.status} {userDisplayNames[hour.user.email]} {hour.status === 'VALIDATED' || hour.status === 'REJECTED' ? ( ) : ( <> )} ))}
{hours.length > 10 && !showAll && (
)}

Totaux par utilisateur

Utilisateur Heures Validées Actions {Object.entries(userTotals).map(([userId, total]) => ( {userMap[userId]?.name} {formatHours(total)} {userMap[userId]?.role === 'SUPER_ADMIN' ? ( 'Super Admin' ) : ( )} ))}
{isSuperAdmin && ( Créer un compte
setNewEmail(e.target.value)} required />
setNewPassword(e.target.value)} required />
setNewFirstName(e.target.value)} required />
setNewLastName(e.target.value)} required />
)} Paramètres du Club
setSettings({ ...settings, name: e.target.value }) } />
setLogoFile(e.target.files?.[0] || null)} /> {settings.logo &&

Actuel : {settings.logo}

}
{selectedUser && ( Confirmation Êtes-vous sûr de vouloir supprimer cet utilisateur ? )}
); }