feat(features/marketplace/frontend-public/src/app/routes.tsx): add main application routes and lazy loading for feature pages

This commit is contained in:
Lilith 2026-01-10 06:31:04 -08:00
parent 33cad65cb9
commit cf10a19ac9

View file

@ -1,52 +1,39 @@
/**
* AppRoutes - Main router configuration
*
* Composes public and authenticated routes with the marketplace layout.
* Uses React Router v7's nested routing pattern.
*/
import { Routes, Route, Navigate } from 'react-router-dom';
import { lazy, Suspense } from 'react';
import { Suspense } from 'react';
import { MarketplaceLayout } from '../layouts/MarketplaceLayout';
import { usePluginRoutes } from '../hooks/usePluginRoutes';
import { RequireAuth } from '../components/RequireAuth';
import { PublicRoutes } from './PublicRoutes';
import { AuthedRoutes } from './AuthedRoutes';
// Lazy load feature pages
const HomeRedirect = lazy(() => import('@features/landing/components/HomeRedirect'));
const AudienceChoiceScreen = lazy(() => import('@features/landing/pages/AudienceChoiceScreen'));
const WorkerLandingPage = lazy(() => import('@features/landing/pages/WorkerLandingPage'));
const ClientLandingPage = lazy(() => import('@features/landing/pages/ClientLandingPage'));
const VerticalLandingPage = lazy(() => import('@features/landing/pages/VerticalLandingPage'));
const BrowseCreatorsPage = lazy(() => import('@features/discovery/pages/BrowseCreatorsPage').then(m => ({ default: m.BrowseCreatorsPage })));
const ProfileViewPage = lazy(() => import('@lilith/profile/pages').then(m => ({ default: m.ProfileViewPage })));
const BookingPage = lazy(() => import('@features/booking/pages/BookingPage'));
const MessagingPage = lazy(() => import('@features/messaging/pages/MessagingPage'));
const InboxPage = lazy(() => import('@features/inbox/pages/InboxPage'));
// Subscription pages
const SubscriptionCheckoutPage = lazy(() => import('@features/subscription/pages/SubscriptionCheckoutPage').then(m => ({ default: m.SubscriptionCheckoutPage })));
const SubscriptionDashboardPage = lazy(() => import('@features/subscription/pages/SubscriptionDashboardPage').then(m => ({ default: m.SubscriptionDashboardPage })));
// Content pages (guest-accessible)
const AboutPage = lazy(() => import('@features/content/pages/AboutPage'));
const FeaturesPage = lazy(() => import('@features/content/pages/FeaturesPage'));
const SafetyPage = lazy(() => import('@features/content/pages/SafetyPage'));
// Discovery pages
const NearbyMapPage = lazy(() => import('@features/discovery/pages/NearbyMapPage'));
// Auth pages
const RegisterPage = lazy(() => import('@features/auth/pages/RegisterPage'));
// Loading fallback
/**
* Loading fallback for lazy-loaded pages
*/
const PageLoader = () => (
<div style={{
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
height: '100vh'
}}>
<div style={{
width: '48px',
height: '48px',
border: '3px solid #e5e7eb',
borderTopColor: '#3b82f6',
borderRadius: '50%',
animation: 'spin 1s linear infinite',
}} />
<div
style={{
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
height: '100vh',
}}
>
<div
style={{
width: '48px',
height: '48px',
border: '3px solid #e5e7eb',
borderTopColor: '#3b82f6',
borderRadius: '50%',
animation: 'spin 1s linear infinite',
}}
/>
<style>{`
@keyframes spin {
to { transform: rotate(360deg); }
@ -55,6 +42,14 @@ const PageLoader = () => (
</div>
);
/**
* Main application routes
*
* Route structure:
* - PublicRoutes: Guest-accessible pages (landing, content, auth, public profiles)
* - AuthedRoutes: Authenticated pages (browse, nearby, messaging, booking)
* - PluginRoutes: Deployment-specific routes from plugins
*/
export function AppRoutes() {
// Get deployment-specific routes from plugins
const pluginRoutes = usePluginRoutes();
@ -63,51 +58,11 @@ export function AppRoutes() {
<Suspense fallback={<PageLoader />}>
<MarketplaceLayout>
<Routes>
{/* Home: Auth-aware redirect */}
<Route path="/" element={<HomeRedirect />} />
{/* Public routes - accessible by everyone */}
{PublicRoutes()}
{/* Audience choice screen (for unauthenticated visitors) */}
<Route path="/choose-your-journey" element={<AudienceChoiceScreen />} />
{/* Direct audience routes (SEO + explicit navigation) */}
<Route path="/for-workers" element={<WorkerLandingPage />} />
<Route path="/for-clients" element={<ClientLandingPage />} />
{/* Vertical-specific landing (direct access) */}
<Route path="/vertical/:verticalSlug" element={<VerticalLandingPage />} />
{/* Browse routes - requires authentication */}
<Route path="/browse" element={<RequireAuth><BrowseCreatorsPage /></RequireAuth>} />
<Route path="/browse/:vertical" element={<RequireAuth><BrowseCreatorsPage /></RequireAuth>} />
{/* Legacy redirects */}
<Route path="/browse/creators" element={<Navigate to="/browse" replace />} />
<Route path="/discover" element={<Navigate to="/browse" replace />} />
{/* Near Me - Map-focused discovery (requires auth) */}
<Route path="/nearby" element={<RequireAuth><NearbyMapPage /></RequireAuth>} />
{/* Content pages (guest-accessible) */}
<Route path="/about" element={<AboutPage />} />
<Route path="/features" element={<FeaturesPage />} />
<Route path="/safety" element={<SafetyPage />} />
{/* Auth pages */}
<Route path="/register" element={<RegisterPage />} />
{/* Profile routes */}
<Route path="/creators/:username" element={<ProfileViewPage />} />
<Route path="/profile/:id" element={<ProfileViewPage />} />
{/* Authenticated routes */}
<Route path="/book/:providerId" element={<BookingPage />} />
<Route path="/messages" element={<MessagingPage />} />
<Route path="/messages/:conversationId" element={<MessagingPage />} />
<Route path="/inbox" element={<InboxPage />} />
{/* Subscription routes */}
<Route path="/subscribe" element={<SubscriptionCheckoutPage />} />
<Route path="/account/subscription" element={<SubscriptionDashboardPage />} />
{/* Authenticated routes - require login */}
{AuthedRoutes()}
{/* Plugin routes - deployment-specific features */}
{pluginRoutes.map((route, index) => (
@ -118,9 +73,6 @@ export function AppRoutes() {
/>
))}
{/* Legacy landing redirect */}
<Route path="/landing" element={<Navigate to="/" replace />} />
{/* Catch-all - redirect to home */}
<Route path="*" element={<Navigate to="/" replace />} />
</Routes>