website refactor
This commit is contained in:
146
apps/website/templates/StewardingTemplate.tsx
Normal file
146
apps/website/templates/StewardingTemplate.tsx
Normal file
@@ -0,0 +1,146 @@
|
||||
'use client';
|
||||
|
||||
import { PenaltyHistoryList } from '@/components/leagues/PenaltyHistoryList';
|
||||
import { QuickPenaltyModal } from '@/components/leagues/QuickPenaltyModal';
|
||||
import { ReviewProtestModal } from '@/components/leagues/ReviewProtestModal';
|
||||
import { StewardingQueuePanel } from '@/components/leagues/StewardingQueuePanel';
|
||||
import { StewardingStats } from '@/components/leagues/StewardingStats';
|
||||
import { PenaltyFAB } from '@/components/races/PenaltyFAB';
|
||||
import type { StewardingViewData } from '@/lib/view-data/leagues/StewardingViewData';
|
||||
import {
|
||||
SharedBox,
|
||||
SharedButton,
|
||||
SharedStack,
|
||||
SharedText,
|
||||
SharedCard
|
||||
} from '@/components/shared/UIComponents';
|
||||
import { TemplateProps } from '@/lib/contracts/components/ComponentContracts';
|
||||
|
||||
interface StewardingTemplateProps extends TemplateProps<StewardingViewData> {
|
||||
activeTab: 'pending' | 'history';
|
||||
onTabChange: (tab: 'pending' | 'history') => void;
|
||||
selectedProtest: any;
|
||||
onReviewProtest: (id: string) => void;
|
||||
onCloseProtestModal: () => void;
|
||||
onAcceptProtest: (protestId: string, penaltyType: string, penaltyValue: number, stewardNotes: string) => Promise<void>;
|
||||
onRejectProtest: (protestId: string, stewardNotes: string) => Promise<void>;
|
||||
showQuickPenaltyModal: boolean;
|
||||
setShowQuickPenaltyModal: (show: boolean) => void;
|
||||
allPendingProtests: any[];
|
||||
allResolvedProtests: any[];
|
||||
racesMap: any;
|
||||
driverMap: any;
|
||||
currentDriverId: string;
|
||||
}
|
||||
|
||||
export function StewardingTemplate({
|
||||
viewData,
|
||||
activeTab,
|
||||
onTabChange,
|
||||
selectedProtest,
|
||||
onReviewProtest,
|
||||
onCloseProtestModal,
|
||||
onAcceptProtest,
|
||||
onRejectProtest,
|
||||
showQuickPenaltyModal,
|
||||
setShowQuickPenaltyModal,
|
||||
allPendingProtests,
|
||||
allResolvedProtests,
|
||||
racesMap,
|
||||
driverMap,
|
||||
currentDriverId,
|
||||
}: StewardingTemplateProps) {
|
||||
return (
|
||||
<SharedStack gap={6}>
|
||||
<StewardingStats
|
||||
totalPending={viewData.totalPending}
|
||||
totalResolved={viewData.totalResolved}
|
||||
totalPenalties={viewData.totalPenalties}
|
||||
/>
|
||||
|
||||
{/* Tab navigation */}
|
||||
<SharedBox borderBottom borderColor="border-charcoal-outline">
|
||||
<SharedStack direction="row" gap={4}>
|
||||
<SharedBox
|
||||
borderBottom={activeTab === 'pending'}
|
||||
borderColor={activeTab === 'pending' ? 'border-primary-blue' : undefined}
|
||||
>
|
||||
<SharedButton
|
||||
variant="ghost"
|
||||
onClick={() => onTabChange('pending')}
|
||||
rounded={false}
|
||||
>
|
||||
<SharedStack direction="row" align="center" gap={2}>
|
||||
<SharedText weight="medium" color={activeTab === 'pending' ? 'text-primary-blue' : undefined}>Pending Protests</SharedText>
|
||||
{viewData.totalPending > 0 && (
|
||||
<SharedBox px={2} py={0.5} fontSize="0.75rem" bg="bg-warning-amber/20" color="text-warning-amber" rounded="full">
|
||||
{viewData.totalPending}
|
||||
</SharedBox>
|
||||
)}
|
||||
</SharedStack>
|
||||
</SharedButton>
|
||||
</SharedBox>
|
||||
<SharedBox
|
||||
borderBottom={activeTab === 'history'}
|
||||
borderColor={activeTab === 'history' ? 'border-primary-blue' : undefined}
|
||||
>
|
||||
<SharedButton
|
||||
variant="ghost"
|
||||
onClick={() => onTabChange('history')}
|
||||
rounded={false}
|
||||
>
|
||||
<SharedText weight="medium" color={activeTab === 'history' ? 'text-primary-blue' : undefined}>History</SharedText>
|
||||
</SharedButton>
|
||||
</SharedBox>
|
||||
</SharedStack>
|
||||
</SharedBox>
|
||||
|
||||
{/* Content */}
|
||||
{activeTab === 'pending' ? (
|
||||
<StewardingQueuePanel
|
||||
protests={allPendingProtests}
|
||||
onReview={onReviewProtest}
|
||||
/>
|
||||
) : (
|
||||
<SharedCard>
|
||||
<SharedBox p={6}>
|
||||
<PenaltyHistoryList
|
||||
protests={allResolvedProtests}
|
||||
races={racesMap}
|
||||
drivers={driverMap}
|
||||
/>
|
||||
</SharedBox>
|
||||
</SharedCard>
|
||||
)}
|
||||
|
||||
{activeTab === 'history' && (
|
||||
<PenaltyFAB onClick={() => setShowQuickPenaltyModal(true)} />
|
||||
)}
|
||||
|
||||
{selectedProtest && (
|
||||
<ReviewProtestModal
|
||||
protest={selectedProtest}
|
||||
onClose={onCloseProtestModal}
|
||||
onAccept={onAcceptProtest}
|
||||
onReject={onRejectProtest}
|
||||
/>
|
||||
)}
|
||||
|
||||
{showQuickPenaltyModal && (
|
||||
<QuickPenaltyModal
|
||||
drivers={viewData.drivers.map(d => ({
|
||||
id: d.id,
|
||||
name: d.name,
|
||||
iracingId: '',
|
||||
country: '',
|
||||
joinedAt: '',
|
||||
avatarUrl: null,
|
||||
}) as any)}
|
||||
onClose={() => setShowQuickPenaltyModal(false)}
|
||||
adminId={currentDriverId || ''}
|
||||
races={viewData.races.map(r => ({ id: r.id, track: r.track, scheduledAt: new Date(r.scheduledAt) }))}
|
||||
/>
|
||||
)}
|
||||
</SharedStack>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user