"use client"; import { useState, useEffect } from "react"; import { motion } from "framer-motion"; import { UserPlus, Trash2, ShieldCheck, Edit2, Users, FileText, Folder } from "lucide-react"; import Button from "../ui/Button"; import Modal from "../ui/Modal"; import UserAvatar from "../ui/UserAvatar"; import { EmptyState } from "../ui/PageHeader"; import toast from "react-hot-toast"; interface UserData { id: string; username: string | null; email: string | null; name: string | null; role: string; twoFactorEnabled: boolean; createdAt: string; _count?: { files: number; folders: number }; } const roleLabels: Record = { admin: "Admin", user: "Utilisateur", viewer: "Lecteur" }; const roleColors: Record = { admin: "bg-rose-500/10 text-rose-600 dark:text-rose-400 ring-rose-500/20", user: "bg-blue-500/10 text-blue-700 dark:text-blue-300 ring-blue-500/20", viewer: "bg-gray-100 text-gray-600 dark:bg-white/[0.06] dark:text-gray-300 ring-gray-500/15", }; const emptyForm = { username: "", name: "", password: "", role: "user" }; function UserForm({ create, form, setForm }: { create: boolean; form: typeof emptyForm; setForm: (f: typeof emptyForm) => void }) { return (
setForm({ ...form, username: e.target.value.toLowerCase().replace(/\s/g, "") })} className="field h-11" autoFocus={create} autoComplete="off" />
setForm({ ...form, name: e.target.value })} className="field h-11" />
setForm({ ...form, password: e.target.value })} className="field h-11" autoComplete="new-password" />
); } export default function UserManagement() { const [users, setUsers] = useState([]); const [loading, setLoading] = useState(true); const [showCreate, setShowCreate] = useState(false); const [editUser, setEditUser] = useState(null); const [deleteUser, setDeleteUser] = useState(null); const [saving, setSaving] = useState(false); const [form, setForm] = useState(emptyForm); const fetchUsers = async () => { const res = await fetch("/api/users"); if (res.ok) setUsers(await res.json()); setLoading(false); }; useEffect(() => { fetchUsers(); }, []); const handleCreate = async () => { setSaving(true); const res = await fetch("/api/users", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(form) }); setSaving(false); if (res.ok) { toast.success("Utilisateur créé"); setShowCreate(false); setForm(emptyForm); fetchUsers(); } else { const data = await res.json(); toast.error(data.error || "Erreur"); } }; const handleUpdate = async () => { if (!editUser) return; const data: Record = {}; if (form.name) data.name = form.name; if (form.username) data.username = form.username; if (form.role) data.role = form.role; if (form.password) data.password = form.password; setSaving(true); const res = await fetch(`/api/users/${editUser.id}`, { method: "PATCH", headers: { "Content-Type": "application/json" }, body: JSON.stringify(data) }); setSaving(false); if (res.ok) { toast.success("Utilisateur modifié"); setEditUser(null); fetchUsers(); } else toast.error("Erreur lors de la modification"); }; const handleDelete = async () => { if (!deleteUser) return; setSaving(true); const res = await fetch(`/api/users/${deleteUser.id}`, { method: "DELETE" }); setSaving(false); setDeleteUser(null); if (res.ok) { toast.success("Utilisateur supprimé"); fetchUsers(); } else { const data = await res.json(); toast.error(data.error || "Erreur"); } }; return (

{loading ? "Chargement…" : `${users.length} compte${users.length !== 1 ? "s" : ""}`}

{loading ? (
{[0, 1, 2].map((i) => (
))}
) : users.length === 0 ? ( ) : (
{/* En-tête desktop */}
UtilisateurRôleContenu2FA
{users.map((user, i) => (

{user.name || user.username || user.id}

@{user.username}{user.email ? ` · ${user.email}` : ""}

{roleLabels[user.role] || user.role} {user._count?.files || 0} fichiers · {user._count?.folders || 0} dossiers {user.twoFactorEnabled && }
{user._count?.files || 0} {user._count?.folders || 0}
{user.twoFactorEnabled ? ( Activée ) : ( — )}
))}
)} setShowCreate(false)} title="Nouvel utilisateur" footer={<>} > setEditUser(null)} title="Modifier l'utilisateur" description={editUser ? `@${editUser.username}` : undefined} footer={<>} > setDeleteUser(null)} title="Supprimer cet utilisateur ?" description={deleteUser ? `${deleteUser.name || deleteUser.username}` : undefined} footer={<>} >

Le compte sera supprimé et ne pourra plus se connecter.

); }