Checkpoint: Ajout de la fonctionnalité de création d'utilisateurs : ajout de la fonction createUser dans db.ts, création de la procédure tRPC users.create, ajout du bouton "Ajouter un utilisateur" dans la page AdminUsers avec icône Plus, création du dialogue de création avec formulaire complet (OpenID, nom, email, rôle) et gestion des états de création avec validation et messages de succès/erreur
This commit is contained in:
@@ -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<string>("all");
|
||||
const [filterStatus, setFilterStatus] = useState<string>("all");
|
||||
const [createDialogOpen, setCreateDialogOpen] = useState(false);
|
||||
const [editDialogOpen, setEditDialogOpen] = useState(false);
|
||||
const [deleteDialogOpen, setDeleteDialogOpen] = useState(false);
|
||||
const [selectedUser, setSelectedUser] = useState<any>(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 (
|
||||
<div className="container mx-auto py-8">
|
||||
<div className="mb-6">
|
||||
<h1 className="text-3xl font-bold mb-2">Gestion des Utilisateurs</h1>
|
||||
<p className="text-muted-foreground">
|
||||
Gérez les comptes utilisateurs de l'application
|
||||
</p>
|
||||
<div className="mb-6 flex justify-between items-start">
|
||||
<div>
|
||||
<h1 className="text-3xl font-bold mb-2">Gestion des Utilisateurs</h1>
|
||||
<p className="text-muted-foreground">
|
||||
Gérez les comptes utilisateurs de l'application
|
||||
</p>
|
||||
</div>
|
||||
<Button onClick={handleCreate}>
|
||||
<Plus className="h-4 w-4 mr-2" />
|
||||
Ajouter un utilisateur
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
{/* Filtres */}
|
||||
@@ -280,6 +330,78 @@ export default function AdminUsers() {
|
||||
</Table>
|
||||
</div>
|
||||
|
||||
{/* Dialog de création */}
|
||||
<Dialog open={createDialogOpen} onOpenChange={setCreateDialogOpen}>
|
||||
<DialogContent>
|
||||
<DialogHeader>
|
||||
<DialogTitle>Créer un nouvel utilisateur</DialogTitle>
|
||||
<DialogDescription>
|
||||
Ajoutez un nouvel utilisateur à l'application
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
|
||||
<div className="space-y-4">
|
||||
<div>
|
||||
<Label htmlFor="createOpenId">Identifiant OpenID *</Label>
|
||||
<Input
|
||||
id="createOpenId"
|
||||
value={createForm.openId}
|
||||
onChange={(e) => setCreateForm({ ...createForm, openId: e.target.value })}
|
||||
placeholder="Identifiant unique de l'utilisateur"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<Label htmlFor="createName">Nom</Label>
|
||||
<Input
|
||||
id="createName"
|
||||
value={createForm.name}
|
||||
onChange={(e) => setCreateForm({ ...createForm, name: e.target.value })}
|
||||
placeholder="Nom de l'utilisateur"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<Label htmlFor="createEmail">Email</Label>
|
||||
<Input
|
||||
id="createEmail"
|
||||
type="email"
|
||||
value={createForm.email}
|
||||
onChange={(e) => setCreateForm({ ...createForm, email: e.target.value })}
|
||||
placeholder="email@exemple.com"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<Label htmlFor="createRole">Rôle</Label>
|
||||
<Select
|
||||
value={createForm.role}
|
||||
onValueChange={(value: "user" | "admin") =>
|
||||
setCreateForm({ ...createForm, role: value })
|
||||
}
|
||||
>
|
||||
<SelectTrigger id="createRole">
|
||||
<SelectValue />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="user">Utilisateur</SelectItem>
|
||||
<SelectItem value="admin">Administrateur</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<DialogFooter>
|
||||
<Button variant="outline" onClick={() => setCreateDialogOpen(false)}>
|
||||
Annuler
|
||||
</Button>
|
||||
<Button onClick={handleSaveCreate} disabled={createMutation.isPending}>
|
||||
{createMutation.isPending ? "Création..." : "Créer"}
|
||||
</Button>
|
||||
</DialogFooter>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
|
||||
{/* Dialog de modification */}
|
||||
<Dialog open={editDialogOpen} onOpenChange={setEditDialogOpen}>
|
||||
<DialogContent>
|
||||
|
||||
Reference in New Issue
Block a user