mirror of
http://88.130.71.182:3000/BlitTech/contexta_fe.git
synced 2026-06-12 23:23:22 +00:00
Updates Apr3: new pages, components, and widespread UI/API improvements
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
93
src/App.tsx
93
src/App.tsx
@@ -2,7 +2,9 @@ import React, { lazy, Suspense } from 'react'
|
||||
import { Routes, Route, Navigate } from 'react-router-dom'
|
||||
import { useAuthStore } from '@/store/authStore'
|
||||
import { AppLayout } from '@/components/Layout'
|
||||
import { AdminLayout } from '@/components/AdminLayout'
|
||||
import { PublicLayout } from '@/components/PublicLayout'
|
||||
import { ErrorBoundary } from '@/components/ErrorBoundary'
|
||||
import { Spinner } from '@/components/ui'
|
||||
import './App.css'
|
||||
|
||||
@@ -22,6 +24,16 @@ const AnalyticsPage = lazy(() => import('@/pages/AnalyticsPage').then(m => ({ de
|
||||
const PublicChatPage = lazy(() => import('@/pages/PublicChatPage').then(m => ({ default: m.PublicChatPage })))
|
||||
const InboxPage = lazy(() => import('@/pages/InboxPage').then(m => ({ default: m.InboxPage })))
|
||||
const LeadsPage = lazy(() => import('@/pages/LeadsPage').then(m => ({ default: m.LeadsPage })))
|
||||
const AppointmentsPage = lazy(() => import('@/pages/AppointmentsPage').then(m => ({ default: m.AppointmentsPage })))
|
||||
const CampaignsPage = lazy(() => import('@/pages/CampaignsPage').then(m => ({ default: m.CampaignsPage })))
|
||||
const PublicBookingPage = lazy(() => import('@/pages/PublicBookingPage').then(m => ({ default: m.PublicBookingPage })))
|
||||
|
||||
// Admin pages
|
||||
const AdminDashboardPage = lazy(() => import('@/pages/admin/AdminDashboardPage').then(m => ({ default: m.AdminDashboardPage })))
|
||||
const AdminUsersPage = lazy(() => import('@/pages/admin/AdminUsersPage').then(m => ({ default: m.AdminUsersPage })))
|
||||
const AdminChatbotsPage = lazy(() => import('@/pages/admin/AdminChatbotsPage').then(m => ({ default: m.AdminChatbotsPage })))
|
||||
const AdminConversationsPage = lazy(() => import('@/pages/admin/AdminConversationsPage').then(m => ({ default: m.AdminConversationsPage })))
|
||||
const AdminSystemPage = lazy(() => import('@/pages/admin/AdminSystemPage').then(m => ({ default: m.AdminSystemPage })))
|
||||
|
||||
const PageLoader = () => (
|
||||
<div className="flex items-center justify-center min-h-screen">
|
||||
@@ -35,6 +47,13 @@ const PrivateRoute: React.FC<{ children: React.ReactNode }> = ({ children }) =>
|
||||
return <AppLayout>{children}</AppLayout>
|
||||
}
|
||||
|
||||
const AdminRoute: React.FC<{ children: React.ReactNode }> = ({ children }) => {
|
||||
const { isAuthenticated, user } = useAuthStore()
|
||||
if (!isAuthenticated) return <Navigate to="/login" replace />
|
||||
if (!user?.is_admin) return <Navigate to="/dashboard" replace />
|
||||
return <AdminLayout>{children}</AdminLayout>
|
||||
}
|
||||
|
||||
const PublicOnlyRoute: React.FC<{ children: React.ReactNode }> = ({ children }) => {
|
||||
const { isAuthenticated } = useAuthStore()
|
||||
if (isAuthenticated) return <Navigate to="/dashboard" replace />
|
||||
@@ -50,38 +69,52 @@ const SmartPublicRoute: React.FC<{ children: React.ReactNode }> = ({ children })
|
||||
}
|
||||
|
||||
export const App: React.FC = () => (
|
||||
<Suspense fallback={<PageLoader />}>
|
||||
<Routes>
|
||||
{/* Public - Landing has its own nav */}
|
||||
<Route path="/" element={<LandingPage />} />
|
||||
<ErrorBoundary>
|
||||
<Suspense fallback={<PageLoader />}>
|
||||
<Routes>
|
||||
{/* Public - Landing has its own nav */}
|
||||
<Route path="/" element={<LandingPage />} />
|
||||
|
||||
{/* Public pages - wrapped in SmartPublicRoute for proper nav */}
|
||||
<Route path="/pricing" element={<SmartPublicRoute><PricingPage /></SmartPublicRoute>} />
|
||||
<Route path="/marketplace" element={<SmartPublicRoute><MarketplacePage /></SmartPublicRoute>} />
|
||||
<Route path="/marketplace/:id" element={<SmartPublicRoute><ChatbotDetailPage /></SmartPublicRoute>} />
|
||||
{/* Public pages - wrapped in SmartPublicRoute for proper nav */}
|
||||
<Route path="/pricing" element={<SmartPublicRoute><PricingPage /></SmartPublicRoute>} />
|
||||
<Route path="/marketplace" element={<SmartPublicRoute><MarketplacePage /></SmartPublicRoute>} />
|
||||
<Route path="/marketplace/:id" element={<SmartPublicRoute><ChatbotDetailPage /></SmartPublicRoute>} />
|
||||
|
||||
{/* Public chat - no auth, no layout */}
|
||||
<Route path="/chat/:id" element={<PublicChatPage />} />
|
||||
{/* Public chat - no auth, no layout */}
|
||||
<Route path="/chat/:id" element={<PublicChatPage />} />
|
||||
|
||||
{/* Auth */}
|
||||
<Route path="/login" element={<PublicOnlyRoute><LoginPage /></PublicOnlyRoute>} />
|
||||
<Route path="/signup" element={<PublicOnlyRoute><SignupPage /></PublicOnlyRoute>} />
|
||||
<Route path="/forgot-password" element={<PublicOnlyRoute><ForgotPasswordPage /></PublicOnlyRoute>} />
|
||||
<Route path="/reset-password" element={<ResetPasswordPage />} />
|
||||
{/* Public booking - no auth, no layout */}
|
||||
<Route path="/book/:chatbotId" element={<PublicBookingPage />} />
|
||||
|
||||
{/* Protected */}
|
||||
<Route path="/dashboard" element={<PrivateRoute><DashboardPage /></PrivateRoute>} />
|
||||
<Route path="/analytics" element={<PrivateRoute><AnalyticsPage /></PrivateRoute>} />
|
||||
<Route path="/chatbots/new" element={<PrivateRoute><ChatbotBuilderPage /></PrivateRoute>} />
|
||||
<Route path="/chatbots/:id/edit" element={<PrivateRoute><ChatbotBuilderPage /></PrivateRoute>} />
|
||||
<Route path="/chatbots/:id/preview" element={<PrivateRoute><ChatbotBuilderPage /></PrivateRoute>} />
|
||||
<Route path="/inbox" element={<PrivateRoute><InboxPage /></PrivateRoute>} />
|
||||
<Route path="/leads" element={<PrivateRoute><LeadsPage /></PrivateRoute>} />
|
||||
<Route path="/settings" element={<PrivateRoute><SettingsPage /></PrivateRoute>} />
|
||||
<Route path="/settings/billing" element={<PrivateRoute><SettingsPage /></PrivateRoute>} />
|
||||
{/* Auth */}
|
||||
<Route path="/login" element={<PublicOnlyRoute><LoginPage /></PublicOnlyRoute>} />
|
||||
<Route path="/signup" element={<PublicOnlyRoute><SignupPage /></PublicOnlyRoute>} />
|
||||
<Route path="/forgot-password" element={<PublicOnlyRoute><ForgotPasswordPage /></PublicOnlyRoute>} />
|
||||
<Route path="/reset-password" element={<ResetPasswordPage />} />
|
||||
|
||||
{/* Fallback */}
|
||||
<Route path="*" element={<Navigate to="/" replace />} />
|
||||
</Routes>
|
||||
</Suspense>
|
||||
)
|
||||
{/* Protected */}
|
||||
<Route path="/dashboard" element={<PrivateRoute><DashboardPage /></PrivateRoute>} />
|
||||
<Route path="/analytics" element={<PrivateRoute><AnalyticsPage /></PrivateRoute>} />
|
||||
<Route path="/chatbots/new" element={<PrivateRoute><ChatbotBuilderPage /></PrivateRoute>} />
|
||||
<Route path="/chatbots/:id/edit" element={<PrivateRoute><ChatbotBuilderPage /></PrivateRoute>} />
|
||||
<Route path="/chatbots/:id/preview" element={<PrivateRoute><ChatbotBuilderPage /></PrivateRoute>} />
|
||||
<Route path="/inbox" element={<PrivateRoute><InboxPage /></PrivateRoute>} />
|
||||
<Route path="/leads" element={<PrivateRoute><LeadsPage /></PrivateRoute>} />
|
||||
<Route path="/appointments" element={<PrivateRoute><AppointmentsPage /></PrivateRoute>} />
|
||||
<Route path="/campaigns" element={<PrivateRoute><CampaignsPage /></PrivateRoute>} />
|
||||
<Route path="/settings" element={<PrivateRoute><SettingsPage /></PrivateRoute>} />
|
||||
<Route path="/settings/billing" element={<PrivateRoute><SettingsPage /></PrivateRoute>} />
|
||||
|
||||
{/* Admin */}
|
||||
<Route path="/admin" element={<AdminRoute><AdminDashboardPage /></AdminRoute>} />
|
||||
<Route path="/admin/users" element={<AdminRoute><AdminUsersPage /></AdminRoute>} />
|
||||
<Route path="/admin/chatbots" element={<AdminRoute><AdminChatbotsPage /></AdminRoute>} />
|
||||
<Route path="/admin/conversations" element={<AdminRoute><AdminConversationsPage /></AdminRoute>} />
|
||||
<Route path="/admin/system" element={<AdminRoute><AdminSystemPage /></AdminRoute>} />
|
||||
|
||||
{/* Fallback */}
|
||||
<Route path="*" element={<Navigate to="/" replace />} />
|
||||
</Routes>
|
||||
</Suspense>
|
||||
</ErrorBoundary>
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user