import { useEffect, useState } from 'react' import { BrowserRouter, Routes, Route, Navigate, useNavigate } from 'react-router-dom' import useAuthStore from './store/authStore' import AppLayout from './layouts/AppLayout' import LoginPage from './pages/LoginPage' import SetupWizard from './pages/SetupWizard' import DashboardPage from './pages/DashboardPage' import TablesPage from './pages/TablesPage' import OrderDetailPage from './pages/OrderDetailPage' import ManagementPage from './pages/ManagementPage' import ReportsPage from './pages/reports/ReportsPage' import SettingsPage from './pages/Settings/SettingsPage' import client from './api/client' function Spinner() { return (
) } // Rehydrates user from stored token before rendering any routes. // Prevents the flicker where a valid token causes a redirect to /login on refresh. function AuthRehydrator({ children }) { const { token, user, rehydrate, logout } = useAuthStore() const [ready, setReady] = useState(false) useEffect(() => { if (token && !user) { client.get('/api/auth/me') .then(r => { rehydrate(r.data, token) }) .catch(() => { logout() }) .finally(() => setReady(true)) } else { setReady(true) } }, []) // intentionally runs once on mount if (!ready) return return children } function RequireAuth({ children }) { const token = useAuthStore(s => s.token) return token ? children : } // Checks /api/setup/status on mount and redirects to /setup if no managers exist. function SetupGuard({ children }) { const [checked, setChecked] = useState(false) const navigate = useNavigate() useEffect(() => { client.get('/api/setup/status') .then(({ data }) => { if (data.needs_setup) navigate('/setup', { replace: true }) }) .catch(() => { // Backend unreachable — proceed, login will surface the error. }) .finally(() => setChecked(true)) }, [navigate]) if (!checked) return return children } export default function App() { return ( } /> } /> }> } /> } /> } /> } /> } /> } /> } /> } /> ) }