diff --git a/Frontend/src/__tests__/economy.test.ts b/Frontend/src/__tests__/economy.test.ts index d54e42f..57c30c5 100644 --- a/Frontend/src/__tests__/economy.test.ts +++ b/Frontend/src/__tests__/economy.test.ts @@ -11,6 +11,50 @@ import { DEFAULT_GENERATORS, } from "../core/economy"; +// PrestigePanel visibility guard — canPrestige drives render condition +// Ces tests valident l'invariant : le panneau prestige ne doit jamais être +// visible (canPrestige = false) si les ressources sont inférieures au seuil. +describe("PrestigePanel visibility (canPrestige guard)", () => { + it("canPrestige = false pour resources = 0 → panneau non visible", () => { + expect(canPrestige({ ...DEFAULT_STATE, resources: 0 })).toBe(false); + }); + + it("canPrestige = false pour resources = 999 999 → panneau non visible", () => { + expect(canPrestige({ ...DEFAULT_STATE, resources: 999_999 })).toBe(false); + }); + + it("canPrestige = true pour resources = 1 000 000 → panneau visible", () => { + expect(canPrestige({ ...DEFAULT_STATE, resources: 1_000_000 })).toBe(true); + }); +}); + +describe("applyPrestige — post-prestige state", () => { + const prestigeState = { + ...DEFAULT_STATE, + resources: 1_500_000, + generators: DEFAULT_STATE.generators.map((g) => ({ ...g, owned: 3 })), + prestigeCount: 0, + prestigeMultiplier: 1, + }; + + it("ressources = 0 après prestige", () => { + expect(applyPrestige(prestigeState).resources).toBe(0); + }); + + it("multiplicateur = 1.1 après premier prestige", () => { + expect(applyPrestige(prestigeState).prestigeMultiplier).toBeCloseTo(1.1); + }); + + it("tous les générateurs owned = 0 après prestige", () => { + const result = applyPrestige(prestigeState); + expect(result.generators.every((g) => g.owned === 0)).toBe(true); + }); + + it("prestigeCount incrémenté à 1 après premier prestige", () => { + expect(applyPrestige(prestigeState).prestigeCount).toBe(1); + }); +}); + describe("generatorCost", () => { it("retourne baseCost quand owned = 0", () => { const gen = { ...DEFAULT_GENERATORS[0], owned: 0 }; diff --git a/Frontend/src/components/MilestoneBar.tsx b/Frontend/src/components/MilestoneBar.tsx new file mode 100644 index 0000000..1386a2a --- /dev/null +++ b/Frontend/src/components/MilestoneBar.tsx @@ -0,0 +1,50 @@ +// MilestoneBar.tsx — Progression vers le prochain prestige +// Barre visuelle ressources / 1 000 000 + indicateur restant + +import React from "react"; + +const PRESTIGE_THRESHOLD = 1_000_000; + +interface MilestoneBarProps { + resources: number; +} + +export function MilestoneBar({ resources }: MilestoneBarProps) { + const progress = Math.min(resources / PRESTIGE_THRESHOLD, 1); + const progressPercent = (progress * 100).toFixed(1); + const remaining = Math.max(PRESTIGE_THRESHOLD - resources, 0); + + const formatNumber = (n: number): string => { + if (n >= 1_000_000) return `${(n / 1_000_000).toFixed(2)}M`; + if (n >= 1_000) return `${(n / 1_000).toFixed(1)}k`; + return Math.floor(n).toString(); + }; + + return ( +
+
+ Prochain prestige : {formatNumber(resources)} / {formatNumber(PRESTIGE_THRESHOLD)} +
+
+
+
+ {remaining > 0 && ( +
+ {formatNumber(remaining)} ressources restantes +
+ )} + {remaining === 0 && ( +
Prestige disponible !
+ )} +
+ ); +} diff --git a/Frontend/src/components/PrestigePanel.tsx b/Frontend/src/components/PrestigePanel.tsx new file mode 100644 index 0000000..13461df --- /dev/null +++ b/Frontend/src/components/PrestigePanel.tsx @@ -0,0 +1,57 @@ +// PrestigePanel.tsx — Boucle de prestige long terme +// Visible uniquement quand canPrestige = true (ressources ≥ 1 000 000) + +import React from "react"; + +interface PrestigePanelProps { + prestigeCount: number; + prestigeMultiplier: number; + canPrestige: boolean; + onPrestige: () => void; +} + +export function PrestigePanel({ + prestigeCount, + prestigeMultiplier, + canPrestige, + onPrestige, +}: PrestigePanelProps) { + const handlePrestige = () => { + const confirmed = window.confirm( + `Prestige — Reset total : ressources et générateurs à zéro.\n` + + `Récompense : +0.1× multiplicateur permanent.\n\n` + + `Multiplicateur actuel : ×${prestigeMultiplier.toFixed(1)}\n` + + `Multiplicateur après : ×${(prestigeMultiplier + 0.1).toFixed(1)}\n\n` + + `Confirmer le prestige ?` + ); + if (confirmed) { + onPrestige(); + } + }; + + return ( +
+
+ Prestiges : {prestigeCount} + + Multiplicateur : ×{prestigeMultiplier.toFixed(1)} + +
+ + {canPrestige && ( +
+
+ Récompense disponible : +0.1× multiplicateur permanent +
+ +
+ )} +
+ ); +}