feat(sprint1-step3): PrestigePanel + MilestoneBar + équilibrage générateurs fixes

This commit is contained in:
2026-03-17 07:09:14 +01:00
parent c69da320cc
commit 9f0ccda99b
3 changed files with 151 additions and 0 deletions

View File

@@ -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 (
<div className="milestone-bar" aria-label="Progression vers le prestige">
<div className="milestone-label">
Prochain prestige : {formatNumber(resources)} / {formatNumber(PRESTIGE_THRESHOLD)}
</div>
<div
className="milestone-track"
role="progressbar"
aria-valuenow={Math.floor(progress * 100)}
aria-valuemin={0}
aria-valuemax={100}
>
<div
className="milestone-fill"
style={{ width: `${progressPercent}%` }}
/>
</div>
{remaining > 0 && (
<div className="milestone-remaining">
{formatNumber(remaining)} ressources restantes
</div>
)}
{remaining === 0 && (
<div className="milestone-ready">Prestige disponible !</div>
)}
</div>
);
}

View File

@@ -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 (
<div className="prestige-panel">
<div className="prestige-stats">
<span className="prestige-count">Prestiges : {prestigeCount}</span>
<span className="prestige-multiplier">
Multiplicateur : ×{prestigeMultiplier.toFixed(1)}
</span>
</div>
{canPrestige && (
<div className="prestige-action">
<div className="prestige-reward">
Récompense disponible : <strong>+0.1× multiplicateur permanent</strong>
</div>
<button
className="prestige-button"
onClick={handlePrestige}
aria-label="Déclencher le prestige"
>
Prestige
</button>
</div>
)}
</div>
);
}