From 5a747222fc9f3e0006a33d235792500517161d23 Mon Sep 17 00:00:00 2001 From: Blomios Date: Sun, 26 Apr 2026 12:51:16 +0200 Subject: [PATCH] feat: dofus icone added to guide view and font changed --- src/components/DofusIconWidget.tsx | 111 +++++++++++++++++++++++++++++ src/components/GuideView.tsx | 50 ++++++++----- src/components/HomeView.tsx | 97 +------------------------ src/index.css | 1 + 4 files changed, 148 insertions(+), 111 deletions(-) create mode 100644 src/components/DofusIconWidget.tsx diff --git a/src/components/DofusIconWidget.tsx b/src/components/DofusIconWidget.tsx new file mode 100644 index 0000000..a1076da --- /dev/null +++ b/src/components/DofusIconWidget.tsx @@ -0,0 +1,111 @@ +import { useEffect } from "react"; + +const DOFUS_SHIMMER_STYLE_ID = "dofus-icon-shimmer"; + +function injectShimmerStyle() { + if (document.getElementById(DOFUS_SHIMMER_STYLE_ID)) return; + const style = document.createElement("style"); + style.id = DOFUS_SHIMMER_STYLE_ID; + style.textContent = ` + @keyframes dofus-shimmer { + from { filter: brightness(1); } + to { filter: brightness(1.35); } + } + `; + document.head.appendChild(style); +} + +// 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"; +export 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 function DofusIcon({ gid, pct, size = 44, left = 0 }: { gid: string; pct: number; size?: number; left?: number }) { + useEffect(injectShimmerStyle, []); + + 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 && ( + + )} +
+ ); +} diff --git a/src/components/GuideView.tsx b/src/components/GuideView.tsx index 9a9addc..4ec09bb 100644 --- a/src/components/GuideView.tsx +++ b/src/components/GuideView.tsx @@ -3,6 +3,7 @@ import { useStore } from "../store"; import { SectionItem, QuestItem, CombatType } from "../types"; import QuestDetailPanel from "./QuestDetailPanel"; import { TextWithCoords } from "./TextWithCoords"; +import { DofusIcon, GID_TO_ICON } from "./DofusIconWidget"; function useWindowWidth() { const [width, setWidth] = useState(window.innerWidth); @@ -59,7 +60,7 @@ export default function GuideView() { ); } - const { name, effect, recommended_level, resources, sections, combat_legend } = activeGuideData; + const { name, effect, recommended_level, resources, sections, combat_legend, gid } = activeGuideData; const allQuests = collectAllQuests(sections); const completedCount = allQuests.filter(q => completedQuests.has(q)).length; @@ -73,28 +74,43 @@ export default function GuideView() { {/* Header */}
-
-

{name}

- {recommended_level && ( -
- Niv. recommandé : {recommended_level} + {/* Zone gauche : icône + nom + niveau recommandé */} +
+ {GID_TO_ICON[gid] && ( +
+
)} -
-
-
- {completedCount} / {allQuests.length} +
+

+ {name} +

+ {recommended_level && ( +
+ Niv. recommandé : {recommended_level} +
+ )}
-
{pct}%
-
-
+
+
+ + {completedCount} / {allQuests.length} quêtes + + {pct}% +
+
+
+
{effect && ( diff --git a/src/components/HomeView.tsx b/src/components/HomeView.tsx index a4322ac..2714b3c 100644 --- a/src/components/HomeView.tsx +++ b/src/components/HomeView.tsx @@ -1,39 +1,5 @@ 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 -}; +import { DofusIcon, GID_TO_ICON } from "./DofusIconWidget"; export default function HomeView({ needsSync, onSync }: { needsSync?: boolean; onSync?: () => void }) { const { guides, openGuide, profiles, activeProfileId, syncing } = useStore(); @@ -49,7 +15,7 @@ export default function HomeView({ needsSync, onSync }: { needsSync?: boolean; o
{/* Header */}
-

+

Tougli — Guide Dofus

{activeProfile && ( @@ -160,63 +126,6 @@ function Section({ title, guides, onOpen }: { ); } -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; @@ -232,7 +141,7 @@ function GuideCard({ guide, onOpen }: { return ( // Wrapper pour permettre à l'icône de déborder vers le haut
- +