CognxSafeTrack
fix(conversations): resolve /conversations blank page + slug→UUID KB routes + WABA banner
9f72dd7 | 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 { 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 { 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; | |
| 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; | |