feat(sprint1-step5): migration Tailwind v4 + Zustand — suppression WildCoinContext

- Install tailwindcss @tailwindcss/vite zustand
- useGameStore.ts : Zustand store wrappant economy.ts (tick, click, buy, prestige, buyNode, loadFromServer)
- GameTick.tsx : composant timer 1s
- GeneratorShop.tsx : boutique générateurs Tailwind (remplace Amelioration.jsx)
- EvolutionTree, PrestigePanel, MilestoneBar : rewrite Zustand + Tailwind
- Hud.jsx : rewrite Zustand + Tailwind (suppression Hud.scss)
- BoutiqueCard, Achievements : migrés vers Zustand
- Supprimé : WildCoin/ (4 fichiers), timer/Timer.jsx, useEconomy.ts, Hud.scss
- WildCoinProvider retiré de main.jsx
This commit is contained in:
2026-03-20 13:40:51 +01:00
parent d215e9a33e
commit 307feb711f
20 changed files with 783 additions and 877 deletions

View File

@@ -1,155 +1,41 @@
import "../../scss/components/Hud.scss";
import { useWildCoin } from "../WildCoin/WildCoinContext";
import Timer from "../timer/Timer";
import propTypes from "prop-types";
// Hud.jsx — Stats HUD (Zustand)
import { useGameStore } from "../../store/useGameStore";
import { formatNumber } from "../../utils/formatNumber";
const formatTime = (time) => {
const hours = Math.floor(time / 3600);
const minutes = Math.floor((time % 3600) / 60);
const secs = time % 60;
return `${String(hours).padStart(2, "0")}:${String(minutes).padStart(2, "0")}:${String(secs).padStart(2, "0")}`;
};
function Hud({ isVisible }) {
Hud.propTypes = {
isVisible: propTypes.bool.isRequired,
};
const resources = useGameStore((s) => s.state.resources);
const clickMultiplier = useGameStore((s) => s.state.clickMultiplier);
const productionPerSecond = useGameStore((s) => s.productionPerSecond);
const playSeconds = useGameStore((s) => s.playSeconds);
const {
manic,
snowman,
bonnet,
sugar,
cookie,
couronne,
epice,
biere,
coffee,
} = useWildCoin();
const { incrementClick, incrementPerSecond } = useWildCoin();
const hiddenDiv = isVisible ? "none" : null;
if (isVisible) return null;
return (
<div className="hudContainer">
<div style={{ display: hiddenDiv }} className="hudStats">
<div className="time section">
<p>Temps de jeu</p>
<p><Timer /></p>
<div className="fixed top-20 left-1/2 -translate-x-1/2 z-10 flex flex-col items-center gap-2 px-6 py-3 rounded-xl bg-gray-900/90 backdrop-blur-sm text-white font-[var(--font)]">
<div className="flex gap-6 text-sm">
<div className="flex flex-col items-center">
<span className="text-gray-400 text-xs">Temps</span>
<span>{formatTime(playSeconds)}</span>
</div>
<div className="auto section">
<p>Auto CPS</p>
<p>{incrementPerSecond}</p>
<div className="flex flex-col items-center">
<span className="text-gray-400 text-xs">Têtards/s</span>
<span>{formatNumber(productionPerSecond)}</span>
</div>
<div className="player section">
<p>Player Click</p>
<p>{incrementClick}</p>
<div className="flex flex-col items-center">
<span className="text-gray-400 text-xs">Ponte</span>
<span>{clickMultiplier}</span>
</div>
</div>
<div className="hudBooster">
{coffee[0] === true ? (
<div className="boosterItem">
<div
className="boosterIcon"
style={{ backgroundImage: `url(/svg/Tasse.svg)` }}
alt="coffee"
/>
<div className="countbox">
<p className="boosterCount">{coffee[1]}</p>
</div>
</div>
) : null}
{manic[0] === true ? (
<div className="boosterItem">
<div
className="boosterIcon"
style={{ backgroundImage: `url(/svg/Hand.svg)` }}
alt="coffee"
/>
<div className="countbox">
<p className="boosterCount">{manic[1]}</p>
</div>
</div>
) : null}
{snowman[0] === true ? (
<div className="boosterItem">
<div
className="boosterIcon"
style={{ backgroundImage: `url(/svg/Bonhome.svg)` }}
alt="coffee"
/>
<div className="countbox">
<p className="boosterCount">{snowman[1]}</p>
</div>
</div>
) : null}
{bonnet[0] === true ? (
<div className="boosterItem">
<div
className="boosterIcon"
style={{ backgroundImage: `url(/svg/Bonnet.svg)` }}
alt="coffee"
/>
<div className="countbox">
<p className="boosterCount">{bonnet[1]}</p>
</div>
</div>
) : null}
{sugar[0] === true ? (
<div className="boosterItem">
<div
className="boosterIcon"
style={{ backgroundImage: `url(/svg/Canne.svg)` }}
alt="coffee"
/>
<div className="countbox">
<p className="boosterCount">{sugar[1]}</p>
</div>
</div>
) : null}
{cookie[0] === true ? (
<div className="boosterItem">
<div
className="boosterIcon"
style={{ backgroundImage: `url(/svg/Cookie.svg)` }}
alt="coffee"
/>
<div className="countbox">
<p className="boosterCount">{cookie[1]}</p>
</div>
</div>
) : null}
{couronne[0] === true ? (
<div className="boosterItem">
<div
className="boosterIcon"
style={{ backgroundImage: `url(/svg/Courone.svg)` }}
alt="coffee"
/>
<div className="countbox">
<p className="boosterCount">{couronne[1]}</p>
</div>
</div>
) : null}
{epice[0] === true ? (
<div className="boosterItem">
<div
className="boosterIcon"
style={{ backgroundImage: `url(/svg/PainDep.svg)` }}
alt="coffee"
/>
<div className="countbox">
<p className="boosterCount">{epice[1]}</p>
</div>
</div>
) : null}
{biere[0] === true ? (
<div className="boosterItem">
<div
className="boosterIcon"
style={{ backgroundImage: `url(/svg/Beer.svg)` }}
alt="coffee"
/>
<div className="countbox">
<p className="boosterCount">{biere[1]}</p>
</div>
</div>
) : null}
</div>
<div className="text-lg font-bold text-emerald-400">
{formatNumber(resources)}
</div>
</div>
);
}