import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'; import { itemApi, materialApi } from '../api/endpoints'; import { api } from '../api/client'; import type { CharacterItem } from '../api/types'; import { Package, Sword, Shield, Coins } from 'lucide-react'; const RARITY_LABEL: Record = { common: 'Commun', rare: 'Rare', epic: 'Épique', legendary: 'Légendaire', }; function ItemCard({ ci, onEquip, onUnequip, onSell, selling }: { ci: CharacterItem; onEquip: () => void; onUnequip: () => void; onSell: () => void; selling: boolean; }) { const { item } = ci; const forgeBonusATK = item.type === 'weapon' ? ci.forgeLevel * 2 : 0; const forgeBonusDEF = item.type === 'armor' ? ci.forgeLevel * 2 : 0; const totalATK = item.attackBonus + forgeBonusATK; const totalDEF = item.defenseBonus + forgeBonusDEF; const sellPrice = Math.floor((item as any).buyPrice * 0.4) || 0; const bonuses = [ totalATK > 0 && `+${totalATK} ATK${forgeBonusATK > 0 ? ` (${item.attackBonus}+${forgeBonusATK})` : ''}`, totalDEF > 0 && `+${totalDEF} DEF${forgeBonusDEF > 0 ? ` (${item.defenseBonus}+${forgeBonusDEF})` : ''}`, item.forceBonus && `+${item.forceBonus} FOR`, item.agiliteBonus && `+${item.agiliteBonus} AGI`, item.intelligenceBonus && `+${item.intelligenceBonus} INT`, item.chanceBonus && `+${item.chanceBonus} CHA`, item.vitaliteBonus && `+${item.vitaliteBonus} VIT`, ].filter(Boolean).join(' · '); return (
{ci.equipped && ( Équipé )} {ci.forgeLevel > 0 && ( +{ci.forgeLevel} )}
{item.type === 'weapon' ? '⚔️' : '🛡️'}
{item.name}
{RARITY_LABEL[item.rarity]}
{bonuses &&
{bonuses}
}
{!ci.equipped ? : } {!ci.equipped && sellPrice > 0 && ( )}
); } export function InventoryPage() { const qc = useQueryClient(); const { data: inventory, isLoading: loadInv } = useQuery({ queryKey: ['inventory'], queryFn: itemApi.inventory, }); const { data: materials, isLoading: loadMat } = useQuery({ queryKey: ['materials'], queryFn: materialApi.inventory, }); const equipMut = useMutation({ mutationFn: (id: string) => itemApi.equip(id), onSuccess: () => qc.invalidateQueries({ queryKey: ['inventory'] }), }); const unequipMut = useMutation({ mutationFn: (slot: 'weapon' | 'armor') => itemApi.unequip(slot), onSuccess: () => qc.invalidateQueries({ queryKey: ['inventory'] }), }); const sellMut = useMutation({ mutationFn: (charItemId: string) => api.post(`/shop/sell/${charItemId}`), onSuccess: () => { qc.invalidateQueries({ queryKey: ['inventory'] }); qc.invalidateQueries({ queryKey: ['character'] }); }, }); if (loadInv || loadMat) return
Chargement…
; const weapons = inventory?.filter(ci => ci.item.type === 'weapon') ?? []; const armors = inventory?.filter(ci => ci.item.type === 'armor') ?? []; return (

Inventaire

{inventory?.length === 0 && (
Inventaire vide — gagne des combats pour lootter des matériaux et crafter des équipements !
)} {/* Armes */} {weapons.length > 0 && (

Armes ({weapons.length})

{weapons.map(ci => ( equipMut.mutate(ci.id)} onUnequip={() => unequipMut.mutate('weapon')} onSell={() => sellMut.mutate(ci.id)} selling={sellMut.isPending} /> ))}
)} {/* Armures */} {armors.length > 0 && (

Armures ({armors.length})

{armors.map(ci => ( equipMut.mutate(ci.id)} onUnequip={() => unequipMut.mutate('armor')} onSell={() => sellMut.mutate(ci.id)} selling={sellMut.isPending} /> ))}
)} {/* Matériaux */} {materials && materials.length > 0 && (

🌿 Matériaux

{materials.map(cm => (
🌿
{cm.material.name}
×{cm.quantity}
))}
)}
); }