harden media

This commit is contained in:
2025-12-31 15:39:28 +01:00
parent 92226800df
commit 8260bf7baf
413 changed files with 8361 additions and 1544 deletions

View File

@@ -14,7 +14,8 @@ import {
} from 'lucide-react';
import type { LeagueSummaryViewModel } from '@/lib/view-models/LeagueSummaryViewModel';
import { getLeagueCoverClasses } from '@/lib/leagueCovers';
import { useServices } from '@/lib/services/ServiceProvider';
import PlaceholderImage from '@/components/ui/PlaceholderImage';
import { getMediaUrl } from '@/lib/utilities/media';
interface LeagueCardProps {
league: LeagueSummaryViewModel;
@@ -114,9 +115,8 @@ function isNewLeague(createdAt: string | Date): boolean {
}
export default function LeagueCard({ league, onClick }: LeagueCardProps) {
const { mediaService } = useServices();
const coverUrl = mediaService.getLeagueCover(league.id);
const logoUrl = mediaService.getLeagueLogo(league.id);
const coverUrl = getMediaUrl('league-cover', league.id);
const logoUrl = league.logoUrl;
const ChampionshipIcon = getChampionshipIcon(league.scoring?.primaryChampionshipType);
const championshipLabel = getChampionshipLabel(league.scoring?.primaryChampionshipType);
@@ -190,15 +190,19 @@ export default function LeagueCard({ league, onClick }: LeagueCardProps) {
{/* Logo */}
<div className="absolute left-4 -bottom-6 z-10">
<div className="w-12 h-12 rounded-lg overflow-hidden border-2 border-iron-gray bg-deep-graphite shadow-xl">
<img
src={logoUrl}
alt={`${league.name} logo`}
width={48}
height={48}
className="h-full w-full object-cover"
loading="lazy"
decoding="async"
/>
{logoUrl ? (
<img
src={logoUrl}
alt={`${league.name} logo`}
width={48}
height={48}
className="h-full w-full object-cover"
loading="lazy"
decoding="async"
/>
) : (
<PlaceholderImage size={48} />
)}
</div>
</div>
</div>

View File

@@ -1,7 +1,7 @@
'use client';
import MembershipStatus from '@/components/leagues/MembershipStatus';
import { useServices } from '@/lib/services/ServiceProvider';
import { getMediaUrl } from '@/lib/utilities/media';
import Image from 'next/image';
@@ -28,8 +28,7 @@ export default function LeagueHeader({
ownerId,
mainSponsor,
}: LeagueHeaderProps) {
const { mediaService } = useServices();
const logoUrl = mediaService.getLeagueLogo(leagueId);
const logoUrl = getMediaUrl('league-logo', leagueId);
return (
<div className="mb-8">

View File

@@ -43,7 +43,7 @@ export default function LeagueMembers({
const byId: Record<string, DriverViewModel> = {};
for (const dto of driverDtos) {
byId[dto.id] = new DriverViewModel(dto);
byId[dto.id] = new DriverViewModel({ ...dto, avatarUrl: (dto as any).avatarUrl ?? null });
}
setDriversById(byId);
} else {

View File

@@ -48,6 +48,7 @@ export default function LeagueOwnershipTransfer({
driver={new DriverViewModel({
id: ownerSummary.driver.id,
name: ownerSummary.driver.name,
avatarUrl: (ownerSummary.driver as any).avatarUrl ?? null,
iracingId: ownerSummary.driver.iracingId,
country: ownerSummary.driver.country,
bio: ownerSummary.driver.bio,

View File

@@ -8,7 +8,8 @@ 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 { useServices } from '@/lib/services/ServiceProvider';
import { getMediaUrl } from '@/lib/utilities/media';
import PlaceholderImage from '@/components/ui/PlaceholderImage';
// Position background colors
const getPositionBgColor = (position: number): string => {
@@ -52,7 +53,6 @@ export default function StandingsTable({
onRemoveMember,
onUpdateRole
}: StandingsTableProps) {
const { mediaService } = useServices();
const [hoveredRow, setHoveredRow] = useState<string | null>(null);
const [activeMenu, setActiveMenu] = useState<{ driverId: string; type: 'member' | 'points' } | null>(null);
const menuRef = useRef<HTMLDivElement>(null);
@@ -320,16 +320,20 @@ export default function StandingsTable({
{/* Avatar */}
<div className="relative">
<div className="w-10 h-10 rounded-full bg-primary-blue/20 overflow-hidden flex items-center justify-center shrink-0">
{driver && (
<Image
src={mediaService.getDriverAvatar(driver.id)}
alt={driver.name}
width={40}
height={40}
className="w-full h-full object-cover"
/>
)}
</div>
{driver && (
driver.avatarUrl ? (
<Image
src={driver.avatarUrl}
alt={driver.name}
width={40}
height={40}
className="w-full h-full object-cover"
/>
) : (
<PlaceholderImage size={40} />
)
)}
</div>
{/* Nationality flag */}
{driver && driver.country && (
<div className="absolute -bottom-1 -right-1">