This commit is contained in:
Tomas Dvorak
2025-10-28 22:38:27 +01:00
parent 3d621e2187
commit 823fabee02
106 changed files with 9011 additions and 3930 deletions
+55 -7
View File
@@ -3,6 +3,34 @@ import { Image, ImageProps, Skeleton } from '@chakra-ui/react';
import { getTeamLogo } from '../../utils/sportLogosAPI';
import { getLogoStyle, getLogoClassName } from '../../utils/logoUtils';
import '../../styles/logos.css';
import { usePublicSettings } from '../../hooks/usePublicSettings';
import { assetUrl } from '../../utils/url';
// Lightweight cached overrides loader
let __teamOverridesCache: { ts: number; data: { by_id?: Record<string, { name?: string; logo_url?: string }>; by_name?: Record<string, string> } } | null = null;
const loadTeamOverrides = async (): Promise<{ by_id?: Record<string, { name?: string; logo_url?: string }>; by_name?: Record<string, string> }> => {
const now = Date.now();
if (__teamOverridesCache && now - __teamOverridesCache.ts < 60_000) {
return __teamOverridesCache.data || {};
}
try {
const res = await fetch(`/api/v1/public/team-logo-overrides?t=${now}`, { cache: 'no-cache' });
if (res.ok) {
const json = await res.json();
__teamOverridesCache = { ts: now, data: json || {} };
return json || {};
}
} catch {}
try {
const res2 = await fetch('/cache/prefetch/team_logo_overrides.json', { cache: 'no-cache' });
if (res2.ok) {
const json = await res2.json();
__teamOverridesCache = { ts: now, data: json || {} };
return json || {};
}
} catch {}
__teamOverridesCache = { ts: now, data: {} };
return {};
};
interface TeamLogoProps extends Omit<ImageProps, 'src'> {
teamId?: string;
@@ -32,6 +60,7 @@ export const TeamLogo: React.FC<TeamLogoProps> = ({
const [logoUrl, setLogoUrl] = useState<string | null>(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(false);
const { data: publicSettings } = usePublicSettings();
useEffect(() => {
let mounted = true;
@@ -40,11 +69,30 @@ export const TeamLogo: React.FC<TeamLogoProps> = ({
try {
setLoading(true);
setError(false);
const url = await getTeamLogo(teamId, teamName, facrLogo);
if (mounted) {
setLogoUrl(url);
// Load admin overrides (cached)
let overrides: { by_id?: Record<string, { name?: string; logo_url?: string }> } = {};
try { overrides = await loadTeamOverrides(); } catch {}
// Prefer local club logo for own team when IDs match
if (
teamId && publicSettings?.club_id && String(teamId) === String(publicSettings.club_id) && publicSettings?.club_logo_url
) {
if (mounted) {
setLogoUrl(assetUrl(publicSettings.club_logo_url) || publicSettings.club_logo_url);
}
} else if (teamId && overrides?.by_id?.[teamId]?.logo_url) {
const v = overrides.by_id[teamId]!.logo_url as string;
if (mounted) {
if (typeof v === 'string' && v.startsWith('/')) {
setLogoUrl(assetUrl(v) || v);
} else {
setLogoUrl(v);
}
}
} else {
const url = await getTeamLogo(teamId, teamName, facrLogo);
if (mounted) {
setLogoUrl(url);
}
}
} catch (e) {
console.error('Failed to fetch logo:', e);
@@ -65,7 +113,7 @@ export const TeamLogo: React.FC<TeamLogoProps> = ({
return () => {
mounted = false;
};
}, [teamId, teamName, facrLogo]);
}, [teamId, teamName, facrLogo, publicSettings?.club_id, publicSettings?.club_logo_url]);
// Size mapping
const sizeMap = {
@@ -101,7 +149,7 @@ export const TeamLogo: React.FC<TeamLogoProps> = ({
return (
<Image
src={logoUrl || '/logo192.png'}
src={(assetUrl(logoUrl || undefined) || logoUrl || '/logo192.png')}
alt={alt || teamName || 'Team logo'}
{...sizeProps}
{...imageProps}