diff --git a/frontend/src/admin.ts b/frontend/src/admin.ts index c5d9271..a623292 100644 --- a/frontend/src/admin.ts +++ b/frontend/src/admin.ts @@ -31,6 +31,7 @@ const adminConfig = { const MAX_UPLOAD_BYTES = 2 * 1024 * 1024 * 1024; const UPLOAD_CHUNK_BYTES = 8 * 1024 * 1024; const UPLOAD_RESUME_KEY_PREFIX = "linearvoid-upload-resume:"; +const API_URL = import.meta.env.VITE_PUBLIC_APP_URL?.trim() || window.location.origin; const state = { mediaUploading: false, @@ -131,7 +132,7 @@ const pageCache: Record = {}; async function loadPageContent(tabName: string): Promise { if (pageCache[tabName]) return pageCache[tabName]; - const response = await fetch(`/admin/${tabName}.html`); + const response = await fetch(`${API_URL}/admin/${tabName}.html`); if (!response.ok) throw new Error(`Failed to load page: ${tabName}`); const html = await response.text(); pageCache[tabName] = html; @@ -175,7 +176,7 @@ async function switchTab(tabName: string) { export async function refreshOverview() { try { - const response = await fetch("/api/admin/overview"); + const response = await fetch(`${API_URL}/api/admin/overview`); if (!response.ok) throw new Error(`HTTP ${response.status}`); const payload = await response.json(); @@ -202,7 +203,7 @@ export async function refreshOverview() { export async function refreshAnalytics() { setStatus("analytics-status", "Loading analytics..."); try { - const response = await fetch("/api/admin/analytics"); + const response = await fetch(`${API_URL}/api/admin/analytics`); if (!response.ok) throw new Error(`HTTP ${response.status}`); const payload = await response.json(); @@ -240,7 +241,7 @@ export async function refreshAnalytics() { async function refreshPlaylist() { setStatus("playlist-status", "Loading playlist..."); try { - const response = await fetch("/api/admin/playlist"); + const response = await fetch(`${API_URL}/api/admin/playlist`); if (!response.ok) throw new Error(`HTTP ${response.status}`); const payload = await response.json(); @@ -522,7 +523,7 @@ async function submitOverride(e: Event) { const endTime = (document.getElementById("override-end") as HTMLInputElement).value; const reason = (document.getElementById("override-reason") as HTMLInputElement).value; try { - const resp = await fetch("/api/admin/schedule/overrides", { + const resp = await fetch(`${API_URL}/api/admin/schedule/overrides`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ @@ -551,7 +552,7 @@ async function submitOverride(e: Event) { async function deleteOverride(id: number) { try { - await fetch(`/api/admin/schedule/overrides?id=${id}`, { method: "DELETE" }); + await fetch(`${API_URL}/api/admin/schedule/overrides?id=${id}`, { method: "DELETE" }); refreshOverrides(); } catch { /* ignore */ @@ -749,9 +750,12 @@ async function uploadVideo(file: File) { setStatus("media-status", `Uploading ${file.name} (${chunkIndex + 1}/${effectiveTotalChunks} chunks)...`); } - const completeResponse = await fetch(`/api/admin/media/uploads/${encodeURIComponent(uploadId)}/complete`, { - method: "POST", - }); + const completeResponse = await fetch( + `${API_URL}/api/admin/media/uploads/${encodeURIComponent(uploadId)}/complete`, + { + method: "POST", + }, + ); if (!completeResponse.ok) { throw new Error(await readErrorMessage(completeResponse)); @@ -791,7 +795,7 @@ async function editMedia(file: MediaEntry) { setStatus("media-status", `Saving metadata for ${file.name}...`); try { - const response = await fetch(`/api/admin/media/${file.id}`, { + const response = await fetch(`${API_URL}/api/admin/media/${file.id}`, { method: "PUT", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ title, status, tags }), @@ -816,7 +820,7 @@ async function normalizeMedia(file: MediaEntry) { setStatus("media-status", `Normalizing ${file.name}...`); try { - const response = await fetch(`/api/admin/media/${file.id}/normalize`, { method: "POST" }); + const response = await fetch(`${API_URL}/api/admin/media/${file.id}/normalize`, { method: "POST" }); if (!response.ok) throw new Error(await readErrorMessage(response)); setStatus("media-status", `Normalization started for ${file.name}.`); @@ -836,7 +840,7 @@ function pollNormalizationStatus(id: number, attempt: number) { } window.setTimeout(async () => { try { - const response = await fetch(`/api/admin/media/${id}`); + const response = await fetch(`${API_URL}/api/admin/media/${id}`); if (!response.ok) return; const file = (await response.json()) as MediaEntry; if (file.status === "normalizing" || file.status === "needs_normalization") { @@ -869,7 +873,7 @@ async function deleteMedia(file: MediaEntry) { setStatus("media-status", `Deleting ${file.name}...`); try { - const response = await fetch(`/api/admin/media/${file.id}`, { + const response = await fetch(`${API_URL}/api/admin/media/${file.id}`, { method: "DELETE", }); if (!response.ok) throw new Error(`HTTP ${response.status}`); @@ -887,7 +891,7 @@ async function deleteMedia(file: MediaEntry) { async function refreshModerationLogs() { setStatus("moderation-status", "Loading moderation logs..."); try { - const response = await fetch(`/api/admin/moderation/logs?limit=${adminConfig.moderationLogLimit}`); + const response = await fetch(`${API_URL}/api/admin/moderation/logs?limit=${adminConfig.moderationLogLimit}`); if (!response.ok) throw new Error(`HTTP ${response.status}`); const payload = await response.json(); @@ -988,7 +992,7 @@ async function refreshChatLog() { if (chatLogState.username) params.set("username", chatLogState.username); if (chatLogState.text) params.set("text", chatLogState.text); - const response = await fetch(`/api/admin/chat-log?${params}`); + const response = await fetch(`${API_URL}/api/admin/chat-log?${params}`); if (!response.ok) throw new Error(`HTTP ${response.status}`); const payload = await response.json(); @@ -1118,7 +1122,7 @@ async function deleteChatEntry(id: number) { setStatus("chat-log-status", `Deleting message #${id}...`); try { - const response = await fetch(`/api/admin/chat-log/${id}`, { + const response = await fetch(`${API_URL}/api/admin/chat-log/${id}`, { method: "DELETE", }); if (!response.ok) throw new Error(`HTTP ${response.status}`); @@ -1268,7 +1272,7 @@ async function restartService(service: string) { const status = document.getElementById("restart-status"); if (status) status.textContent = `Requesting restart of ${service}...`; try { - const resp = await fetch(`/api/admin/restart?service=${service}`, { method: "POST" }); + const resp = await fetch(`${API_URL}/api/admin/restart?service=${service}`, { method: "POST" }); const data = await resp.json(); if (status) status.textContent = data.message; } catch (err) {