From e7733449dd2671cfacbbf9d5f933e45efd43b59f Mon Sep 17 00:00:00 2001 From: poduck Date: Sat, 13 Dec 2025 01:48:45 -0500 Subject: [PATCH] Move tenant dashboard routes under /dashboard/ prefix MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 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 --- frontend/src/App.tsx | 169 +++++++++--------- .../src/components/NotificationDropdown.tsx | 4 +- .../src/components/PaymentSettingsSection.tsx | 2 +- frontend/src/components/QuotaOverageModal.tsx | 2 +- .../src/components/QuotaWarningBanner.tsx | 2 +- frontend/src/components/Sidebar.tsx | 39 ++-- frontend/src/components/TrialBanner.tsx | 2 +- frontend/src/components/UpgradePrompt.tsx | 4 +- .../dashboard/OpenTicketsWidget.tsx | 4 +- frontend/src/layouts/BusinessLayout.tsx | 4 +- frontend/src/layouts/SettingsLayout.tsx | 38 ++-- frontend/src/pages/CreatePlugin.tsx | 8 +- frontend/src/pages/HelpGuide.tsx | 54 +++--- frontend/src/pages/HelpTicketing.tsx | 2 +- frontend/src/pages/MyPlugins.tsx | 10 +- frontend/src/pages/PluginMarketplace.tsx | 6 +- frontend/src/pages/TrialExpired.tsx | 2 +- frontend/src/pages/Upgrade.tsx | 2 +- frontend/src/pages/help/HelpComprehensive.tsx | 32 ++-- frontend/src/pages/help/HelpContracts.tsx | 6 +- frontend/src/pages/help/HelpCustomers.tsx | 10 +- frontend/src/pages/help/HelpDashboard.tsx | 6 +- frontend/src/pages/help/HelpMessages.tsx | 6 +- frontend/src/pages/help/HelpPayments.tsx | 6 +- frontend/src/pages/help/HelpPlugins.tsx | 4 +- frontend/src/pages/help/HelpResources.tsx | 10 +- frontend/src/pages/help/HelpScheduler.tsx | 8 +- frontend/src/pages/help/HelpServices.tsx | 10 +- frontend/src/pages/help/HelpSettingsApi.tsx | 6 +- .../src/pages/help/HelpSettingsAppearance.tsx | 10 +- frontend/src/pages/help/HelpSettingsAuth.tsx | 6 +- .../src/pages/help/HelpSettingsBilling.tsx | 10 +- .../src/pages/help/HelpSettingsBooking.tsx | 12 +- .../src/pages/help/HelpSettingsDomains.tsx | 6 +- frontend/src/pages/help/HelpSettingsEmail.tsx | 10 +- .../src/pages/help/HelpSettingsGeneral.tsx | 10 +- frontend/src/pages/help/HelpSettingsQuota.tsx | 8 +- .../pages/help/HelpSettingsResourceTypes.tsx | 10 +- frontend/src/pages/help/HelpStaff.tsx | 10 +- frontend/src/pages/help/HelpTasks.tsx | 6 +- frontend/src/pages/help/StaffHelp.tsx | 2 +- .../platform/components/BusinessEditModal.tsx | 3 +- .../pages/settings/CustomDomainsSettings.tsx | 2 +- frontend/src/pages/settings/QuotaSettings.tsx | 2 +- 44 files changed, 284 insertions(+), 281 deletions(-) diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index c10de2f..bf2b62a 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -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 ( }> - } /> - } /> - } /> + } /> + } /> + } /> {/* Trial-expired users can access billing settings to upgrade */} : } + path="/dashboard/settings/*" + element={hasAccess(['owner']) ? : } /> - } /> + } /> ); @@ -672,30 +672,33 @@ const AppContent: React.FC = () => { /> } > + {/* Redirect root to dashboard */} + } /> + {/* Trial and Upgrade Routes */} - } /> - } /> + } /> + } /> {/* Regular Routes */} : user.role === 'staff' ? : } /> {/* Staff Schedule - vertical timeline view */} ) : ( - + ) } /> - } /> - } /> + } /> + } /> @@ -704,205 +707,205 @@ const AppContent: React.FC = () => { ) } /> - } /> - } /> - } /> - } /> - } /> + } /> + } /> + } /> + } /> + } /> {/* New help pages */} - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> ) : ( - + ) } /> ) : ( - + ) } /> ) : ( - + ) } /> ) : ( - + ) } /> ) : ( - + ) } /> - } /> + } /> ) : ( - + ) } /> ) : ( - + ) } /> ) : ( - + ) } /> ) : ( - + ) } /> ) : ( - + ) } /> ) : ( - + ) } /> ) : ( - + ) } /> ) : ( - + ) } /> ) : ( - + ) } /> : + hasAccess(['owner', 'manager']) ? : } /> ) : ( - + ) } /> ) : ( - + ) } /> {/* Settings Routes with Nested Layout */} {hasAccess(['owner']) ? ( - }> - } /> + }> + } /> } /> } /> } /> @@ -918,11 +921,11 @@ const AppContent: React.FC = () => { } /> ) : ( - } /> + } /> )} - } /> - } /> - } /> + } /> + } /> + } /> diff --git a/frontend/src/components/NotificationDropdown.tsx b/frontend/src/components/NotificationDropdown.tsx index 6963f94..a7473cd 100644 --- a/frontend/src/components/NotificationDropdown.tsx +++ b/frontend/src/components/NotificationDropdown.tsx @@ -59,7 +59,7 @@ const NotificationDropdown: React.FC = ({ variant = ' // Handle time-off request notifications - navigate to time blocks page // Includes both new requests and modified requests that need re-approval if (notification.data?.type === 'time_off_request' || notification.data?.type === 'time_off_request_modified') { - navigate('/time-blocks'); + navigate('/dashboard/time-blocks'); setIsOpen(false); return; } @@ -224,7 +224,7 @@ const NotificationDropdown: React.FC = ({ variant = ' diff --git a/frontend/src/components/QuotaWarningBanner.tsx b/frontend/src/components/QuotaWarningBanner.tsx index 3f462de..c7f078c 100644 --- a/frontend/src/components/QuotaWarningBanner.tsx +++ b/frontend/src/components/QuotaWarningBanner.tsx @@ -78,7 +78,7 @@ const QuotaWarningBanner: React.FC = ({ overages, onDis
= ({ business, user, isCollapsed, toggleCo {/* Core Features - Always visible */} = ({ business, user, isCollapsed, toggleCo /> {!isStaff && ( } /> )} {!isStaff && ( = ({ business, user, isCollapsed, toggleCo )} {isStaff && ( = ({ business, user, isCollapsed, toggleCo )} {(role === 'staff' || role === 'resource') && ( = ({ business, user, isCollapsed, toggleCo {canViewManagementPages && ( } /> } /> = ({ business, user, isCollapsed, toggleCo {canViewAdminPages && ( <> = ({ business, user, isCollapsed, toggleCo /> {canUse('contracts') && ( = ({ business, user, isCollapsed, toggleCo /> )} = ({ business, user, isCollapsed, toggleCo {canSendMessages && ( = ({ business, user, isCollapsed, toggleCo )} {canViewTickets && ( = ({ business, user, isCollapsed, toggleCo {canViewAdminPages && ( = ({ business, user, isCollapsed, toggleCo {canViewAdminPages && ( = ({ business, user, isCollapsed, toggleCo {canViewSettings && ( )} = ({ business }) => { const trialEndDate = business.trialEnd ? new Date(business.trialEnd).toLocaleDateString() : ''; const handleUpgrade = () => { - navigate('/upgrade'); + navigate('/dashboard/upgrade'); }; const handleDismiss = () => { diff --git a/frontend/src/components/UpgradePrompt.tsx b/frontend/src/components/UpgradePrompt.tsx index 014cd56..145d207 100644 --- a/frontend/src/components/UpgradePrompt.tsx +++ b/frontend/src/components/UpgradePrompt.tsx @@ -51,7 +51,7 @@ const BannerPrompt: React.FC<{ feature: FeatureKey; showDescription: boolean }>

)} @@ -97,7 +97,7 @@ const OverlayPrompt: React.FC<{ {FEATURE_DESCRIPTIONS[feature]}

diff --git a/frontend/src/components/dashboard/OpenTicketsWidget.tsx b/frontend/src/components/dashboard/OpenTicketsWidget.tsx index fb7b421..788f43f 100644 --- a/frontend/src/components/dashboard/OpenTicketsWidget.tsx +++ b/frontend/src/components/dashboard/OpenTicketsWidget.tsx @@ -83,7 +83,7 @@ const OpenTicketsWidget: React.FC = ({ openTickets.slice(0, 5).map((ticket) => (
@@ -110,7 +110,7 @@ const OpenTicketsWidget: React.FC = ({ {openTickets.length > 5 && ( View all {openTickets.length} tickets diff --git a/frontend/src/layouts/BusinessLayout.tsx b/frontend/src/layouts/BusinessLayout.tsx index ff926b1..d423966 100644 --- a/frontend/src/layouts/BusinessLayout.tsx +++ b/frontend/src/layouts/BusinessLayout.tsx @@ -83,13 +83,13 @@ const BusinessLayoutContent: React.FC = ({ business, user, // Check for trial expiration and redirect useEffect(() => { // Don't check if already on trial-expired page - if (location.pathname === '/trial-expired') { + if (location.pathname === '/dashboard/trial-expired') { return; } // Redirect to trial-expired page if trial has expired if (business.isTrialExpired && business.status === 'Trial') { - navigate('/trial-expired', { replace: true }); + navigate('/dashboard/trial-expired', { replace: true }); } }, [business.isTrialExpired, business.status, location.pathname, navigate]); diff --git a/frontend/src/layouts/SettingsLayout.tsx b/frontend/src/layouts/SettingsLayout.tsx index da7b70f..2324c62 100644 --- a/frontend/src/layouts/SettingsLayout.tsx +++ b/frontend/src/layouts/SettingsLayout.tsx @@ -39,11 +39,11 @@ interface ParentContext { // Map settings pages to their required plan features const SETTINGS_PAGE_FEATURES: Record = { - '/settings/branding': 'white_label', - '/settings/custom-domains': 'custom_domain', - '/settings/api': 'api_access', - '/settings/authentication': 'custom_oauth', - '/settings/sms-calling': 'sms_reminders', + '/dashboard/settings/branding': 'white_label', + '/dashboard/settings/custom-domains': 'custom_domain', + '/dashboard/settings/api': 'api_access', + '/dashboard/settings/authentication': 'custom_oauth', + '/dashboard/settings/sms-calling': 'sms_reminders', }; const SettingsLayout: React.FC = () => { @@ -72,7 +72,7 @@ const SettingsLayout: React.FC = () => { {/* Back Button */}
@@ -185,7 +185,7 @@ const HelpGuide: React.FC = () => { Can't find what you're looking for? Our support team is ready to help.

Contact Support diff --git a/frontend/src/pages/HelpTicketing.tsx b/frontend/src/pages/HelpTicketing.tsx index 683168b..807b2b4 100644 --- a/frontend/src/pages/HelpTicketing.tsx +++ b/frontend/src/pages/HelpTicketing.tsx @@ -409,7 +409,7 @@ const HelpTicketing: React.FC = () => { )}

) : ( diff --git a/frontend/src/pages/PluginMarketplace.tsx b/frontend/src/pages/PluginMarketplace.tsx index 28418f2..695f716 100644 --- a/frontend/src/pages/PluginMarketplace.tsx +++ b/frontend/src/pages/PluginMarketplace.tsx @@ -605,7 +605,7 @@ const PluginMarketplace: React.FC = () => { setShowDetailsModal(false); setSelectedPlugin(null); setShowCode(false); - navigate('/plugins/my-plugins'); + navigate('/dashboard/plugins/my-plugins'); }} className="flex items-center gap-2 px-4 py-2 bg-green-600 text-white rounded-lg hover:bg-green-700 transition-colors font-medium" > @@ -664,7 +664,7 @@ const PluginMarketplace: React.FC = () => { onClick={() => { setShowWhatsNextModal(false); setSelectedPlugin(null); - navigate('/tasks'); + navigate('/dashboard/tasks'); }} className="w-full flex items-center gap-4 p-4 border border-gray-200 dark:border-gray-700 rounded-lg hover:border-blue-500 dark:hover:border-blue-500 hover:bg-blue-50 dark:hover:bg-blue-900/20 transition-colors text-left group" > @@ -687,7 +687,7 @@ const PluginMarketplace: React.FC = () => { onClick={() => { setShowWhatsNextModal(false); setSelectedPlugin(null); - navigate('/plugins/my-plugins'); + navigate('/dashboard/plugins/my-plugins'); }} className="w-full flex items-center gap-4 p-4 border border-gray-200 dark:border-gray-700 rounded-lg hover:border-purple-500 dark:hover:border-purple-500 hover:bg-purple-50 dark:hover:bg-purple-900/20 transition-colors text-left group" > diff --git a/frontend/src/pages/TrialExpired.tsx b/frontend/src/pages/TrialExpired.tsx index ba0312d..18279bf 100644 --- a/frontend/src/pages/TrialExpired.tsx +++ b/frontend/src/pages/TrialExpired.tsx @@ -67,7 +67,7 @@ const TrialExpired: React.FC = () => { const paidTierFeatures = getTierFeatures(business.plan); const handleUpgrade = () => { - navigate('/payments'); + navigate('/dashboard/payments'); }; const handleDowngrade = () => { diff --git a/frontend/src/pages/Upgrade.tsx b/frontend/src/pages/Upgrade.tsx index 399aa74..3b36e53 100644 --- a/frontend/src/pages/Upgrade.tsx +++ b/frontend/src/pages/Upgrade.tsx @@ -114,7 +114,7 @@ const Upgrade: React.FC = () => { alert(`Upgrading to ${selectedPlan} (${billingPeriod})\nThis would redirect to Stripe Checkout.`); // After successful payment, redirect to dashboard - navigate('/'); + navigate('/dashboard'); } catch (err) { setError(t('upgrade.errors.processingFailed')); console.error('Upgrade error:', err); diff --git a/frontend/src/pages/help/HelpComprehensive.tsx b/frontend/src/pages/help/HelpComprehensive.tsx index 66c826b..1495fb5 100644 --- a/frontend/src/pages/help/HelpComprehensive.tsx +++ b/frontend/src/pages/help/HelpComprehensive.tsx @@ -104,7 +104,7 @@ const HelpComprehensive: React.FC = () => {

{t('helpComprehensive.header.title')}

- + {t('helpComprehensive.header.contactSupport')} @@ -194,7 +194,7 @@ const HelpComprehensive: React.FC = () => {
  • 1
    - + {t('helpComprehensive.gettingStarted.step1Title')} @@ -204,7 +204,7 @@ const HelpComprehensive: React.FC = () => {
  • 2
    - + {t('helpComprehensive.gettingStarted.step2Title')} @@ -214,7 +214,7 @@ const HelpComprehensive: React.FC = () => {
  • 3
    - + {t('helpComprehensive.gettingStarted.step3Title')} @@ -224,7 +224,7 @@ const HelpComprehensive: React.FC = () => {
  • 4
    - + {t('helpComprehensive.gettingStarted.step4Title')} @@ -234,7 +234,7 @@ const HelpComprehensive: React.FC = () => {
  • 5
    - + {t('helpComprehensive.gettingStarted.step5Title')} @@ -705,7 +705,7 @@ const HelpComprehensive: React.FC = () => {
    - +

    {t('helpComprehensive.timeBlocks.timeBlocksDocumentation')}

    @@ -783,7 +783,7 @@ const HelpComprehensive: React.FC = () => {

    {t('helpComprehensive.plugins.learnMore')}

    - +

    {t('helpComprehensive.plugins.pluginDocumentation')}

    @@ -921,7 +921,7 @@ const HelpComprehensive: React.FC = () => {
    - +

    {t('helpComprehensive.contracts.contractsDocumentation')}

    @@ -1003,27 +1003,27 @@ const HelpComprehensive: React.FC = () => {

    {t('helpComprehensive.settings.otherSettings')}

    - +

    {t('helpComprehensive.settings.resourceTypesLink')}

    {t('helpComprehensive.settings.resourceTypesLinkDesc')}

    - +

    {t('helpComprehensive.settings.emailTemplatesLink')}

    {t('helpComprehensive.settings.emailTemplatesLinkDesc')}

    - +

    {t('helpComprehensive.settings.customDomainsLink')}

    {t('helpComprehensive.settings.customDomainsLinkDesc')}

    - +

    {t('helpComprehensive.settings.billingLink')}

    {t('helpComprehensive.settings.billingLinkDesc')}

    - +

    {t('helpComprehensive.settings.apiSettingsLink')}

    {t('helpComprehensive.settings.apiSettingsLinkDesc')}

    - +

    {t('helpComprehensive.settings.usageQuotaLink')}

    {t('helpComprehensive.settings.usageQuotaLinkDesc')}

    @@ -1041,7 +1041,7 @@ const HelpComprehensive: React.FC = () => { {t('helpComprehensive.footer.description')}

    +
    ); diff --git a/frontend/src/pages/help/HelpCustomers.tsx b/frontend/src/pages/help/HelpCustomers.tsx index e788c36..a319409 100644 --- a/frontend/src/pages/help/HelpCustomers.tsx +++ b/frontend/src/pages/help/HelpCustomers.tsx @@ -425,7 +425,7 @@ const HelpCustomers: React.FC = () => {

    Related Features

    @@ -433,7 +433,7 @@ const HelpCustomers: React.FC = () => { @@ -441,7 +441,7 @@ const HelpCustomers: React.FC = () => { @@ -449,7 +449,7 @@ const HelpCustomers: React.FC = () => { @@ -467,7 +467,7 @@ const HelpCustomers: React.FC = () => { Our support team is ready to help with any questions about managing customers.

    +
    ); diff --git a/frontend/src/pages/help/HelpPayments.tsx b/frontend/src/pages/help/HelpPayments.tsx index 09cae98..dd06a23 100644 --- a/frontend/src/pages/help/HelpPayments.tsx +++ b/frontend/src/pages/help/HelpPayments.tsx @@ -141,12 +141,12 @@ const HelpPayments: React.FC = () => {

    Related Features

    - + Scheduler Guide - + Billing Settings @@ -158,7 +158,7 @@ const HelpPayments: React.FC = () => {

    Need More Help?

    Our support team is ready to help with any questions.

    - +
    ); diff --git a/frontend/src/pages/help/HelpPlugins.tsx b/frontend/src/pages/help/HelpPlugins.tsx index 681331b..4e13122 100644 --- a/frontend/src/pages/help/HelpPlugins.tsx +++ b/frontend/src/pages/help/HelpPlugins.tsx @@ -238,7 +238,7 @@ const HelpPlugins: React.FC = () => { the scripting language, available API methods, and example code.

    View Developer Docs @@ -259,7 +259,7 @@ const HelpPlugins: React.FC = () => { Our support team is ready to help with any questions about plugins.

    {t('quota.page.upgradeInstead', 'Upgrade Plan Instead')}