UI: echter Build hinter nginx, relative API-Pfade, Logs-Seite ehrlich

Vorher lief der Vite-ENTWICKLUNGSSERVER als Produktion, und vier Dateien
riefen hartkodiert http://localhost:8000 auf — vom PC aus fragte der Browser
damit den PC selbst nach Laufwerken (deshalb blieb das UI immer leer);
Settings nutzte ein nie gesetztes VITE_API_URL. Die Logs-Seite zeigte fest
einprogrammierte Fantasie-Einträge ("The Matrix gerippt").

- lib/api.ts: axios-Instanz mit baseURL /api; nginx proxied /api → api:8000
  (ein Origin, kein CORS), SSE-tauglich (proxy_buffering off)
- Dockerfile: Vite-Build → nginx:alpine statt npm run dev
- Logs + LiveLog von echtem /logs-Endpoint; MetadataPreview: echte Laufwerke
  aus /devices statt erfundener /dev/bluray-Optionen, startet echten Job

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Hitonabi
2026-07-23 15:02:39 +02:00
parent eee3a83d0e
commit f2da1ad525
8 changed files with 111 additions and 61 deletions
+2 -4
View File
@@ -1,6 +1,6 @@
import { useState, useEffect } from 'react'
import axios from 'axios'
import { HardDrive, Disc, AlertCircle, CheckCircle, RefreshCw } from 'lucide-react'
import { api } from '../lib/api'
import { useDarkMode } from '../context/ThemeContext'
interface Device {
@@ -13,8 +13,6 @@ interface Device {
model?: string
}
const API_URL = 'http://localhost:8000'
export default function DeviceDiscovery() {
const [devices, setDevices] = useState<Device[]>([])
const [loading, setLoading] = useState(true)
@@ -22,7 +20,7 @@ export default function DeviceDiscovery() {
const refreshDevices = async () => {
try {
const response = await axios.get(`${API_URL}/devices`)
const response = await api.get('/devices')
setDevices(response.data)
} catch (error) {
console.error('Fehler beim Laden der Geräte:', error)
+16 -10
View File
@@ -1,6 +1,6 @@
import { useState, useEffect } from 'react'
import axios from 'axios'
import { Terminal, Disc, Play, CheckCircle, AlertCircle, Clock, Download } from 'lucide-react'
import { Terminal, Play, CheckCircle, AlertCircle } from 'lucide-react'
import { api } from '../lib/api'
import { useDarkMode } from '../context/ThemeContext'
interface LiveLogEntry {
@@ -16,12 +16,10 @@ export default function LiveLogSection() {
const [currentJob, setCurrentJob] = useState<any>(null)
const { theme } = useDarkMode()
const API_URL = 'http://localhost:8000'
useEffect(() => {
const fetchJobs = async () => {
try {
const response = await axios.get(`${API_URL}/jobs`)
const response = await api.get('/jobs')
const jobs = response.data
const current = jobs.find((j: any) => j.status === 'processing')
setCurrentJob(current || jobs.find((j: any) => j.status === 'pending'))
@@ -30,15 +28,23 @@ export default function LiveLogSection() {
}
}
fetchJobs()
const jobInterval = setInterval(fetchJobs, 5000)
const fetchLogs = async () => {
try {
const response = await api.get('/logs', { params: { limit: 50 } })
setLogs(response.data)
} catch (error) {
console.error('Fehler beim Laden der Logs:', error)
}
}
// TODO: WebSocket/SSE für Echtzeit-Logs implementieren
// const logInterval = setInterval(fetchLogs, 1000)
fetchJobs()
fetchLogs()
const jobInterval = setInterval(fetchJobs, 5000)
const logInterval = setInterval(fetchLogs, 5000)
return () => {
clearInterval(jobInterval)
// clearInterval(logInterval)
clearInterval(logInterval)
}
}, [])