wip
This commit is contained in:
@@ -1,11 +1,20 @@
|
||||
'use client';
|
||||
|
||||
import React from 'react';
|
||||
import React, { useEffect, useMemo, useState } from 'react';
|
||||
import Link from 'next/link';
|
||||
import Image from 'next/image';
|
||||
import MembershipStatus from '@/components/leagues/MembershipStatus';
|
||||
import FeatureLimitationTooltip from '@/components/alpha/FeatureLimitationTooltip';
|
||||
import { getLeagueCoverClasses } from '@/lib/leagueCovers';
|
||||
import {
|
||||
getDriverRepository,
|
||||
getDriverStats,
|
||||
getAllDriverRankings,
|
||||
getImageService,
|
||||
} from '@/lib/di-container';
|
||||
import type { DriverDTO } from '@gridpilot/racing/application/dto/DriverDTO';
|
||||
import { EntityMappers } from '@gridpilot/racing/application/mappers/EntityMappers';
|
||||
import DriverSummaryPill from '@/components/profile/DriverSummaryPill';
|
||||
|
||||
interface LeagueHeaderProps {
|
||||
leagueId: string;
|
||||
@@ -22,7 +31,72 @@ export default function LeagueHeader({
|
||||
ownerId,
|
||||
ownerName,
|
||||
}: LeagueHeaderProps) {
|
||||
const coverUrl = `https://picsum.photos/seed/${leagueId}/1200/280?blur=2`;
|
||||
const imageService = getImageService();
|
||||
const coverUrl = imageService.getLeagueCover(leagueId);
|
||||
const logoUrl = imageService.getLeagueLogo(leagueId);
|
||||
|
||||
const [ownerDriver, setOwnerDriver] = useState<DriverDTO | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
let isMounted = true;
|
||||
|
||||
async function loadOwner() {
|
||||
try {
|
||||
const driverRepo = getDriverRepository();
|
||||
const entity = await driverRepo.findById(ownerId);
|
||||
if (!entity || !isMounted) return;
|
||||
setOwnerDriver(EntityMappers.toDriverDTO(entity));
|
||||
} catch (err) {
|
||||
console.error('Failed to load league owner for header:', err);
|
||||
}
|
||||
}
|
||||
|
||||
loadOwner();
|
||||
|
||||
return () => {
|
||||
isMounted = false;
|
||||
};
|
||||
}, [ownerId]);
|
||||
|
||||
const ownerSummary = useMemo(() => {
|
||||
if (!ownerDriver) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const stats = getDriverStats(ownerDriver.id);
|
||||
const allRankings = getAllDriverRankings();
|
||||
|
||||
let rating: number | null = stats?.rating ?? null;
|
||||
let rank: number | null = null;
|
||||
|
||||
if (stats) {
|
||||
if (typeof stats.overallRank === 'number' && stats.overallRank > 0) {
|
||||
rank = stats.overallRank;
|
||||
} else {
|
||||
const indexInGlobal = allRankings.findIndex(
|
||||
(stat) => stat.driverId === stats.driverId,
|
||||
);
|
||||
if (indexInGlobal !== -1) {
|
||||
rank = indexInGlobal + 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (rating === null) {
|
||||
const globalEntry = allRankings.find(
|
||||
(stat) => stat.driverId === stats.driverId,
|
||||
);
|
||||
if (globalEntry) {
|
||||
rating = globalEntry.rating;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
driver: ownerDriver,
|
||||
rating,
|
||||
rank,
|
||||
};
|
||||
}, [ownerDriver]);
|
||||
|
||||
return (
|
||||
<div className="mb-8">
|
||||
@@ -36,6 +110,17 @@ export default function LeagueHeader({
|
||||
className="object-cover opacity-80"
|
||||
sizes="100vw"
|
||||
/>
|
||||
<div className="absolute left-6 bottom-4 flex items-center">
|
||||
<div className="h-16 w-16 rounded-full overflow-hidden border-2 border-charcoal-outline bg-deep-graphite/95 shadow-[0_0_18px_rgba(0,0,0,0.7)]">
|
||||
<Image
|
||||
src={logoUrl}
|
||||
alt={`${leagueName} logo`}
|
||||
width={64}
|
||||
height={64}
|
||||
className="w-full h-full object-cover"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -56,14 +141,27 @@ export default function LeagueHeader({
|
||||
<p className="text-gray-400 mb-2">{description}</p>
|
||||
)}
|
||||
|
||||
<div className="text-sm text-gray-400 mb-6">
|
||||
<span className="mr-2">Owner:</span>
|
||||
<Link
|
||||
href={`/drivers/${ownerId}?from=league&leagueId=${leagueId}`}
|
||||
className="text-primary-blue hover:underline"
|
||||
>
|
||||
{ownerName}
|
||||
</Link>
|
||||
<div className="mb-6 flex flex-col gap-2">
|
||||
<span className="text-sm text-gray-400">Owner</span>
|
||||
{ownerSummary ? (
|
||||
<div className="inline-flex items-center gap-3">
|
||||
<DriverSummaryPill
|
||||
driver={ownerSummary.driver}
|
||||
rating={ownerSummary.rating}
|
||||
rank={ownerSummary.rank}
|
||||
href={`/drivers/${ownerSummary.driver.id}?from=league&leagueId=${leagueId}`}
|
||||
/>
|
||||
</div>
|
||||
) : (
|
||||
<div className="text-sm text-gray-500">
|
||||
<Link
|
||||
href={`/drivers/${ownerId}?from=league&leagueId=${leagueId}`}
|
||||
className="text-primary-blue hover:underline"
|
||||
>
|
||||
{ownerName}
|
||||
</Link>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user