Files
spotlightcam/frontend/src/App.jsx
Radosław Gierwiało c4372930dd feat(content): add How It Works page with markdown support
- Create HowItWorksPage component with markdown rendering
- Add how-it-works.md with Lorem Ipsum placeholder content
- Add /how-it-works route in App.jsx
- Add How It Works link to homepage footer (Product section)
2025-12-05 18:33:25 +01:00

251 lines
6.9 KiB
JavaScript

import { BrowserRouter, Routes, Route, Navigate } from 'react-router-dom';
import { Toaster } from 'react-hot-toast';
import { AuthProvider, useAuth } from './contexts/AuthContext';
import HomePage from './pages/HomePage';
import LoginPage from './pages/LoginPage';
import RegisterPage from './pages/RegisterPage';
import VerifyEmailPage from './pages/VerifyEmailPage';
import ForgotPasswordPage from './pages/ForgotPasswordPage';
import ResetPasswordPage from './pages/ResetPasswordPage';
import DashboardPage from './pages/DashboardPage';
import EventsPage from './pages/EventsPage';
import EventChatPage from './pages/EventChatPage';
import EventDetailsPage from './pages/admin/EventDetailsPage';
import EventCheckinPage from './pages/EventCheckinPage';
import MatchChatPage from './pages/MatchChatPage';
import MatchesPage from './pages/MatchesPage';
import RatePartnerPage from './pages/RatePartnerPage';
import HistoryPage from './pages/HistoryPage';
import ProfilePage from './pages/ProfilePage';
import PublicProfilePage from './pages/PublicProfilePage';
import ActivityLogsPage from './pages/admin/ActivityLogsPage';
import ContactMessagesPage from './pages/admin/ContactMessagesPage';
import ContactPage from './pages/ContactPage';
import AboutUsPage from './pages/AboutUsPage';
import HowItWorksPage from './pages/HowItWorksPage';
import NotFoundPage from './pages/NotFoundPage';
import VerificationBanner from './components/common/VerificationBanner';
import InstallPWA from './components/pwa/InstallPWA';
// Protected Route Component with Verification Banner
const ProtectedRoute = ({ children }) => {
const { isAuthenticated, loading } = useAuth();
if (loading) {
return (
<div className="min-h-screen flex items-center justify-center">
<div className="text-lg text-gray-600">Loading...</div>
</div>
);
}
if (!isAuthenticated) {
return <Navigate to="/login" replace />;
}
return (
<>
<VerificationBanner />
{children}
</>
);
};
// Public Route Component (redirect to dashboard if already logged in)
const PublicRoute = ({ children }) => {
const { isAuthenticated, loading } = useAuth();
if (loading) {
return (
<div className="min-h-screen flex items-center justify-center">
<div className="text-lg text-gray-600">Loading...</div>
</div>
);
}
if (isAuthenticated) {
return <Navigate to="/dashboard" replace />;
}
return children;
};
function App() {
return (
<BrowserRouter>
<AuthProvider>
{/* PWA Install Prompt */}
<InstallPWA />
{/* Toast Notifications */}
<Toaster
position="top-right"
toastOptions={{
duration: 4000,
style: {
background: '#333',
color: '#fff',
},
success: {
iconTheme: {
primary: '#22c55e',
secondary: '#fff',
},
},
error: {
iconTheme: {
primary: '#ef4444',
secondary: '#fff',
},
},
}}
/>
<Routes>
{/* Public Routes */}
<Route
path="/login"
element={
<PublicRoute>
<LoginPage />
</PublicRoute>
}
/>
<Route
path="/register"
element={
<PublicRoute>
<RegisterPage />
</PublicRoute>
}
/>
<Route path="/verify-email" element={<VerifyEmailPage />} />
<Route path="/forgot-password" element={<ForgotPasswordPage />} />
<Route path="/reset-password" element={<ResetPasswordPage />} />
{/* Protected Routes */}
<Route
path="/dashboard"
element={
<ProtectedRoute>
<DashboardPage />
</ProtectedRoute>
}
/>
<Route
path="/events"
element={
<ProtectedRoute>
<EventsPage />
</ProtectedRoute>
}
/>
<Route
path="/events/:slug/chat"
element={
<ProtectedRoute>
<EventChatPage />
</ProtectedRoute>
}
/>
<Route
path="/admin/events/:slug/details"
element={
<ProtectedRoute>
<EventDetailsPage />
</ProtectedRoute>
}
/>
<Route
path="/events/checkin/:token"
element={
<ProtectedRoute>
<EventCheckinPage />
</ProtectedRoute>
}
/>
<Route
path="/matches"
element={
<ProtectedRoute>
<MatchesPage />
</ProtectedRoute>
}
/>
<Route
path="/matches/:slug/chat"
element={
<ProtectedRoute>
<MatchChatPage />
</ProtectedRoute>
}
/>
<Route
path="/matches/:slug/rate"
element={
<ProtectedRoute>
<RatePartnerPage />
</ProtectedRoute>
}
/>
<Route
path="/history"
element={
<ProtectedRoute>
<HistoryPage />
</ProtectedRoute>
}
/>
<Route
path="/profile"
element={
<ProtectedRoute>
<ProfilePage />
</ProtectedRoute>
}
/>
{/* Admin Routes */}
<Route
path="/admin/activity-logs"
element={
<ProtectedRoute>
<ActivityLogsPage />
</ProtectedRoute>
}
/>
<Route
path="/admin/contact-messages"
element={
<ProtectedRoute>
<ContactMessagesPage />
</ProtectedRoute>
}
/>
{/* Home Page */}
<Route path="/" element={<HomePage />} />
{/* Contact Page - Public route */}
<Route path="/contact" element={<ContactPage />} />
{/* About Us Page - Public route */}
<Route path="/about-us" element={<AboutUsPage />} />
{/* How It Works Page - Public route */}
<Route path="/how-it-works" element={<HowItWorksPage />} />
{/* Public Profile - /u/username format (no auth required) */}
<Route path="/u/:username" element={<PublicProfilePage />} />
{/* 404 Not Found - Catch all unmatched routes */}
<Route path="*" element={<NotFoundPage />} />
</Routes>
</AuthProvider>
</BrowserRouter>
);
}
export default App;