feat(ui): SoC Refactoring & Config Validation

- Theme Context ausgelagert (ThemeContext.tsx + useDarkMode.ts)
- Config Validation mit TMDB-API-Key Pflicht (config_validation.py)
- Cache Key Centralization (cache/keys.py)
- CD-Ripping mit abcde implementiert (Worker)
- Docker Compose mit Healthchecks & LOG_LEVEL
- ROADMAP.md & SAVEPOINT.md aktualisiert
This commit is contained in:
Hitonabi
2026-07-22 16:38:19 +02:00
parent e710151c91
commit 95c1f9b105
18 changed files with 406 additions and 104 deletions
+20 -19
View File
@@ -1,6 +1,7 @@
import { useEffect, useState } from 'react'
import axios from 'axios'
import { Clock, Activity, HardDrive, BarChart, AlertCircle, CheckCircle, Disc, Play, Pause, SkipForward } from 'lucide-react'
import { useDarkMode } from '../context/ThemeContext'
interface Job {
id: string
@@ -41,8 +42,9 @@ async function fetchDevices(): Promise<Device[]> {
}
}
function StatusBadge({ status, darkMode }: { status: string, darkMode?: boolean }) {
const styles = darkMode
function StatusBadge({ status }: { status: string }) {
const { theme } = useDarkMode()
const styles = theme === 'dark'
? {
pending: 'bg-amber-900/30 text-amber-400 ring-amber-700/20',
processing: 'bg-blue-900/30 text-blue-400 ring-blue-700/20',
@@ -70,8 +72,9 @@ function StatusBadge({ status, darkMode }: { status: string, darkMode?: boolean
)
}
function TypeBadge({ type, darkMode }: { type: string, darkMode?: boolean }) {
const colors = darkMode
function TypeBadge({ type }: { type: string }) {
const { theme } = useDarkMode()
const colors = theme === 'dark'
? 'bg-slate-800 text-slate-300'
: 'bg-slate-100 text-slate-700'
@@ -89,8 +92,9 @@ function TypeBadge({ type, darkMode }: { type: string, darkMode?: boolean }) {
)
}
function ProgressBar({ progress, darkMode }: { progress: number, darkMode?: boolean }) {
const bgColors = darkMode
function ProgressBar({ progress }: { progress: number }) {
const { theme } = useDarkMode()
const bgColors = theme === 'dark'
? {
empty: 'bg-slate-700',
indicator: 'bg-gradient-to-r from-indigo-500 to-purple-600',
@@ -102,7 +106,7 @@ function ProgressBar({ progress, darkMode }: { progress: number, darkMode?: bool
done: 'bg-emerald-500',
}
const textColors = darkMode
const textColors = theme === 'dark'
? {
label: 'text-slate-400',
value: 'text-slate-200',
@@ -134,11 +138,7 @@ export default function Dashboard() {
const [jobs, setJobs] = useState<Job[]>([])
const [devices, setDevices] = useState<Device[]>([])
const [loading, setLoading] = useState(true)
const [darkMode, setDarkMode] = useState(false)
useEffect(() => {
const savedTheme = localStorage.getItem('theme')
setDarkMode(savedTheme === 'dark')
const { theme } = useDarkMode()
const loadData = async () => {
try {
@@ -188,28 +188,28 @@ export default function Dashboard() {
label="Warteschlange"
value={stats.pending.toString()}
color="amber"
darkMode={darkMode}
darkMode={theme === 'dark'}
/>
<StatCard
icon={Activity}
label="Bearbeitung"
value={stats.processing.toString()}
color="blue"
darkMode={darkMode}
darkMode={theme === 'dark'}
/>
<StatCard
icon={CheckCircle}
label="Fertig"
value={stats.completed.toString()}
color="emerald"
darkMode={darkMode}
darkMode={theme === 'dark'}
/>
<StatCard
icon={AlertCircle}
label="Fehler"
value={stats.failed.toString()}
color="rose"
darkMode={darkMode}
darkMode={theme === 'dark'}
/>
</div>
@@ -275,7 +275,7 @@ export default function Dashboard() {
<p className="text-xs text-slate-500 font-mono">{device.path}</p>
</div>
</div>
<TypeBadge type={device.type} darkMode={darkMode} />
<TypeBadge type={device.type} />
</div>
<div className="flex items-center justify-between mt-4">
@@ -337,13 +337,13 @@ export default function Dashboard() {
</div>
</td>
<td className="px-6 py-4 whitespace-nowrap">
<StatusBadge status={job.status} darkMode={darkMode} />
<StatusBadge status={job.status} />
</td>
<td className="px-6 py-4 whitespace-nowrap text-sm text-slate-500">
{job.device}
</td>
<td className="px-6 py-4 whitespace-nowrap">
<ProgressBar progress={job.progress} darkMode={darkMode} />
<ProgressBar progress={job.progress} />
</td>
<td className="px-6 py-4 whitespace-nowrap text-sm text-slate-500">
{new Date(job.startTime).toLocaleString('de-DE')}
@@ -360,6 +360,7 @@ export default function Dashboard() {
}
function StatCard({ icon: Icon, label, value, color, darkMode }: { icon: any, label: string, value: string, color: string, darkMode: boolean }) {
const { theme } = useDarkMode()
const bgColors = darkMode
? {
card: 'bg-slate-800 border-slate-700',