refacto: constants.ts — source unique frontend
All checks were successful
CI/CD — Build & Deploy / Build & Deploy (push) Successful in 41s
All checks were successful
CI/CD — Build & Deploy / Build & Deploy (push) Successful in 41s
- Centralise RARITY_COLORS, RARITY_LABELS, ZONE_INFO, STAT_LABELS - Centralise COMBAT_COST, REST_COST, FORGE_*, ATTACK_TYPES - Supprime 6 duplications dans CombatPage, GuidePage, ShopPage, ForgePage, InventoryPage
This commit is contained in:
72
frontend/src/constants.ts
Normal file
72
frontend/src/constants.ts
Normal file
@@ -0,0 +1,72 @@
|
||||
// ── Game Constants — Source unique frontend ──
|
||||
// Centralise toutes les constantes dupliquées dans les pages.
|
||||
|
||||
export const RARITY_COLORS: Record<string, string> = {
|
||||
common: '#9ca3af',
|
||||
rare: '#5ba4f5',
|
||||
epic: '#a78bfa',
|
||||
legendary: '#f4c94e',
|
||||
};
|
||||
|
||||
export const RARITY_LABELS: Record<string, string> = {
|
||||
common: 'Commun',
|
||||
rare: 'Rare',
|
||||
epic: 'Épique',
|
||||
legendary: 'Légendaire',
|
||||
};
|
||||
|
||||
export const ZONE_INFO: Record<string, { name: string; emoji: string; color: string }> = {
|
||||
marais: { name: 'Les Marais', emoji: '🌿', color: '#3ddc84' },
|
||||
egouts: { name: 'Les Égouts', emoji: '🕳️', color: '#5ba4f5' },
|
||||
desert: { name: 'Le Désert', emoji: '🏜️', color: '#f4c94e' },
|
||||
};
|
||||
|
||||
export const STAT_LABELS: Record<string, string> = {
|
||||
force: 'Force',
|
||||
agilite: 'Agilité',
|
||||
intelligence: 'Intelligence',
|
||||
chance: 'Chance',
|
||||
vitalite: 'Vitalité',
|
||||
};
|
||||
|
||||
export const TYPE_EMOJI: Record<string, string> = {
|
||||
weapon: '⚔️',
|
||||
armor: '🛡️',
|
||||
consumable: '🧪',
|
||||
};
|
||||
|
||||
// ── Coûts de jeu ──
|
||||
|
||||
export const COMBAT_COST = 5;
|
||||
export const REST_COST = 10;
|
||||
export const FORGE_ENDURANCE_COST = 10;
|
||||
|
||||
export const FORGE_GOLD_COST: Record<number, number> = {
|
||||
1: 50,
|
||||
2: 100,
|
||||
3: 200,
|
||||
4: 400,
|
||||
5: 700,
|
||||
};
|
||||
|
||||
export const FORGE_FAIL_CHANCE: Record<number, number> = {
|
||||
1: 0,
|
||||
2: 0,
|
||||
3: 20,
|
||||
4: 30,
|
||||
5: 40,
|
||||
};
|
||||
|
||||
export const FORGE_TABLE = [
|
||||
{ level: 1, gold: 50, endurance: 10, risk: '0%', bonus: '+2' },
|
||||
{ level: 2, gold: 100, endurance: 10, risk: '0%', bonus: '+4' },
|
||||
{ level: 3, gold: 200, endurance: 10, risk: '20%', bonus: '+6' },
|
||||
{ level: 4, gold: 400, endurance: 10, risk: '30%', bonus: '+8' },
|
||||
{ level: 5, gold: 700, endurance: 10, risk: '40%', bonus: '+10' },
|
||||
];
|
||||
|
||||
export const ATTACK_TYPES = [
|
||||
{ id: 'melee', label: 'Mêlée', emoji: '⚔️', stat: 'Force × 1.5' },
|
||||
{ id: 'ranged', label: 'Distance', emoji: '🏹', stat: 'Agilité × 1.5' },
|
||||
{ id: 'magic', label: 'Magie', emoji: '✨', stat: 'Intelligence × 1.5' },
|
||||
];
|
||||
@@ -5,14 +5,7 @@ import { combatApi, characterApi } from '../api/endpoints';
|
||||
import type { Monster, CombatResult, MultiCombatResult, CombatLog } from '../api/types';
|
||||
import { Swords, Trophy, Skull, Clock, Zap, Heart, Lock } from 'lucide-react';
|
||||
|
||||
const COMBAT_COST = 5;
|
||||
const REST_COST = 10;
|
||||
|
||||
const ATTACK_TYPES = [
|
||||
{ id: 'melee', label: 'Mêlée', emoji: '⚔️', stat: 'Force × 1.5' },
|
||||
{ id: 'ranged', label: 'Distance', emoji: '🏹', stat: 'Agilité × 1.5' },
|
||||
{ id: 'magic', label: 'Magie', emoji: '✨', stat: 'Intelligence × 1.5' },
|
||||
];
|
||||
import { COMBAT_COST, REST_COST, ATTACK_TYPES, ZONE_INFO } from '../constants';
|
||||
|
||||
function MonsterCard({ m, selected, onSelect, playerLevel }: { m: Monster; selected: boolean; onSelect: () => void; playerLevel: number }) {
|
||||
const tooHard = m.minLevel > playerLevel + 2;
|
||||
@@ -211,11 +204,7 @@ export function CombatPage() {
|
||||
monstersByZone.set(zone, list);
|
||||
}
|
||||
|
||||
const ZONE_LABELS: Record<string, { name: string; emoji: string }> = {
|
||||
marais: { name: 'Les Marais', emoji: '🌿' },
|
||||
egouts: { name: 'Les Égouts', emoji: '🕳️' },
|
||||
desert: { name: 'Le Désert', emoji: '🏜️' },
|
||||
};
|
||||
const ZONE_LABELS = ZONE_INFO;
|
||||
|
||||
// Locked zones (zones not in monsters response = locked)
|
||||
const lockedZones = (zones ?? []).filter((z: any) => !z.unlocked);
|
||||
|
||||
@@ -5,10 +5,10 @@ import { itemApi, forgeApi, characterApi } from '../api/endpoints';
|
||||
import type { CharacterItem } from '../api/types';
|
||||
import { Shield, CheckCircle, XCircle, AlertTriangle, Zap, Coins } from 'lucide-react';
|
||||
|
||||
const FORGE_RISK = [0, 0, 0, 20, 30, 40];
|
||||
const FORGE_LABEL = ['—', '—', 'Garanti', '20% échec', '30% échec', '40% échec'];
|
||||
const FORGE_ENDURANCE_COST = 10;
|
||||
const FORGE_GOLD_COST: Record<number, number> = { 1: 50, 2: 100, 3: 200, 4: 400, 5: 700 };
|
||||
import { FORGE_FAIL_CHANCE, FORGE_ENDURANCE_COST, FORGE_GOLD_COST } from '../constants';
|
||||
|
||||
const FORGE_RISK = [0, 0, 0, FORGE_FAIL_CHANCE[3], FORGE_FAIL_CHANCE[4], FORGE_FAIL_CHANCE[5]];
|
||||
const FORGE_LABEL = ['—', '—', 'Garanti', `${FORGE_FAIL_CHANCE[3]}% échec`, `${FORGE_FAIL_CHANCE[4]}% échec`, `${FORGE_FAIL_CHANCE[5]}% échec`];
|
||||
|
||||
function ForgePanel({ nextLevel, risk, endurance, gold, isPending, onForge }: {
|
||||
nextLevel: number; risk: number; endurance: number; gold: number; isPending: boolean; onForge: () => void;
|
||||
|
||||
@@ -3,29 +3,12 @@ import { useNavigate } from 'react-router-dom';
|
||||
import type { Monster, Item, Recipe } from '../api/types';
|
||||
import { Swords, Shield, Map as MapIcon, Hammer, ShoppingBag, BookOpen, Sparkles, Search, Gamepad2 } from 'lucide-react';
|
||||
import { useGuideData } from '../hooks/useGuideData';
|
||||
|
||||
// ── Constants ──
|
||||
import { RARITY_COLORS, RARITY_LABELS, FORGE_TABLE, ZONE_INFO } from '../constants';
|
||||
|
||||
const ZONES = [
|
||||
{ id: 'marais', name: 'Les Marais', emoji: '🌿', desc: 'Zone de départ. Monstres niv. 1-9. Terre de boue et de brume.', color: '#3ddc84' },
|
||||
{ id: 'egouts', name: 'Les Égouts', emoji: '🕳️', desc: 'Sous-terrain infesté. Monstres niv. 4-10. Rats, slimes et croco.', color: '#5ba4f5' },
|
||||
{ id: 'desert', name: 'Le Désert', emoji: '🏜️', desc: 'Sable brûlant. Monstres niv. 8-15. Scorpions, momies et le Sphinx.', color: '#f4c94e' },
|
||||
];
|
||||
|
||||
const RARITY_COLORS: Record<string, string> = {
|
||||
common: '#9ca3af', rare: '#5ba4f5', epic: '#a78bfa', legendary: '#f4c94e',
|
||||
};
|
||||
|
||||
const RARITY_LABELS: Record<string, string> = {
|
||||
common: 'Commun', rare: 'Rare', epic: 'Épique', legendary: 'Légendaire',
|
||||
};
|
||||
|
||||
const FORGE_TABLE = [
|
||||
{ level: 1, gold: 50, endurance: 10, risk: '0%', bonus: '+2' },
|
||||
{ level: 2, gold: 100, endurance: 10, risk: '0%', bonus: '+4' },
|
||||
{ level: 3, gold: 200, endurance: 10, risk: '20%', bonus: '+6' },
|
||||
{ level: 4, gold: 400, endurance: 10, risk: '30%', bonus: '+8' },
|
||||
{ level: 5, gold: 700, endurance: 10, risk: '40%', bonus: '+10' },
|
||||
{ id: 'marais', ...ZONE_INFO.marais, desc: 'Zone de départ. Monstres niv. 1-9. Terre de boue et de brume.' },
|
||||
{ id: 'egouts', ...ZONE_INFO.egouts, desc: 'Sous-terrain infesté. Monstres niv. 4-10. Rats, slimes et croco.' },
|
||||
{ id: 'desert', ...ZONE_INFO.desert, desc: 'Sable brûlant. Monstres niv. 8-15. Scorpions, momies et le Sphinx.' },
|
||||
];
|
||||
|
||||
const TABS = [
|
||||
|
||||
@@ -5,9 +5,7 @@ import { api } from '../api/client';
|
||||
import type { CharacterItem } from '../api/types';
|
||||
import { Package, Sword, Shield, Coins } from 'lucide-react';
|
||||
|
||||
const RARITY_LABEL: Record<string, string> = {
|
||||
common: 'Commun', rare: 'Rare', epic: 'Épique', legendary: 'Légendaire',
|
||||
};
|
||||
import { RARITY_LABELS as RARITY_LABEL, FORGE_GOLD_COST as FORGE_COSTS_MAP } from '../constants';
|
||||
|
||||
function ItemCard({ ci, onEquip, onUnequip, onSell, selling }: {
|
||||
ci: CharacterItem; onEquip: () => void; onUnequip: () => void; onSell: () => void; selling: boolean;
|
||||
@@ -17,9 +15,8 @@ function ItemCard({ ci, onEquip, onUnequip, onSell, selling }: {
|
||||
const forgeBonusDEF = item.type === 'armor' ? ci.forgeLevel * 2 : 0;
|
||||
const totalATK = item.attackBonus + forgeBonusATK;
|
||||
const totalDEF = item.defenseBonus + forgeBonusDEF;
|
||||
const FORGE_COSTS: Record<number, number> = { 1: 50, 2: 100, 3: 200, 4: 400, 5: 700 };
|
||||
let forgeInvestment = 0;
|
||||
for (let i = 1; i <= ci.forgeLevel; i++) forgeInvestment += FORGE_COSTS[i] ?? 0;
|
||||
for (let i = 1; i <= ci.forgeLevel; i++) forgeInvestment += FORGE_COSTS_MAP[i] ?? 0;
|
||||
const sellPrice = Math.floor(((item as any).buyPrice || 0) * 0.4 + forgeInvestment * 0.5);
|
||||
|
||||
const bonuses = [
|
||||
|
||||
@@ -4,24 +4,7 @@ import { characterApi } from '../api/endpoints';
|
||||
import { api } from '../api/client';
|
||||
import { Coins, ShoppingBag, Sword, Shield, Heart, Zap } from 'lucide-react';
|
||||
|
||||
const RARITY_COLORS: Record<string, string> = {
|
||||
common: '#9ca3af',
|
||||
rare: '#5ba4f5',
|
||||
epic: '#a78bfa',
|
||||
legendary: '#f4c94e',
|
||||
};
|
||||
|
||||
const TYPE_EMOJI: Record<string, string> = {
|
||||
weapon: '⚔️',
|
||||
armor: '🛡️',
|
||||
consumable: '🧪',
|
||||
};
|
||||
|
||||
const ZONE_LABELS: Record<string, string> = {
|
||||
marais: '🌿 Marais',
|
||||
egouts: '🕳️ Égouts',
|
||||
desert: '🏜️ Désert',
|
||||
};
|
||||
import { RARITY_COLORS, TYPE_EMOJI, ZONE_INFO } from '../constants';
|
||||
|
||||
interface ShopItem {
|
||||
id: string;
|
||||
@@ -153,7 +136,7 @@ export function ShopPage() {
|
||||
{sortedZones.map(([zone, items]) => (
|
||||
<div key={zone} style={{ marginBottom: '1.5rem' }}>
|
||||
<p style={{ margin: '0 0 0.5rem', fontSize: 13, fontWeight: 700, color: '#9ca3af' }}>
|
||||
{zone === 'general' ? '🧪 Consommables' : ZONE_LABELS[zone] ?? zone}
|
||||
{zone === 'general' ? '🧪 Consommables' : ZONE_INFO[zone] ? `${ZONE_INFO[zone].emoji} ${ZONE_INFO[zone].name}` : zone}
|
||||
</p>
|
||||
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 6 }}>
|
||||
{items.map(item => (
|
||||
|
||||
Reference in New Issue
Block a user