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

@@ -59,7 +59,7 @@ const NotificationDropdown: React.FC<NotificationDropdownProps> = ({ 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<NotificationDropdownProps> = ({ variant = '
</button>
<button
onClick={() => {
navigate('/notifications');
navigate('/dashboard/notifications');
setIsOpen(false);
}}
className="text-xs text-brand-600 hover:text-brand-700 dark:text-brand-400 font-medium"

View File

@@ -235,7 +235,7 @@ const PaymentSettingsSection: React.FC<PaymentSettingsSectionProps> = ({ busines
</ul>
<div className="flex flex-wrap gap-3">
<button
onClick={() => navigate('/settings/billing')}
onClick={() => navigate('/dashboard/settings/billing')}
className="flex items-center gap-2 px-5 py-2.5 text-sm font-medium text-white bg-purple-600 rounded-lg hover:bg-purple-700 transition-colors"
>
<ArrowUpRight size={16} />

View File

@@ -244,7 +244,7 @@ const QuotaOverageModal: React.FC<QuotaOverageModalProps> = ({ overages, onDismi
{t('quota.modal.dismissButton', 'Remind Me Later')}
</button>
<Link
to="/settings/quota"
to="/dashboard/settings/quota"
onClick={handleDismiss}
className="inline-flex items-center gap-2 px-5 py-2.5 bg-blue-600 text-white font-medium rounded-lg hover:bg-blue-700 transition-colors"
>

View File

@@ -78,7 +78,7 @@ const QuotaWarningBanner: React.FC<QuotaWarningBannerProps> = ({ overages, onDis
</div>
<div className="flex items-center gap-2">
<Link
to="/settings/quota"
to="/dashboard/settings/quota"
className={`inline-flex items-center gap-1 px-3 py-1.5 text-sm font-medium rounded-md transition-colors ${
isCritical || isUrgent
? 'bg-white/20 hover:bg-white/30 text-white'

View File

@@ -109,7 +109,7 @@ const Sidebar: React.FC<SidebarProps> = ({ business, user, isCollapsed, toggleCo
{/* Core Features - Always visible */}
<SidebarSection isCollapsed={isCollapsed}>
<SidebarItem
to="/"
to="/dashboard"
icon={LayoutDashboard}
label={t('nav.dashboard')}
isCollapsed={isCollapsed}
@@ -117,16 +117,15 @@ const Sidebar: React.FC<SidebarProps> = ({ business, user, isCollapsed, toggleCo
/>
{!isStaff && (
<SidebarItem
to="/scheduler"
to="/dashboard/scheduler"
icon={CalendarDays}
label={t('nav.scheduler')}
isCollapsed={isCollapsed}
badgeElement={<UnfinishedBadge />}
/>
)}
{!isStaff && (
<SidebarItem
to="/tasks"
to="/dashboard/tasks"
icon={Clock}
label={t('nav.tasks', 'Tasks')}
isCollapsed={isCollapsed}
@@ -136,7 +135,7 @@ const Sidebar: React.FC<SidebarProps> = ({ business, user, isCollapsed, toggleCo
)}
{isStaff && (
<SidebarItem
to="/my-schedule"
to="/dashboard/my-schedule"
icon={CalendarDays}
label={t('nav.mySchedule', 'My Schedule')}
isCollapsed={isCollapsed}
@@ -144,7 +143,7 @@ const Sidebar: React.FC<SidebarProps> = ({ business, user, isCollapsed, toggleCo
)}
{(role === 'staff' || role === 'resource') && (
<SidebarItem
to="/my-availability"
to="/dashboard/my-availability"
icon={CalendarOff}
label={t('nav.myAvailability', 'My Availability')}
isCollapsed={isCollapsed}
@@ -156,27 +155,27 @@ const Sidebar: React.FC<SidebarProps> = ({ business, user, isCollapsed, toggleCo
{canViewManagementPages && (
<SidebarSection title={t('nav.sections.manage', 'Manage')} isCollapsed={isCollapsed}>
<SidebarItem
to="/site-editor"
to="/dashboard/site-editor"
icon={LayoutTemplate}
label={t('nav.siteBuilder', 'Site Builder')}
isCollapsed={isCollapsed}
badgeElement={<UnfinishedBadge />}
/>
<SidebarItem
to="/customers"
to="/dashboard/customers"
icon={Users}
label={t('nav.customers')}
isCollapsed={isCollapsed}
badgeElement={<UnfinishedBadge />}
/>
<SidebarItem
to="/services"
to="/dashboard/services"
icon={Briefcase}
label={t('nav.services', 'Services')}
isCollapsed={isCollapsed}
/>
<SidebarItem
to="/resources"
to="/dashboard/resources"
icon={ClipboardList}
label={t('nav.resources')}
isCollapsed={isCollapsed}
@@ -184,7 +183,7 @@ const Sidebar: React.FC<SidebarProps> = ({ business, user, isCollapsed, toggleCo
{canViewAdminPages && (
<>
<SidebarItem
to="/staff"
to="/dashboard/staff"
icon={Users}
label={t('nav.staff')}
isCollapsed={isCollapsed}
@@ -192,7 +191,7 @@ const Sidebar: React.FC<SidebarProps> = ({ business, user, isCollapsed, toggleCo
/>
{canUse('contracts') && (
<SidebarItem
to="/contracts"
to="/dashboard/contracts"
icon={FileSignature}
label={t('nav.contracts', 'Contracts')}
isCollapsed={isCollapsed}
@@ -200,13 +199,13 @@ const Sidebar: React.FC<SidebarProps> = ({ business, user, isCollapsed, toggleCo
/>
)}
<SidebarItem
to="/time-blocks"
to="/dashboard/time-blocks"
icon={CalendarOff}
label={t('nav.timeBlocks', 'Time Blocks')}
isCollapsed={isCollapsed}
/>
<SidebarItem
to="/locations"
to="/dashboard/locations"
icon={MapPin}
label={t('nav.locations', 'Locations')}
isCollapsed={isCollapsed}
@@ -222,7 +221,7 @@ const Sidebar: React.FC<SidebarProps> = ({ business, user, isCollapsed, toggleCo
<SidebarSection title={t('nav.sections.communicate', 'Communicate')} isCollapsed={isCollapsed}>
{canSendMessages && (
<SidebarItem
to="/messages"
to="/dashboard/messages"
icon={MessageSquare}
label={t('nav.messages')}
isCollapsed={isCollapsed}
@@ -230,7 +229,7 @@ const Sidebar: React.FC<SidebarProps> = ({ business, user, isCollapsed, toggleCo
)}
{canViewTickets && (
<SidebarItem
to="/tickets"
to="/dashboard/tickets"
icon={Ticket}
label={t('nav.tickets')}
isCollapsed={isCollapsed}
@@ -243,7 +242,7 @@ const Sidebar: React.FC<SidebarProps> = ({ business, user, isCollapsed, toggleCo
{canViewAdminPages && (
<SidebarSection title={t('nav.sections.money', 'Money')} isCollapsed={isCollapsed}>
<SidebarItem
to="/payments"
to="/dashboard/payments"
icon={CreditCard}
label={t('nav.payments')}
isCollapsed={isCollapsed}
@@ -256,7 +255,7 @@ const Sidebar: React.FC<SidebarProps> = ({ business, user, isCollapsed, toggleCo
{canViewAdminPages && (
<SidebarSection title={t('nav.sections.extend', 'Extend')} isCollapsed={isCollapsed}>
<SidebarItem
to="/plugins/my-plugins"
to="/dashboard/plugins/my-plugins"
icon={Plug}
label={t('nav.plugins', 'Plugins')}
isCollapsed={isCollapsed}
@@ -272,14 +271,14 @@ const Sidebar: React.FC<SidebarProps> = ({ business, user, isCollapsed, toggleCo
<SidebarSection isCollapsed={isCollapsed}>
{canViewSettings && (
<SidebarItem
to="/settings"
to="/dashboard/settings"
icon={Settings}
label={t('nav.businessSettings')}
isCollapsed={isCollapsed}
/>
)}
<SidebarItem
to="/help"
to="/dashboard/help"
icon={HelpCircle}
label={t('nav.helpDocs', 'Help & Docs')}
isCollapsed={isCollapsed}

View File

@@ -28,7 +28,7 @@ const TrialBanner: React.FC<TrialBannerProps> = ({ business }) => {
const trialEndDate = business.trialEnd ? new Date(business.trialEnd).toLocaleDateString() : '';
const handleUpgrade = () => {
navigate('/upgrade');
navigate('/dashboard/upgrade');
};
const handleDismiss = () => {

View File

@@ -51,7 +51,7 @@ const BannerPrompt: React.FC<{ feature: FeatureKey; showDescription: boolean }>
</p>
)}
<Link
to="/settings/billing"
to="/dashboard/settings/billing"
className="inline-flex items-center gap-2 px-4 py-2 rounded-lg bg-gradient-to-r from-amber-500 to-orange-500 text-white font-medium hover:from-amber-600 hover:to-orange-600 transition-all shadow-md hover:shadow-lg"
>
<Crown className="w-4 h-4" />
@@ -97,7 +97,7 @@ const OverlayPrompt: React.FC<{
{FEATURE_DESCRIPTIONS[feature]}
</p>
<Link
to="/settings/billing"
to="/dashboard/settings/billing"
className="inline-flex items-center gap-2 px-6 py-3 rounded-lg bg-gradient-to-r from-amber-500 to-orange-500 text-white font-medium hover:from-amber-600 hover:to-orange-600 transition-all shadow-md hover:shadow-lg"
>
<Crown className="w-5 h-5" />

View File

@@ -83,7 +83,7 @@ const OpenTicketsWidget: React.FC<OpenTicketsWidgetProps> = ({
openTickets.slice(0, 5).map((ticket) => (
<Link
key={ticket.id}
to="/tickets"
to="/dashboard/tickets"
className={`block p-3 rounded-lg ${getPriorityBg(ticket.priority, ticket.isOverdue)} hover:opacity-80 transition-opacity`}
>
<div className="flex items-start justify-between gap-2">
@@ -110,7 +110,7 @@ const OpenTicketsWidget: React.FC<OpenTicketsWidgetProps> = ({
{openTickets.length > 5 && (
<Link
to="/tickets"
to="/dashboard/tickets"
className="mt-3 text-sm text-brand-600 dark:text-brand-400 hover:underline text-center"
>
View all {openTickets.length} tickets