import { useState } from 'react'; import { BrowserRouter, Routes, Route, Navigate, useLocation } from 'react-router-dom'; import { BusinessProvider, useBusiness } from './context/BusinessContext'; import apiClient from './api/client'; import BusinessReviewModal from './components/BusinessReviewModal'; import Sidebar from './components/Sidebar'; import Businesses from './pages/Businesses'; import Providers from './pages/Providers'; import GlobalSms from './pages/GlobalSms'; import Analytics from './pages/Analytics'; import Events from './pages/Events'; import Templates from './pages/Templates'; import { Link } from 'react-router-dom'; function SubLayout({ children }) { const { activeBusiness, activeBusinessId, hasGlobalSms } = useBusiness(); const [reviewBusiness, setReviewBusiness] = useState(null); const [reviewLoading, setReviewLoading] = useState(false); const [reviewError, setReviewError] = useState(''); async function handleOpenReview() { if (!activeBusinessId || reviewLoading) return; setReviewError(''); if (activeBusiness?.scrapeArtifacts?.json) { setReviewBusiness(activeBusiness); return; } setReviewLoading(true); try { const response = await apiClient.get(`/api/businesses/${activeBusinessId}`); setReviewBusiness(response.data); } catch (error) { setReviewError(error.response?.data?.error || 'Failed to load brand review.'); } finally { setReviewLoading(false); } } return ( <>
{hasGlobalSms && ( )}
{children}
{reviewBusiness && ( setReviewBusiness(null)} /> )} ); } // 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, isSetupComplete } = useBusiness(); const location = useLocation(); if (loading) { return (
); } if (!activeBusinessId) { return ; } if (!isSetupComplete && !isGlobalSmsRoute) { return ; } return children; } export default function App() { return ( } /> } /> } /> } /> } /> } /> } /> ); }