Spaces:
Running
Running
File size: 4,295 Bytes
afd56bc | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 | import { BrowserRouter, Routes, Route, Navigate } from 'react-router-dom';
import { Toaster } from 'react-hot-toast';
import { SignedIn, SignedOut, SignIn, SignUp } from '@clerk/clerk-react';
import React, { Suspense, lazy } from 'react';
import Layout from './components/dashboard/Layout';
import { ApiInterceptor } from './components/ApiInterceptor';
import { ErrorBoundary } from './components/common/ErrorBoundary';
import { CookieConsentBanner } from './components/common/CookieConsentBanner';
const Pricing = lazy(() => import('./pages/Pricing'));
const Projects = lazy(() => import('./pages/Projects'));
const ProjectWorkspace = lazy(() => import('./pages/ProjectWorkspace'));
const LandingPage = lazy(() => import('./pages/LandingPage'));
const About = lazy(() => import('./pages/About'));
const Help = lazy(() => import('./pages/Help'));
const Settings = lazy(() => import('./pages/Settings'));
const Regulamin = lazy(() => import('./pages/Regulamin'));
const PolitykaPrywatnosci = lazy(() => import('./pages/PolitykaPrywatnosci'));
const Nabory = lazy(() => import('./pages/Nabory'));
const AdminDashboard = lazy(() => import('./pages/AdminDashboard'));
const BetaGuide = lazy(() => import('./pages/BetaGuide'));
const ProtectedLayout = () => {
return (
<>
<SignedIn>
<Layout />
</SignedIn>
<SignedOut>
<Navigate to="/sign-in" replace />
</SignedOut>
</>
);
};
function App() {
return (
<ErrorBoundary context="App">
<BrowserRouter>
<ApiInterceptor>
<Toaster position="top-right" toastOptions={{
style: { background: 'var(--bg-elevated)', color: 'var(--text-primary)', border: '1px solid var(--border-strong)' }
}} />
<CookieConsentBanner />
<Suspense fallback={
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', minHeight: '100vh', background: 'var(--bg-base)', color: 'var(--text-muted)' }}>
Ładowanie aplikacji...
</div>
}>
<Routes>
{/* Ścieżki publiczne */}
<Route path="/" element={<LandingPage />} />
<Route path="/sign-in/*" element={
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', minHeight: '100vh', background: 'var(--bg-base)' }}>
<SignIn routing="path" path="/sign-in" signUpUrl="/sign-up" forceRedirectUrl="/dashboard" />
</div>
} />
<Route path="/sign-up/*" element={
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', minHeight: '100vh', background: 'var(--bg-base)' }}>
<SignUp routing="path" path="/sign-up" signInUrl="/sign-in" forceRedirectUrl="/dashboard" />
</div>
} />
{/* Strony prawne — publiczne (bez logowania) */}
<Route path="/regulamin" element={<Regulamin />} />
<Route path="/polityka-prywatnosci" element={<PolitykaPrywatnosci />} />
{/* Cennik — publiczny (widoczny przed logowaniem) */}
<Route path="/pricing" element={<Pricing />} />
<Route path="/cennik" element={<Pricing />} />
{/* Ścieżki chronione (wymagające zalogowania) */}
<Route element={<ProtectedLayout />}>
<Route path="/dashboard" element={<Navigate to="/projects" replace />} />
{/* pricing jest też w publicznych ścieżkach powyżej */}
<Route path="/projects" element={<Projects />} />
<Route path="/projects/:id" element={<ProjectWorkspace />} />
<Route path="/nabory" element={<Nabory />} />
<Route path="/about" element={<About />} />
<Route path="/help" element={<Help />} />
<Route path="/settings" element={<Settings />} />
<Route path="/admin" element={<AdminDashboard />} />
<Route path="/beta" element={<BetaGuide />} />
</Route>
{/* Zabezpieczenie przed błędem nawigacji */}
<Route path="*" element={<Navigate to="/" replace />} />
</Routes>
</Suspense>
</ApiInterceptor>
</BrowserRouter>
</ErrorBoundary>
);
}
export default App;
|