diff --git a/client/src/pages/AdminUsers.tsx b/client/src/pages/AdminUsers.tsx index bed879b..da7bc87 100644 --- a/client/src/pages/AdminUsers.tsx +++ b/client/src/pages/AdminUsers.tsx @@ -28,15 +28,22 @@ import { } from "@/components/ui/select"; import { Badge } from "@/components/ui/badge"; import { toast } from "sonner"; -import { Pencil, Trash2, UserCheck, UserX, Search } from "lucide-react"; +import { Pencil, Trash2, UserCheck, UserX, Search, Plus } from "lucide-react"; export default function AdminUsers() { const [searchTerm, setSearchTerm] = useState(""); const [filterRole, setFilterRole] = useState("all"); const [filterStatus, setFilterStatus] = useState("all"); + const [createDialogOpen, setCreateDialogOpen] = useState(false); const [editDialogOpen, setEditDialogOpen] = useState(false); const [deleteDialogOpen, setDeleteDialogOpen] = useState(false); const [selectedUser, setSelectedUser] = useState(null); + const [createForm, setCreateForm] = useState({ + openId: "", + name: "", + email: "", + role: "user" as "user" | "admin", + }); const [editForm, setEditForm] = useState({ name: "", email: "", @@ -44,6 +51,24 @@ export default function AdminUsers() { }); const { data: users = [], refetch } = trpc.users.list.useQuery(); + + const createMutation = trpc.users.create.useMutation({ + onSuccess: () => { + toast.success("Utilisateur créé avec succès"); + refetch(); + setCreateDialogOpen(false); + setCreateForm({ + openId: "", + name: "", + email: "", + role: "user", + }); + }, + onError: (error) => { + toast.error(`Erreur : ${error.message}`); + }, + }); + const updateMutation = trpc.users.update.useMutation({ onSuccess: () => { toast.success("Utilisateur modifié avec succès"); @@ -76,6 +101,25 @@ export default function AdminUsers() { }, }); + const handleCreate = () => { + setCreateDialogOpen(true); + }; + + const handleSaveCreate = () => { + if (!createForm.openId) { + toast.error("L'identifiant OpenID est obligatoire"); + return; + } + + createMutation.mutate({ + openId: createForm.openId, + name: createForm.name || undefined, + email: createForm.email || undefined, + role: createForm.role, + isActive: true, + }); + }; + const handleEdit = (user: any) => { setSelectedUser(user); setEditForm({ @@ -142,11 +186,17 @@ export default function AdminUsers() { return (
-
-

Gestion des Utilisateurs

-

- Gérez les comptes utilisateurs de l'application -

+
+
+

Gestion des Utilisateurs

+

+ Gérez les comptes utilisateurs de l'application +

+
+
{/* Filtres */} @@ -280,6 +330,78 @@ export default function AdminUsers() {
+ {/* Dialog de création */} + + + + Créer un nouvel utilisateur + + Ajoutez un nouvel utilisateur à l'application + + + +
+
+ + setCreateForm({ ...createForm, openId: e.target.value })} + placeholder="Identifiant unique de l'utilisateur" + /> +
+ +
+ + setCreateForm({ ...createForm, name: e.target.value })} + placeholder="Nom de l'utilisateur" + /> +
+ +
+ + setCreateForm({ ...createForm, email: e.target.value })} + placeholder="email@exemple.com" + /> +
+ +
+ + +
+
+ + + + + +
+
+ {/* Dialog de modification */} diff --git a/server/db.ts b/server/db.ts index 7c1d6f7..9c03231 100644 --- a/server/db.ts +++ b/server/db.ts @@ -376,6 +376,14 @@ export async function deleteInscription(id: number) { // ==================== GESTION DES UTILISATEURS ==================== +export async function createUser(data: InsertUser) { + const db = await getDb(); + if (!db) throw new Error("Database not available"); + + const result = await db.insert(users).values(data); + return result; +} + export async function getAllUsers() { const db = await getDb(); if (!db) return []; diff --git a/server/routers.ts b/server/routers.ts index 2170316..77f2a22 100644 --- a/server/routers.ts +++ b/server/routers.ts @@ -548,6 +548,17 @@ export const appRouter = router({ return db.getUserById(input.id); }), + create: adminProcedure.input(z.object({ + openId: z.string().min(1), + name: z.string().optional(), + email: z.string().email().optional(), + role: z.enum(["user", "admin"]).default("user"), + isActive: z.boolean().default(true), + })).mutation(async ({ input }) => { + await db.createUser(input); + return { success: true }; + }), + update: adminProcedure.input(z.object({ id: z.number(), name: z.string().optional(), diff --git a/todo.md b/todo.md index 54e894f..3eec80b 100644 --- a/todo.md +++ b/todo.md @@ -188,3 +188,10 @@ - [x] Ajouter la gestion des rôles (admin, user) - [x] Intégrer la page dans le menu de navigation - [x] Tester toutes les fonctionnalités de gestion des utilisateurs + +## Ajout de la fonctionnalité de création d'utilisateurs + +- [x] Ajouter une procédure tRPC pour créer un nouvel utilisateur +- [x] Ajouter un bouton "Ajouter un utilisateur" dans la page AdminUsers +- [x] Créer un dialogue de création avec formulaire (nom, email, rôle) +- [x] Tester la création d'un nouvel utilisateur