Files
TetaRdPG/frontend/src/components/CreateCharacter.tsx
Tetardtek 2c94e4f3aa
All checks were successful
CI/CD — Build & Deploy / Build & Deploy (push) Successful in 32s
refacto: migration Tailwind — composants (6 fichiers)
- RarityBadge, RarityDot → Tailwind classes
- MonsterCard → flex/text-rpg-* classes
- CreateCharacter → full Tailwind (max-w, grid, gap)
- Onboarding → Tailwind + responsive grid-cols-1 mobile
- CombatViews (Log+Multi+History) → Tailwind
- NotFoundPage → full Tailwind
- Pattern posé : couleurs dynamiques en style, layout en classes
2026-03-24 23:54:06 +01:00

69 lines
2.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { useState } from 'react';
import { useMutation, useQueryClient } from '@tanstack/react-query';
import { characterApi } from '../api/endpoints';
import { STAT_LABELS } from '../constants';
const STATS = ['force', 'agilite', 'intelligence', 'chance', 'vitalite'] as const;
export function CreateCharacter() {
const qc = useQueryClient();
const [name, setName] = useState('');
const [pts, setPts] = useState<Record<string, number>>({ force:1, agilite:1, intelligence:1, chance:1, vitalite:1 });
const used = Object.values(pts).reduce((a, b) => a + b, 0) - 5;
const remaining = 5 - used;
const mut = useMutation({
mutationFn: () => characterApi.create(name, pts),
onSuccess: () => qc.invalidateQueries({ queryKey: ['character'] }),
});
const adjust = (stat: string, delta: number) => {
const next = (pts[stat] ?? 1) + delta;
if (next < 1 || next > 10) return;
if (delta > 0 && remaining <= 0) return;
setPts(p => ({ ...p, [stat]: next }));
};
return (
<div className="max-w-md mx-auto mt-16">
<div className="card card-gold p-6">
<h2 className="text-rpg-gold text-xl font-bold mb-1">Créer ton personnage</h2>
<p className="text-rpg-muted text-sm mb-5">
{remaining > 0 ? `${remaining} point${remaining > 1 ? 's' : ''} à répartir` : 'Tous les points répartis'}
</p>
<input
className="input-rpg mb-4"
placeholder="Nom du personnage"
value={name}
onChange={e => setName(e.target.value)}
maxLength={30}
/>
<div className="flex flex-col gap-2 mb-5">
{STATS.map(s => (
<div key={s} className="flex items-center justify-between">
<span className="text-sm text-rpg-text w-28">{STAT_LABELS[s]}</span>
<div className="flex items-center gap-2">
<button className="btn btn-ghost px-2 py-0.5 text-sm" onClick={() => adjust(s, -1)}></button>
<span className="w-5 text-center font-bold text-rpg-gold">{pts[s]}</span>
<button className="btn btn-ghost px-2 py-0.5 text-sm" onClick={() => adjust(s, +1)}>+</button>
</div>
</div>
))}
</div>
<button
className="btn btn-gold w-full"
disabled={!name.trim() || remaining !== 0 || mut.isPending}
onClick={() => mut.mutate()}
>
{mut.isPending ? 'Création…' : 'Commencer l\'aventure ⚔️'}
</button>
{mut.isError && <p className="text-rpg-red text-xs mt-2">{(mut.error as Error).message}</p>}
</div>
</div>
);
}