Checkpoint: Centralisation de la création des formateurs
## Modifications effectuées : ### Page Formateurs (Configuration > Formateurs) - Suppression du bouton "Ajouter un formateur" - Suppression du dialogue de création et des mutations associées - Ajout d'un message informatif indiquant que la création se fait via Configuration > Utilisateurs - La page conserve les fonctionnalités de modification et suppression des formateurs existants ### Logique de création - Les formateurs doivent maintenant être créés uniquement via Configuration > Utilisateurs - Lors de la création d'un utilisateur avec le rôle "Formateur", celui-ci apparaît automatiquement dans la page Formateurs - Cette centralisation évite les doublons et simplifie le workflow de gestion La page Formateurs devient une page de consultation et de gestion (modification email, suppression) plutôt qu'une page de création.
This commit is contained in:
@@ -33,10 +33,10 @@ import {
|
|||||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
|
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
|
||||||
import { Badge } from "@/components/ui/badge";
|
import { Badge } from "@/components/ui/badge";
|
||||||
import { toast } from "sonner";
|
import { toast } from "sonner";
|
||||||
import { Plus, Pencil, Trash2, Mail, User, AlertCircle, CheckCircle2 } from "lucide-react";
|
import { Pencil, Trash2, Mail, User, AlertCircle, CheckCircle2 } from "lucide-react";
|
||||||
|
|
||||||
export default function AdminFormateurs() {
|
export default function AdminFormateurs() {
|
||||||
const [isCreateDialogOpen, setIsCreateDialogOpen] = useState(false);
|
|
||||||
const [isEditDialogOpen, setIsEditDialogOpen] = useState(false);
|
const [isEditDialogOpen, setIsEditDialogOpen] = useState(false);
|
||||||
const [isDeleteDialogOpen, setIsDeleteDialogOpen] = useState(false);
|
const [isDeleteDialogOpen, setIsDeleteDialogOpen] = useState(false);
|
||||||
const [selectedFormateur, setSelectedFormateur] = useState<{
|
const [selectedFormateur, setSelectedFormateur] = useState<{
|
||||||
@@ -50,17 +50,7 @@ export default function AdminFormateurs() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const { data: formateurs, isLoading, refetch } = trpc.formateurs.list.useQuery();
|
const { data: formateurs, isLoading, refetch } = trpc.formateurs.list.useQuery();
|
||||||
const createMutation = trpc.formateurs.create.useMutation({
|
|
||||||
onSuccess: () => {
|
|
||||||
toast.success("Formateur créé avec succès");
|
|
||||||
setIsCreateDialogOpen(false);
|
|
||||||
setFormData({ nom: "", email: "" });
|
|
||||||
refetch();
|
|
||||||
},
|
|
||||||
onError: (error) => {
|
|
||||||
toast.error(`Erreur: ${error.message}`);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
const updateMutation = trpc.formateurs.update.useMutation({
|
const updateMutation = trpc.formateurs.update.useMutation({
|
||||||
onSuccess: () => {
|
onSuccess: () => {
|
||||||
toast.success("Formateur mis à jour avec succès");
|
toast.success("Formateur mis à jour avec succès");
|
||||||
@@ -84,16 +74,7 @@ export default function AdminFormateurs() {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const handleCreate = () => {
|
|
||||||
if (!formData.nom.trim()) {
|
|
||||||
toast.error("Le nom est obligatoire");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
createMutation.mutate({
|
|
||||||
nom: formData.nom.trim(),
|
|
||||||
email: formData.email.trim() || undefined,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleEdit = () => {
|
const handleEdit = () => {
|
||||||
if (!selectedFormateur) return;
|
if (!selectedFormateur) return;
|
||||||
@@ -133,20 +114,18 @@ export default function AdminFormateurs() {
|
|||||||
return (
|
return (
|
||||||
<DashboardLayout>
|
<DashboardLayout>
|
||||||
<div className="space-y-6">
|
<div className="space-y-6">
|
||||||
<div className="flex items-center justify-between">
|
<div>
|
||||||
<div>
|
<h1 className="text-2xl font-bold">Gestion des Formateurs</h1>
|
||||||
<h1 className="text-2xl font-bold">Gestion des Formateurs</h1>
|
<p className="text-muted-foreground">
|
||||||
<p className="text-muted-foreground">
|
Gérez les formateurs et leurs adresses email pour les notifications
|
||||||
Gérez les formateurs et leurs adresses email pour les notifications
|
</p>
|
||||||
</p>
|
<Card className="mt-4 border-blue-200 bg-blue-50">
|
||||||
</div>
|
<CardContent className="pt-4">
|
||||||
<Button onClick={() => {
|
<p className="text-sm text-blue-700">
|
||||||
setFormData({ nom: "", email: "" });
|
<strong>Note :</strong> Pour créer un nouveau formateur, rendez-vous dans <strong>Configuration > Utilisateurs</strong> et créez un compte avec le rôle "Formateur". Les formateurs créés apparaîtront automatiquement ici.
|
||||||
setIsCreateDialogOpen(true);
|
</p>
|
||||||
}}>
|
</CardContent>
|
||||||
<Plus className="h-4 w-4 mr-2" />
|
</Card>
|
||||||
Ajouter un formateur
|
|
||||||
</Button>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Alerte si des formateurs n'ont pas d'email */}
|
{/* Alerte si des formateurs n'ont pas d'email */}
|
||||||
@@ -304,50 +283,7 @@ export default function AdminFormateurs() {
|
|||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
|
|
||||||
{/* Dialog de création */}
|
|
||||||
<Dialog open={isCreateDialogOpen} onOpenChange={setIsCreateDialogOpen}>
|
|
||||||
<DialogContent>
|
|
||||||
<DialogHeader>
|
|
||||||
<DialogTitle>Ajouter un formateur</DialogTitle>
|
|
||||||
<DialogDescription>
|
|
||||||
Renseignez les informations du nouveau formateur. L'email est optionnel mais
|
|
||||||
nécessaire pour recevoir les notifications.
|
|
||||||
</DialogDescription>
|
|
||||||
</DialogHeader>
|
|
||||||
<div className="space-y-4 py-4">
|
|
||||||
<div className="space-y-2">
|
|
||||||
<Label htmlFor="nom">Nom complet *</Label>
|
|
||||||
<Input
|
|
||||||
id="nom"
|
|
||||||
value={formData.nom}
|
|
||||||
onChange={(e) => setFormData({ ...formData, nom: e.target.value })}
|
|
||||||
placeholder="Jean Dupont"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div className="space-y-2">
|
|
||||||
<Label htmlFor="email">Adresse email</Label>
|
|
||||||
<Input
|
|
||||||
id="email"
|
|
||||||
type="email"
|
|
||||||
value={formData.email}
|
|
||||||
onChange={(e) => setFormData({ ...formData, email: e.target.value })}
|
|
||||||
placeholder="jean.dupont@exemple.fr"
|
|
||||||
/>
|
|
||||||
<p className="text-sm text-muted-foreground">
|
|
||||||
L'email permet de recevoir les notifications d'inscription et d'annulation.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<DialogFooter>
|
|
||||||
<Button variant="outline" onClick={() => setIsCreateDialogOpen(false)}>
|
|
||||||
Annuler
|
|
||||||
</Button>
|
|
||||||
<Button onClick={handleCreate} disabled={createMutation.isPending}>
|
|
||||||
{createMutation.isPending ? "Création..." : "Créer"}
|
|
||||||
</Button>
|
|
||||||
</DialogFooter>
|
|
||||||
</DialogContent>
|
|
||||||
</Dialog>
|
|
||||||
|
|
||||||
{/* Dialog de modification */}
|
{/* Dialog de modification */}
|
||||||
<Dialog open={isEditDialogOpen} onOpenChange={setIsEditDialogOpen}>
|
<Dialog open={isEditDialogOpen} onOpenChange={setIsEditDialogOpen}>
|
||||||
|
|||||||
5
todo.md
5
todo.md
@@ -481,3 +481,8 @@
|
|||||||
- [x] Déplacer "Suivi Questionnaires" vers TRAÇABILITÉ
|
- [x] Déplacer "Suivi Questionnaires" vers TRAÇABILITÉ
|
||||||
- [x] Déplacer "Établissements" vers TRAÇABILITÉ
|
- [x] Déplacer "Établissements" vers TRAÇABILITÉ
|
||||||
- [x] Déplacer "Historique" (sous-menu de Rappels) vers TRAÇABILITÉ avec le nom "Rappels"
|
- [x] Déplacer "Historique" (sous-menu de Rappels) vers TRAÇABILITÉ avec le nom "Rappels"
|
||||||
|
|
||||||
|
## Centralisation de la création des formateurs
|
||||||
|
- [x] Retirer le bouton de création de formateur de la page Formateurs
|
||||||
|
- [x] Supprimer le dialogue de création et les mutations associées
|
||||||
|
- [x] Ajouter un message explicatif indiquant que la création se fait via la page Utilisateurs
|
||||||
|
|||||||
Reference in New Issue
Block a user