import React, { JSX, useEffect, useState } from "react"; import { fetchPlayers } from "./api"; import { User, UserRole } from "../components/interfaces/users"; // type User = { // id: string; // name: string; // email: string; // role: "user" | "admin"; // banned?: boolean; // }; type Team = { id: string; name: string; members: number; }; type EventItem = { id: string; title: string; date: string; // ISO location?: string; }; const containerStyle: React.CSSProperties = { display: "flex", height: "100%", gap: 20, padding: 20, boxSizing: "border-box", fontFamily: "Inter, Roboto, Arial, sans-serif", }; const sidebarStyle: React.CSSProperties = { width: 220, borderRight: "1px solid #e6e6e6", paddingRight: 12, }; const tabButtonStyle = (active: boolean): React.CSSProperties => ({ display: "block", width: "100%", textAlign: "left", padding: "8px 10px", marginBottom: 6, cursor: "pointer", borderRadius: 6, background: active ? "#0b5fff1a" : "transparent", border: active ? "1px solid #0b5fff33" : "1px solid transparent", }); const contentStyle: React.CSSProperties = { flex: 1, minWidth: 0, overflowY: "auto", }; export default function Administration(): JSX.Element { const [activeTab, setActiveTab] = useState< "users" | "teams" | "events" | "settings" >("users"); const [users, setUsers] = useState([]); const [teams, setTeams] = useState([]); const [events, setEvents] = useState([]); const [loading, setLoading] = useState(false); const [error, setError] = useState(null); // Form state for creating event const [newEventTitle, setNewEventTitle] = useState(""); const [newEventDate, setNewEventDate] = useState(""); const [newEventLocation, setNewEventLocation] = useState(""); const token = localStorage.getItem('token'); useEffect(() => { // fetch all admin resources when component mounts if (token) refreshAll(); }, []); async function refreshAll() { if (!token) return; setLoading(true); setError(null); try { // Replace these endpoints with your backend API const users = await fetchPlayers(token); setUsers(users); console.log("Fetched users:", users); const [uRes, tRes, eRes] = await Promise.all([ fetch("/api/admin/players"), fetch("/api/admin/teams"), fetch("/api/admin/events"), ]); if (!uRes.ok || !tRes.ok || !eRes.ok) { throw new Error("Failed to fetch admin resources"); } // console.log(uRes); const [uJson, tJson, eJson] = await Promise.all([ uRes.json(), tRes.json(), eRes.json(), ]); // setUsers(uRes as User[]); setTeams(tJson as Team[]); setEvents(eJson as EventItem[]); } catch (err: any) { setError(err?.message ?? "Unknown error"); } finally { setLoading(false); } } async function toggleAdmin(user: User) { const promote = user.Roles.includes(UserRole.Admin) ? false : true; if ( !window.confirm( `${promote ? "Promote" : "Demote"} ${user.Username} to ${ promote ? "admin" : "user" }?` ) ) return; try { const res = await fetch(`/api/admin/users/${user.UUID}/role`, { method: "PATCH", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ role: promote ? "admin" : "user" }), }); if (!res.ok) throw new Error("Failed to change role"); setUsers((prev) => prev.map((u) => (u.UUID === user.UUID ? { ...u, role: promote ? "admin" : "user" } : u)) ); } catch (err: any) { alert(err?.message ?? "Failed to update role"); } } // async function toggleBan(user: User) { // const ban = user.isActive; // if (!window.confirm(`${ban ? "Ban" : "Unban"} ${user.username}?`)) return; // try { // const res = await fetch(`/api/admin/users/${user.id}/ban`, { // method: "PATCH", // headers: { "Content-Type": "application/json" }, // body: JSON.stringify({ banned: ban }), // }); // if (!res.ok) throw new Error("Failed to update ban"); // setUsers((prev) => prev.map((u) => (u.id === user.id ? { ...u, banned: ban } : u))); // } catch (err: any) { // alert(err?.message ?? "Failed to update ban"); // } // } async function deleteTeam(team: Team) { if (!window.confirm(`Delete team "${team.name}"? This cannot be undone.`)) return; try { const res = await fetch(`/api/admin/teams/${team.id}`, { method: "DELETE" }); if (!res.ok) throw new Error("Failed to delete team"); setTeams((prev) => prev.filter((t) => t.id !== team.id)); } catch (err: any) { alert(err?.message ?? "Failed to delete team"); } } async function createEvent(e: React.FormEvent) { e.preventDefault(); if (!newEventTitle || !newEventDate) { alert("Title and date required"); return; } try { const payload = { title: newEventTitle, date: new Date(newEventDate).toISOString(), location: newEventLocation || undefined, }; const res = await fetch("/api/admin/events", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(payload), }); if (!res.ok) throw new Error("Failed to create event"); const created: EventItem = await res.json(); setEvents((prev) => [created, ...prev]); setNewEventTitle(""); setNewEventDate(""); setNewEventLocation(""); setActiveTab("events"); } catch (err: any) { alert(err?.message ?? "Failed to create event"); } } async function deleteEvent(ev: EventItem) { if (!window.confirm(`Delete event "${ev.title}"?`)) return; try { const res = await fetch(`/api/admin/events/${ev.id}`, { method: "DELETE" }); if (!res.ok) throw new Error("Failed to delete event"); setEvents((prev) => prev.filter((x) => x.id !== ev.id)); } catch (err: any) { alert(err?.message ?? "Failed to delete event"); } } return (
{activeTab === "users" && (

Users

Manage user accounts, roles and bans.

{users.length === 0 ? (

No users found.

) : ( {users.map((u) => ( {/* */} {/* */} ))}
Name Email Role Status Actions
{u.Username} {u.Email} {u.Roles}{u.banned ? "Banned" : "Active"} */} {/* */} {/*
)}
)} {activeTab === "teams" && (

Teams

Manage teams and membership.

{teams.length === 0 ? (

No teams found.

) : (
    {teams.map((t) => (
  • {t.name}
    {t.members} members
  • ))}
)}
)} {activeTab === "events" && (

Events

Create and manage events

setNewEventTitle(e.target.value)} style={{ padding: 8, flex: 1 }} /> setNewEventDate(e.target.value)} style={{ padding: 8 }} /> setNewEventLocation(e.target.value)} style={{ padding: 8 }} />
{events.length === 0 ? (

No events.

) : (
    {events.map((ev) => (
  • {ev.title}
    {new Date(ev.date).toLocaleString()} {ev.location ? `• ${ev.location}` : ""}
  • ))}
)}
)} {activeTab === "settings" && (

Settings

Application-wide administrative settings.

Use these settings to control global features. Implement actual controls as needed.

)}
); }