Skip to content

[Web] Restaurant dashboard — layout, shell, sidebar navigation, and auth guard #188

Description

@zakkiyyat

Overview

Build the restaurant dashboard shell — the persistent layout, sidebar navigation, and authentication guard that wraps every page under `/dashboard`. This is the structural foundation that all other dashboard pages (menu editor, analytics, settings) will build inside.

This issue produces no business features by itself, but it must be completed before any other dashboard page can be built.


Figma Reference

📐 Figma: [Dashboard shell — sidebar, header bar, breadcrumb, mobile nav drawer, responsive breakpoints — placeholder, link to be added by design lead]


Routes

All pages under `/dashboard/*` use this layout.

Path Page
`/dashboard` Home / KPI summary (Sprint 6) — placeholder for now
`/dashboard/menu` Menu editor (issue #184)
`/dashboard/orders` Order queue (Sprint 4) — placeholder
`/dashboard/analytics` Analytics (Sprint 6) — placeholder
`/dashboard/settings` Restaurant settings (Sprint 6) — placeholder

File Structure

```
apps/web/app/dashboard/
layout.tsx # Auth guard + DashboardShell wrapper
page.tsx # Placeholder: "Dashboard coming soon"
menu/page.tsx # Issue #184
orders/page.tsx # Placeholder
analytics/page.tsx # Placeholder
settings/page.tsx # Placeholder

components/dashboard/
DashboardShell.tsx # Root layout: sidebar + content area
Sidebar.tsx # Nav links, restaurant name, logo
TopBar.tsx # Page title, user menu (logout)
NavLink.tsx # Active-state-aware link component
```


Authentication Guard

`apps/web/app/dashboard/layout.tsx` must:

  1. Check if the user is authenticated (read from `AuthContext`)
  2. If not authenticated → redirect to `/login`
  3. If authenticated but has no restaurant → redirect to `/onboarding`
  4. If authenticated and has a restaurant → render the dashboard shell

Use a Client Component for the guard logic (since it reads from context). The children can remain Server Components.


Sidebar Navigation

Links to show:

Icon Label Path
🏠 Dashboard `/dashboard`
🍽️ Menu `/dashboard/menu`
📋 Orders `/dashboard/orders`
📊 Analytics `/dashboard/analytics`
⚙️ Settings `/dashboard/settings`

Use real icons from a package (e.g. `lucide-react`) — not emoji.

Active link: highlight the current route's nav item.

Bottom of sidebar: restaurant logo thumbnail + restaurant name (fetched from context or API).


Top Bar

  • Page title (dynamic — passed via a context or layout slot)
  • User email or display name
  • Logout button (calls `useAuth().logout()` then redirects to `/login`)

Responsive Behaviour

Breakpoint Behaviour
≥ 1024 px Sidebar always visible on the left
< 1024 px Sidebar hidden; hamburger button in top bar opens a slide-in drawer

Placeholder Pages

For dashboard pages not yet built (orders, analytics, settings), render:

```tsx

Coming soon

This section will be available in a future sprint.

\`\`\`

Do not add links to routes that don't exist.


Acceptance Criteria

  • Unauthenticated users visiting any `/dashboard/*` route are redirected to `/login`
  • Authenticated users with no restaurant are redirected to `/onboarding`
  • Active sidebar link is visually highlighted based on the current route
  • Sidebar collapses to a drawer on screens narrower than 1024 px
  • Drawer opens/closes via a hamburger button; closes on nav link click or outside click
  • Logout button clears auth state and redirects to `/login`
  • Restaurant name and logo appear in the sidebar (fetched from `GET /api/restaurants/me`)
  • The layout does not cause layout shift on page transition
  • All placeholder pages render without errors

Out of Scope

  • Role-based access (all authenticated restaurant owners see the full sidebar)
  • Notifications bell (Sprint 7)
  • Dark mode (future)

Metadata

Metadata

Labels

GrantFox OSSIssue tracked in GrantFox OSSMaybe RewardedIssue may be eligible for a GrantFox rewardOfficial CampaignCampaign: Official Campaignintermediate~2–3 day effortsprint-1Sprint 1: Restaurant & Menu FoundationwebWeb dashboard (Next.js)

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions