'use client'; import React, { useEffect, useState, use } from 'react'; import { useRouter, useSearchParams } from 'next/navigation'; import { fetchFounderClubContext, FounderClubContext, sanitizePortalError, } from '../../../../../lib/club-data'; import { FounderPortalShell } from '../../../../../components/founder-portal/founder-portal-shell'; import { RolesAndRanksSummary } from '../../../../../components/founder-portal/roles-and-ranks-summary'; import { OverviewSkeleton } from '../../../../../components/founder-portal/skeleton-state'; import { SafeErrorState } from '../../../../../components/founder-portal/safe-error-state'; import { firebaseAuth } from '../../../../../lib/firebase-client'; interface PageProps { params: Promise<{ clubId: string }>; } export default function ClubFounderRanksRolesPage({ params }: PageProps) { const { clubId } = use(params); const router = useRouter(); const searchParams = useSearchParams(); const [context, setContext] = useState(null); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [unauthenticated, setUnauthenticated] = useState(false); async function loadData() { setLoading(true); setError(null); setUnauthenticated(false); try { await firebaseAuth.authStateReady(); const currentUser = firebaseAuth.currentUser; const isDemoPreview = searchParams?.get('preview') === 'demo'; if (!isDemoPreview && !currentUser) { setUnauthenticated(true); setLoading(false); return; } const ctx = await fetchFounderClubContext(clubId, currentUser?.uid, { allowDemoPreview: isDemoPreview, }); setContext(ctx); } catch (err) { setError(sanitizePortalError(err, "Ranks and roles couldn't be loaded.")); } finally { setLoading(false); } } useEffect(() => { void loadData(); }, [clubId]); if (loading) { return (
); } if (unauthenticated) { return (
router.push('/login')} />
); } if (error || !context) { return (
router.push('/clubs')} onRetry={loadData} />
); } return (
{/* Header */}
Governance & Authority // {context.club.name}

Ranks & Roles

Administrative role authority vs honorary squad rank designations.

{/* Roles and Ranks Summary Component */} {/* Rank Hierarchy Detail Table */}
military_tech

Squad Rank Structure

6 Recognized Titles
{[ { rank: 'President', desc: 'Club founder and chief organizational executive.', level: 'Rank 1' }, { rank: 'Vice President', desc: 'Senior operational deputy and squadron coordinator.', level: 'Rank 2' }, { rank: 'Road Captain', desc: 'Leads pace line, group positioning, and on-road safety.', level: 'Rank 3' }, { rank: 'Road Marshal', desc: 'Rear sweep and group communications integrity.', level: 'Rank 4' }, { rank: 'Senior Rider', desc: 'Veteran rider with 1,000+ verified club group miles.', level: 'Rank 5' }, { rank: 'Member', desc: 'Verified active rider in regular squadron standing.', level: 'Rank 6' }, ].map((r) => (
{r.rank} {r.level}

{r.desc}

))}
); }