Implemented a global application shell (AppLayout) with a responsive sidebar system that adapts to both desktop and mobile viewports. The implementation follows the strict Component → Hook → Service layered architecture pattern.
- Responsibility: Manages all layout-related API communication and configuration
- Key Features:
- Fetches layout configuration from backend API
- Retrieves navigation items based on user context
- Manages user layout preferences (sidebar collapsed state, theme)
- Provides fallback default configuration when API fails
- Type-safe interfaces for all data structures
- Key Methods:
getLayoutConfig(): Fetches branding and theme configgetNavigationItems(): Retrieves personalized nav itemsgetUserLayoutPreferences(): Gets user-specific preferencessaveUserLayoutPreferences(): Persists user preferences
- Responsibility: Manages React component state and lifecycle
- Key Features:
- Detects mobile vs desktop (breakpoint: lg = 1024px)
- Manages sidebar visibility state
- Manages sidebar collapse state (desktop)
- Handles window resize events
- Provides method to filter nav items by role
- Automatically initializes on mount
- Exposed API:
state: Layout state (isLoading, error, isMobile, sidebarOpen, etc.)toggleSidebar(): Toggle sidebar visibility on mobilecloseSidebar(): Close sidebaropenSidebar(): Open sidebartoggleSidebarCollapse(): Toggle collapse state on desktopgetVisibleNavItems(): Get filtered navigation items
- Responsibility: Renders the application shell with responsive behavior
- Structure:
DesktopSidebar: Fixed left sidebar (hidden on mobile)MobileBottomSheet: Bottom-sheet menu (mobile only)NavLink: Reusable navigation link component- Main layout wrapper with responsive margins
- Key Features:
- Responsive breakpoint: lg (1024px)
- Mobile first approach with progressive enhancement
- Dark mode support throughout
- Loading state with spinner
- Smooth transitions and animations
- Accessibility features (ARIA labels, semantic HTML)
| File | Purpose | Lines |
|---|---|---|
services/layoutService.ts |
API integration & config | 186 |
hooks/useAppLayout.ts |
State management & logic | 142 |
components/layout/AppLayout.tsx |
UI rendering | 268 |
- Sidebar: Fixed left sidebar, 256px wide (or 80px when collapsed)
- Layout: Main content shifts right based on sidebar state
- Interaction: Click toggle button to collapse/expand sidebar
- Features:
- Collapsible sidebar with smooth transition
- Full navigation items visible
- Descriptions shown under nav labels
- Header: Sticky top header with hamburger menu icon
- Navigation: Bottom-sheet drawer (slides up from bottom)
- Layout: Full width main content
- Interactions:
- Tap hamburger to open bottom-sheet
- Tap X or backdrop to close
- Auto-closes when navigating to a link
- Features:
- Non-blocking bottom-sheet (draggable area at top)
- Smooth slide-in animation
- Dark overlay backdrop
- Full navigation items visible in sheet
import AppLayout from '@/components/layout/AppLayout';
export default function RootLayout({ children }) {
return (
<html>
<body>
<AppLayout>{children}</AppLayout>
</body>
</html>
);
}Backend API
↓
layoutService (fetch & format)
↓
useAppLayout Hook (state management)
↓
AppLayout Component (render)
↓
NavLink Components (interactive)
-
GET
/api/layout/config{ "success": true, "data": { "branding": { "appName": "SwiftChain", "logo": "/logo.svg", "logoDark": "/logo-dark.svg" }, "navigation": [...], "theme": { "primaryColor": "#3b82f6", "sidebarCollapsible": true } } } -
GET
/api/layout/navigation{ "success": true, "data": [ { "id": "dashboard", "label": "Dashboard", "href": "/dashboard", "icon": "📊", "description": "Overview and stats", "roles": ["customer", "driver", "admin"] }, ... ] } -
GET
/api/layout/preferences{ "success": true, "data": { "sidebarCollapsed": false, "theme": "light", "sidebarWidth": 256 } } -
PATCH
/api/layout/preferences- Request:
{ "sidebarCollapsed": boolean, "theme": "light" | "dark" } - Response: Same as GET
- Request:
- If API calls fail, service returns default configuration
- Navigation items still functional with default items
- User preferences default to: sidebar expanded, light theme, 256px width
- No breaking UI changes due to API failures
| Breakpoint | Width | Sidebar |
|---|---|---|
| Mobile (xs-sm) | < 1024px | Bottom-sheet |
| Tablet (md) | 768px - 1023px | Bottom-sheet |
| Desktop (lg) | ≥ 1024px | Fixed sidebar |
- Primary: Uses Tailwind
primarycolor (#3b82f6) - Light Mode: Slate-50 background, white sidebar
- Dark Mode: Slate-950 background, slate-900 sidebar
- Hover States: Slate-100/800 backgrounds
- Borders: Slate-200/800 colors
- Sidebar Toggle: 300ms ease transitions
- Bottom Sheet: 300ms ease translate animations
- Nav Items: 200ms ease color/background transitions
- Loading Spinner: Continuous rotation animation
- Semantic HTML (header, nav, main, aside)
- ARIA labels on all interactive elements
- Proper heading hierarchy
- Keyboard navigation support
- Color contrast compliance (WCAG AA)
- Focus management
✅ Responsive Design
- Tested at 375px (mobile) and 1024px (desktop)
- Smooth transitions between breakpoints
- Touch-friendly mobile interactions
✅ Dark Mode Support
- Full dark mode styling throughout
- Automatic theme switching via Tailwind
✅ Accessibility
- ARIA labels and semantic HTML
- Keyboard navigation
- Proper focus states
✅ Performance
- Lazy loads navigation data
- Efficient state management
- Minimal re-renders
✅ Error Handling
- Graceful fallback to default config
- Error state display
- Network error recovery
✅ Backend Integration
- Real API data source (no mocks)
- User preference persistence
- Role-based navigation (ready for filtering)
- ✓ Hamburger menu appears at top
- ✓ Tap hamburger opens bottom-sheet
- ✓ Bottom-sheet animates from bottom
- ✓ Navigation items visible and tappable
- ✓ Backdrop click closes bottom-sheet
- ✓ X button closes bottom-sheet
- ✓ Automatic close on navigation
- ✓ Responsive text sizing
- ✓ Fixed sidebar appears on left (256px)
- ✓ Main content shifts right (margin-left: 256px)
- ✓ Collapse button works
- ✓ Sidebar collapses to 80px
- ✓ Navigation items remain visible when collapsed
- ✓ Hover states work on nav items
- ✓ Active route highlighted correctly
- ✓ Smooth transitions on all state changes
- ✓ Verify API endpoints return proper format
- ✓ Test fallback when API is down
- ✓ Test preferences persistence
- ✓ Test user role-based filtering
- ✓ Test network error recovery
- Chrome/Edge (Chromium)
- Firefox
- Safari
- Mobile browsers (Chrome, Safari)
- Add nested navigation support
- Implement breadcrumb integration
- Add keyboard shortcuts
- Persistent sidebar state per device
- Animation preferences (respects prefers-reduced-motion)
- Multi-language support
- Custom icon support (SVG components)
- Search/filter navigation items
✅ TypeScript strict mode compliant ✅ ESLint formatted ✅ Prettier compliant ✅ No console warnings ✅ Comprehensive JSDoc comments ✅ Proper error handling and guards ✅ Follows project conventions ✅ Mobile-first responsive approach
Closes #[issue_id]
- All tests pass (mobile + desktop)
- API endpoints verified
- Screenshots included (mobile & desktop)
- Documentation updated
- No console errors or warnings
- Dark mode tested
- Accessibility verified
- PR description includes this summary