hot fix #3 dev day #70

This commit is contained in:
Tomas Dvorak
2025-10-24 18:15:36 +02:00
parent 80f833b926
commit 36f0f454ce
42 changed files with 124 additions and 127 deletions
@@ -20,6 +20,7 @@ import { assetUrl } from '../../utils/url';
import { getPublicSettings } from '../../services/settings';
import { getZoneramaManifestWithFallbacks, getZoneramaAlbum, putZoneramaPick, saveAlbumToCache } from '../../services/zonerama';
import { facrApi } from '../../services/facr/facrApi';
import { API_URL } from '../../services/api';
import AlbumPhotoPicker from '../../components/admin/AlbumPhotoPicker';
import PollLinker from '../../components/admin/PollLinker';
import ThumbnailPreview from '../../components/common/ThumbnailPreview';
@@ -49,8 +50,7 @@ const MatchLinkBadge: React.FC<{ articleId: number }> = ({ articleId }) => {
retry: false,
queryFn: async () => {
try {
const apiUrl = process.env.REACT_APP_API_URL || 'http://localhost:8080/api/v1';
const origin = new URL(apiUrl).origin;
const origin = new URL(API_URL, typeof window !== 'undefined' ? window.location.origin : 'http://localhost:3000').origin;
const url = `${origin}/cache/prefetch/facr_club_info.json`;
const res = await fetch(url, { cache: 'no-cache' });
if (!res.ok) return null;
@@ -188,8 +188,7 @@ const ArticlesAdminPage = () => {
React.useEffect(() => {
(async () => {
try {
const apiUrl = process.env.REACT_APP_API_URL || 'http://localhost:8080/api/v1';
const origin = new URL(apiUrl).origin;
const origin = new URL(API_URL, typeof window !== 'undefined' ? window.location.origin : 'http://localhost:3000').origin;
const url = `${origin}/cache/prefetch/facr_club_info.json`;
const res = await fetch(url, { headers: { 'Cache-Control': 'no-cache' } });
if (!res.ok) return;
@@ -495,13 +494,12 @@ const ArticlesAdminPage = () => {
try {
setZLoading(true);
// Use correct API endpoint format based on album-api.md
const apiUrl = process.env.REACT_APP_API_URL || 'http://localhost:8080/api/v1';
const params = new URLSearchParams({
link: link,
photo_limit: '48',
rendered: 'true'
});
const res = await fetch(`${apiUrl}/zonerama-album?${params.toString()}`);
const res = await fetch(`${API_URL}/zonerama-album?${params.toString()}`);
if (!res.ok) throw new Error('Failed to fetch album');
const data = await res.json();
@@ -38,6 +38,7 @@ import {
} from '../../services/competitionAliases';
import AdminLayout from '../../layouts/AdminLayout';
import { PageHeader } from '../../components/admin/PageHeader';
import { API_URL } from '../../services/api';
const CompetitionAliasesAdminPage: React.FC = () => {
const cardBg = useColorModeValue('white', 'gray.800');
@@ -79,10 +80,8 @@ const CompetitionAliasesAdminPage: React.FC = () => {
try {
if (/^https?:\/\//i.test(path)) return path;
if (path.startsWith('/cache') || path.startsWith('/uploads')) {
const base = (process.env.REACT_APP_API_BASE_URL || process.env.REACT_APP_API_URL || 'http://localhost:8080/api/v1');
const u = new URL(base);
u.pathname = path;
return u.toString();
const origin = new URL(API_URL, typeof window !== 'undefined' ? window.location.origin : 'http://localhost:3000').origin;
return new URL(path, origin).toString();
}
return path;
} catch {
@@ -124,10 +123,8 @@ const CompetitionAliasesAdminPage: React.FC = () => {
try {
if (/^https?:\/\//i.test(path)) return path;
if (path.startsWith('/cache') || path.startsWith('/uploads')) {
const base = (process.env.REACT_APP_API_BASE_URL || process.env.REACT_APP_API_URL || 'http://localhost:8080/api/v1');
const u = new URL(base);
u.pathname = path;
return u.toString();
const origin = new URL(API_URL, typeof window !== 'undefined' ? window.location.origin : 'http://localhost:3000').origin;
return new URL(path, origin).toString();
}
return path;
} catch {
+2 -2
View File
@@ -63,6 +63,7 @@ import {
formatFileSize,
getFileIcon,
} from '../../services/files';
import { API_URL } from '../../services/api';
const FilesAdminPage: React.FC = () => {
const toast = useToast();
@@ -187,8 +188,7 @@ const FilesAdminPage: React.FC = () => {
const getImageUrl = (url: string) => {
if (url.startsWith('http')) return url;
const apiUrl = process.env.REACT_APP_API_URL || 'http://localhost:8080/api/v1';
const origin = new URL(apiUrl).origin;
const origin = new URL(API_URL, typeof window !== 'undefined' ? window.location.origin : 'http://localhost:3000').origin;
return `${origin}${url}`;
};
@@ -46,6 +46,7 @@ import { useSearchParams } from 'react-router-dom';
import { parse } from 'date-fns';
import { assetUrl } from '../../utils/url';
import { batchFetchLogosFromSportLogosAPI } from '../../utils/sportLogosAPI';
import { API_URL } from '../../services/api';
const MatchesAdminPage = () => {
const queryClient = useQueryClient();
@@ -155,8 +156,7 @@ const MatchesAdminPage = () => {
queryKey: ['admin-matches-list-cache'],
queryFn: async () => {
// Read cached FACR club info
const apiUrl = process.env.REACT_APP_API_URL || 'http://localhost:8080/api/v1';
const origin = new URL(apiUrl).origin;
const origin = new URL(API_URL, typeof window !== 'undefined' ? window.location.origin : 'http://localhost:3000').origin;
const url = `${origin}/cache/prefetch/facr_club_info.json`;
const res = await fetch(url, { headers: { 'Cache-Control': 'no-cache' } });
if (!res.ok) throw new Error(`Failed to load cache: ${res.status}`);
@@ -225,8 +225,7 @@ const MatchesAdminPage = () => {
const { data: facrClubInfo } = useQuery({
queryKey: ['facr-club-info-name'],
queryFn: async () => {
const apiUrl = process.env.REACT_APP_API_URL || 'http://localhost:8080/api/v1';
const origin = new URL(apiUrl).origin;
const origin = new URL(API_URL, typeof window !== 'undefined' ? window.location.origin : 'http://localhost:3000').origin;
const url = `${origin}/cache/prefetch/facr_club_info.json`;
const res = await fetch(url, { headers: { 'Cache-Control': 'no-cache' } });
if (!res.ok) return null;
@@ -42,6 +42,7 @@ import { Player, getPlayers, createPlayer, updatePlayer, deletePlayer } from '..
import { uploadFile } from '../../services/articles';
import { translateNationality } from '../../utils/nationality';
import ThumbnailPreview from '../../components/common/ThumbnailPreview';
import { API_URL } from '../../services/api';
type Editing = Partial<Player> & { id?: number };
@@ -55,8 +56,7 @@ const PlayersAdminPage: React.FC = () => {
// If it's already absolute, return as-is
if (/^https?:\/\//i.test(url)) return url;
// If it's an uploads path, prefix with API origin
const apiUrl = process.env.REACT_APP_API_URL || 'http://localhost:8080/api/v1';
const origin = new URL(apiUrl).origin;
const origin = new URL(API_URL, typeof window !== 'undefined' ? window.location.origin : 'http://localhost:3000').origin;
if (url.startsWith('/uploads/')) return `${origin}${url}`;
// Fallback: treat as relative to origin
return `${origin}${url.startsWith('/') ? '' : '/'}${url}`;
@@ -39,6 +39,7 @@ import { FiEdit2, FiPlus, FiTrash2, FiUpload, FiExternalLink } from 'react-icons
import AdminLayout from '../../layouts/AdminLayout';
import { Sponsor, getSponsors, createSponsor, updateSponsor, deleteSponsor } from '../../services/sponsors';
import { uploadFile } from '../../services/articles';
import { API_URL } from '../../services/api';
const SponsorsAdminPage: React.FC = () => {
const cardBg = useColorModeValue('white', 'gray.800');
@@ -47,8 +48,7 @@ const SponsorsAdminPage: React.FC = () => {
const normalizeImageUrl = (url?: string) => {
if (!url || url === '') return '/logo192.png';
if (/^https?:\/\//i.test(url)) return url;
const apiUrl = process.env.REACT_APP_API_URL || 'http://localhost:8080/api/v1';
const origin = new URL(apiUrl).origin;
const origin = new URL(API_URL, typeof window !== 'undefined' ? window.location.origin : 'http://localhost:3000').origin;
if (url.startsWith('/uploads/')) return `${origin}${url}`;
return `${origin}${url.startsWith('/') ? '' : '/'}${url}`;
};
@@ -4,6 +4,7 @@ import { useMemo, useState } from 'react';
import AdminLayout from '../../layouts/AdminLayout';
import { assetUrl } from '../../utils/url';
import { TeamLogo } from '../../components/common/TeamLogo';
import { API_URL } from '../../services/api';
type TableRow = {
rank?: string;
@@ -22,8 +23,7 @@ const StandingsAdminPage: React.FC = () => {
const { data, isLoading, error } = useQuery<any>({
queryKey: ['facr-tables-cache'],
queryFn: async () => {
const apiUrl = process.env.REACT_APP_API_URL || 'http://localhost:8080/api/v1';
const origin = new URL(apiUrl).origin;
const origin = new URL(API_URL, typeof window !== 'undefined' ? window.location.origin : 'http://localhost:3000').origin;
const url = `${origin}/cache/prefetch/facr_tables.json`;
const res = await fetch(url, { headers: { 'Cache-Control': 'no-cache' } });
if (!res.ok) throw new Error(`Failed to load cache: ${res.status}`);
+2 -2
View File
@@ -51,6 +51,7 @@ import { searchClubs, uploadImage, putTeamLogoOverride, fetchTeamLogoOverrides,
import { getFacrTablesCache } from '../../services/facr/cache';
import { assetUrl } from '../../utils/url';
import { useEffect, useMemo, useRef, useState } from 'react';
import { API_URL } from '../../services/api';
type TableRow = {
@@ -77,8 +78,7 @@ const TeamsAdminPage = () => {
const competitions: any[] = Array.isArray(data?.competitions) ? data!.competitions : [];
// Backend origin (used to resolve relative URLs like /uploads/...)
const apiUrl = process.env.REACT_APP_API_URL || 'http://localhost:8080/api/v1';
const backendOrigin = new URL(apiUrl).origin;
const backendOrigin = new URL(API_URL, typeof window !== 'undefined' ? window.location.origin : 'http://localhost:3000').origin;
// Load public/admin overrides map to apply on cache-fed view
const { data: overrides = {} } = useQuery({