import { useState, useEffect } from "react"; import { trpc } from "@/lib/trpc"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"; import { Switch } from "@/components/ui/switch"; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"; import { Badge } from "@/components/ui/badge"; import { toast } from "sonner"; import { Loader2, Save, Settings, CheckCircle2, XCircle, History } from "lucide-react"; import DashboardLayout from "@/components/DashboardLayout"; export default function AdminParametres() { const { data: parametres, isLoading, refetch } = trpc.parametres.get.useQuery(); const { data: historique, isLoading: isLoadingHistorique } = trpc.parametres.getHistorique.useQuery({ limit: 20 }); const [urlPublique, setUrlPublique] = useState(""); const [delaiExpirationQR, setDelaiExpirationQR] = useState(30); const [dureeValiditeToken, setDureeValiditeToken] = useState(24); const [notificationsActives, setNotificationsActives] = useState(true); const [testUrlStatus, setTestUrlStatus] = useState<{ loading: boolean; result?: { accessible: boolean; message: string } }>({ loading: false }); // Initialiser les valeurs quand les données sont chargées useEffect(() => { if (parametres) { setUrlPublique(parametres.urlPublique); setDelaiExpirationQR(parametres.delaiExpirationQR); setDureeValiditeToken(parametres.dureeValiditeToken); setNotificationsActives(parametres.notificationsActives); } }, [parametres]); const updateMutation = trpc.parametres.update.useMutation({ onSuccess: () => { toast.success("Paramètres mis à jour avec succès"); refetch(); }, onError: (error) => { toast.error(`Erreur : ${error.message}`); }, }); const testUrlMutation = trpc.parametres.testerUrl.useMutation({ onSuccess: (result) => { setTestUrlStatus({ loading: false, result }); if (result.accessible) { toast.success(result.message); } else { toast.error(result.message); } }, onError: (error) => { setTestUrlStatus({ loading: false }); toast.error(`Erreur lors du test : ${error.message}`); }, }); const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); // Validation de l'URL try { new URL(urlPublique); } catch { toast.error("L'URL saisie n'est pas valide"); return; } updateMutation.mutate({ urlPublique, delaiExpirationQR, dureeValiditeToken, notificationsActives, }); }; const handleTestUrl = () => { try { new URL(urlPublique); setTestUrlStatus({ loading: true }); testUrlMutation.mutate({ url: urlPublique }); } catch { toast.error("L'URL saisie n'est pas valide"); } }; if (isLoading) { return ( ); } return ( Paramètres de l'application Configuration globale de l'application {/* Configuration générale */} Configuration générale Paramètres globaux de l'application {/* URL publique */} URL publique de l'application { setUrlPublique(e.target.value); setTestUrlStatus({ loading: false }); }} required className="flex-1" /> {testUrlStatus.loading ? ( <> Test... > ) : testUrlStatus.result ? ( testUrlStatus.result.accessible ? ( <> Accessible > ) : ( <> Erreur > ) ) : ( "Tester l'URL" )} Cette URL est utilisée pour générer les QR codes d'émargement. Exemple : https://formations.itinova.org (sans slash à la fin) {/* Délai d'expiration QR codes */} Délai d'expiration des QR codes (minutes) setDelaiExpirationQR(parseInt(e.target.value))} required /> Durée de validité des QR codes d'émargement après leur génération (entre 5 et 120 minutes) {/* Durée de validité des tokens */} Durée de validité des tokens d'émargement (heures) setDureeValiditeToken(parseInt(e.target.value))} required /> Durée pendant laquelle les tokens d'émargement restent valides (entre 1 et 72 heures) {/* Notifications actives */} Notifications automatiques Activer ou désactiver l'envoi automatique de notifications {updateMutation.isPending ? ( <> Enregistrement... > ) : ( <> Enregistrer > )} {/* Historique des modifications */} Historique des modifications Traçabilité des changements de paramètres {isLoadingHistorique ? ( ) : !historique || historique.length === 0 ? ( Aucune modification enregistrée ) : ( Date Utilisateur Champ modifié Ancienne valeur Nouvelle valeur {historique.map((entry) => ( {new Date(entry.dateModification).toLocaleString('fr-FR', { day: '2-digit', month: '2-digit', year: 'numeric', hour: '2-digit', minute: '2-digit', })} {entry.userName} {entry.champModifie} {entry.ancienneValeur || vide} {entry.nouvelleValeur || vide} ))} )} ); }
Configuration globale de l'application
Cette URL est utilisée pour générer les QR codes d'émargement. Exemple : https://formations.itinova.org (sans slash à la fin)
Durée de validité des QR codes d'émargement après leur génération (entre 5 et 120 minutes)
Durée pendant laquelle les tokens d'émargement restent valides (entre 1 et 72 heures)
Activer ou désactiver l'envoi automatique de notifications