import { useEffect, useState } from 'react' import axios from 'axios' import { Clock, Activity, HardDrive, BarChart, AlertCircle, CheckCircle } from 'lucide-react' import type { LucideIcon } from 'lucide-react' interface Job { id: string type: 'cd' | 'dvd' | 'bluray' status: 'pending' | 'processing' | 'completed' | 'failed' device: string startTime: string endTime?: string progress: number } interface Device { id: string name: string type: 'cd' | 'dvd' | 'bluray' path: string status: 'empty' | 'ready' | 'ripping' } const API_URL = 'http://localhost:8000' async function fetchJobs(): Promise { try { const response = await axios.get(`${API_URL}/jobs`) return response.data } catch { return [] } } async function fetchDevices(): Promise { try { const response = await axios.get(`${API_URL}/devices`) return response.data } catch { return [] } } function StatusBadge({ status }: { status: string }) { const styles = { pending: 'bg-yellow-100 text-yellow-800', processing: 'bg-blue-100 text-blue-800', completed: 'bg-green-100 text-green-800', failed: 'bg-red-100 text-red-800', } const labels = { pending: 'In Warteschlange', processing: 'In Bearbeitung', completed: 'Abgeschlossen', failed: 'Fehlgeschlagen', } return ( {labels[status as keyof typeof labels] || status} ) } function ProgressBar({ progress }: { progress: number }) { return (
) } export default function Dashboard() { const [jobs, setJobs] = useState([]) const [devices, setDevices] = useState([]) const [loading, setLoading] = useState(true) useEffect(() => { const loadData = async () => { try { const [jobsData, devicesData] = await Promise.all([ fetchJobs(), fetchDevices() ]) setJobs(jobsData) setDevices(devicesData) } finally { setLoading(false) } } loadData() const interval = setInterval(loadData, 5000) return () => clearInterval(interval) }, []) const stats = { pending: jobs.filter(j => j.status === 'pending').length, processing: jobs.filter(j => j.status === 'processing').length, completed: jobs.filter(j => j.status === 'completed').length, failed: jobs.filter(j => j.status === 'failed').length, } if (loading) { return (
) } return (

Dashboard

Übersicht über alle Ripping-Jobs und Geräte

{/* Stats Cards */}
{/* Devices */}

Geräte

{devices.length === 0 ? (
Keine Geräte gefunden
) : ( devices.map(device => (

{device.name}

{device.type}
{device.path}
{device.status === 'empty' ? 'Leer' : device.status === 'ready' ? 'Bereit' : 'Rippt'}
)) )}
{/* Recent Jobs */}

Neueste Jobs

{jobs.length === 0 ? ( ) : ( jobs.slice(0, 10).map(job => ( )) )}
Typ Status Gerät Fortschritt Startzeit
Keine Jobs vorhanden
{job.type} {job.device} {new Date(job.startTime).toLocaleString('de-DE')}
) } function StatCard({ icon: Icon, label, value, color }: { icon: LucideIcon, label: string, value: string, color: string }) { const colors = { yellow: 'bg-yellow-50 text-yellow-600', blue: 'bg-blue-50 text-blue-600', green: 'bg-green-50 text-green-600', red: 'bg-red-50 text-red-600', } return (

{label}

{value}

) }