Add missing frontend platform components and update production deployment
This commit adds all previously untracked files and modifications needed for production deployment: - New marketing components (BenefitsSection, CodeBlock, PluginShowcase, PricingTable) - Platform admin components (EditPlatformEntityModal, PlatformListRow, PlatformListing, PlatformTable) - Updated deployment configuration and scripts - Various frontend API and component improvements 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
* Main App Component - Integrated with Real API
|
||||
*/
|
||||
|
||||
import React, { useState } from 'react';
|
||||
import React, { useState, Suspense } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { BrowserRouter as Router, Routes, Route, Navigate } from 'react-router-dom';
|
||||
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
||||
@@ -12,9 +12,9 @@ import { useUpdateBusiness } from './hooks/useBusiness';
|
||||
import { setCookie } from './utils/cookies';
|
||||
|
||||
// Import Login Page
|
||||
import LoginPage from './pages/LoginPage';
|
||||
import MFAVerifyPage from './pages/MFAVerifyPage';
|
||||
import OAuthCallback from './pages/OAuthCallback';
|
||||
const LoginPage = React.lazy(() => import('./pages/LoginPage'));
|
||||
const MFAVerifyPage = React.lazy(() => import('./pages/MFAVerifyPage'));
|
||||
const OAuthCallback = React.lazy(() => import('./pages/OAuthCallback'));
|
||||
|
||||
// Import layouts
|
||||
import BusinessLayout from './layouts/BusinessLayout';
|
||||
@@ -23,51 +23,51 @@ import CustomerLayout from './layouts/CustomerLayout';
|
||||
import MarketingLayout from './layouts/MarketingLayout';
|
||||
|
||||
// Import marketing pages
|
||||
import HomePage from './pages/marketing/HomePage';
|
||||
import FeaturesPage from './pages/marketing/FeaturesPage';
|
||||
import PricingPage from './pages/marketing/PricingPage';
|
||||
import AboutPage from './pages/marketing/AboutPage';
|
||||
import ContactPage from './pages/marketing/ContactPage';
|
||||
import SignupPage from './pages/marketing/SignupPage';
|
||||
const HomePage = React.lazy(() => import('./pages/marketing/HomePage'));
|
||||
const FeaturesPage = React.lazy(() => import('./pages/marketing/FeaturesPage'));
|
||||
const PricingPage = React.lazy(() => import('./pages/marketing/PricingPage'));
|
||||
const AboutPage = React.lazy(() => import('./pages/marketing/AboutPage'));
|
||||
const ContactPage = React.lazy(() => import('./pages/marketing/ContactPage'));
|
||||
const SignupPage = React.lazy(() => import('./pages/marketing/SignupPage'));
|
||||
|
||||
// Import pages
|
||||
import Dashboard from './pages/Dashboard';
|
||||
import Scheduler from './pages/Scheduler';
|
||||
import Customers from './pages/Customers';
|
||||
import Settings from './pages/Settings';
|
||||
import Payments from './pages/Payments';
|
||||
import Resources from './pages/Resources';
|
||||
import Services from './pages/Services';
|
||||
import Staff from './pages/Staff';
|
||||
import CustomerDashboard from './pages/customer/CustomerDashboard';
|
||||
import CustomerSupport from './pages/customer/CustomerSupport';
|
||||
import ResourceDashboard from './pages/resource/ResourceDashboard';
|
||||
import BookingPage from './pages/customer/BookingPage';
|
||||
import TrialExpired from './pages/TrialExpired';
|
||||
import Upgrade from './pages/Upgrade';
|
||||
const Dashboard = React.lazy(() => import('./pages/Dashboard'));
|
||||
const Scheduler = React.lazy(() => import('./pages/Scheduler'));
|
||||
const Customers = React.lazy(() => import('./pages/Customers'));
|
||||
const Settings = React.lazy(() => import('./pages/Settings'));
|
||||
const Payments = React.lazy(() => import('./pages/Payments'));
|
||||
const Resources = React.lazy(() => import('./pages/Resources'));
|
||||
const Services = React.lazy(() => import('./pages/Services'));
|
||||
const Staff = React.lazy(() => import('./pages/Staff'));
|
||||
const CustomerDashboard = React.lazy(() => import('./pages/customer/CustomerDashboard'));
|
||||
const CustomerSupport = React.lazy(() => import('./pages/customer/CustomerSupport'));
|
||||
const ResourceDashboard = React.lazy(() => import('./pages/resource/ResourceDashboard'));
|
||||
const BookingPage = React.lazy(() => import('./pages/customer/BookingPage'));
|
||||
const TrialExpired = React.lazy(() => import('./pages/TrialExpired'));
|
||||
const Upgrade = React.lazy(() => import('./pages/Upgrade'));
|
||||
|
||||
// Import platform pages
|
||||
import PlatformDashboard from './pages/platform/PlatformDashboard';
|
||||
import PlatformBusinesses from './pages/platform/PlatformBusinesses';
|
||||
import PlatformSupportPage from './pages/platform/PlatformSupport';
|
||||
import PlatformUsers from './pages/platform/PlatformUsers';
|
||||
import PlatformStaff from './pages/platform/PlatformStaff';
|
||||
import PlatformSettings from './pages/platform/PlatformSettings';
|
||||
import ProfileSettings from './pages/ProfileSettings';
|
||||
import VerifyEmail from './pages/VerifyEmail';
|
||||
import EmailVerificationRequired from './pages/EmailVerificationRequired';
|
||||
import AcceptInvitePage from './pages/AcceptInvitePage';
|
||||
import TenantOnboardPage from './pages/TenantOnboardPage';
|
||||
import Tickets from './pages/Tickets'; // Import Tickets page
|
||||
import HelpGuide from './pages/HelpGuide'; // Import Platform Guide page
|
||||
import HelpTicketing from './pages/HelpTicketing'; // Import Help page for ticketing
|
||||
import HelpApiDocs from './pages/HelpApiDocs'; // Import API documentation page
|
||||
import HelpPluginDocs from './pages/HelpPluginDocs'; // Import Plugin documentation page
|
||||
import PlatformSupport from './pages/PlatformSupport'; // Import Platform Support page (for businesses to contact SmoothSchedule)
|
||||
import PluginMarketplace from './pages/PluginMarketplace'; // Import Plugin Marketplace page
|
||||
import MyPlugins from './pages/MyPlugins'; // Import My Plugins page
|
||||
import Tasks from './pages/Tasks'; // Import Tasks page for scheduled plugin executions
|
||||
import EmailTemplates from './pages/EmailTemplates'; // Import Email Templates page
|
||||
const PlatformDashboard = React.lazy(() => import('./pages/platform/PlatformDashboard'));
|
||||
const PlatformBusinesses = React.lazy(() => import('./pages/platform/PlatformBusinesses'));
|
||||
const PlatformSupportPage = React.lazy(() => import('./pages/platform/PlatformSupport'));
|
||||
const PlatformUsers = React.lazy(() => import('./pages/platform/PlatformUsers'));
|
||||
const PlatformStaff = React.lazy(() => import('./pages/platform/PlatformStaff'));
|
||||
const PlatformSettings = React.lazy(() => import('./pages/platform/PlatformSettings'));
|
||||
const ProfileSettings = React.lazy(() => import('./pages/ProfileSettings'));
|
||||
const VerifyEmail = React.lazy(() => import('./pages/VerifyEmail'));
|
||||
const EmailVerificationRequired = React.lazy(() => import('./pages/EmailVerificationRequired'));
|
||||
const AcceptInvitePage = React.lazy(() => import('./pages/AcceptInvitePage'));
|
||||
const TenantOnboardPage = React.lazy(() => import('./pages/TenantOnboardPage'));
|
||||
const Tickets = React.lazy(() => import('./pages/Tickets')); // Import Tickets page
|
||||
const HelpGuide = React.lazy(() => import('./pages/HelpGuide')); // Import Platform Guide page
|
||||
const HelpTicketing = React.lazy(() => import('./pages/HelpTicketing')); // Import Help page for ticketing
|
||||
const HelpApiDocs = React.lazy(() => import('./pages/HelpApiDocs')); // Import API documentation page
|
||||
const HelpPluginDocs = React.lazy(() => import('./pages/HelpPluginDocs')); // Import Plugin documentation page
|
||||
const PlatformSupport = React.lazy(() => import('./pages/PlatformSupport')); // Import Platform Support page (for businesses to contact SmoothSchedule)
|
||||
const PluginMarketplace = React.lazy(() => import('./pages/PluginMarketplace')); // Import Plugin Marketplace page
|
||||
const MyPlugins = React.lazy(() => import('./pages/MyPlugins')); // Import My Plugins page
|
||||
const Tasks = React.lazy(() => import('./pages/Tasks')); // Import Tasks page for scheduled plugin executions
|
||||
const EmailTemplates = React.lazy(() => import('./pages/EmailTemplates')); // Import Email Templates page
|
||||
import { Toaster } from 'react-hot-toast'; // Import Toaster for notifications
|
||||
|
||||
const queryClient = new QueryClient({
|
||||
@@ -219,23 +219,25 @@ const AppContent: React.FC = () => {
|
||||
// Logged-in users will see a "Go to Dashboard" link in the navbar
|
||||
if (isRootDomain()) {
|
||||
return (
|
||||
<Routes>
|
||||
<Route element={<MarketingLayout user={user} />}>
|
||||
<Route path="/" element={<HomePage />} />
|
||||
<Route path="/features" element={<FeaturesPage />} />
|
||||
<Route path="/pricing" element={<PricingPage />} />
|
||||
<Route path="/about" element={<AboutPage />} />
|
||||
<Route path="/contact" element={<ContactPage />} />
|
||||
<Route path="/signup" element={<SignupPage />} />
|
||||
</Route>
|
||||
<Route path="/login" element={<LoginPage />} />
|
||||
<Route path="/mfa-verify" element={<MFAVerifyPage />} />
|
||||
<Route path="/oauth/callback/:provider" element={<OAuthCallback />} />
|
||||
<Route path="/verify-email" element={<VerifyEmail />} />
|
||||
<Route path="/accept-invite" element={<AcceptInvitePage />} />
|
||||
<Route path="/tenant-onboard" element={<TenantOnboardPage />} />
|
||||
<Route path="*" element={<Navigate to="/" replace />} />
|
||||
</Routes>
|
||||
<Suspense fallback={<LoadingScreen />}>
|
||||
<Routes>
|
||||
<Route element={<MarketingLayout user={user} />}>
|
||||
<Route path="/" element={<HomePage />} />
|
||||
<Route path="/features" element={<FeaturesPage />} />
|
||||
<Route path="/pricing" element={<PricingPage />} />
|
||||
<Route path="/about" element={<AboutPage />} />
|
||||
<Route path="/contact" element={<ContactPage />} />
|
||||
<Route path="/signup" element={<SignupPage />} />
|
||||
</Route>
|
||||
<Route path="/login" element={<LoginPage />} />
|
||||
<Route path="/mfa-verify" element={<MFAVerifyPage />} />
|
||||
<Route path="/oauth/callback/:provider" element={<OAuthCallback />} />
|
||||
<Route path="/verify-email" element={<VerifyEmail />} />
|
||||
<Route path="/accept-invite" element={<AcceptInvitePage />} />
|
||||
<Route path="/tenant-onboard" element={<TenantOnboardPage />} />
|
||||
<Route path="*" element={<Navigate to="/" replace />} />
|
||||
</Routes>
|
||||
</Suspense>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -257,23 +259,25 @@ const AppContent: React.FC = () => {
|
||||
}
|
||||
|
||||
return (
|
||||
<Routes>
|
||||
<Route element={<MarketingLayout user={user} />}>
|
||||
<Route path="/" element={<HomePage />} />
|
||||
<Route path="/features" element={<FeaturesPage />} />
|
||||
<Route path="/pricing" element={<PricingPage />} />
|
||||
<Route path="/about" element={<AboutPage />} />
|
||||
<Route path="/contact" element={<ContactPage />} />
|
||||
<Route path="/signup" element={<SignupPage />} />
|
||||
</Route>
|
||||
<Route path="/login" element={<LoginPage />} />
|
||||
<Route path="/mfa-verify" element={<MFAVerifyPage />} />
|
||||
<Route path="/oauth/callback/:provider" element={<OAuthCallback />} />
|
||||
<Route path="/verify-email" element={<VerifyEmail />} />
|
||||
<Route path="/accept-invite" element={<AcceptInvitePage />} />
|
||||
<Route path="/tenant-onboard" element={<TenantOnboardPage />} />
|
||||
<Route path="*" element={<Navigate to="/" replace />} />
|
||||
</Routes>
|
||||
<Suspense fallback={<LoadingScreen />}>
|
||||
<Routes>
|
||||
<Route element={<MarketingLayout user={user} />}>
|
||||
<Route path="/" element={<HomePage />} />
|
||||
<Route path="/features" element={<FeaturesPage />} />
|
||||
<Route path="/pricing" element={<PricingPage />} />
|
||||
<Route path="/about" element={<AboutPage />} />
|
||||
<Route path="/contact" element={<ContactPage />} />
|
||||
<Route path="/signup" element={<SignupPage />} />
|
||||
</Route>
|
||||
<Route path="/login" element={<LoginPage />} />
|
||||
<Route path="/mfa-verify" element={<MFAVerifyPage />} />
|
||||
<Route path="/oauth/callback/:provider" element={<OAuthCallback />} />
|
||||
<Route path="/verify-email" element={<VerifyEmail />} />
|
||||
<Route path="/accept-invite" element={<AcceptInvitePage />} />
|
||||
<Route path="/tenant-onboard" element={<TenantOnboardPage />} />
|
||||
<Route path="*" element={<Navigate to="/" replace />} />
|
||||
</Routes>
|
||||
</Suspense>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -350,49 +354,51 @@ const AppContent: React.FC = () => {
|
||||
|
||||
if (isPlatformUser) {
|
||||
return (
|
||||
<Routes>
|
||||
<Route
|
||||
element={
|
||||
<PlatformLayout
|
||||
user={user}
|
||||
darkMode={darkMode}
|
||||
toggleTheme={toggleTheme}
|
||||
onSignOut={handleSignOut}
|
||||
/>
|
||||
}
|
||||
>
|
||||
{(user.role === 'superuser' || user.role === 'platform_manager') && (
|
||||
<>
|
||||
<Route path="/platform/dashboard" element={<PlatformDashboard />} />
|
||||
<Route path="/platform/businesses" element={<PlatformBusinesses onMasquerade={handleMasquerade} />} />
|
||||
<Route path="/platform/users" element={<PlatformUsers onMasquerade={handleMasquerade} />} />
|
||||
<Route path="/platform/staff" element={<PlatformStaff />} />
|
||||
</>
|
||||
)}
|
||||
<Route path="/platform/support" element={<PlatformSupportPage />} />
|
||||
<Route path="/help/guide" element={<HelpGuide />} />
|
||||
<Route path="/help/ticketing" element={<HelpTicketing />} />
|
||||
<Route path="/help/api" element={<HelpApiDocs />} />
|
||||
<Route path="/help/plugins" element={<HelpPluginDocs />} />
|
||||
{user.role === 'superuser' && (
|
||||
<Route path="/platform/settings" element={<PlatformSettings />} />
|
||||
)}
|
||||
<Route path="/platform/profile" element={<ProfileSettings />} />
|
||||
<Route path="/verify-email" element={<VerifyEmail />} />
|
||||
<Suspense fallback={<LoadingScreen />}>
|
||||
<Routes>
|
||||
<Route
|
||||
path="*"
|
||||
element={
|
||||
<Navigate
|
||||
to={
|
||||
user.role === 'superuser' || user.role === 'platform_manager'
|
||||
? '/platform/dashboard'
|
||||
: '/platform/support'
|
||||
}
|
||||
<PlatformLayout
|
||||
user={user}
|
||||
darkMode={darkMode}
|
||||
toggleTheme={toggleTheme}
|
||||
onSignOut={handleSignOut}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
</Route>
|
||||
</Routes>
|
||||
>
|
||||
{(user.role === 'superuser' || user.role === 'platform_manager') && (
|
||||
<>
|
||||
<Route path="/platform/dashboard" element={<PlatformDashboard />} />
|
||||
<Route path="/platform/businesses" element={<PlatformBusinesses onMasquerade={handleMasquerade} />} />
|
||||
<Route path="/platform/users" element={<PlatformUsers onMasquerade={handleMasquerade} />} />
|
||||
<Route path="/platform/staff" element={<PlatformStaff />} />
|
||||
</>
|
||||
)}
|
||||
<Route path="/platform/support" element={<PlatformSupportPage />} />
|
||||
<Route path="/help/guide" element={<HelpGuide />} />
|
||||
<Route path="/help/ticketing" element={<HelpTicketing />} />
|
||||
<Route path="/help/api" element={<HelpApiDocs />} />
|
||||
<Route path="/help/plugins" element={<HelpPluginDocs />} />
|
||||
{user.role === 'superuser' && (
|
||||
<Route path="/platform/settings" element={<PlatformSettings />} />
|
||||
)}
|
||||
<Route path="/platform/profile" element={<ProfileSettings />} />
|
||||
<Route path="/verify-email" element={<VerifyEmail />} />
|
||||
<Route
|
||||
path="*"
|
||||
element={
|
||||
<Navigate
|
||||
to={
|
||||
user.role === 'superuser' || user.role === 'platform_manager'
|
||||
? '/platform/dashboard'
|
||||
: '/platform/support'
|
||||
}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
</Route>
|
||||
</Routes>
|
||||
</Suspense>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -424,26 +430,28 @@ const AppContent: React.FC = () => {
|
||||
}
|
||||
|
||||
return (
|
||||
<Routes>
|
||||
<Route
|
||||
element={
|
||||
<CustomerLayout
|
||||
business={business}
|
||||
user={user}
|
||||
darkMode={darkMode}
|
||||
toggleTheme={toggleTheme}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<Route path="/" element={<CustomerDashboard />} />
|
||||
<Route path="/book" element={<BookingPage />} />
|
||||
<Route path="/payments" element={<Payments />} />
|
||||
<Route path="/support" element={<CustomerSupport />} />
|
||||
<Route path="/profile" element={<ProfileSettings />} />
|
||||
<Route path="/verify-email" element={<VerifyEmail />} />
|
||||
<Route path="*" element={<Navigate to="/" />} />
|
||||
</Route>
|
||||
</Routes>
|
||||
<Suspense fallback={<LoadingScreen />}>
|
||||
<Routes>
|
||||
<Route
|
||||
element={
|
||||
<CustomerLayout
|
||||
business={business}
|
||||
user={user}
|
||||
darkMode={darkMode}
|
||||
toggleTheme={toggleTheme}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<Route path="/" element={<CustomerDashboard />} />
|
||||
<Route path="/book" element={<BookingPage />} />
|
||||
<Route path="/payments" element={<Payments />} />
|
||||
<Route path="/support" element={<CustomerSupport />} />
|
||||
<Route path="/profile" element={<ProfileSettings />} />
|
||||
<Route path="/verify-email" element={<VerifyEmail />} />
|
||||
<Route path="*" element={<Navigate to="/" />} />
|
||||
</Route>
|
||||
</Routes>
|
||||
</Suspense>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -492,11 +500,13 @@ const AppContent: React.FC = () => {
|
||||
// Check if email verification is required
|
||||
if (!user.email_verified) {
|
||||
return (
|
||||
<Routes>
|
||||
<Route path="/email-verification-required" element={<EmailVerificationRequired />} />
|
||||
<Route path="/verify-email" element={<VerifyEmail />} />
|
||||
<Route path="*" element={<Navigate to="/email-verification-required" replace />} />
|
||||
</Routes>
|
||||
<Suspense fallback={<LoadingScreen />}>
|
||||
<Routes>
|
||||
<Route path="/email-verification-required" element={<EmailVerificationRequired />} />
|
||||
<Route path="/verify-email" element={<VerifyEmail />} />
|
||||
<Route path="*" element={<Navigate to="/email-verification-required" replace />} />
|
||||
</Routes>
|
||||
</Suspense>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -511,157 +521,161 @@ const AppContent: React.FC = () => {
|
||||
// If trial expired and not on allowed route, redirect to trial-expired
|
||||
if (isTrialExpired && !isOnAllowedRoute) {
|
||||
return (
|
||||
<Routes>
|
||||
<Route path="/trial-expired" element={<TrialExpired />} />
|
||||
<Route path="/upgrade" element={<Upgrade />} />
|
||||
<Route path="/profile" element={<ProfileSettings />} />
|
||||
<Route
|
||||
path="/settings"
|
||||
element={hasAccess(['owner']) ? <Settings /> : <Navigate to="/trial-expired" />}
|
||||
/>
|
||||
<Route path="*" element={<Navigate to="/trial-expired" replace />} />
|
||||
</Routes>
|
||||
<Suspense fallback={<LoadingScreen />}>
|
||||
<Routes>
|
||||
<Route path="/trial-expired" element={<TrialExpired />} />
|
||||
<Route path="/upgrade" element={<Upgrade />} />
|
||||
<Route path="/profile" element={<ProfileSettings />} />
|
||||
<Route
|
||||
path="/settings"
|
||||
element={hasAccess(['owner']) ? <Settings /> : <Navigate to="/trial-expired" />}
|
||||
/>
|
||||
<Route path="*" element={<Navigate to="/trial-expired" replace />} />
|
||||
</Routes>
|
||||
</Suspense>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Routes>
|
||||
<Route
|
||||
element={
|
||||
<BusinessLayout
|
||||
business={business}
|
||||
user={user}
|
||||
darkMode={darkMode}
|
||||
toggleTheme={toggleTheme}
|
||||
onSignOut={handleSignOut}
|
||||
updateBusiness={handleUpdateBusiness}
|
||||
/>
|
||||
}
|
||||
>
|
||||
{/* Trial and Upgrade Routes */}
|
||||
<Route path="/trial-expired" element={<TrialExpired />} />
|
||||
<Route path="/upgrade" element={<Upgrade />} />
|
||||
<Suspense fallback={<LoadingScreen />}>
|
||||
<Routes>
|
||||
<Route
|
||||
element={
|
||||
<BusinessLayout
|
||||
business={business}
|
||||
user={user}
|
||||
darkMode={darkMode}
|
||||
toggleTheme={toggleTheme}
|
||||
onSignOut={handleSignOut}
|
||||
updateBusiness={handleUpdateBusiness}
|
||||
/>
|
||||
}
|
||||
>
|
||||
{/* Trial and Upgrade Routes */}
|
||||
<Route path="/trial-expired" element={<TrialExpired />} />
|
||||
<Route path="/upgrade" element={<Upgrade />} />
|
||||
|
||||
{/* Regular Routes */}
|
||||
<Route
|
||||
path="/"
|
||||
element={user.role === 'resource' ? <ResourceDashboard /> : <Dashboard />}
|
||||
/>
|
||||
<Route path="/scheduler" element={<Scheduler />} />
|
||||
<Route path="/tickets" element={<Tickets />} />
|
||||
<Route path="/help/guide" element={<HelpGuide />} />
|
||||
<Route path="/help/ticketing" element={<HelpTicketing />} />
|
||||
<Route path="/help/api" element={<HelpApiDocs />} />
|
||||
<Route path="/help/plugins" element={<HelpPluginDocs />} />
|
||||
<Route
|
||||
path="/plugins/marketplace"
|
||||
element={
|
||||
hasAccess(['owner', 'manager']) ? (
|
||||
<PluginMarketplace />
|
||||
) : (
|
||||
<Navigate to="/" />
|
||||
)
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="/plugins/my-plugins"
|
||||
element={
|
||||
hasAccess(['owner', 'manager']) ? (
|
||||
<MyPlugins />
|
||||
) : (
|
||||
<Navigate to="/" />
|
||||
)
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="/tasks"
|
||||
element={
|
||||
hasAccess(['owner', 'manager']) ? (
|
||||
<Tasks />
|
||||
) : (
|
||||
<Navigate to="/" />
|
||||
)
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="/email-templates"
|
||||
element={
|
||||
hasAccess(['owner', 'manager']) ? (
|
||||
<EmailTemplates />
|
||||
) : (
|
||||
<Navigate to="/" />
|
||||
)
|
||||
}
|
||||
/>
|
||||
<Route path="/support" element={<PlatformSupport />} />
|
||||
<Route
|
||||
path="/customers"
|
||||
element={
|
||||
hasAccess(['owner', 'manager', 'staff']) ? (
|
||||
<Customers onMasquerade={handleMasquerade} effectiveUser={user} />
|
||||
) : (
|
||||
<Navigate to="/" />
|
||||
)
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="/services"
|
||||
element={
|
||||
hasAccess(['owner', 'manager', 'staff']) ? (
|
||||
<Services />
|
||||
) : (
|
||||
<Navigate to="/" />
|
||||
)
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="/resources"
|
||||
element={
|
||||
hasAccess(['owner', 'manager', 'staff']) ? (
|
||||
<Resources onMasquerade={handleMasquerade} effectiveUser={user} />
|
||||
) : (
|
||||
<Navigate to="/" />
|
||||
)
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="/staff"
|
||||
element={
|
||||
hasAccess(['owner', 'manager']) ? (
|
||||
<Staff onMasquerade={handleMasquerade} effectiveUser={user} />
|
||||
) : (
|
||||
<Navigate to="/" />
|
||||
)
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="/payments"
|
||||
element={
|
||||
hasAccess(['owner', 'manager']) ? <Payments /> : <Navigate to="/" />
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="/messages"
|
||||
element={
|
||||
hasAccess(['owner', 'manager']) ? (
|
||||
<div className="p-8">
|
||||
<h1 className="text-2xl font-bold mb-4">Messages</h1>
|
||||
<p className="text-gray-600">Messages feature coming soon...</p>
|
||||
</div>
|
||||
) : (
|
||||
<Navigate to="/" />
|
||||
)
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="/settings"
|
||||
element={hasAccess(['owner']) ? <Settings /> : <Navigate to="/" />}
|
||||
/>
|
||||
<Route path="/profile" element={<ProfileSettings />} />
|
||||
<Route path="/verify-email" element={<VerifyEmail />} />
|
||||
<Route path="*" element={<Navigate to="/" />} />
|
||||
</Route>
|
||||
</Routes>
|
||||
{/* Regular Routes */}
|
||||
<Route
|
||||
path="/"
|
||||
element={user.role === 'resource' ? <ResourceDashboard /> : <Dashboard />}
|
||||
/>
|
||||
<Route path="/scheduler" element={<Scheduler />} />
|
||||
<Route path="/tickets" element={<Tickets />} />
|
||||
<Route path="/help/guide" element={<HelpGuide />} />
|
||||
<Route path="/help/ticketing" element={<HelpTicketing />} />
|
||||
<Route path="/help/api" element={<HelpApiDocs />} />
|
||||
<Route path="/help/plugins" element={<HelpPluginDocs />} />
|
||||
<Route
|
||||
path="/plugins/marketplace"
|
||||
element={
|
||||
hasAccess(['owner', 'manager']) ? (
|
||||
<PluginMarketplace />
|
||||
) : (
|
||||
<Navigate to="/" />
|
||||
)
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="/plugins/my-plugins"
|
||||
element={
|
||||
hasAccess(['owner', 'manager']) ? (
|
||||
<MyPlugins />
|
||||
) : (
|
||||
<Navigate to="/" />
|
||||
)
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="/tasks"
|
||||
element={
|
||||
hasAccess(['owner', 'manager']) ? (
|
||||
<Tasks />
|
||||
) : (
|
||||
<Navigate to="/" />
|
||||
)
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="/email-templates"
|
||||
element={
|
||||
hasAccess(['owner', 'manager']) ? (
|
||||
<EmailTemplates />
|
||||
) : (
|
||||
<Navigate to="/" />
|
||||
)
|
||||
}
|
||||
/>
|
||||
<Route path="/support" element={<PlatformSupport />} />
|
||||
<Route
|
||||
path="/customers"
|
||||
element={
|
||||
hasAccess(['owner', 'manager', 'staff']) ? (
|
||||
<Customers onMasquerade={handleMasquerade} effectiveUser={user} />
|
||||
) : (
|
||||
<Navigate to="/" />
|
||||
)
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="/services"
|
||||
element={
|
||||
hasAccess(['owner', 'manager', 'staff']) ? (
|
||||
<Services />
|
||||
) : (
|
||||
<Navigate to="/" />
|
||||
)
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="/resources"
|
||||
element={
|
||||
hasAccess(['owner', 'manager', 'staff']) ? (
|
||||
<Resources onMasquerade={handleMasquerade} effectiveUser={user} />
|
||||
) : (
|
||||
<Navigate to="/" />
|
||||
)
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="/staff"
|
||||
element={
|
||||
hasAccess(['owner', 'manager']) ? (
|
||||
<Staff onMasquerade={handleMasquerade} effectiveUser={user} />
|
||||
) : (
|
||||
<Navigate to="/" />
|
||||
)
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="/payments"
|
||||
element={
|
||||
hasAccess(['owner', 'manager']) ? <Payments /> : <Navigate to="/" />
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="/messages"
|
||||
element={
|
||||
hasAccess(['owner', 'manager']) ? (
|
||||
<div className="p-8">
|
||||
<h1 className="text-2xl font-bold mb-4">Messages</h1>
|
||||
<p className="text-gray-600">Messages feature coming soon...</p>
|
||||
</div>
|
||||
) : (
|
||||
<Navigate to="/" />
|
||||
)
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="/settings"
|
||||
element={hasAccess(['owner']) ? <Settings /> : <Navigate to="/" />}
|
||||
/>
|
||||
<Route path="/profile" element={<ProfileSettings />} />
|
||||
<Route path="/verify-email" element={<VerifyEmail />} />
|
||||
<Route path="*" element={<Navigate to="/" />} />
|
||||
</Route>
|
||||
</Routes>
|
||||
</Suspense>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user