All checks were successful
Automated Container Build / build-and-push (push) Successful in 1m23s
96 lines
2.6 KiB
TypeScript
96 lines
2.6 KiB
TypeScript
'use client';
|
|
|
|
import { useState, useEffect } from 'react';
|
|
import api from '@/lib/api';
|
|
import SetupWizard from '@/components/SetupWizard';
|
|
import LoginPage from '@/components/LoginPage';
|
|
import FileExplorer from '@/components/FileExplorer';
|
|
|
|
type AppState = 'loading' | 'setup' | 'login' | 'app';
|
|
|
|
export default function Home() {
|
|
const [state, setState] = useState<AppState>('loading');
|
|
|
|
useEffect(() => {
|
|
checkState();
|
|
|
|
const handleAuthError = () => {
|
|
api.clearTokens();
|
|
setState('login');
|
|
};
|
|
window.addEventListener('auth_error', handleAuthError);
|
|
return () => window.removeEventListener('auth_error', handleAuthError);
|
|
}, []);
|
|
|
|
async function checkState() {
|
|
try {
|
|
const { setup_complete } = await api.checkSetup();
|
|
if (!setup_complete) {
|
|
setState('setup');
|
|
return;
|
|
}
|
|
|
|
if (api.isAuthenticated()) {
|
|
setState('app');
|
|
// Load and apply saved theme from API
|
|
try {
|
|
const data = await api.getSettings();
|
|
const s = data.settings || data;
|
|
const theme = s.theme || 'dark';
|
|
document.documentElement.setAttribute('data-theme', theme);
|
|
document.documentElement.style.setProperty('color-scheme', theme);
|
|
if (theme === 'light') document.documentElement.classList.remove('dark');
|
|
else document.documentElement.classList.add('dark');
|
|
localStorage.setItem('theme', theme);
|
|
} catch {
|
|
// Theme sync is non-critical
|
|
}
|
|
} else {
|
|
setState('login');
|
|
}
|
|
} catch {
|
|
setState('login');
|
|
}
|
|
}
|
|
|
|
function handleSetupComplete() {
|
|
setState('login');
|
|
}
|
|
|
|
function handleLoginSuccess() {
|
|
setState('app');
|
|
}
|
|
|
|
function handleLogout() {
|
|
api.logout();
|
|
setState('login');
|
|
}
|
|
|
|
if (state === 'loading') {
|
|
return (
|
|
<div className="flex items-center justify-center min-h-screen" style={{ backgroundColor: 'var(--color-bg-primary)' }}>
|
|
<div className="flex flex-col items-center gap-4">
|
|
<div
|
|
className="w-10 h-10 rounded-full border-2 border-t-transparent"
|
|
style={{
|
|
borderColor: 'var(--color-accent)',
|
|
borderTopColor: 'transparent',
|
|
animation: 'spin 0.8s linear infinite',
|
|
}}
|
|
/>
|
|
<p style={{ color: 'var(--color-text-secondary)' }}>Loading...</p>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
if (state === 'setup') {
|
|
return <SetupWizard onComplete={handleSetupComplete} />;
|
|
}
|
|
|
|
if (state === 'login') {
|
|
return <LoginPage onSuccess={handleLoginSuccess} />;
|
|
}
|
|
|
|
return <FileExplorer onLogout={handleLogout} />;
|
|
}
|