Add Week 3 polish and late-game features
VC funding system (seed through IPO with requirements gating), 15 achievements with engine checker, model tuning presets and unlockable sliders, overload policy controls, open-source mechanic with reputation boost, enhanced Recharts analytics (subscriber/reputation/revenue vs expenses charts), M&A acquisition system, sidebar NEW badges on era transitions, tutorial hints, and wired-up settings toggles. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,60 @@
|
||||
import { useGameStore } from '@/store';
|
||||
import { ACHIEVEMENT_DEFINITIONS } from '@ai-tycoon/game-engine';
|
||||
import {
|
||||
Trophy, Lock, Server, Brain, Rocket, DollarSign, Sprout, Users,
|
||||
Globe, Sparkles, TrendingUp, Building2, Atom, Cpu, FlaskConical,
|
||||
GitBranch, Zap,
|
||||
} from 'lucide-react';
|
||||
|
||||
const ICON_MAP: Record<string, React.ComponentType<{ size?: number; className?: string }>> = {
|
||||
Trophy, Server, Brain, Rocket, DollarSign, Sprout, Users,
|
||||
Globe, Sparkles, TrendingUp, Building2, Atom, Cpu, FlaskConical,
|
||||
GitBranch, Zap,
|
||||
};
|
||||
|
||||
export function AchievementsPage() {
|
||||
const unlocked = useGameStore((s) => s.achievements.unlocked);
|
||||
const unlockedIds = new Set(unlocked.map(a => a.id));
|
||||
|
||||
return (
|
||||
<div className="space-y-6">
|
||||
<div className="flex items-center justify-between">
|
||||
<h2 className="text-2xl font-bold">Achievements</h2>
|
||||
<span className="text-sm text-surface-400">
|
||||
{unlocked.length} / {ACHIEVEMENT_DEFINITIONS.length} unlocked
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-3 gap-4">
|
||||
{ACHIEVEMENT_DEFINITIONS.map(def => {
|
||||
const isUnlocked = unlockedIds.has(def.id);
|
||||
const IconComponent = ICON_MAP[def.icon] ?? Trophy;
|
||||
|
||||
return (
|
||||
<div
|
||||
key={def.id}
|
||||
className={`rounded-xl border p-4 transition-all ${
|
||||
isUnlocked
|
||||
? 'bg-surface-900 border-accent/40 shadow-lg shadow-accent/5'
|
||||
: 'bg-surface-900/50 border-surface-700 opacity-60'
|
||||
}`}
|
||||
>
|
||||
<div className="flex items-start gap-3">
|
||||
<div className={`p-2 rounded-lg ${isUnlocked ? 'bg-accent/20 text-accent-light' : 'bg-surface-800 text-surface-500'}`}>
|
||||
{isUnlocked ? <IconComponent size={20} /> : <Lock size={20} />}
|
||||
</div>
|
||||
<div>
|
||||
<h4 className={`font-semibold text-sm ${isUnlocked ? '' : 'text-surface-400'}`}>{def.name}</h4>
|
||||
<p className="text-xs text-surface-400 mt-0.5">{def.description}</p>
|
||||
{isUnlocked && (
|
||||
<p className="text-xs text-accent mt-1">Unlocked</p>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user