Skip to content

FRD: Admin Shell Recipe

Document Summary

FieldDetails
Feature NameAdmin Shell Seed Recipe
StatusDraft
OwnerDavid Holmes
ContributorsEngineering, Design
Target Releasev2.0.0 (P2)
Related LinksRoadmap item #79, ADR-027 (Default Tech Stack)
Last Updated2026-05-26

Introduction

Overview

The Admin Shell recipe provides a copy-pasteable scaffold for building admin dashboards and back-office applications. It composes existing design system components — saas-sidebar-layout.tsx, screen-shell.tsx, global-search-bar.tsx — into a complete application shell with resource navigation, authentication guard, notification integration, and global search. The recipe ships as a runnable example with stories and tests that developers clone and customize for their domain.

Goals

  • Provide a complete, copy-pasteable admin shell scaffold using existing design system components.
  • Demonstrate resource navigation with sidebar sections, nested items, and active-state highlighting.
  • Show an authentication guard pattern that redirects unauthenticated users.
  • Integrate notification display (toast + notification center).
  • Include global search wired to the application shell.
  • Ship as a runnable example folder with stories and tests.

Non-Goals

  • Building new layout primitives (uses existing saas-sidebar-layout.tsx and screen-shell.tsx).
  • Implementing a real authentication backend or identity provider.
  • Building a real notification service or WebSocket integration.
  • Providing a complete CRUD scaffold (this is the shell, not the page content).
  • Role-based access control (RBAC) implementation.

Scope

In Scope

AreaDescription
App shell compositionSaasSidebarLayout + ScreenShell + header + sidebar
Resource navigationSidebar with grouped sections, icons, nested items, badges, and active state
Auth guardRoute-level component that checks auth state and redirects if unauthenticated
Notification integrationToast notifications for actions; notification center in the header
Global searchGlobalSearchBar integrated into the header
User menuAvatar dropdown with profile, settings, and logout
Responsive behaviorSidebar collapse on mobile; hamburger toggle
BreadcrumbsRoute-aware breadcrumb trail below the header
StoriesStorybook stories demonstrating shell states
TestsUnit tests for auth guard, navigation, and shell composition
Recipe MDXDocumentation page with usage guide

Out of Scope

AreaReason
New layout primitivesUses existing components
Real auth backendConsumer responsibility; recipe uses mock auth
Real notification serviceConsumer responsibility; recipe uses mock notifications
CRUD page patternsSeparate recipe; this covers the shell only
RBAC / permissionsConsumer responsibility; recipe shows auth-or-not guard
Data tables / formsSeparate components; shell provides the frame

Users and Pain Points

User Groups

UserDescriptionNeeds
Application developersEngineers building admin dashboardsA complete starting point they can copy and extend
DesignersTeam members reviewing admin UX consistencyA documented pattern for consistent admin shells
New team membersEngineers onboarding to admin projectsA working example showing how to compose layout components

Pain Points

UserPain PointImpact
Application developersBuilding an admin shell from scratch each time, composing sidebar, header, auth, and navigationWasted time; inconsistent admin UX across products
Application developersNo documented pattern for auth guards in the design system contextAuth integration is done differently in each admin app
Application developersUnclear how to integrate global search, notifications, and breadcrumbs with the layoutFeatures are added ad hoc with inconsistent placement

Definitions

TermDefinition
Admin shellThe outer application frame: sidebar, header, content area, and supporting features (search, notifications, auth)
Resource navigationSidebar menu items organized by domain (e.g., Users, Products, Settings) with nesting and active states
Auth guardA route wrapper that checks authentication state and redirects unauthenticated users to a login page
Notification centerA header element showing unread notification count with a dropdown listing recent notifications
ScaffoldA copy-pasteable starting point that developers customize for their specific application

Current State

Existing Behavior

saas-sidebar-layout.tsx provides a sidebar + content layout frame. screen-shell.tsx provides a content-area shell with header and body sections. global-search-bar.tsx provides a search input with keyboard shortcut. These exist as standalone components without a documented composition pattern for admin applications.

Current Limitations

  • No recipe showing how to compose these components into a complete admin shell.
  • No auth guard pattern documented.
  • No notification integration pattern.
  • No resource navigation example with grouped sections and active states.
  • No breadcrumb integration pattern.

Existing Workarounds

  • Developers study existing admin applications or build from scratch.
  • Each admin app composes the layout components differently.
  • Auth guards and notification integration are implemented ad hoc.

Proposed Solution

Summary

Create a recipe folder (src/recipes/admin-shell/) containing a composed admin shell, mock auth and notification services, navigation configuration, and documentation. Ship with Storybook stories demonstrating authenticated, unauthenticated, and various navigation states.

Key Capabilities

  • AdminShell component composing SaasSidebarLayout, ScreenShell, header bar, and sidebar navigation.
  • AdminNav configuration type for defining sidebar sections with icons, labels, paths, and nested items.
  • AuthGuard component that wraps routes and redirects unauthenticated users.
  • NotificationCenter header element with unread count badge and dropdown.
  • UserMenu avatar dropdown with profile, settings, and logout actions.
  • AdminBreadcrumbs route-aware breadcrumb trail.
  • Mock auth service (useAuth) and mock notification service (useNotifications).
  • Global search integrated into the header via GlobalSearchBar.

User Experience

Developers browse the recipe in Storybook, see the complete admin shell with navigation, search, notifications, and breadcrumbs. They copy the recipe, replace mock services with real ones, and customize the navigation configuration for their domain.

Developer Experience

The recipe is a self-contained folder. Navigation is defined as a typed configuration object. The auth guard is a wrapper component. Services are injected via React context so mocking is straightforward. Stories show authenticated/unauthenticated states, different navigation configurations, and responsive behavior.


Requirements

IDRequirementPriorityNotes
FR-001The recipe must compose SaasSidebarLayout and ScreenShellMustExisting components
FR-002The recipe must show resource navigation with sections, icons, and active statesMustCore admin UX
FR-003The recipe must include an auth guard patternMustSecurity baseline
FR-004The recipe must include notification integrationMustCommon admin feature
FR-005The recipe must include global search in the headerMustUses GlobalSearchBar
FR-006The recipe must include a user menuMustProfile, settings, logout
FR-007The recipe must show responsive sidebar collapseMustMobile support
FR-008The recipe should include breadcrumbsShouldNavigation context
FR-009The recipe must ship with storiesMustVisual reference
FR-010The recipe must ship with testsMustQuality gate

Priority Definitions

PriorityMeaning
MustRequired for this feature to ship.
ShouldImportant, but can be deferred if needed.
CouldNice to have. Not required for initial release.

Functional Requirements

IDRequirementUser BenefitPriority
FUNC-001Sidebar renders navigation sections from a typed configuration arrayDeclarative navigation definitionMust
FUNC-002Each nav item shows an icon, label, and optional badge (e.g., unread count)Clear visual hierarchyMust
FUNC-003Nested nav items expand/collapse on parent clickOrganized deep navigationMust
FUNC-004Active nav item is highlighted based on the current routeWayfindingMust
FUNC-005AuthGuard checks auth state on mount and redirects to /login if unauthenticatedRoute protectionMust
FUNC-006AuthGuard shows a loading state while checking authPrevents flash of wrong contentMust
FUNC-007NotificationCenter shows unread count badge in the headerQuick notification visibilityMust
FUNC-008NotificationCenter dropdown lists recent notifications with timestamp and dismiss actionNotification managementMust
FUNC-009UserMenu shows avatar, name, and dropdown with profile, settings, and logoutAccount managementMust
FUNC-010On mobile (below breakpoint), sidebar collapses to a hamburger toggleResponsive layoutMust
FUNC-011Breadcrumbs show the current route hierarchy below the headerNavigation contextShould
FUNC-012GlobalSearchBar in the header opens with Cmd+K / Ctrl+K keyboard shortcutQuick search accessMust

Non-Functional Requirements

IDRequirementCategoryPriority
NFR-001Recipe code must be copy-pasteable and self-containedMaintainabilityMust
NFR-002All recipe code must pass TypeScript strict modeCorrectnessMust
NFR-003Stories must render in light and dark themesCompatibilityMust
NFR-004Auth guard must not flash protected content before redirectSecurityMust
NFR-005Sidebar collapse/expand must not cause layout shift in the content areaPerformanceMust
NFR-006Navigation configuration must support at least 3 levels of nestingFlexibilityShould

API / Interface Requirements

Public API

This is a recipe, not a published package. No new public API is exported from the design system.

NameTypeDescriptionRequired
Recipe foldersourcesrc/recipes/admin-shell/ with components, config types, and servicesYes
Recipe MDXdocumentationStorybook MDX page documenting the scaffoldYes
Recipe storiesstoriesStorybook stories showing all shell statesYes
Recipe teststestsVitest tests for auth guard and navigationYes

Example Usage

import { AdminShell } from "./admin-shell";
import type { AdminNavConfig } from "./admin-shell";
const navigation: AdminNavConfig = [
{
label: "Dashboard",
icon: "LayoutDashboard",
path: "/",
},
{
label: "Users",
icon: "Users",
path: "/users",
children: [
{ label: "All Users", path: "/users" },
{ label: "Roles", path: "/users/roles" },
],
},
{
label: "Settings",
icon: "Settings",
path: "/settings",
},
];
function App() {
return (
<AuthProvider>
<AdminShell
navigation={navigation}
appName="My Admin"
logoSrc="/logo.svg"
>
<Routes />
</AdminShell>
</AuthProvider>
);
}

API Notes

  • AdminShell accepts navigation, appName, logoSrc, and children.
  • AdminNavConfig is an array of NavSection objects with optional children for nesting.
  • Auth and notification services are provided via React context; the recipe ships mock implementations.
  • The recipe is router-agnostic; active state detection uses window.location.pathname by default with an override prop.

Accessibility Requirements

IDRequirementNotes
A11Y-001Sidebar navigation must use &lt;nav&gt; with aria-label="Main navigation"Landmark for screen readers
A11Y-002Expandable nav sections must use aria-expandedScreen readers announce collapse state
A11Y-003Active nav item must use aria-current="page"Screen readers announce current page
A11Y-004Hamburger toggle must have aria-label="Toggle navigation" and aria-expandedMobile accessibility
A11Y-005Notification center dropdown must be keyboard-navigableArrow keys, Enter, Escape
A11Y-006User menu dropdown must be keyboard-navigableArrow keys, Enter, Escape
A11Y-007Skip-to-content link must be providedKeyboard users can skip navigation
A11Y-008Focus must move to content area after navigation selection on mobileSidebar closes and focus moves to content

Checklist

  • Keyboard support is defined.
  • Focus behavior is defined.
  • Screen reader behavior is defined.
  • Color contrast requirements are met.
  • Reduced motion behavior is considered.
  • Semantic HTML expectations are documented.
  • ARIA usage is defined only where needed.

Content and Documentation Requirements

IDRequirementLocationPriority
DOC-001Recipe MDX page with shell composition guideStorybook MDXMust
DOC-002Navigation configuration guideStorybook MDXMust
DOC-003Auth guard integration guideStorybook MDXMust
DOC-004”How to customize” section for replacing mock servicesStorybook MDXMust
DOC-005Responsive behavior notesStorybook MDXMust
DOC-006Accessibility notes for admin navigationStorybook MDXMust

Documentation Should Include

  • Overview of the admin shell pattern
  • When to use this recipe
  • Prerequisites (which components to install)
  • Navigation configuration
  • Auth guard setup
  • Notification integration
  • Global search integration
  • User menu customization
  • Responsive behavior
  • Breadcrumb configuration
  • Accessibility notes
  • Common mistakes

Dependencies

DependencyTypeOwnerStatusNotes
saas-sidebar-layout.tsxDesign SystemDavid HolmesReadyExisting layout component
screen-shell.tsxDesign SystemDavid HolmesReadyExisting shell component
global-search-bar.tsxDesign SystemDavid HolmesReadyExisting search component
React 18+EngineeringDavid HolmesReadyPeer dependency
VitestEngineeringDavid HolmesReadyTest runner
Icon libraryDesign SystemDavid HolmesReadyFor nav icons

Risks and Tradeoffs

Risk / TradeoffImpactMitigation
Recipe is router-agnostic but most apps use a specific routerDevelopers must adapt active-state detectionDefault uses pathname; document override pattern for TanStack Router
Mock auth service may not reflect real auth complexityDevelopers may underestimate auth integration effortDocument the mock as a starting point; link to auth-flows recipe (#80) for complete auth patterns
Large recipe may be overwhelming for simple admin appsSome developers may not need all featuresDocument which sections are optional; structure code so features can be removed independently
No RBAC means all authenticated users see all navigationInsufficient for multi-role applicationsDocument RBAC as a consumer responsibility; show where permission checks would be added

Open Questions

IDQuestionOwnerStatusResolution
Q-001Should the recipe include a dark mode toggle in the header?David HolmesOpen
Q-002Should the recipe include a settings page scaffold or just the shell?David HolmesOpen
Q-003Should navigation support external links (opening in new tab) alongside internal routes?David HolmesOpen
Q-004Should the recipe include a help/support button pattern?David HolmesOpen

Acceptance Criteria

IDCriteriaRelated Requirement
AC-001Admin shell composes SaasSidebarLayout and ScreenShellFR-001
AC-002Sidebar renders navigation from a typed configuration arrayFUNC-001
AC-003Active nav item is highlighted based on current routeFUNC-004
AC-004Nested nav items expand/collapseFUNC-003
AC-005Auth guard redirects unauthenticated users without flashing protected contentFUNC-005, NFR-004
AC-006Notification center shows unread count and lists notificationsFUNC-007, FUNC-008
AC-007Global search activates with Cmd+K / Ctrl+KFUNC-012
AC-008Sidebar collapses on mobile with hamburger toggleFUNC-010
AC-009Stories demonstrate authenticated, unauthenticated, and various navigation statesFR-009
AC-010Unit tests pass covering auth guard, navigation rendering, and responsive behaviorFR-010
AC-011All recipe code passes TypeScript strict modeNFR-002
AC-012Recipe MDX renders in Storybook without errorsDOC-001

LLM Handoff Instructions

Expected LLM Behavior

  • Follow the requirements and acceptance criteria in this document.
  • Do not expand scope beyond the In Scope section.
  • Respect the Out of Scope section.
  • Use existing design system components (SaasSidebarLayout, ScreenShell, GlobalSearchBar); do not rebuild them.
  • Navigation must be configuration-driven, not hardcoded.
  • Auth guard must show a loading state, not flash protected content.
  • Mock services must be clearly separated from shell components so consumers can replace them.
  • Use design system tokens for all styling.
  • Place the recipe in src/recipes/admin-shell/.

LLM Should Not

  • Invent undocumented product behavior.
  • Implement real authentication or notification backends.
  • Add new dependencies without justification.
  • Change existing design system components.
  • Hardcode navigation items.
  • Implement RBAC or permissions.
  • Use inline styles instead of design system tokens.

Decision Log

DateDecisionReasonOwner
2026-05-26Recipe, not a published componentAdmin shells vary too much across products for a one-size-fits-all componentDavid Holmes
2026-05-26Configuration-driven navigationDeclarative nav is easier to maintain and test than imperative JSX treesDavid Holmes
2026-05-26Router-agnostic with pathname defaultAvoids coupling the recipe to a specific router; most routers can provide pathnameDavid Holmes
2026-05-26Mock services via React contextClean separation enables easy replacement in consumer applicationsDavid Holmes

Document History

DateAuthorChange
2026-05-26David HolmesInitial draft