Checkpoint: Affichage unifié des formateurs dans la page Utilisateurs

## Modifications effectuées :

### Backend (server/routers.ts)
- Ajout de la procédure `users.listWithFormateurs` qui retourne :
  * Tous les utilisateurs
  * Tous les formateurs avec leur statut de compte (hasAccount, user)
- Cette procédure combine les données des tables `users` et `formateurs`

### Frontend (client/src/pages/AdminUsers.tsx)
- Remplacement de `users.list` par `users.listWithFormateurs`
- Ajout d'une section dédiée "Formateurs sans compte utilisateur" affichée en haut de la page
- Cette section liste tous les formateurs qui n'ont pas encore de compte utilisateur
- Bouton "Créer un compte" pour chaque formateur qui :
  * Pré-remplit le formulaire avec les données du formateur (nom, email)
  * Lie automatiquement le `formateurId`
  * Définit le rôle sur "formateur"

## Résultat
Les formateurs existants dans la table `formateurs` sont maintenant visibles dans la page Utilisateurs. L'administrateur peut facilement créer un compte pour chaque formateur en un clic, ce qui lie automatiquement le compte au formateur existant.
This commit is contained in:
Manus
2026-01-08 03:44:41 -05:00
parent 5367c7ea7a
commit 6184dff68f
3 changed files with 82 additions and 2 deletions

View File

@@ -58,8 +58,9 @@ export default function AdminUsers() {
formateurId: undefined as number | undefined,
});
const { data: users = [], refetch } = trpc.users.list.useQuery();
const { data: formateurs = [] } = trpc.formateurs.list.useQuery();
const { data: usersData, refetch } = trpc.users.listWithFormateurs.useQuery();
const users = usersData?.users || [];
const formateurs = usersData?.formateurs || [];
const createMutation = trpc.users.create.useMutation({
onSuccess: () => {
@@ -295,6 +296,46 @@ export default function AdminUsers() {
</div>
</div>
{/* Formateurs sans compte */}
{formateurs.filter(f => !f.hasAccount).length > 0 && (
<div className="mb-6 p-4 border border-orange-200 bg-orange-50 rounded-lg">
<h3 className="font-semibold text-orange-800 mb-2">
Formateurs sans compte utilisateur ({formateurs.filter(f => !f.hasAccount).length})
</h3>
<p className="text-sm text-orange-700 mb-4">
Ces formateurs existent dans le système mais n'ont pas de compte utilisateur. Créez un compte pour leur permettre de se connecter.
</p>
<div className="space-y-2">
{formateurs.filter(f => !f.hasAccount).map((formateur) => (
<div key={formateur.id} className="flex items-center justify-between bg-white p-3 rounded border">
<div>
<p className="font-medium">{formateur.nom}</p>
<p className="text-sm text-muted-foreground">{formateur.email || "Pas d'email"}</p>
</div>
<Button
size="sm"
onClick={() => {
setCreateForm({
openId: `formateur_${formateur.id}_${Date.now()}`,
name: formateur.nom,
email: formateur.email || "",
username: "",
password: "",
role: "formateur",
formateurId: formateur.id,
});
setCreateDialogOpen(true);
}}
>
<Plus className="h-4 w-4 mr-2" />
Créer un compte
</Button>
</div>
))}
</div>
</div>
)}
{/* Compteur de résultats */}
<div className="mb-4">
<p className="text-sm text-muted-foreground">