From 4f960ff41f133ea0f7de079662bc4b414d09bf98 Mon Sep 17 00:00:00 2001 From: Blomios Date: Sun, 26 Apr 2026 10:58:52 +0200 Subject: [PATCH] feat: add dofus Icones on main page --- .claude/agents/react-ui-designer.md | 13 +++ src/components/HomeView.tsx | 165 +++++++++++++++++++++++----- src/types.ts | 1 + 3 files changed, 152 insertions(+), 27 deletions(-) diff --git a/.claude/agents/react-ui-designer.md b/.claude/agents/react-ui-designer.md index fd5de98..a17b447 100644 --- a/.claude/agents/react-ui-designer.md +++ b/.claude/agents/react-ui-designer.md @@ -65,6 +65,19 @@ You are fluent in: 4. **Régression** — Regression analysis (if applicable) 5. **Code corrigé** — Provide corrected code snippets for all 🔴 and 🟠 issues +## Unit Testing — Mandatory Protocol + +After **every** feature implementation or code update, you must: + +1. **Run the full test suite** to detect regressions: + ```bash + cd /home/anthony/Documents/Projects/TougliGui && npm run test + ``` +2. **Write or update unit tests** for anything you added or changed. Tests live in `src/__tests__/`. Use Vitest + Testing Library (already configured in the project). +3. **Report the test results** at the end of your response: number of tests passing, any failures, and which tests you added or modified. + +Never consider a task complete without running the tests. If a test fails, fix the issue before reporting done. + ## Behavioral Guidelines - **Default language**: Respond in the same language as the user (French or English). - **Be decisive**: When multiple valid approaches exist, recommend one and explain briefly why. diff --git a/src/components/HomeView.tsx b/src/components/HomeView.tsx index e16359d..a4322ac 100644 --- a/src/components/HomeView.tsx +++ b/src/components/HomeView.tsx @@ -1,5 +1,40 @@ import { useStore } from "../store"; +// Mapping statique gid (Google Sheets ID) -> URL icône via api.dofusdb.fr +// Pattern URL : https://api.dofusdb.fr/img/items/{iconId}.png +const DOFUS_ICON_BASE = "https://api.dofusdb.fr/img/items"; +const GID_TO_ICON: Record = { + "474870200": `${DOFUS_ICON_BASE}/23009.png`, // Dofawa + "743703882": `${DOFUS_ICON_BASE}/23025.png`, // Dofus Argenté + "103963898": `${DOFUS_ICON_BASE}/23006.png`, // Dofus Cawotte + "1075294690": `${DOFUS_ICON_BASE}/23022.png`, // Dokoko + "1567240526": `${DOFUS_ICON_BASE}/23020.png`, // Dofus des Veilleurs + "1011508069": `${DOFUS_ICON_BASE}/23002.png`, // Dofus Emeraude + "2045137654": `${DOFUS_ICON_BASE}/23001.png`, // Dofus Pourpre + "1967508888": `${DOFUS_ICON_BASE}/23032.png`, // Domakuro + "1382359191": `${DOFUS_ICON_BASE}/23033.png`, // Dorigami + "1413546794": `${DOFUS_ICON_BASE}/23003.png`, // Dofus Turquoise + "1641656252": `${DOFUS_ICON_BASE}/23005.png`, // Dofus des Glaces + "953522228": `${DOFUS_ICON_BASE}/23023.png`, // Dofus Abyssal + "818597042": `${DOFUS_ICON_BASE}/23039.png`, // Dofoozbz + "1021129660": `${DOFUS_ICON_BASE}/23016.png`, // Dofus Nébuleux + "595670723": `${DOFUS_ICON_BASE}/23004.png`, // Dofus Vulbis + "544349966": `${DOFUS_ICON_BASE}/23008.png`, // Dofus Tacheté + "1150302145": `${DOFUS_ICON_BASE}/23024.png`, // Dofus Forgelave + "882278553": `${DOFUS_ICON_BASE}/23007.png`, // Dofus Ebène + "200570588": `${DOFUS_ICON_BASE}/23011.png`, // Dofus Ivoire + "1209269839": `${DOFUS_ICON_BASE}/23012.png`, // Dofus Ocre + "462784268": `${DOFUS_ICON_BASE}/23027.png`, // Dofus Argenté Scintillant + "1543573905": `${DOFUS_ICON_BASE}/23034.png`, // Dofus Cauchemar + "1007491889": `${DOFUS_ICON_BASE}/23035.png`, // Dom de Pin + "1047555165": `${DOFUS_ICON_BASE}/23036.png`, // Dofus Sylvestre + "2105601828": `${DOFUS_ICON_BASE}/23029.png`, // Dofus Cacao + "474510463": `${DOFUS_ICON_BASE}/23017.png`, // Dokille + "62476099": `${DOFUS_ICON_BASE}/23018.png`, // Dolmanax + "1873654554": `${DOFUS_ICON_BASE}/23019.png`, // Dotruche + "360188709": `${DOFUS_ICON_BASE}/23010.png`, // Dofus Kaliptus +}; + export default function HomeView({ needsSync, onSync }: { needsSync?: boolean; onSync?: () => void }) { const { guides, openGuide, profiles, activeProfileId, syncing } = useStore(); @@ -118,13 +153,70 @@ function Section({ title, guides, onOpen }: { }}> {title} -
+
{guides.map(g => )}
); } +function DofusIcon({ gid, pct, size = 44 }: { gid: string; pct: number; size?: number }) { + const iconUrl = GID_TO_ICON[gid] ?? null; + if (!iconUrl) return null; + + // L'icône colorée est clippée du bas vers le haut selon pct. + // clipPath: inset(top right bottom left) — on réduit depuis le haut. + const filledClip = `inset(${100 - pct}% 0 0 0)`; + + return ( +
+ {/* Calque grisé (base) */} + + {/* Calque coloré, progressivement révélé du bas vers le haut */} + {pct > 0 && ( + + )} +
+ ); +} + function GuideCard({ guide, onOpen }: { guide: import("../types").GuideListItem; onOpen: (gid: string) => void; @@ -132,44 +224,62 @@ function GuideCard({ guide, onOpen }: { const pct = guide.total_quests > 0 ? Math.round((guide.completed_quests / guide.total_quests) * 100) : 0; const isDone = pct === 100 && guide.total_quests > 0; const inProgress = guide.completed_quests > 0 && !isDone; + const hasIcon = GID_TO_ICON[guide.gid] != null; const accentColor = isDone ? "#4ade80" : inProgress ? "#f0c040" : "#4a9eff"; + const borderColor = isDone ? "rgba(74,222,128,0.25)" : "#2d3748"; return ( - + + ); } diff --git a/src/types.ts b/src/types.ts index 866ecc3..b04d56c 100644 --- a/src/types.ts +++ b/src/types.ts @@ -10,6 +10,7 @@ export interface GuideListItem { last_synced_at: string | null; total_quests: number; completed_quests: number; + image_url?: string; } export interface CombatType {