Initial scaffold: AI Tycoon monorepo with core game loop
Turborepo monorepo with three packages: - packages/shared: TypeScript types for all 14 game systems + balance constants + formatting utils - packages/game-engine: Pure TS simulation engine with tick processor, economy, infrastructure, compute, research, market, and reputation systems - apps/web: React + Vite + Tailwind + Zustand frontend with sidebar dashboard layout, new game screen, dashboard with charts, infrastructure management, and model training pages Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,80 @@
|
||||
import { useGameStore } from '@/store';
|
||||
|
||||
export function SettingsPage() {
|
||||
const settings = useGameStore((s) => s.meta.settings);
|
||||
const companyName = useGameStore((s) => s.meta.companyName);
|
||||
|
||||
const handleReset = () => {
|
||||
if (confirm('Are you sure you want to reset all progress? This cannot be undone.')) {
|
||||
localStorage.removeItem('ai-tycoon-save');
|
||||
window.location.reload();
|
||||
}
|
||||
};
|
||||
|
||||
const handleExport = () => {
|
||||
const state = useGameStore.getState();
|
||||
const { activePage, notifications, ...gameState } = state;
|
||||
const blob = new Blob([JSON.stringify(gameState)], { type: 'application/json' });
|
||||
const url = URL.createObjectURL(blob);
|
||||
const a = document.createElement('a');
|
||||
a.href = url;
|
||||
a.download = `ai-tycoon-${companyName.replace(/\s+/g, '-').toLowerCase()}.json`;
|
||||
a.click();
|
||||
URL.revokeObjectURL(url);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="space-y-6 max-w-2xl">
|
||||
<h2 className="text-2xl font-bold">Settings</h2>
|
||||
|
||||
<div className="bg-surface-900 border border-surface-700 rounded-xl p-4 space-y-4">
|
||||
<h3 className="font-semibold">Game</h3>
|
||||
|
||||
<div className="flex items-center justify-between">
|
||||
<div>
|
||||
<div className="text-sm">Sound Effects</div>
|
||||
<div className="text-xs text-surface-400">Play UI sounds and notifications</div>
|
||||
</div>
|
||||
<ToggleSwitch checked={settings.soundEnabled} onChange={() => {}} />
|
||||
</div>
|
||||
|
||||
<div className="flex items-center justify-between">
|
||||
<div>
|
||||
<div className="text-sm">Music</div>
|
||||
<div className="text-xs text-surface-400">Background music (coming soon)</div>
|
||||
</div>
|
||||
<ToggleSwitch checked={settings.soundEnabled} onChange={() => {}} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="bg-surface-900 border border-surface-700 rounded-xl p-4 space-y-4">
|
||||
<h3 className="font-semibold">Save Data</h3>
|
||||
<div className="flex gap-3">
|
||||
<button
|
||||
onClick={handleExport}
|
||||
className="px-4 py-2 rounded bg-surface-800 hover:bg-surface-700 border border-surface-600 text-sm"
|
||||
>
|
||||
Export Save
|
||||
</button>
|
||||
<button
|
||||
onClick={handleReset}
|
||||
className="px-4 py-2 rounded bg-danger/20 hover:bg-danger/30 border border-danger/50 text-danger text-sm"
|
||||
>
|
||||
Reset Progress
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function ToggleSwitch({ checked, onChange }: { checked: boolean; onChange: () => void }) {
|
||||
return (
|
||||
<button
|
||||
onClick={onChange}
|
||||
className={`w-10 h-6 rounded-full transition-colors ${checked ? 'bg-accent' : 'bg-surface-600'}`}
|
||||
>
|
||||
<div className={`w-4 h-4 bg-white rounded-full transition-transform mx-1 mt-1 ${checked ? 'translate-x-4' : ''}`} />
|
||||
</button>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user