File size: 5,644 Bytes
de6a95b 2c400a5 de6a95b 1ef1cda 6dd9bad de6a95b 1ef1cda 7b0c22b 1ef1cda 7b0c22b 0f2f80a 8280d7d 1ef1cda cc442ef 1ef1cda 6282d86 a966957 2c400a5 0349430 2ab1980 0349430 2c400a5 6282d86 e289c5c 2ab1980 e289c5c 2ab1980 ef6a2b7 a966957 2ab1980 e289c5c e286845 cc6456d 6282d86 0349430 2c400a5 e286845 2c400a5 e286845 2c400a5 8280d7d 2c400a5 7b0c22b 0f2f80a 9f72dd7 2c400a5 0349430 cc442ef 6dd9bad cc442ef 6dd9bad 0349430 cc442ef b150436 | 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 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 | import React from 'react';
import { BrowserRouter as Router, Routes, Route, Navigate } from 'react-router-dom';
import { AuthProvider, useAuth } from '@/lib/auth';
import { TenantProvider } from '@/lib/tenant';
import { ToastContext, useToastState } from '@/hooks/useToast';
import { Toaster } from '@/components/ui/Toaster';
import LoginPage from '@/pages/LoginPage';
import DashboardPage from '@/pages/DashboardPage';
import TrackListPage from '@/pages/TrackListPage';
import TrackFormPage from '@/pages/TrackFormPage';
import TrackDaysPage from '@/pages/TrackDaysPage';
import UserListPage from '@/pages/UserListPage';
import SettingsPage from '@/pages/SettingsPage';
import AIAgentSetup from '@/pages/AIAgentSetup';
import LiveFeed from '@/pages/LiveFeed';
import TrainingLab from '@/pages/TrainingLab';
import ClientsManagementView from '@/pages/ClientsManagementView';
import OnboardingWizard from '@/pages/OnboardingWizard';
import ResetPasswordPage from '@/pages/ResetPasswordPage';
import AnalyticsPage from '@/pages/AnalyticsPage';
import ContactsPage from '@/pages/ContactsPage';
import ConversationalDashboard from '@/pages/ConversationalDashboard';
import CrmConversationalDashboard from '@/pages/CrmConversationalDashboard';
import KnowledgeBasePage from '@/pages/KnowledgeBasePage';
import CampaignHistoryPage from '@/pages/CampaignHistoryPage';
import TemplatesPage from '@/pages/TemplatesPage';
import BillingPage from '@/pages/BillingPage';
import { useTenant } from '@/lib/tenant';
import { api } from '@/lib/api';
import MainLayout from '@/components/layouts/MainLayout';
import SuperAdminRouter from '@/pages/super-admin/SuperAdminRouter';
import { logError } from '@/lib/logger';
function ProtectedRoute({ children }: { children: React.ReactNode }) {
const { token } = useAuth();
if (!token) return <Navigate to="/login" replace />;
return <>{children}</>;
}
function AppShell() {
const { token, user } = useAuth();
const { selectedOrgId, setSelectedOrgId, currentOrg } = useTenant();
const [orgs, setOrgs] = React.useState<any[]>([]);
const isSuperAdmin = user?.role === 'SUPER_ADMIN' || user?.role === 'ADMIN';
React.useEffect(() => {
if (!token || !isSuperAdmin) return;
api.get('/v1/organizations', token)
.then(setOrgs)
.catch(err => logError("[APP] Failed to fetch organizations:", err));
}, [token, isSuperAdmin]);
// Force org selection for Org Admin
React.useEffect(() => {
if (user?.organizationId && !isSuperAdmin) {
setSelectedOrgId(user.organizationId);
}
}, [user, isSuperAdmin, setSelectedOrgId]);
const isCrmActive = !!currentOrg?.isCrmActive;
if (selectedOrgId === 'xamle-admin-org') {
return <SuperAdminRouter />;
}
return (
<MainLayout isSuperAdmin={isSuperAdmin} orgs={orgs}>
<Routes>
<Route
path="/"
element={
isCrmActive
? <CrmConversationalDashboard />
: <DashboardPage />
}
/>
<Route path="/analytics" element={<AnalyticsPage />} />
<Route
path="/crm"
element={
isCrmActive
? <CrmConversationalDashboard />
: <ConversationalDashboard />
}
/>
<Route path="/contacts" element={<ContactsPage />} />
<Route path="/content" element={<TrackListPage />} />
<Route path="/content/new" element={<TrackFormPage />} />
<Route path="/content/:id" element={<TrackFormPage />} />
<Route path="/content/:trackId/days" element={<TrackDaysPage />} />
<Route path="/live-feed" element={<LiveFeed />} />
<Route path="/ai-setup" element={<AIAgentSetup />} />
<Route path="/clients" element={<ClientsManagementView />} />
<Route path="/training" element={<TrainingLab />} />
<Route path="/users" element={<UserListPage />} />
<Route path="/settings" element={<SettingsPage />} />
<Route path="/billing" element={<BillingPage />} />
<Route path="/onboarding" element={<OnboardingWizard />} />
<Route path="/reset-password" element={<ResetPasswordPage />} />
<Route path="/kb" element={<KnowledgeBasePage />} />
<Route path="/campaign-history" element={<CampaignHistoryPage />} />
<Route path="/whatsapp-templates" element={<TemplatesPage />} />
<Route
path="/conversations"
element={isCrmActive ? <CrmConversationalDashboard /> : <ConversationalDashboard />}
/>
</Routes>
</MainLayout>
);
}
function App() {
const toastState = useToastState();
return (
<ToastContext.Provider value={toastState}>
<AuthProvider>
<TenantProvider>
<Router>
<Routes>
<Route path="/login" element={<LoginPage />} />
<Route path="/*" element={<ProtectedRoute><AppShell /></ProtectedRoute>} />
</Routes>
</Router>
</TenantProvider>
</AuthProvider>
<Toaster />
</ToastContext.Provider>
);
}
export default App;
|