Restructure navigation: move setup items to Settings with accordion menu
Move rarely-used setup items from main sidebar to Settings to keep daily-use features prominent: - Services → Settings > Business section - Locations → Settings > Business section - Site Builder → Settings > Branding section Settings sidebar changes: - Convert static sections to accordion (one open at a time) - Auto-expand section based on current URL - Preserve all permission checks for moved items Add redirects from old URLs to new locations for backwards compatibility. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -10,15 +10,12 @@ import {
|
||||
MessageSquare,
|
||||
LogOut,
|
||||
ClipboardList,
|
||||
Briefcase,
|
||||
Ticket,
|
||||
HelpCircle,
|
||||
Clock,
|
||||
Plug,
|
||||
FileSignature,
|
||||
CalendarOff,
|
||||
LayoutTemplate,
|
||||
MapPin,
|
||||
Image,
|
||||
} from 'lucide-react';
|
||||
import { Business, User } from '../types';
|
||||
@@ -159,25 +156,14 @@ const Sidebar: React.FC<SidebarProps> = ({ business, user, isCollapsed, toggleCo
|
||||
|
||||
{/* Manage Section - Show if user has any manage-related permission */}
|
||||
{(canViewManagementPages ||
|
||||
hasPermission('can_access_site_builder') ||
|
||||
hasPermission('can_access_gallery') ||
|
||||
hasPermission('can_access_customers') ||
|
||||
hasPermission('can_access_services') ||
|
||||
hasPermission('can_access_resources') ||
|
||||
hasPermission('can_access_staff') ||
|
||||
hasPermission('can_access_contracts') ||
|
||||
hasPermission('can_access_time_blocks') ||
|
||||
hasPermission('can_access_locations')
|
||||
hasPermission('can_access_time_blocks')
|
||||
) && (
|
||||
<SidebarSection title={t('nav.sections.manage', 'Manage')} isCollapsed={isCollapsed}>
|
||||
{hasPermission('can_access_site_builder') && (
|
||||
<SidebarItem
|
||||
to="/dashboard/site-editor"
|
||||
icon={LayoutTemplate}
|
||||
label={t('nav.siteBuilder', 'Site Builder')}
|
||||
isCollapsed={isCollapsed}
|
||||
/>
|
||||
)}
|
||||
{hasPermission('can_access_gallery') && (
|
||||
<SidebarItem
|
||||
to="/dashboard/gallery"
|
||||
@@ -194,14 +180,6 @@ const Sidebar: React.FC<SidebarProps> = ({ business, user, isCollapsed, toggleCo
|
||||
isCollapsed={isCollapsed}
|
||||
/>
|
||||
)}
|
||||
{hasPermission('can_access_services') && (
|
||||
<SidebarItem
|
||||
to="/dashboard/services"
|
||||
icon={Briefcase}
|
||||
label={t('nav.services', 'Services')}
|
||||
isCollapsed={isCollapsed}
|
||||
/>
|
||||
)}
|
||||
{hasPermission('can_access_resources') && (
|
||||
<SidebarItem
|
||||
to="/dashboard/resources"
|
||||
@@ -235,15 +213,6 @@ const Sidebar: React.FC<SidebarProps> = ({ business, user, isCollapsed, toggleCo
|
||||
isCollapsed={isCollapsed}
|
||||
/>
|
||||
)}
|
||||
{hasPermission('can_access_locations') && (
|
||||
<SidebarItem
|
||||
to="/dashboard/locations"
|
||||
icon={MapPin}
|
||||
label={t('nav.locations', 'Locations')}
|
||||
isCollapsed={isCollapsed}
|
||||
locked={!canUse('multi_location')}
|
||||
/>
|
||||
)}
|
||||
</SidebarSection>
|
||||
)}
|
||||
|
||||
|
||||
@@ -256,6 +256,55 @@ export const SettingsSidebarSection: React.FC<SettingsSidebarSectionProps> = ({
|
||||
);
|
||||
};
|
||||
|
||||
interface SettingsAccordionSectionProps {
|
||||
title: string;
|
||||
sectionKey: string;
|
||||
isOpen: boolean;
|
||||
onToggle: (sectionKey: string) => void;
|
||||
children: React.ReactNode;
|
||||
hasVisibleItems?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Collapsible accordion section for settings sidebar
|
||||
* Only one section can be open at a time (controlled by parent)
|
||||
*/
|
||||
export const SettingsAccordionSection: React.FC<SettingsAccordionSectionProps> = ({
|
||||
title,
|
||||
sectionKey,
|
||||
isOpen,
|
||||
onToggle,
|
||||
children,
|
||||
hasVisibleItems = true,
|
||||
}) => {
|
||||
// Don't render if no visible items
|
||||
if (!hasVisibleItems) return null;
|
||||
|
||||
return (
|
||||
<div className="space-y-0.5">
|
||||
<button
|
||||
onClick={() => onToggle(sectionKey)}
|
||||
className="flex items-center justify-between w-full px-4 py-2 text-xs font-semibold uppercase tracking-wider text-gray-500 dark:text-gray-400 hover:bg-gray-50 dark:hover:bg-gray-800 rounded-lg transition-colors"
|
||||
>
|
||||
<span>{title}</span>
|
||||
<ChevronDown
|
||||
size={14}
|
||||
className={`transition-transform duration-200 ${isOpen ? 'rotate-180' : ''}`}
|
||||
/>
|
||||
</button>
|
||||
<div
|
||||
className={`overflow-hidden transition-all duration-200 ease-in-out ${
|
||||
isOpen ? 'max-h-[500px] opacity-100' : 'max-h-0 opacity-0'
|
||||
}`}
|
||||
>
|
||||
<div className="space-y-0.5 pt-1">
|
||||
{children}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
interface SettingsSidebarItemProps {
|
||||
to: string;
|
||||
icon: LucideIcon;
|
||||
|
||||
Reference in New Issue
Block a user