arbritage/App.tsx

153 lines
5.4 KiB
TypeScript
Raw Permalink Normal View History

2026-01-26 14:20:25 +00:00
import React from 'react';
import { BrowserRouter as Router, Routes, Route, Navigate, useLocation } from 'react-router-dom';
import TopBar from './layouts/TopBar';
import Dashboard from './pages/Dashboard';
import Sourcing from './pages/Sourcing';
import Orders from './pages/Orders';
import Inventory from './pages/Inventory';
import Financial from './pages/Financial';
import Customers from './pages/Customers';
import Sales from './pages/Sales';
import Suppliers from './pages/Suppliers';
import Users from './pages/Users';
import Login from './pages/Login';
import Calculator from './pages/Printing/Calculator'; // 3D
import Filaments from './pages/Printing/Filaments'; // 3D
import Printers from './pages/Printing/Printers'; // 3D
2026-01-26 14:20:25 +00:00
import Products from './pages/Products'; // New
import Reports from './pages/Reports';
import Settings from './pages/Settings';
import { CRMProvider, useCRM } from './context/CRMContext';
import Sidebar from './layouts/Sidebar';
import Header from './layouts/Header';
import { useTheme } from './context/ThemeContext';
// Simple Layout Wrapper to handle Sidebar/Header display
const AppLayout: React.FC = () => {
const location = useLocation();
const { session, authLoading } = useCRM();
const { theme } = useTheme();
const isLoginPage = location.pathname === '/login';
const [isMobileMenuOpen, setIsMobileMenuOpen] = React.useState(false); // Moved to top level
2026-01-26 14:20:25 +00:00
if (authLoading) {
return (
<div className="h-screen w-full flex items-center justify-center bg-background text-foreground">
<div className="animate-spin rounded-full h-8 w-8 border-t-2 border-b-2 border-primary"></div>
</div>
);
}
if (!session && !isLoginPage) {
return <Navigate to="/login" replace />;
}
if (session && isLoginPage) {
return <Navigate to="/" replace />;
}
if (isLoginPage) {
return (
<div className="flex bg-background text-foreground h-screen w-screen relative overflow-hidden">
<Routes>
<Route path="/login" element={<Login />} />
</Routes>
</div>
);
}
// LAYOUT STRATEGIES
// 1. SIMPLE / CLEAN (Light) -> Uses TopBar (ERP Style)
if (theme === 'light') {
return (
<div className="min-h-screen bg-background flex flex-col font-sans antialiased text-foreground overflow-x-hidden selection:bg-primary selection:text-primary-foreground">
<TopBar />
<main className="flex-grow flex flex-col pt-4">
<div className="w-full max-w-[1600px] mx-auto p-4 md:p-8 flex-grow space-y-4">
<AppRoutes />
</div>
</main>
</div>
);
}
// 2. OCEAN / COMPLEX -> Uses Compact Sidebar (To be refined) or Modified TopBar
if (theme === 'ocean') {
return (
<div className="flex h-screen bg-background text-foreground font-sans antialiased selection:bg-cyan-500/30 selection:text-cyan-200 overflow-hidden">
{/* Sidebar for Ocean */}
<Sidebar />
<div className="flex-1 flex flex-col min-w-0 overflow-hidden">
<Header />
<main className="flex-1 overflow-y-auto p-4 md:p-6 scroll-smooth">
<div className="max-w-[1800px] mx-auto space-y-6 pb-20">
<AppRoutes />
</div>
</main>
</div>
</div>
);
}
// 3. DARK / PRO (Default) -> Sidebar + Header (Glassmorphism)
return (
<div className="flex h-screen bg-background text-foreground font-sans antialiased selection:bg-indigo-500/30 selection:text-indigo-200 overflow-hidden">
<Sidebar isOpen={isMobileMenuOpen} onClose={() => setIsMobileMenuOpen(false)} />
<div className="flex-1 flex flex-col min-w-0 overflow-hidden relative">
{/* Background Blob Effect for Pro Theme */}
<div className="absolute top-[-20%] left-[-10%] w-[500px] h-[500px] bg-indigo-600/20 rounded-full blur-[120px] pointer-events-none"></div>
<Header onMenuClick={() => setIsMobileMenuOpen(!isMobileMenuOpen)} />
<main className="flex-1 overflow-y-auto p-4 md:p-8 scroll-smooth z-10">
<AppRoutes />
</main>
</div>
</div>
);
};
// Extracted Routes to avoid duplication
const AppRoutes = () => (
<Routes>
<Route path="/" element={<Dashboard />} />
<Route path="/printing/calculator" element={<Calculator />} />
<Route path="/printing/filaments" element={<Filaments />} />
<Route path="/printing/printers" element={<Printers />} />
2026-01-26 14:20:25 +00:00
<Route path="/sourcing" element={<Sourcing />} />
<Route path="/orders" element={<Orders />} />
<Route path="/sales" element={<Sales />} />
<Route path="/products" element={<Products />} />
<Route path="/reports" element={<Reports />} />
<Route path="/settings" element={<Settings />} />
<Route path="/financial" element={<Financial />} />
<Route path="/customers" element={<Customers />} />
<Route path="/inventory" element={<Inventory />} />
<Route path="/suppliers" element={<Suppliers />} />
<Route path="/users" element={<Users />} />
<Route path="*" element={<Navigate to="/" replace />} />
</Routes>
);
import ErrorBoundary from './components/ErrorBoundary';
import { ThemeProvider } from './context/ThemeContext';
const App: React.FC = () => {
return (
<ErrorBoundary>
<ThemeProvider>
<CRMProvider>
{/* Main Router Setup */}
<Router>
<AppLayout />
</Router>
</CRMProvider>
</ThemeProvider>
</ErrorBoundary>
);
};
export default App;