Move tenant dashboard routes under /dashboard/ prefix

- Update App.tsx routes to use /dashboard/ prefix for all business user routes
- Add redirect from / to /dashboard for authenticated business users
- Update Sidebar.tsx navigation links with /dashboard/ prefix
- Update SettingsLayout.tsx settings navigation paths
- Update all help pages with /dashboard/help/ routes
- Update navigate() calls in components:
  - TrialBanner, PaymentSettingsSection, NotificationDropdown
  - BusinessLayout, UpgradePrompt, QuotaWarningBanner
  - QuotaOverageModal, OpenTicketsWidget, CreatePlugin
  - MyPlugins, PluginMarketplace, HelpTicketing
  - HelpGuide, Upgrade, TrialExpired
  - CustomDomainsSettings, QuotaSettings
- Fix hardcoded lvh.me URL in BusinessEditModal to use buildSubdomainUrl

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
poduck
2025-12-13 01:48:45 -05:00
parent 29bcb27e76
commit e7733449dd
44 changed files with 284 additions and 281 deletions

View File

@@ -634,7 +634,7 @@ const AppContent: React.FC = () => {
const isTrialExpired = business.isTrialExpired || (business.status === 'Trial' && business.trialEnd && new Date(business.trialEnd) < new Date());
// Allowed routes when trial is expired
const allowedWhenExpired = ['/trial-expired', '/upgrade', '/settings', '/profile'];
const allowedWhenExpired = ['/dashboard/trial-expired', '/dashboard/upgrade', '/dashboard/settings', '/dashboard/profile'];
const currentPath = window.location.pathname;
const isOnAllowedRoute = allowedWhenExpired.some(route => currentPath.startsWith(route));
@@ -643,15 +643,15 @@ const AppContent: React.FC = () => {
return (
<Suspense fallback={<LoadingScreen />}>
<Routes>
<Route path="/trial-expired" element={<TrialExpired />} />
<Route path="/upgrade" element={<Upgrade />} />
<Route path="/profile" element={<ProfileSettings />} />
<Route path="/dashboard/trial-expired" element={<TrialExpired />} />
<Route path="/dashboard/upgrade" element={<Upgrade />} />
<Route path="/dashboard/profile" element={<ProfileSettings />} />
{/* Trial-expired users can access billing settings to upgrade */}
<Route
path="/settings/*"
element={hasAccess(['owner']) ? <Navigate to="/upgrade" /> : <Navigate to="/trial-expired" />}
path="/dashboard/settings/*"
element={hasAccess(['owner']) ? <Navigate to="/dashboard/upgrade" /> : <Navigate to="/dashboard/trial-expired" />}
/>
<Route path="*" element={<Navigate to="/trial-expired" replace />} />
<Route path="*" element={<Navigate to="/dashboard/trial-expired" replace />} />
</Routes>
</Suspense>
);
@@ -672,30 +672,33 @@ const AppContent: React.FC = () => {
/>
}
>
{/* Redirect root to dashboard */}
<Route path="/" element={<Navigate to="/dashboard" replace />} />
{/* Trial and Upgrade Routes */}
<Route path="/trial-expired" element={<TrialExpired />} />
<Route path="/upgrade" element={<Upgrade />} />
<Route path="/dashboard/trial-expired" element={<TrialExpired />} />
<Route path="/dashboard/upgrade" element={<Upgrade />} />
{/* Regular Routes */}
<Route
path="/"
path="/dashboard"
element={user.role === 'resource' ? <ResourceDashboard /> : user.role === 'staff' ? <StaffDashboard user={user} /> : <Dashboard />}
/>
{/* Staff Schedule - vertical timeline view */}
<Route
path="/my-schedule"
path="/dashboard/my-schedule"
element={
hasAccess(['staff']) ? (
<StaffSchedule user={user} />
) : (
<Navigate to="/" />
<Navigate to="/dashboard" />
)
}
/>
<Route path="/scheduler" element={<Scheduler />} />
<Route path="/tickets" element={<Tickets />} />
<Route path="/dashboard/scheduler" element={<Scheduler />} />
<Route path="/dashboard/tickets" element={<Tickets />} />
<Route
path="/help"
path="/dashboard/help"
element={
user.role === 'staff' ? (
<StaffHelp user={user} />
@@ -704,205 +707,205 @@ const AppContent: React.FC = () => {
)
}
/>
<Route path="/help/guide" element={<HelpGuide />} />
<Route path="/help/ticketing" element={<HelpTicketing />} />
<Route path="/help/api" element={<HelpApiDocs />} />
<Route path="/help/plugins/docs" element={<HelpPluginDocs />} />
<Route path="/help/email" element={<HelpEmailSettings />} />
<Route path="/dashboard/help/guide" element={<HelpGuide />} />
<Route path="/dashboard/help/ticketing" element={<HelpTicketing />} />
<Route path="/dashboard/help/api" element={<HelpApiDocs />} />
<Route path="/dashboard/help/plugins/docs" element={<HelpPluginDocs />} />
<Route path="/dashboard/help/email" element={<HelpEmailSettings />} />
{/* New help pages */}
<Route path="/help/dashboard" element={<HelpDashboard />} />
<Route path="/help/scheduler" element={<HelpScheduler />} />
<Route path="/help/tasks" element={<HelpTasks />} />
<Route path="/help/customers" element={<HelpCustomers />} />
<Route path="/help/services" element={<HelpServices />} />
<Route path="/help/resources" element={<HelpResources />} />
<Route path="/help/staff" element={<HelpStaff />} />
<Route path="/help/time-blocks" element={<HelpTimeBlocks />} />
<Route path="/help/messages" element={<HelpMessages />} />
<Route path="/help/payments" element={<HelpPayments />} />
<Route path="/help/contracts" element={<HelpContracts />} />
<Route path="/help/plugins" element={<HelpPlugins />} />
<Route path="/help/settings/general" element={<HelpSettingsGeneral />} />
<Route path="/help/settings/resource-types" element={<HelpSettingsResourceTypes />} />
<Route path="/help/settings/booking" element={<HelpSettingsBooking />} />
<Route path="/help/settings/appearance" element={<HelpSettingsAppearance />} />
<Route path="/help/settings/email" element={<HelpSettingsEmail />} />
<Route path="/help/settings/domains" element={<HelpSettingsDomains />} />
<Route path="/help/settings/api" element={<HelpSettingsApi />} />
<Route path="/help/settings/auth" element={<HelpSettingsAuth />} />
<Route path="/help/settings/billing" element={<HelpSettingsBilling />} />
<Route path="/help/settings/quota" element={<HelpSettingsQuota />} />
<Route path="/dashboard/help/dashboard" element={<HelpDashboard />} />
<Route path="/dashboard/help/scheduler" element={<HelpScheduler />} />
<Route path="/dashboard/help/tasks" element={<HelpTasks />} />
<Route path="/dashboard/help/customers" element={<HelpCustomers />} />
<Route path="/dashboard/help/services" element={<HelpServices />} />
<Route path="/dashboard/help/resources" element={<HelpResources />} />
<Route path="/dashboard/help/staff" element={<HelpStaff />} />
<Route path="/dashboard/help/time-blocks" element={<HelpTimeBlocks />} />
<Route path="/dashboard/help/messages" element={<HelpMessages />} />
<Route path="/dashboard/help/payments" element={<HelpPayments />} />
<Route path="/dashboard/help/contracts" element={<HelpContracts />} />
<Route path="/dashboard/help/plugins" element={<HelpPlugins />} />
<Route path="/dashboard/help/settings/general" element={<HelpSettingsGeneral />} />
<Route path="/dashboard/help/settings/resource-types" element={<HelpSettingsResourceTypes />} />
<Route path="/dashboard/help/settings/booking" element={<HelpSettingsBooking />} />
<Route path="/dashboard/help/settings/appearance" element={<HelpSettingsAppearance />} />
<Route path="/dashboard/help/settings/email" element={<HelpSettingsEmail />} />
<Route path="/dashboard/help/settings/domains" element={<HelpSettingsDomains />} />
<Route path="/dashboard/help/settings/api" element={<HelpSettingsApi />} />
<Route path="/dashboard/help/settings/auth" element={<HelpSettingsAuth />} />
<Route path="/dashboard/help/settings/billing" element={<HelpSettingsBilling />} />
<Route path="/dashboard/help/settings/quota" element={<HelpSettingsQuota />} />
<Route
path="/plugins/marketplace"
path="/dashboard/plugins/marketplace"
element={
hasAccess(['owner', 'manager']) ? (
<PluginMarketplace />
) : (
<Navigate to="/" />
<Navigate to="/dashboard" />
)
}
/>
<Route
path="/plugins/my-plugins"
path="/dashboard/plugins/my-plugins"
element={
hasAccess(['owner', 'manager']) ? (
<MyPlugins />
) : (
<Navigate to="/" />
<Navigate to="/dashboard" />
)
}
/>
<Route
path="/plugins/create"
path="/dashboard/plugins/create"
element={
hasAccess(['owner', 'manager']) ? (
<CreatePlugin />
) : (
<Navigate to="/" />
<Navigate to="/dashboard" />
)
}
/>
<Route
path="/tasks"
path="/dashboard/tasks"
element={
hasAccess(['owner', 'manager']) ? (
<Tasks />
) : (
<Navigate to="/" />
<Navigate to="/dashboard" />
)
}
/>
<Route
path="/email-templates"
path="/dashboard/email-templates"
element={
hasAccess(['owner', 'manager']) ? (
<EmailTemplates />
) : (
<Navigate to="/" />
<Navigate to="/dashboard" />
)
}
/>
<Route path="/support" element={<PlatformSupport />} />
<Route path="/dashboard/support" element={<PlatformSupport />} />
<Route
path="/customers"
path="/dashboard/customers"
element={
hasAccess(['owner', 'manager']) ? (
<Customers onMasquerade={handleMasquerade} effectiveUser={user} />
) : (
<Navigate to="/" />
<Navigate to="/dashboard" />
)
}
/>
<Route
path="/services"
path="/dashboard/services"
element={
hasAccess(['owner', 'manager']) ? (
<Services />
) : (
<Navigate to="/" />
<Navigate to="/dashboard" />
)
}
/>
<Route
path="/resources"
path="/dashboard/resources"
element={
hasAccess(['owner', 'manager']) ? (
<Resources onMasquerade={handleMasquerade} effectiveUser={user} />
) : (
<Navigate to="/" />
<Navigate to="/dashboard" />
)
}
/>
<Route
path="/staff"
path="/dashboard/staff"
element={
hasAccess(['owner', 'manager']) ? (
<Staff onMasquerade={handleMasquerade} effectiveUser={user} />
) : (
<Navigate to="/" />
<Navigate to="/dashboard" />
)
}
/>
<Route
path="/time-blocks"
path="/dashboard/time-blocks"
element={
hasAccess(['owner', 'manager']) ? (
<TimeBlocks />
) : (
<Navigate to="/" />
<Navigate to="/dashboard" />
)
}
/>
<Route
path="/locations"
path="/dashboard/locations"
element={
hasAccess(['owner', 'manager']) ? (
<Locations />
) : (
<Navigate to="/" />
<Navigate to="/dashboard" />
)
}
/>
<Route
path="/my-availability"
path="/dashboard/my-availability"
element={
hasAccess(['staff', 'resource']) ? (
<MyAvailability user={user} />
) : (
<Navigate to="/" />
<Navigate to="/dashboard" />
)
}
/>
<Route
path="/contracts"
path="/dashboard/contracts"
element={
hasAccess(['owner', 'manager']) && canUse('contracts') ? (
<Contracts />
) : (
<Navigate to="/" />
<Navigate to="/dashboard" />
)
}
/>
<Route
path="/contracts/templates"
path="/dashboard/contracts/templates"
element={
hasAccess(['owner', 'manager']) && canUse('contracts') ? (
<ContractTemplates />
) : (
<Navigate to="/" />
<Navigate to="/dashboard" />
)
}
/>
<Route
path="/payments"
path="/dashboard/payments"
element={
hasAccess(['owner', 'manager']) ? <Payments /> : <Navigate to="/" />
hasAccess(['owner', 'manager']) ? <Payments /> : <Navigate to="/dashboard" />
}
/>
<Route
path="/messages"
path="/dashboard/messages"
element={
hasAccess(['owner', 'manager']) && user?.can_send_messages ? (
<Messages />
) : (
<Navigate to="/" />
<Navigate to="/dashboard" />
)
}
/>
<Route
path="/site-editor"
path="/dashboard/site-editor"
element={
hasAccess(['owner', 'manager']) ? (
<PageEditor />
) : (
<Navigate to="/" />
<Navigate to="/dashboard" />
)
}
/>
{/* Settings Routes with Nested Layout */}
{hasAccess(['owner']) ? (
<Route path="/settings" element={<SettingsLayout />}>
<Route index element={<Navigate to="/settings/general" replace />} />
<Route path="/dashboard/settings" element={<SettingsLayout />}>
<Route index element={<Navigate to="/dashboard/settings/general" replace />} />
<Route path="general" element={<GeneralSettings />} />
<Route path="branding" element={<BrandingSettings />} />
<Route path="resource-types" element={<ResourceTypesSettings />} />
@@ -918,11 +921,11 @@ const AppContent: React.FC = () => {
<Route path="quota" element={<QuotaSettings />} />
</Route>
) : (
<Route path="/settings/*" element={<Navigate to="/" />} />
<Route path="/dashboard/settings/*" element={<Navigate to="/dashboard" />} />
)}
<Route path="/profile" element={<ProfileSettings />} />
<Route path="/verify-email" element={<VerifyEmail />} />
<Route path="*" element={<Navigate to="/" />} />
<Route path="/dashboard/profile" element={<ProfileSettings />} />
<Route path="/dashboard/verify-email" element={<VerifyEmail />} />
<Route path="*" element={<Navigate to="/dashboard" />} />
</Route>
</Routes>
</Suspense>