Files
2026-02-25 00:50:23 +05:30

139 lines
4.0 KiB
TypeScript

import React, { useEffect, useRef } from 'react';
import { useDesktopStore } from '@/stores/desktopStore';
import { NebulaBackground } from '@/components/nebula/NebulaBackground';
import { VaultDoor } from '@/sections/VaultDoor';
import { ProjectNexus } from '@/sections/ProjectNexus';
import { Dock } from '@/components/dock/Dock';
import { ProductionHub } from '@/components/apps/ProductionHub';
import { AssetVault } from '@/components/apps/AssetVault';
import { EngineRoom } from '@/components/apps/EngineRoom';
import { UserControl } from '@/components/user/UserControl';
import { SystemPreferencesWindow } from '@/components/settings/SystemPreferencesWindow';
import { useSettingsStore } from '@/stores/settingsStore';
function App() {
const { currentStage } = useDesktopStore();
const initializeSettings = useSettingsStore((state) => state.initializeSettings);
const appRef = useRef<HTMLDivElement>(null);
useEffect(() => {
const root = appRef.current;
if (!root) return;
const maxShift = 16;
let targetX = 0;
let targetY = 0;
let currentX = 0;
let currentY = 0;
let rafId = 0;
const onMouseMove = (e: MouseEvent) => {
const nx = e.clientX / window.innerWidth - 0.5;
const ny = e.clientY / window.innerHeight - 0.5;
targetX = nx * maxShift;
targetY = ny * maxShift;
};
const onMouseLeave = () => {
targetX = 0;
targetY = 0;
};
const tick = () => {
currentX += (targetX - currentX) * 0.08;
currentY += (targetY - currentY) * 0.08;
root.style.setProperty('--parallax-x', `${currentX.toFixed(2)}px`);
root.style.setProperty('--parallax-y', `${currentY.toFixed(2)}px`);
rafId = requestAnimationFrame(tick);
};
window.addEventListener('mousemove', onMouseMove);
window.addEventListener('mouseleave', onMouseLeave);
rafId = requestAnimationFrame(tick);
return () => {
window.removeEventListener('mousemove', onMouseMove);
window.removeEventListener('mouseleave', onMouseLeave);
cancelAnimationFrame(rafId);
};
}, []);
useEffect(() => {
initializeSettings();
}, [initializeSettings]);
return (
<div ref={appRef} className="relative w-screen h-screen overflow-hidden bg-black">
{/* Nebula Background - Always visible */}
<NebulaBackground />
{/* Noise Overlay */}
<div className="noise-overlay parallax-layer-foreground" />
{/* Stage 1: Vault Door */}
{currentStage === 'vault' && <VaultDoor />}
{/* Stage 2: Project Nexus */}
{currentStage === 'nexus' && <ProjectNexus />}
{/* Stage 3: Astral Workspace */}
{currentStage === 'workspace' && <Workspace />}
{/* Global Settings Modal */}
<SystemPreferencesWindow />
</div>
);
}
// Workspace Component (Stage 3)
const Workspace: React.FC = () => {
return (
<div className="fixed inset-0 z-30">
{/* Status Bar */}
<StatusBar />
{/* App Windows */}
<ProductionHub />
<AssetVault />
<EngineRoom />
{/* The Dock */}
<Dock />
</div>
);
};
// Status Bar Component
const StatusBar: React.FC = () => {
const { selectedProject, setStage } = useDesktopStore();
return (
<div className="fixed inset-x-0 top-0 z-[5] pointer-events-none">
{/* Left - Project Name */}
<div className="absolute top-8 left-8 flex items-center gap-4 pointer-events-auto">
<button
type="button"
onClick={() => setStage('nexus')}
className="text-xs font-semibold tracking-[0.15em] uppercase opacity-60 hover:opacity-100 transition-opacity duration-300"
>
Astral Suite
</button>
{selectedProject && (
<>
<span className="text-xs opacity-30">/</span>
<span className="text-xs font-medium">{selectedProject.name}</span>
</>
)}
</div>
{/* Right - User Control */}
<div className="absolute top-6 right-8 pointer-events-auto">
<UserControl />
</div>
</div>
);
};
export default App;