Files
MOPC-Portal/src/app/(admin)/layout.tsx
Matt 70a9752d73 refactor(layouts): shared RoleSwitcherPill across dashboards (§D.6)
Extract ROLE_SWITCH_OPTIONS + switchableRoles computation from the two
duplicated copies (role-nav.tsx + admin-sidebar.tsx) into a single
src/components/layouts/role-switcher.tsx module.

Adds a RoleSwitcherPill component placed top-right of every dashboard:
  - Hidden for single-role users
  - Hidden during impersonation
  - Same visual + click target across /jury, /mentor, /applicant,
    /observer, /award-master AND /admin (admin layout gains a small
    top-bar to host the pill)

Removes the duplicate role-switcher items from the admin sidebar's
bottom user-menu — one source of truth instead of three.

Plan: docs/superpowers/plans/2026-04-28-pr6-multi-role-and-workspace-previews.md
2026-04-28 16:09:40 +02:00

50 lines
1.6 KiB
TypeScript

import { prisma } from '@/lib/prisma'
import { requireRole } from '@/lib/auth-redirect'
import { AdminSidebar } from '@/components/layouts/admin-sidebar'
import { AdminEditionWrapper } from '@/components/layouts/admin-edition-wrapper'
import { RoleSwitcherPill } from '@/components/layouts/role-switcher'
export default async function AdminLayout({
children,
}: {
children: React.ReactNode
}) {
const session = await requireRole('SUPER_ADMIN', 'PROGRAM_ADMIN')
// Fetch all editions (programs) for the edition selector
const editions = await prisma.program.findMany({
select: {
id: true,
name: true,
year: true,
status: true,
},
orderBy: { year: 'desc' },
})
return (
<AdminEditionWrapper editions={editions}>
<div className="min-h-screen bg-background">
<AdminSidebar
user={{
name: session.user.name,
email: session.user.email,
role: session.user.role,
}}
/>
<main className="lg:pl-64">
{/* Spacer for mobile header */}
<div className="h-16 lg:hidden" />
{/* Top-bar — hosts the RoleSwitcherPill so multi-role admins
can switch dashboards from the same screen position used on
every other layout. Pill auto-hides for single-role users. */}
<div className="sticky top-0 z-30 flex h-12 items-center justify-end gap-2 border-b bg-card/80 backdrop-blur px-4">
<RoleSwitcherPill currentBasePath="/admin" />
</div>
<div className="container-app py-6 lg:py-8">{children}</div>
</main>
</div>
</AdminEditionWrapper>
)
}