7.7 KiB
title, tags, created
| title | tags | created | |||
|---|---|---|---|---|---|
| Layouts |
|
2026-05-23 |
Layouts
Page-template wrappers in frontend/src/layouts/. Each layout encapsulates a header, optional sidebar, content slot, and footer — pages mount inside one and never re-implement chrome.
1. Layout variants
| Layout | Used for | Header | Sidebar | Footer |
|---|---|---|---|---|
auth-centered/ |
Sign-in, sign-up, verify, reset-password | Logo only | none | Compact links |
auth-split/ |
Marketing-leaning auth (sign-up with promo panel) | Logo only | Left visual panel | none |
dashboard/ |
Every /dashboard/* route |
Topbar with user menu + notifications + language + settings | Vertical / Mini / Horizontal | none |
main/ |
Public marketing pages (shop/, post/, landing) |
Marketing nav | none | Full footer |
2. Dashboard layout
layouts/dashboard/ is the workhorse. It uses MUI's LayoutSection pattern — slots for header, sidebar, main, footer with media-query-aware responsive behavior.
2.1 Anatomy
┌─────────────────────────────────────────────────────┐
│ TopBar ───────────────────────── search bell ▾ │ ← `header-section`
├─────────┬───────────────────────────────────────────┤
│ Nav │ Breadcrumbs │
│ │ ┌─ Page content (mounted route) ──────┐ │
│ ┌───┐ │ │ │ │
│ │ ○ │ │ │ │ │
│ └───┘ │ │ │ │
│ user │ │ │ │
│ profile│ │ │ │
├─────────┴───────────────────────────────────────────┤
│ (optional) Footer slot — unused in dashboard │
└─────────────────────────────────────────────────────┘
2.2 Sidebar variants
User can switch via the Settings Drawer:
| Variant | Width | Behavior |
|---|---|---|
vertical |
280 px | Default; icon + label, collapsible groups |
mini |
88 px | Icons only; labels in tooltip on hover |
horizontal |
full-width below header | Nav as a horizontal menu — main content below |
2.3 Topbar
Contains, left-to-right:
- Sidebar toggle button (mobile / mini-mode)
- Logo (mini, shown only when sidebar is collapsed)
- Search (Cmd+K palette) — optional
- Language selector (chip with flag)
- Settings drawer toggle (cog icon)
- Notifications drawer toggle (bell with unread count badge)
- Account dropdown (avatar → profile, sign-out)
2.4 Nav configuration
Nav items defined as a tree in a config file (e.g., layouts/dashboard/config-nav-dashboard.ts):
const navData = [
{
subheader: 'Overview',
items: [
{ title: 'Dashboard', path: paths.dashboard.root, icon: ICONS.dashboard },
{ title: 'Chat', path: paths.dashboard.chat, icon: ICONS.chat },
],
},
{
subheader: 'Marketplace',
items: [
{ title: 'Requests', path: paths.dashboard.request.root, icon: ICONS.request,
roles: ['buyer', 'admin'] },
{ title: 'Templates', path: paths.dashboard.template.root, icon: ICONS.template,
roles: ['seller', 'admin'] },
// ...
],
},
// ...
];
Each items[i] may carry roles: string[] to scope visibility. The nav renderer filters items based on the current user's role before rendering — entries without roles are shown to everyone.
2.5 Breadcrumbs
components/custom-breadcrumbs renders the active route trail plus an optional action button slot (e.g., "+ New Request"). Convention: set via the page component.
3. Auth layouts
3.1 auth-centered/
Single column, centered card. Used by sign-in, password reset, email verification.
┌──────────────────────────────┐
│ Logo │
│ │
│ ┌────────────────────┐ │
│ │ Title │ │
│ │ Form fields... │ │
│ │ CTA │ │
│ └────────────────────┘ │
│ │
│ Tiny footer links │
└──────────────────────────────┘
3.2 auth-split/
Two-column on md+, single column on small screens. Left = visual / brand panel; right = form.
┌──────────────┬───────────────┐
│ │ Logo │
│ Visual │ │
│ panel │ Form │
│ (image, │ │
│ quote, │ CTA │
│ benefit) │ │
│ │ Footer │
└──────────────┴───────────────┘
Used for sign-up to balance marketing copy with the form.
4. Main (public) layout
layouts/main/ is for unauthenticated visitor pages. Sticky header, then content, then full footer.
Header includes:
- Logo
- Top-level nav (Shop, Blog, About)
- Language switcher
- "Sign in" / "Sign up" buttons (or "Dashboard" if signed in)
Footer includes:
- Brand block
- Sitemap
- Legal links
- Social media
- Newsletter signup (optional)
5. Responsive behavior
| Breakpoint | xs (<600) | sm (≥600) | md (≥900) | lg (≥1200) | xl (≥1536) |
|---|---|---|---|---|---|
| Dashboard sidebar | drawer overlay | drawer overlay | mini default | full default | full default |
| Auth-split | single col | single col | two col | two col | two col |
| Main nav | hamburger | hamburger | inline | inline | inline |
| Page padding | 16 px | 16 px | 24 px | 32 px | 32 px |
Implementation note: do NOT add @media rules in components. Use the responsive sx syntax:
<Box sx={{ p: { xs: 2, md: 3, lg: 4 } }} />
6. Sticky elements
- TopBar uses
position: sticky; top: 0; z-index: appBarso it stays on scroll. - Action bars on long forms can use the same pattern at bottom (
bottom: 0).
7. Skeleton & loading
- Each
dashboard/*/page.tsxcan ship a siblingloading.tsxthat renders skeleton placeholders matching the final layout. - For long-loading sections, use
<Suspense fallback={<SkeletonX />}>.
8. Error boundaries
- App-level error boundary at root layout catches uncaught render errors.
- Each route segment may ship
error.tsxfor scoped recovery (e.g.,dashboard/shops/error.tsx). - Snackbars handle non-fatal API errors.
9. Adding a new layout
- Create
layouts/<name>/withindex.tsx(default export the layout component). - Slot pattern: accept
children; render header + nav + main + (optional) footer. - Reuse
components/scrollbarfor the main scroll area to keep custom scrollbar styling. - If it's an auth flow, wire it into
app/auth/<flow>/layout.tsx.
10. Related
- Design System Overview · Theme Configuration · Components
- Frontend Architecture — where layouts sit in the tree
- Roles & Personas — role-driven nav filtering
- Settings & Theming — layout variant switcher