website refactor
This commit is contained in:
@@ -1,18 +1,24 @@
|
||||
import React from 'react';
|
||||
import Card from '@/components/ui/Card';
|
||||
import { StandingEntryViewModel } from '@/lib/view-models/StandingEntryViewModel';
|
||||
import { DriverViewModel } from '@/lib/view-models/DriverViewModel';
|
||||
|
||||
interface LeagueChampionshipStatsProps {
|
||||
standings: StandingEntryViewModel[];
|
||||
drivers: DriverViewModel[];
|
||||
standings: Array<{
|
||||
driverId: string;
|
||||
position: number;
|
||||
totalPoints: number;
|
||||
racesFinished: number;
|
||||
}>;
|
||||
drivers: Array<{
|
||||
id: string;
|
||||
name: string;
|
||||
}>;
|
||||
}
|
||||
|
||||
export default function LeagueChampionshipStats({ standings, drivers }: LeagueChampionshipStatsProps) {
|
||||
export function LeagueChampionshipStats({ standings, drivers }: LeagueChampionshipStatsProps) {
|
||||
if (standings.length === 0) return null;
|
||||
|
||||
const leader = standings[0];
|
||||
const totalRaces = Math.max(...standings.map(s => s.races), 0);
|
||||
const totalRaces = Math.max(...standings.map(s => s.racesFinished), 0);
|
||||
|
||||
return (
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
|
||||
@@ -24,7 +30,7 @@ export default function LeagueChampionshipStats({ standings, drivers }: LeagueCh
|
||||
<div>
|
||||
<p className="text-xs text-gray-400 mb-1">Championship Leader</p>
|
||||
<p className="font-bold text-white">{drivers.find(d => d.id === leader?.driverId)?.name || 'N/A'}</p>
|
||||
<p className="text-sm text-yellow-400 font-medium">{leader?.points || 0} points</p>
|
||||
<p className="text-sm text-yellow-400 font-medium">{leader?.totalPoints || 0} points</p>
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
|
||||
@@ -3,14 +3,29 @@
|
||||
import { useState, useRef, useEffect } from 'react';
|
||||
import Link from 'next/link';
|
||||
import Image from 'next/image';
|
||||
import { Star } from 'lucide-react';
|
||||
import type { DriverViewModel } from '@/lib/view-models/DriverViewModel';
|
||||
import type { LeagueMembership } from '@/lib/types/LeagueMembership';
|
||||
import { LeagueRoleDisplay } from '@/lib/display-objects/LeagueRoleDisplay';
|
||||
import CountryFlag from '@/components/ui/CountryFlag';
|
||||
import { getMediaUrl } from '@/lib/utilities/media';
|
||||
import PlaceholderImage from '@/components/ui/PlaceholderImage';
|
||||
|
||||
// League role display data
|
||||
const leagueRoleDisplay = {
|
||||
owner: {
|
||||
text: 'Owner',
|
||||
badgeClasses: 'bg-yellow-500/10 text-yellow-500 border-yellow-500/30',
|
||||
},
|
||||
admin: {
|
||||
text: 'Admin',
|
||||
badgeClasses: 'bg-purple-500/10 text-purple-400 border-purple-500/30',
|
||||
},
|
||||
steward: {
|
||||
text: 'Steward',
|
||||
badgeClasses: 'bg-blue-500/10 text-blue-400 border-blue-500/30',
|
||||
},
|
||||
member: {
|
||||
text: 'Member',
|
||||
badgeClasses: 'bg-primary-blue/10 text-primary-blue border-primary-blue/30',
|
||||
},
|
||||
} as const;
|
||||
|
||||
// Position background colors
|
||||
const getPositionBgColor = (position: number): string => {
|
||||
switch (position) {
|
||||
@@ -23,7 +38,6 @@ const getPositionBgColor = (position: number): string => {
|
||||
|
||||
interface StandingsTableProps {
|
||||
standings: Array<{
|
||||
leagueId: string;
|
||||
driverId: string;
|
||||
position: number;
|
||||
totalPoints: number;
|
||||
@@ -34,19 +48,29 @@ interface StandingsTableProps {
|
||||
bonusPoints: number;
|
||||
teamName?: string;
|
||||
}>;
|
||||
drivers: DriverViewModel[];
|
||||
leagueId: string;
|
||||
memberships?: LeagueMembership[];
|
||||
drivers: Array<{
|
||||
id: string;
|
||||
name: string;
|
||||
avatarUrl: string | null;
|
||||
iracingId?: string;
|
||||
rating?: number;
|
||||
country?: string;
|
||||
}>;
|
||||
memberships?: Array<{
|
||||
driverId: string;
|
||||
role: 'owner' | 'admin' | 'steward' | 'member';
|
||||
joinedAt: string;
|
||||
status: 'active' | 'pending' | 'banned';
|
||||
}>;
|
||||
currentDriverId?: string;
|
||||
isAdmin?: boolean;
|
||||
onRemoveMember?: (driverId: string) => void;
|
||||
onUpdateRole?: (driverId: string, role: string) => void;
|
||||
}
|
||||
|
||||
export default function StandingsTable({
|
||||
export function StandingsTable({
|
||||
standings,
|
||||
drivers,
|
||||
leagueId,
|
||||
memberships = [],
|
||||
currentDriverId,
|
||||
isAdmin = false,
|
||||
@@ -68,11 +92,11 @@ export default function StandingsTable({
|
||||
return () => document.removeEventListener('mousedown', handleClickOutside);
|
||||
}, []);
|
||||
|
||||
const getDriver = (driverId: string): DriverViewModel | undefined => {
|
||||
const getDriver = (driverId: string) => {
|
||||
return drivers.find((d) => d.id === driverId);
|
||||
};
|
||||
|
||||
const getMembership = (driverId: string): LeagueMembership | undefined => {
|
||||
const getMembership = (driverId: string) => {
|
||||
return memberships.find((m) => m.driverId === driverId);
|
||||
};
|
||||
|
||||
@@ -216,7 +240,7 @@ export default function StandingsTable({
|
||||
);
|
||||
};
|
||||
|
||||
const PointsActionMenu = ({ driverId }: { driverId: string }) => {
|
||||
const PointsActionMenu = () => {
|
||||
return (
|
||||
<div
|
||||
ref={menuRef}
|
||||
@@ -280,10 +304,8 @@ export default function StandingsTable({
|
||||
{standings.map((row) => {
|
||||
const driver = getDriver(row.driverId);
|
||||
const membership = getMembership(row.driverId);
|
||||
const roleDisplay = membership ? LeagueRoleDisplay.getLeagueRoleDisplay(membership.role) : null;
|
||||
const roleDisplay = membership ? leagueRoleDisplay[membership.role] : null;
|
||||
const canModify = canModifyMember(row.driverId);
|
||||
// TODO: Hook up real driver stats once API provides it
|
||||
const driverStatsData: null = null;
|
||||
const isRowHovered = hoveredRow === row.driverId;
|
||||
const isMemberMenuOpen = activeMenu?.driverId === row.driverId && activeMenu?.type === 'member';
|
||||
const isPointsMenuOpen = activeMenu?.driverId === row.driverId && activeMenu?.type === 'points';
|
||||
@@ -292,7 +314,7 @@ export default function StandingsTable({
|
||||
|
||||
return (
|
||||
<tr
|
||||
key={`${row.leagueId}-${row.driverId}`}
|
||||
key={row.driverId}
|
||||
className={`border-b border-charcoal-outline/50 transition-all duration-200 ${getPositionBgColor(row.position)} ${isRowHovered ? 'bg-iron-gray/10' : ''} ${isMe ? 'ring-2 ring-primary-blue/50 ring-inset bg-primary-blue/5' : ''}`}
|
||||
onMouseEnter={() => setHoveredRow(row.driverId)}
|
||||
onMouseLeave={() => {
|
||||
@@ -407,7 +429,7 @@ export default function StandingsTable({
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
{isPointsMenuOpen && <PointsActionMenu driverId={row.driverId} />}
|
||||
{isPointsMenuOpen && <PointsActionMenu />}
|
||||
</td>
|
||||
|
||||
{/* Races (Finished/Started) */}
|
||||
|
||||
Reference in New Issue
Block a user