import { useRef, useEffect } from "react"; import type { Character } from "../types"; import TalentList from "./TalentList"; import styles from "./InfoPanel.module.css"; const CLASSES = ["Fighter", "Priest", "Thief", "Wizard"]; const ANCESTRIES = ["Human", "Elf", "Dwarf", "Halfling", "Goblin", "Half-Orc"]; const ALIGNMENTS = ["Lawful", "Neutral", "Chaotic"]; interface InfoPanelProps { character: Character; mode: "view" | "edit"; onUpdate: (id: number, data: Partial) => void; onAddTalent: ( characterId: number, data: { name: string; description: string; effect?: Record; game_talent_id?: number | null; }, ) => void; onRemoveTalent: (characterId: number, talentId: number) => void; } export default function InfoPanel({ character, mode, onUpdate, onAddTalent, onRemoveTalent, }: InfoPanelProps) { const debounceRef = useRef>(); useEffect(() => { return () => { if (debounceRef.current) clearTimeout(debounceRef.current); }; }, []); function handleField(field: string, value: string | number) { if (typeof value === "string") { if (debounceRef.current) clearTimeout(debounceRef.current); debounceRef.current = setTimeout(() => { onUpdate(character.id, { [field]: value }); }, 400); } else { onUpdate(character.id, { [field]: value }); } } return (
onAddTalent(character.id, data)} onRemove={(id) => onRemoveTalent(character.id, id)} mode={mode} />
Info
{mode === "view" ? (
{character.background && (
Background {character.background}
)} {character.deity && (
Deity {character.deity}
)} {character.languages && (
Languages {character.languages}
)}
Alignment {character.alignment}
{character.notes && ( <>
Notes
{character.notes}
)}
) : (
handleField("level", Number(e.target.value))} />
handleField("background", e.target.value)} />
handleField("deity", e.target.value)} />
handleField("languages", e.target.value)} />