'use client'; import { useEffect, useState } from 'react'; import Link from 'next/link'; import { onAuthStateChanged } from 'firebase/auth'; import { useRouter, useSearchParams } from 'next/navigation'; import { firebaseAuth } from '../../lib/firebase-client'; import { fetchClubRides, fetchFounderClubContext, sanitizePortalError, type ClubRidesResult, type FounderClubContext, } from '../../lib/club-data'; import { FounderPortalShell } from './founder-portal-shell'; import { MetricCard } from './metric-card'; import { OverviewSkeleton } from './skeleton-state'; import { SafeErrorState } from './safe-error-state'; export function FounderStatsPage({ clubId }: { clubId: string }) { const router = useRouter(); const searchParams = useSearchParams(); const demo = process.env.NODE_ENV === 'development' && searchParams?.get('preview') === 'demo'; const [context, setContext] = useState(null); const [rides, setRides] = useState(null); const [loading, setLoading] = useState(true); const [access, setAccess] = useState<'sign-in' | 'restricted' | null>(null); const [error, setError] = useState(null); const [retry, setRetry] = useState(0); useEffect(() => { let generation = 0; let disposed = false; const unsubscribe = onAuthStateChanged(firebaseAuth, async (user) => { const current = ++generation; setContext(null); setRides(null); setLoading(true); setAccess(null); setError(null); if (!demo && (!user || user.isAnonymous)) { setAccess('sign-in'); setLoading(false); return; } try { const resolved = await fetchFounderClubContext(clubId, user?.uid, { allowDemoPreview: demo }); if (disposed || current !== generation) return; if (!resolved.permissions.canManageSettings && !resolved.isDemoFixture) { setAccess('restricted'); return; } const clubRides = await fetchClubRides(resolved.club.id, user?.uid, { allowDemoPreview: demo }); if (disposed || current !== generation) return; setContext(resolved); setRides(clubRides); } catch (err) { if (!disposed && current === generation) setError(sanitizePortalError(err, 'Club stats could not be loaded.')); } finally { if (!disposed && current === generation) setLoading(false); } }); return () => { disposed = true; generation++; unsubscribe(); }; }, [clubId, demo, retry]); if (loading) return
; if (access) return router.push(access === 'sign-in' ? '/login' : '/clubs')} />; if (error || !context || !rides) return setRetry((value) => value + 1)} actionLabel="Return to Clubs" onAction={() => router.push('/clubs')} />; const completed = rides.pastRides.filter((ride) => ride.status === 'completed'); const canceled = rides.pastRides.filter((ride) => ride.status === 'canceled'); const confirmedSeats = rides.upcomingRides.reduce((sum, ride) => sum + ride.confirmedCount, 0); const ridePath = `/clubs/${context.club.slug || context.club.id}/manage/rides${demo ? '?preview=demo' : ''}`; return

Club overview

Stats

Current roster and the rides available in club management.

Manage rides

Ride status

From the club rides currently loaded in management.

{[ ['Scheduled', rides.upcomingRides.filter((ride) => ride.status === 'scheduled').length], ['Assembling', rides.upcomingRides.filter((ride) => ride.status === 'assembling').length], ['Underway', rides.upcomingRides.filter((ride) => ride.status === 'underway').length], ['Completed', completed.length], ['Canceled', canceled.length], ['Unclassified', [...rides.upcomingRides, ...rides.pastRides].filter((ride) => !ride.status).length], ].map(([label, count]) =>
{label}
{count}
)}

Recent completed rides

{completed.length === 0 ?

No completed rides in the recent club ride list.

:
    {completed.slice(0, 5).map((ride) =>
  • {ride.title} {ride.confirmedCount} seats
  • )}
}
; }