'use client'; import { useCallback, useEffect, useState } from 'react'; import Link from 'next/link'; import style from '@/styles/admin.module.scss'; type Char = { id: number; name_id: string; name: string; name_jp: string }; type PlayerRow = { id: number; player_key: string; player_name: string; description: string | null; image: string | null; character_id: string | null; name_id?: string; name_jp?: string; }; export function PlayersAdminClient() { const [players, setPlayers] = useState([]); const [characters, setCharacters] = useState([]); const [error, setError] = useState(''); const [loading, setLoading] = useState(true); const [playerKey, setPlayerKey] = useState(''); const [playerName, setPlayerName] = useState(''); const [description, setDescription] = useState(''); const [image, setImage] = useState(''); const [characterId, setCharacterId] = useState(''); const load = useCallback(async () => { setError(''); const [pr, cr] = await Promise.all([ fetch('/api/admin/players', { credentials: 'include' }), fetch('/api/admin/characters', { credentials: 'include' }), ]); const pj = await pr.json().catch(() => ({})); const cj = await cr.json().catch(() => ({})); if (!pr.ok) { setError((pj as { error?: string }).error ?? 'Failed to load players'); setLoading(false); return; } if (!cr.ok) { setError((cj as { error?: string }).error ?? 'Failed to load characters'); setLoading(false); return; } setPlayers((pj as { players: PlayerRow[] }).players ?? []); setCharacters((cj as { characters: Char[] }).characters ?? []); setLoading(false); }, []); useEffect(() => { load(); }, [load]); async function addPlayer(e: React.FormEvent) { e.preventDefault(); setError(''); const res = await fetch('/api/admin/players', { method: 'POST', headers: { 'Content-Type': 'application/json' }, credentials: 'include', body: JSON.stringify({ player_key: playerKey, player_name: playerName, description, image: image || null, character_id: characterId, }), }); const data = await res.json().catch(() => ({})); if (!res.ok) { setError((data as { error?: string }).error ?? 'Create failed'); return; } setPlayerKey(''); setPlayerName(''); setDescription(''); setImage(''); setCharacterId(''); await load(); } async function remove(id: number) { if (!window.confirm('Delete this player?')) return; setError(''); const res = await fetch(`/api/admin/players/${id}`, { method: 'DELETE', credentials: 'include' }); const data = await res.json().catch(() => ({})); if (!res.ok) { setError((data as { error?: string }).error ?? 'Delete failed'); return; } await load(); } return (

← Dashboard

Players

{error ?

{error}

: null} {loading ?

Loading…

: null} {!loading && ( <> {players.map((p) => ( ))}
Key Name Character
{p.player_key} {p.player_name} {p.name_jp ?? p.character_id}

Add player