Files
gridpilot.gg/apps/website/app/races/[id]/RaceDetailPageClient.tsx
2026-01-14 23:46:04 +01:00

86 lines
2.3 KiB
TypeScript

'use client';
import React, { useState, useEffect } from 'react';
import { RaceDetailTemplate, type RaceDetailViewData } from '@/templates/RaceDetailTemplate';
interface RaceDetailPageClientProps {
viewData: RaceDetailViewData;
onBack: () => void;
onRegister: () => void;
onWithdraw: () => void;
onCancel: () => void;
onReopen: () => void;
onEndRace: () => void;
onFileProtest: () => void;
onResultsClick: () => void;
onStewardingClick: () => void;
onLeagueClick: (id: string) => void;
onDriverClick: (id: string) => void;
isOwnerOrAdmin: boolean;
}
export function RaceDetailPageClient({
viewData,
onBack,
onRegister,
onWithdraw,
onCancel,
onReopen,
onEndRace,
onFileProtest,
onResultsClick,
onStewardingClick,
onLeagueClick,
onDriverClick,
isOwnerOrAdmin
}: RaceDetailPageClientProps) {
const [showProtestModal, setShowProtestModal] = useState(false);
const [showEndRaceModal, setShowEndRaceModal] = useState(false);
const [animatedRatingChange, setAnimatedRatingChange] = useState(0);
const ratingChange = viewData.userResult?.ratingChange ?? null;
useEffect(() => {
if (ratingChange !== null) {
let start = 0;
const end = ratingChange;
const duration = 1000;
const startTime = performance.now();
const animate = (currentTime: number) => {
const elapsed = currentTime - startTime;
const progress = Math.min(elapsed / duration, 1);
const eased = 1 - Math.pow(1 - progress, 3);
const current = Math.round(start + (end - start) * eased);
setAnimatedRatingChange(current);
if (progress < 1) {
requestAnimationFrame(animate);
}
};
requestAnimationFrame(animate);
}
}, [ratingChange]);
return (
<RaceDetailTemplate
viewData={viewData}
isLoading={false}
onBack={onBack}
onRegister={onRegister}
onWithdraw={onWithdraw}
onCancel={onCancel}
onReopen={onReopen}
onEndRace={onEndRace}
onFileProtest={onFileProtest}
onResultsClick={onResultsClick}
onStewardingClick={onStewardingClick}
onLeagueClick={onLeagueClick}
onDriverClick={onDriverClick}
isOwnerOrAdmin={isOwnerOrAdmin}
animatedRatingChange={animatedRatingChange}
/>
);
}