Admin Shell

Decision D — the TpEMIS admin shell ships as a real layout component, not a documentation mock. The shell composes a role-aware sidebar (driven by useAdminShell()), the existing AuthHeader with role + tenant switchers, and a main content area that renders the route's children. Sidebar collapse state is persisted via the shadcn cookie pattern, so a user's preference survives reloads.

Pieces of the shell

RoleSwitcher

9 demo roles (platform_admin → authenticated_user). Drives the sidebar's group selection via the shared AdminShellContext.

Active role: University Admin

TenantSwitcher

Picks the active tenant from the design-system's 10-university stub. Supports an optional “all tenants” clear state for platform-admin views.

Active tenant: Njala University

AdminSidebar — role-aware

The sidebar consumes the shadcn ui/sidebar primitive (cookie-backed collapse, mobile Sheet overlay, ⌘ B keyboard shortcut). Pick a role above and the menu groups update live — notice the “Common” sections (IntelliService, Support, My Account) stay fixed across roles.

Selected role: university_admin

The sidebar to the left re-renders on every role change. Try keyboard navigation (Tab, ⌘ B), and click a parent group to expand its children.

IntelliServiceAssistantCard

5-domain assistant card surfaced on the admin dashboard. Each card carries a domain preset (icon + copy), an optional list of suggested prompts, and an “Open assistant” action.

Admission Assistant

Online

Answer applicant questions, summarize program requirements, and pre-screen incomplete applications.

Financial Assistant

Online

Look up fee balances, explain payment plans, and walk students through scholarship applications.

Library Assistant

Online

Find resources, suggest reading lists, and connect students with subject librarians.

Where to next

  • Open /tpemis/admin/dashboard for the working shell — stat cards, IntelliService row, notifications, recent activity.
  • Read src/app/components/admin/adminMenuConfig.ts to customize role-specific groups.
  • Wrap any new authenticated route in <AuthenticatedLayout /> — pass availableTenants when the role is tenant-scoped.