feat: endurance tickets — coûts visibles partout + budget dashboard
All checks were successful
CI/CD — Build & Deploy / Build & Deploy (push) Successful in 31s

Combat: coût 5 affiché, compteur "X combats possibles", bouton disabled
Forge: coût 10 + or affiché (baissé de 15 à 10), bouton disabled
Dashboard: indicateur budget "X combats · Y forges · Z repos"
Repos: coût 10 affiché, disabled si insuffisant
This commit is contained in:
2026-03-24 17:09:06 +01:00
parent cfdc5c9b02
commit eafac3d8c7
4 changed files with 98 additions and 36 deletions

View File

@@ -1,8 +1,10 @@
import { useState } from 'react';
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { combatApi } from '../api/endpoints';
import { combatApi, characterApi } from '../api/endpoints';
import type { Monster, CombatResult } from '../api/types';
import { Swords, Trophy, Skull, Clock } from 'lucide-react';
import { Swords, Trophy, Skull, Clock, Zap } from 'lucide-react';
const COMBAT_COST = 5;
const ATTACK_TYPES = [
{ id: 'melee', label: 'Mêlée', emoji: '⚔️', stat: 'Force × 1.5' },
@@ -84,6 +86,10 @@ export function CombatPage() {
const [attackType, setAttackType] = useState('melee');
const [lastResult, setLastResult] = useState<CombatResult | null>(null);
const { data: char } = useQuery({ queryKey: ['character'], queryFn: characterApi.me });
const endurance = (char as any)?.enduranceCurrent ?? (char as any)?.endurance ?? 0;
const canFight = endurance >= COMBAT_COST;
const { data: monsters, isLoading } = useQuery({
queryKey: ['monsters'],
queryFn: combatApi.monsters,
@@ -150,17 +156,23 @@ export function CombatPage() {
))}
</div>
{/* Coût endurance */}
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 6, marginBottom: 6, fontSize: 12, color: canFight ? '#5ba4f5' : '#e84040' }}>
<Zap size={12} /> Coût : {COMBAT_COST} endurance — Disponible : {endurance}
{canFight && <span style={{ color: '#6b7a99' }}>({Math.floor(endurance / COMBAT_COST)} combats possibles)</span>}
</div>
{/* Bouton combattre */}
<button
className="btn btn-red"
style={{ width: '100%', fontSize: 15, padding: '0.75rem' }}
disabled={!selectedMonster || fight.isPending}
style={{ width: '100%', fontSize: 15, padding: '0.75rem', opacity: canFight ? 1 : 0.5 }}
disabled={!selectedMonster || fight.isPending || !canFight}
onClick={() => fight.mutate()}
>
{fight.isPending ? (
<span><Swords size={14} style={{ display: 'inline', marginRight: 6 }} />Combat…</span>
) : (
<span>⚔️ Combattre {selectedMonster ? `— ${selectedMonster.name}` : ''}</span>
<span>⚔️ Combattre {selectedMonster ? `— ${selectedMonster.name}` : ''} ({COMBAT_COST}⚡)</span>
)}
</button>