remove core from pages

This commit is contained in:
2025-12-18 19:14:50 +01:00
parent 9814d9682c
commit 4a3087ae35
35 changed files with 552 additions and 354 deletions

View File

@@ -3,12 +3,12 @@
import Button from '@/components/ui/Button';
import Card from '@/components/ui/Card';
import { useEffectiveDriverId } from '@/hooks/useEffectiveDriverId';
import { isLeagueAdminOrHigherRole } from '@/lib/leagueRoles';
import { LeagueRoleUtility } from '@/lib/utilities/LeagueRoleUtility';
import { useServices } from '@/lib/services/ServiceProvider';
import { ProtestViewModel } from '@/lib/view-models/ProtestViewModel';
import { RaceViewModel } from '@/lib/view-models/RaceViewModel';
import { ProtestDriverViewModel } from '@/lib/view-models/ProtestDriverViewModel';
import { ProtestDecisionCommandModel, type PenaltyType } from '@/lib/command-models/protests/ProtestDecisionCommandModel';
import type { DriverSummaryDTO } from '@/lib/types/generated/LeagueAdminProtestsDTO';
import type { RaceDTO } from '@/lib/types/generated/RaceDTO';
import {
AlertCircle,
AlertTriangle,
@@ -40,7 +40,7 @@ interface TimelineEvent {
id: string;
type: 'protest_filed' | 'defense_requested' | 'defense_submitted' | 'steward_comment' | 'decision' | 'penalty_applied';
timestamp: Date;
actor: DriverDTO | null;
actor: ProtestDriverViewModel | null;
content: string;
metadata?: Record<string, unknown>;
}
@@ -114,12 +114,12 @@ export default function ProtestReviewPage() {
const leagueId = params.id as string;
const protestId = params.protestId as string;
const currentDriverId = useEffectiveDriverId();
const { protestService } = useServices();
const { protestService, leagueMembershipService } = useServices();
const [protest, setProtest] = useState<ProtestViewModel | null>(null);
const [race, setRace] = useState<RaceDTO | null>(null);
const [protestingDriver, setProtestingDriver] = useState<DriverSummaryDTO | null>(null);
const [accusedDriver, setAccusedDriver] = useState<DriverSummaryDTO | null>(null);
const [race, setRace] = useState<RaceViewModel | null>(null);
const [protestingDriver, setProtestingDriver] = useState<ProtestDriverViewModel | null>(null);
const [accusedDriver, setAccusedDriver] = useState<ProtestDriverViewModel | null>(null);
const [loading, setLoading] = useState(true);
const [isAdmin, setIsAdmin] = useState(false);
@@ -136,12 +136,12 @@ export default function ProtestReviewPage() {
useEffect(() => {
async function checkAdmin() {
const membershipRepo = getLeagueMembershipRepository();
const membership = await membershipRepo.getMembership(leagueId, currentDriverId);
setIsAdmin(membership ? isLeagueAdminOrHigherRole(membership.role) : false);
await leagueMembershipService.fetchLeagueMemberships(leagueId);
const membership = leagueMembershipService.getMembership(leagueId, currentDriverId);
setIsAdmin(membership ? LeagueRoleUtility.isLeagueAdminOrHigherRole(membership.role) : false);
}
checkAdmin();
}, [leagueId, currentDriverId]);
}, [leagueId, currentDriverId, leagueMembershipService]);
useEffect(() => {
async function loadProtest() {
@@ -188,19 +188,19 @@ export default function ProtestReviewPage() {
}
];
// TODO: Add decision event when status/decisions are available in DTO
// if (protest.status === 'upheld' || protest.status === 'dismissed') {
// events.push({
// id: 'decision',
// type: 'decision',
// timestamp: protest.reviewedAt ? new Date(protest.reviewedAt) : new Date(),
// actor: null, // Would need to load steward driver
// content: protest.decisionNotes || (protest.status === 'upheld' ? 'Protest upheld' : 'Protest dismissed'),
// metadata: {
// decision: protest.status
// }
// });
// }
// Add decision event when status/decisions are available in view model
if (protest.status === 'upheld' || protest.status === 'dismissed') {
events.push({
id: 'decision',
type: 'decision',
timestamp: protest.reviewedAt ? new Date(protest.reviewedAt) : new Date(),
actor: null, // Would need to load steward driver
content: protest.decisionNotes || (protest.status === 'upheld' ? 'Protest upheld' : 'Protest dismissed'),
metadata: {
decision: protest.status
}
});
}
return events.sort((a, b) => a.timestamp.getTime() - b.timestamp.getTime());
}, [protest, protestingDriver]);
@@ -315,9 +315,9 @@ export default function ProtestReviewPage() {
);
}
const statusConfig = getStatusConfig('pending'); // TODO: Update when status is available
const statusConfig = getStatusConfig(protest.status);
const StatusIcon = statusConfig.icon;
const isPending = true; // TODO: Update when status is available
const isPending = protest.status === 'pending';
const daysSinceFiled = Math.floor((Date.now() - new Date(protest.submittedAt).getTime()) / (1000 * 60 * 60 * 24));
return (
@@ -404,7 +404,7 @@ export default function ProtestReviewPage() {
</div>
<div className="flex items-center gap-2 text-sm">
<Calendar className="w-4 h-4 text-gray-500" />
<span className="text-gray-300">{new Date(race.date).toLocaleDateString()}</span>
<span className="text-gray-300">{race.formattedDate}</span>
</div>
{/* TODO: Add lap info when available */}
{/* <div className="flex items-center gap-2 text-sm">