MotorSignal-App/website/components/founder-portal/founder-community-page.tsx

66 lines
3.8 KiB
TypeScript

'use client';
import React, { useEffect, useState } from 'react';
import { onAuthStateChanged } from 'firebase/auth';
import { useRouter, useSearchParams } from 'next/navigation';
import { firebaseAuth } from '../../lib/firebase-client';
import { fetchFounderClubContext, sanitizePortalError, type FounderClubContext } from '../../lib/club-data';
import { FounderPortalShell } from './founder-portal-shell';
import { FounderMembers } from './founder-members';
import { FounderWall } from './founder-wall';
import { FounderRoutes } from './founder-routes';
import { FounderChat } from './founder-chat';
import { OverviewSkeleton } from './skeleton-state';
import { SafeErrorState } from './safe-error-state';
export function FounderCommunityPage({ clubId, section }: { clubId: string; section: 'members' | 'wall' | 'routes' | 'chat' }) {
const router = useRouter();
const searchParams = useSearchParams();
const demo = process.env.NODE_ENV === 'development' && searchParams?.get('preview') === 'demo';
const [context, setContext] = useState<FounderClubContext | null>(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
const [access, setAccess] = useState<'sign-in' | 'restricted' | null>(null);
const [retry, setRetry] = useState(0);
useEffect(() => {
let generation = 0;
let disposed = false;
const unsubscribe = onAuthStateChanged(firebaseAuth, async (user) => {
const current = ++generation;
setContext(null); setLoading(true); setAccess(null); setError(null);
if (!demo && (!user || user.isAnonymous)) {
setAccess('sign-in'); setLoading(false); return;
}
try {
const result = await fetchFounderClubContext(clubId, user?.uid, { allowDemoPreview: demo });
if (disposed || current !== generation) return;
if (!result.permissions.canManageSettings && !result.isDemoFixture) setAccess('restricted');
else setContext(result);
} catch (err) {
if (!disposed && current === generation) setError(sanitizePortalError(err));
} finally {
if (!disposed && current === generation) setLoading(false);
}
});
return () => { disposed = true; generation++; unsubscribe(); };
}, [clubId, demo, retry]);
if (loading) return <div className="min-h-screen bg-brand-bg p-6"><OverviewSkeleton /></div>;
if (access) return <SafeErrorState title={access === 'sign-in' ? 'Authentication Required' : 'Management Access Restricted'}
message={access === 'sign-in' ? 'Sign in with your rider account to manage this club.' : 'Only club Owners and Admins can access this management page.'}
actionLabel={access === 'sign-in' ? 'Sign In' : 'Return to Clubs'} onAction={() => router.push(access === 'sign-in' ? '/login' : '/clubs')} />;
if (error || !context) return <SafeErrorState title="Club information unavailable" message={error || undefined}
onRetry={() => setRetry((value) => value + 1)} actionLabel="Return to Clubs" onAction={() => router.push('/clubs')} />;
return <FounderPortalShell club={context.club} permissions={context.permissions} activeNav={section}
onPostAnnouncement={() => {
if (section === 'wall') document.getElementById('wall-post-content')?.focus();
else router.push(`/clubs/${clubId}/manage/wall${demo ? '?preview=demo' : ''}#wall-post-content`);
}}>
{section === 'members' && <FounderMembers key={context.club.id + context.currentUser.uid} context={context} />}
{section === 'wall' && <FounderWall key={context.club.id + context.currentUser.uid} context={context} />}
{section === 'routes' && <FounderRoutes key={context.club.id + context.currentUser.uid} context={context} />}
{section === 'chat' && <FounderChat key={context.club.id + context.currentUser.uid} context={context} />}
</FounderPortalShell>;
}