import React, { JSX, useEffect, useState } from "react"; import { createPlayer, deletePlayer, fetchPlayers, updatePlayer } from "../api"; import { User, UserRole } from "../../components/interfaces/users"; import { sign } from "crypto"; import { create } from "domain"; // /home/henry/code/Volleyball/frontend/src/pages/Administration/Users.tsx type UserForm = { name: string; email: string; role: string; active: boolean; }; const emptyForm = (): UserForm => ({ name: "", email: "", role: UserRole.Player, active: true, }); export default function UsersPage(): JSX.Element { const [users, setUsers] = useState([]); const [loading, setLoading] = useState(false); const [error, setError] = useState(null); const [query, setQuery] = useState(""); const [page, setPage] = useState(1); const pageSize = 20; const [showForm, setShowForm] = useState(false); const [editing, setEditing] = useState(null); const [form, setForm] = useState(emptyForm()); const [formLoading, setFormLoading] = useState(false); const [deletingId, setDeletingId] = useState(null); const [confirmDeleteId, setConfirmDeleteId] = useState(null); useEffect(() => { const ac = new AbortController(); async function load() { setLoading(true); setError(null); try { const params = new URLSearchParams(); if (query) params.set("q", query); params.set("page", String(page)); params.set("limit", String(pageSize)); const token = localStorage.getItem('token'); if (!token) throw new Error("No auth token found"); const data = await fetchPlayers(token); console.log("Loaded users:", data); // const res = await fetch(`/api/users?${params.toString()}`, { // signal: ac.signal, // }); // if (!res.ok) throw new Error(`Failed to load users: ${res.status}`); // const data = await res.json(); // Expecting { users: User[] } or User[] — handle both. const list: User[] = Array.isArray(data) ? data : data.users ?? []; setUsers(list); } catch (err: any) { if (err.name !== "AbortError") setError(err.message || String(err)); } finally { setLoading(false); } } load(); return () => ac.abort(); }, [query, page]); function openCreate() { setEditing(null); setForm(emptyForm()); setShowForm(true); } function openEdit(u: User) { setEditing(u); setForm({ name: u.Username ?? "", email: u.Email ?? "", role: Array.isArray(u.Role) ? u.Role[0] : (u.Role ?? UserRole.Player), active: u.IsActive ?? true, }); setShowForm(true); } async function submitForm(e?: React.FormEvent) { e?.preventDefault(); setFormLoading(true); setError(null); try { const payload = { ...form }; let res: Response; if (editing) { res = await updatePlayer(editing.UUID, { Username: form.name, Email: form.email, }, localStorage.getItem('token') || ""); // res = await createPlayer({ // Username: form.name, // Email: form.email, // }, localStorage.getItem('token') || ""); // res = await fetch(`/api/users/${editing.UUID}`, { // method: "PUT", // headers: { "Content-Type": "application/json" }, // body: JSON.stringify(payload), // }); } else { res = await createPlayer({ Username: form.name, Email: form.email, }, localStorage.getItem('token') || ""); console.log("Create response:", res); // res = await fetch(`/api/users`, { // method: "POST", // headers: { "Content-Type": "application/json" }, // body: JSON.stringify(payload), // }); } // Parse response body (support both fetch Response and already-parsed results) let saved: User; if (res && typeof (res as any).json === "function") { const body = await (res as Response).json(); saved = (body && (body.data ?? body)) as User; } else { // If `res` is already a parsed object (e.g. from axios-like helpers) const obj = res as any; saved = (obj && (obj.data ?? obj)) as User; } // Update local lists setUsers((prev) => { if (editing) return prev.map((p) => (p.UUID === saved.UUID ? saved : p)); return [saved, ...prev]; }); setShowForm(false); setEditing(null); setForm(emptyForm()); } catch (err: any) { setError(err.message || String(err)); } finally { setFormLoading(false); } } async function removeUser(id: string) { setDeletingId(id); setError(null); try { const res = await deletePlayer(id, localStorage.getItem('token') || ""); setUsers((prev) => prev.filter((u) => u.UUID !== id)); } catch (err: any) { setError(err.message || String(err)); console.error("Error deleting user:", err.message); } finally { setDeletingId(null); setConfirmDeleteId(null); } } return (

User Management

{ setQuery(e.target.value); setPage(1); }} style={{ padding: 6, flex: 1 }} />
{error && (
Error: {error}
)}
{loading ? ( ) : users.length === 0 ? ( ) : ( users.map((u) => ( )) )}
Name Email Role Active Created Actions
Loading...
No users found.
{u.Username} {u.Email} {u.Role && Array.isArray(u.Role) ? u.Role.join(", ") : (u.Role ?? "—")} {u.IsActive ? "Yes" : "No"} {u.CreatedAt ? new Date(u.CreatedAt).toLocaleString() : "—"}
Page {page}
{showForm && (
{ // click outside to close setShowForm(false); setEditing(null); }} >
{ e.stopPropagation(); submitForm(e); }} onClick={(e) => e.stopPropagation()} style={{ width: 520, maxWidth: "95%", background: "white", padding: 18, borderRadius: 8, boxShadow: "0 6px 20px rgba(0,0,0,0.12)", }} >

{editing ? "Edit User" : "New User"}

setForm((f) => ({ ...f, name: e.target.value }))} style={{ width: "100%", padding: 8 }} />
setForm((f) => ({ ...f, email: e.target.value }))} style={{ width: "100%", padding: 8 }} />
)} {confirmDeleteId && (
setConfirmDeleteId(null)} >
e.stopPropagation()} style={{ background: "white", padding: 24, borderRadius: 8, boxShadow: "0 6px 20px rgba(0,0,0,0.12)", minWidth: 320, }} >

Confirm Delete

Are you sure you want to delete this user? This action cannot be undone.

)}
); }