108 lines
3.1 KiB
TypeScript
108 lines
3.1 KiB
TypeScript
'use client';
|
||
|
||
import MembershipStatus from '@/components/leagues/MembershipStatus';
|
||
import Image from 'next/image';
|
||
import { useEffect, useState } from 'react';
|
||
|
||
import type { DriverDTO } from '@core/racing/application/dto/DriverDTO';
|
||
import { EntityMappers } from '@core/racing/application/mappers/EntityMappers';
|
||
|
||
// TODO EntityMapper is legacy. Must use ´useServices` hook.
|
||
|
||
// Main sponsor info for "by XYZ" display
|
||
interface MainSponsorInfo {
|
||
name: string;
|
||
logoUrl?: string;
|
||
websiteUrl?: string;
|
||
}
|
||
|
||
export interface LeagueHeaderProps {
|
||
leagueId: string;
|
||
leagueName: string;
|
||
description?: string | null;
|
||
ownerId: string;
|
||
ownerName: string;
|
||
mainSponsor?: MainSponsorInfo | null;
|
||
}
|
||
|
||
export default function LeagueHeader({
|
||
leagueId,
|
||
leagueName,
|
||
description,
|
||
ownerId,
|
||
mainSponsor,
|
||
}: LeagueHeaderProps) {
|
||
const imageService = getImageService();
|
||
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]);
|
||
|
||
|
||
return (
|
||
<div className="mb-8">
|
||
{/* League header with logo - no cover image */}
|
||
<div className="flex items-center justify-between mb-6">
|
||
<div className="flex items-center gap-4">
|
||
<div className="h-16 w-16 rounded-xl overflow-hidden border-2 border-charcoal-outline bg-iron-gray shadow-lg">
|
||
<Image
|
||
src={logoUrl}
|
||
alt={`${leagueName} logo`}
|
||
width={64}
|
||
height={64}
|
||
className="w-full h-full object-cover"
|
||
/>
|
||
</div>
|
||
<div>
|
||
<div className="flex items-center gap-3 mb-1">
|
||
<h1 className="text-2xl font-bold text-white">
|
||
{leagueName}
|
||
{mainSponsor && (
|
||
<span className="text-gray-400 font-normal text-lg ml-2">
|
||
by{' '}
|
||
{mainSponsor.websiteUrl ? (
|
||
<a
|
||
href={mainSponsor.websiteUrl}
|
||
target="_blank"
|
||
rel="noreferrer"
|
||
className="text-primary-blue hover:text-primary-blue/80 transition-colors"
|
||
>
|
||
{mainSponsor.name}
|
||
</a>
|
||
) : (
|
||
<span className="text-primary-blue">{mainSponsor.name}</span>
|
||
)}
|
||
</span>
|
||
)}
|
||
</h1>
|
||
<MembershipStatus leagueId={leagueId} />
|
||
</div>
|
||
{description && (
|
||
<p className="text-gray-400 text-sm max-w-xl">{description}</p>
|
||
)}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
);
|
||
} |