sms-extension-1777874553/client/src/App.jsx
2026-03-26 16:52:15 +05:30

85 lines
3.7 KiB
JavaScript

import { BrowserRouter, Routes, Route, Navigate, useLocation } from 'react-router-dom';
import { BusinessProvider, useBusiness } from './context/BusinessContext';
import Sidebar from './components/Sidebar';
import Businesses from './pages/Businesses';
import Providers from './pages/Providers';
import GlobalSms from './pages/GlobalSms';
import Events from './pages/Events';
import Templates from './pages/Templates';
import { Link } from 'react-router-dom';
function SubLayout({ children }) {
const { activeBusinessId, hasGlobalSms } = useBusiness();
return (
<div className="flex min-h-screen bg-page-bg">
<Sidebar />
<main className="flex-1 ml-60 flex flex-col">
<header className="h-16 border-b border-border-main bg-white flex items-center justify-end px-8 z-10 shrink-0">
{hasGlobalSms && (
<Link
to={`/${activeBusinessId}/settings`}
className="w-10 h-10 rounded-full hover:bg-refresh-hover text-gray-500 hover:text-primary-blue flex items-center justify-center transition-colors shadow-sm border border-border-soft"
title="Settings"
>
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z" /><path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z" /></svg>
</Link>
)}
</header>
<div className="flex-1 p-8 overflow-auto">
{children}
</div>
</main>
</div>
);
}
// Guard: redirect to / if no active business in session.
// Also enforce cURL-first: only the cURL profile route is available until an active profile exists.
function BusinessGuard({ children, isGlobalSmsRoute }) {
const { activeBusinessId, loading, hasGlobalSms } = useBusiness();
const location = useLocation();
if (loading) {
return (
<div className="min-h-screen flex items-center justify-center bg-page-bg">
<div className="w-8 h-8 border-2 border-indigo-200 border-t-primary-blue rounded-full animate-spin" />
</div>
);
}
if (!activeBusinessId) {
return <Navigate to="/" state={{ from: location }} replace />;
}
if (!hasGlobalSms && !isGlobalSmsRoute) {
return <Navigate to={`/${activeBusinessId}/global-sms`} replace />;
}
return children;
}
export default function App() {
return (
<BusinessProvider>
<BrowserRouter>
<Routes>
<Route path="/" element={<Businesses />} />
<Route path="/:businessId/settings" element={
<BusinessGuard><SubLayout><Providers /></SubLayout></BusinessGuard>
} />
<Route path="/:businessId/global-sms" element={
<BusinessGuard isGlobalSmsRoute><SubLayout><GlobalSms /></SubLayout></BusinessGuard>
} />
<Route path="/:businessId/events" element={
<BusinessGuard><SubLayout><Events /></SubLayout></BusinessGuard>
} />
<Route path="/:businessId/templates" element={
<BusinessGuard><SubLayout><Templates /></SubLayout></BusinessGuard>
} />
<Route path="*" element={<Navigate to="/" replace />} />
</Routes>
</BrowserRouter>
</BusinessProvider>
);
}