website refactor
This commit is contained in:
@@ -5,7 +5,7 @@ import { ActivityFeedItem } from '@/components/feed/ActivityFeedItem';
|
||||
import { Icon } from '@/ui/Icon';
|
||||
import { Text } from '@/ui/Text';
|
||||
import { Stack } from '@/ui/Stack';
|
||||
import { processLeagueActivities } from '@/lib/services/league/LeagueActivityService';
|
||||
import { LeagueActivityService } from '@/lib/services/league/LeagueActivityService';
|
||||
|
||||
export type LeagueActivity =
|
||||
| { type: 'race_completed'; raceId: string; raceName: string; timestamp: Date }
|
||||
@@ -37,8 +37,10 @@ export function LeagueActivityFeed({ leagueId, limit = 10 }: LeagueActivityFeedP
|
||||
const { data: raceList = [], isLoading } = useLeagueRaces(leagueId);
|
||||
|
||||
const activities = useMemo(() => {
|
||||
if (isLoading || raceList.length === 0) return [];
|
||||
return processLeagueActivities(raceList, limit);
|
||||
if (isLoading || !Array.isArray(raceList) || raceList.length === 0) return [];
|
||||
const service = new LeagueActivityService();
|
||||
const result = service.processLeagueActivities(raceList, limit);
|
||||
return result.isOk() ? result.unwrap() : [];
|
||||
}, [raceList, isLoading, limit]);
|
||||
|
||||
if (isLoading) {
|
||||
|
||||
@@ -24,7 +24,6 @@ interface LeagueMemberRowProps {
|
||||
|
||||
export function LeagueMemberRow({
|
||||
driver,
|
||||
driverId,
|
||||
isCurrentUser,
|
||||
isTopPerformer,
|
||||
role,
|
||||
|
||||
@@ -44,16 +44,17 @@ export function LeagueMembers({
|
||||
const membershipData = leagueMembershipService.getLeagueMembers(leagueId);
|
||||
setMembers(membershipData);
|
||||
|
||||
const uniqueDriverIds = Array.from(new Set(membershipData.map((m) => m.driverId)));
|
||||
const uniqueDriverIds = Array.from(new Set(membershipData.map((m: LeagueMembership) => m.driverId)));
|
||||
if (uniqueDriverIds.length > 0) {
|
||||
const driverDtos = await driverService.findByIds(uniqueDriverIds);
|
||||
|
||||
const byId: Record<string, DriverViewModel> = {};
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
for (const dto of driverDtos as any[]) {
|
||||
byId[dto.id] = new DriverViewModel({ ...dto, avatarUrl: dto.avatarUrl ?? null });
|
||||
const result = await driverService.findByIds(uniqueDriverIds);
|
||||
if (result.isOk()) {
|
||||
const driverDtos = result.unwrap();
|
||||
const byId: Record<string, DriverViewModel> = {};
|
||||
for (const dto of driverDtos) {
|
||||
byId[dto.id] = new DriverViewModel({ ...dto, avatarUrl: dto.avatarUrl ?? null });
|
||||
}
|
||||
setDriversById(byId);
|
||||
}
|
||||
setDriversById(byId);
|
||||
} else {
|
||||
setDriversById({});
|
||||
}
|
||||
|
||||
@@ -50,8 +50,9 @@ export function LeagueSponsorshipsSection({
|
||||
const [tempPrice, setTempPrice] = useState<string>('');
|
||||
|
||||
// Load season ID if not provided
|
||||
const { data: seasons = [] } = useLeagueSeasons(leagueId);
|
||||
const activeSeason = seasons.find((s) => s.status === 'active') ?? seasons[0];
|
||||
const { data: seasonsResult } = useLeagueSeasons(leagueId);
|
||||
const seasons = seasonsResult?.isOk() ? seasonsResult.unwrap() : [];
|
||||
const activeSeason = seasons.find((s: any) => s.status === 'active') ?? seasons[0];
|
||||
const seasonId = propSeasonId || activeSeason?.seasonId;
|
||||
|
||||
// Load pending sponsorship requests
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
import { DriverViewModel } from "@/lib/view-models/DriverViewModel";
|
||||
import { ProtestViewModel } from "@/lib/view-models/ProtestViewModel";
|
||||
import { RaceViewModel } from "@/lib/view-models/RaceViewModel";
|
||||
import { Box } from "@/ui/Box";
|
||||
import { Card } from "@/ui/Card";
|
||||
import { ProtestListItem } from "./ProtestListItem";
|
||||
@@ -12,17 +11,13 @@ import { Flag } from "lucide-react";
|
||||
|
||||
interface PendingProtestsListProps {
|
||||
protests: ProtestViewModel[];
|
||||
races: Record<string, RaceViewModel>;
|
||||
drivers: Record<string, DriverViewModel>;
|
||||
leagueId: string;
|
||||
onReviewProtest: (protest: ProtestViewModel) => void;
|
||||
onProtestReviewed: () => void;
|
||||
}
|
||||
|
||||
export function PendingProtestsList({
|
||||
protests,
|
||||
drivers,
|
||||
leagueId,
|
||||
onReviewProtest,
|
||||
}: PendingProtestsListProps) {
|
||||
|
||||
|
||||
@@ -57,10 +57,10 @@ export function ReviewProtestModal({
|
||||
const [submitting, setSubmitting] = useState(false);
|
||||
const [showConfirmation, setShowConfirmation] = useState(false);
|
||||
|
||||
const { data: penaltyTypesReference, isLoading: penaltyTypesLoading } = usePenaltyTypesReference();
|
||||
const { data: penaltyTypesReferenceResult, isLoading: penaltyTypesLoading } = usePenaltyTypesReference();
|
||||
|
||||
const penaltyOptions = useMemo(() => {
|
||||
const refs = penaltyTypesReference?.penaltyTypes ?? [];
|
||||
const refs = penaltyTypesReferenceResult?.isOk() ? penaltyTypesReferenceResult.unwrap().penaltyTypes : [];
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
return refs.map((ref: any) => ({
|
||||
type: ref.type as PenaltyType,
|
||||
@@ -71,7 +71,7 @@ export function ReviewProtestModal({
|
||||
Icon: getPenaltyIcon(ref.type),
|
||||
colorClass: getPenaltyColor(ref.type),
|
||||
}));
|
||||
}, [penaltyTypesReference]);
|
||||
}, [penaltyTypesReferenceResult]);
|
||||
|
||||
const selectedPenalty = useMemo(() => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
@@ -99,7 +99,7 @@ export function ReviewProtestModal({
|
||||
}
|
||||
};
|
||||
|
||||
const getPenaltyIcon = (type: PenaltyType) => {
|
||||
function getPenaltyIcon(type: PenaltyType) {
|
||||
switch (type) {
|
||||
case "time_penalty":
|
||||
return Clock;
|
||||
@@ -122,9 +122,9 @@ export function ReviewProtestModal({
|
||||
default:
|
||||
return AlertCircle;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
const getPenaltyName = (type: PenaltyType) => {
|
||||
function getPenaltyName(type: PenaltyType) {
|
||||
switch (type) {
|
||||
case "time_penalty":
|
||||
return "Time Penalty";
|
||||
@@ -147,9 +147,9 @@ export function ReviewProtestModal({
|
||||
default:
|
||||
return type.replaceAll("_", " ");
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
const getPenaltyValueLabel = (valueKind: PenaltyValueKindDTO): string => {
|
||||
function getPenaltyValueLabel(valueKind: PenaltyValueKindDTO): string {
|
||||
switch (valueKind) {
|
||||
case "seconds":
|
||||
return "seconds";
|
||||
@@ -162,9 +162,9 @@ export function ReviewProtestModal({
|
||||
case "none":
|
||||
return "";
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
const getPenaltyDefaultValue = (type: PenaltyType, valueKind: PenaltyValueKindDTO): number => {
|
||||
function getPenaltyDefaultValue(type: PenaltyType, valueKind: PenaltyValueKindDTO): number {
|
||||
if (type === "license_points") return 2;
|
||||
if (type === "race_ban") return 1;
|
||||
switch (valueKind) {
|
||||
@@ -179,9 +179,9 @@ export function ReviewProtestModal({
|
||||
case "none":
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
const getPenaltyColor = (type: PenaltyType) => {
|
||||
function getPenaltyColor(type: PenaltyType) {
|
||||
switch (type) {
|
||||
case "time_penalty":
|
||||
return "text-blue-400 bg-blue-500/10 border-blue-500/30";
|
||||
@@ -204,7 +204,7 @@ export function ReviewProtestModal({
|
||||
default:
|
||||
return "text-warning-amber bg-warning-amber/10 border-warning-amber/30";
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
if (showConfirmation) {
|
||||
return (
|
||||
@@ -351,7 +351,6 @@ export function ReviewProtestModal({
|
||||
</Box>
|
||||
)}
|
||||
</Stack>
|
||||
|
||||
<Box borderTop borderColor="border-gray-800" pt={6}>
|
||||
<Stack gap={4}>
|
||||
<Heading level={3} fontSize="lg" weight="semibold" color="text-white">Stewarding Decision</Heading>
|
||||
@@ -471,4 +470,4 @@ export function ReviewProtestModal({
|
||||
</Stack>
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user