import { useState, useEffect } from 'react' import axios from 'axios' import { BookOpen, Music, Film, AlertCircle, CheckCircle, Search, Loader2 } from 'lucide-react' import type { LucideIcon } from 'lucide-react' import { useDarkMode } from '../context/ThemeContext' interface Metadata { type: 'movie' | 'tv' | 'music' | 'unknown' id: number title: string year?: number overview?: string poster_path?: string backdrop_path?: string runtime?: number genres?: string[] } interface Track { track_number: number title: string duration?: number } interface PrescanResult { disc_type: 'cd' | 'dvd' | 'bluray' title: string year?: number confidence: number metadata?: Metadata tracks?: Track[] } const API_URL = 'http://localhost:8000' export default function MetadataPreview() { const [device, setDevice] = useState('') const [result, setResult] = useState(null) const [loading, setLoading] = useState(false) const [error, setError] = useState(null) const [confirming, setConfirming] = useState(false) const { theme } = useDarkMode() const handleScan = async () => { if (!device) { setError('Bitte wählen Sie ein Gerät aus.') return } setLoading(true) setError(null) try { const response = await axios.post(`${API_URL}/prescan`, { device_path: device }) setResult(response.data) } catch (err) { setError('Pre-Scan fehlgeschlagen.') } finally { setLoading(false) } } const handleConfirm = async () => { if (!result) return setConfirming(true) try { await axios.post(`${API_URL}/metadata/confirm`, { title: result.title, year: result.year, metadata: result.metadata }) // Job erstellen await axios.post(`${API_URL}/jobs`, { device: device, type: result.disc_type }) } catch (err) { setError('Bestätigung fehlgeschlagen.') } finally { setConfirming(false) } } const getIcon = (type: string): LucideIcon => { switch (type) { case 'cd': return Music case 'dvd': case 'bluray': return Film default: return BookOpen } } const getConfidenceColor = (confidence: number): string => { if (confidence >= 0.9) return 'text-green-600 bg-green-100' if (confidence >= 0.7) return 'text-yellow-600 bg-yellow-100' return 'text-red-600 bg-red-100' } return (

Metadaten-Preview

Wählen Sie ein Gerät aus, um die Metadaten vor dem Ripping zu lookupen

{/* Device Selection */}
{error && (
{error}
)} {/* Results */} {result && (
{/* Header */}
{getIcon(result.disc_type)({ size: 32 })} {result.disc_type.toUpperCase()}

{result.title}

{result.year && (

{result.year}

)}
{/* Confidence Score */}
Übereinstimmung: {Math.round(result.confidence * 100)}%
{/* Metadata */}
{result.metadata && (
{result.metadata.overview && (

Beschreibung

{result.metadata.overview}

)} {result.metadata.genres && (

Genre

{result.metadata.genres.map((genre, index) => ( {genre} ))}
)} {result.metadata.runtime && (

Laufzeit

{Math.floor(result.metadata.runtime / 60)}h {result.metadata.runtime % 60}m

)}
)} {/* Tracks */} {result.tracks && result.tracks.length > 0 && (

Tracks

{result.tracks.map((track, index) => (
{track.track_number} {track.title}
{track.duration && ( {Math.floor(track.duration / 60)}:{String(track.duration % 60).padStart(2, '0')} )}
))}
)}
{/* Action */}
Bereit zum Ripping
)}
) }