Split dashboard and leader contacts into dedicated routes, update nav and gates, and fix revalidation paths after the route move.
46 lines
2 KiB
TypeScript
46 lines
2 KiB
TypeScript
import 'server-only'
|
|
|
|
import { redirect } from 'next/navigation'
|
|
|
|
import { isStaffCampaignRole, isUnrestrictedCampaignRole } from '@/lib/campaignRoles'
|
|
import { getCampaignUser } from '@/utilities/campaignAuth'
|
|
|
|
/** Exactly the non-null actor `getCampaignUser` proves (keeps its `email` refinement). */
|
|
export type CampaignPageActor = NonNullable<Awaited<ReturnType<typeof getCampaignUser>>>
|
|
|
|
export type CampaignPageGate = 'staff' | 'unrestricted' | 'noLeader'
|
|
|
|
export const LEADER_CONTACTS_HOME = '/campanha/contatos'
|
|
|
|
/** Staff dashboard (B43 — moved off blank `/campanha`). */
|
|
export const CAMPAIGN_STAFF_QUADRO_PATH = '/campanha/quadro'
|
|
|
|
/**
|
|
* THE staff page prologue (Pass 3 P3-I — was ~110 hand-spelled lines across 30
|
|
* pages, with a real divergence: 5 pages answered a missing session with
|
|
* `return null` — a blank screen — instead of redirecting to login). Gates:
|
|
*
|
|
* - (none) → any authenticated campaign user;
|
|
* - 'staff' → non-staff (leader) goes to `/campanha/contatos` (B43);
|
|
* - 'unrestricted' → non-coordinator/candidate goes to `/campanha`;
|
|
* - 'noLeader' → leader goes to `/campanha/contatos` (B43).
|
|
*
|
|
* A custom `redirectTo` overrides the gate's default target. The convention
|
|
* guard in `codebaseConventions.unit.spec.ts` fails the build on a
|
|
* `getCampaignUser()` call in a `(app)` route page outside this helper.
|
|
*/
|
|
export const requireCampaignPageActor = async (
|
|
options: { gate?: CampaignPageGate; redirectTo?: string } = {},
|
|
): Promise<CampaignPageActor> => {
|
|
const user = await getCampaignUser()
|
|
if (!user) redirect('/campanha/login')
|
|
|
|
const { gate, redirectTo } = options
|
|
const denyRedirect = redirectTo ?? (user.role === 'leader' ? LEADER_CONTACTS_HOME : '/campanha')
|
|
|
|
if (gate === 'staff' && !isStaffCampaignRole(user.role)) redirect(denyRedirect)
|
|
if (gate === 'unrestricted' && !isUnrestrictedCampaignRole(user.role)) redirect(denyRedirect)
|
|
if (gate === 'noLeader' && user.role === 'leader') redirect(denyRedirect)
|
|
|
|
return user
|
|
}
|