import { useState, useEffect } from 'react'; import { jobs } from '../utils/api'; import JobDetails from './JobDetails'; export default function JobList() { const [jobList, setJobList] = useState([]); const [loading, setLoading] = useState(true); const [selectedJob, setSelectedJob] = useState(null); useEffect(() => { loadJobs(); const interval = setInterval(loadJobs, 5000); return () => clearInterval(interval); }, []); const loadJobs = async () => { try { const data = await jobs.list(); setJobList(data); } catch (error) { console.error('Failed to load jobs:', error); } finally { setLoading(false); } }; const handleCancel = async (jobId) => { if (!confirm('Are you sure you want to cancel this job?')) return; try { await jobs.cancel(jobId); loadJobs(); } catch (error) { alert('Failed to cancel job: ' + error.message); } }; const handleDelete = async (jobId) => { if (!confirm('Are you sure you want to permanently delete this job? This action cannot be undone.')) return; try { await jobs.delete(jobId); loadJobs(); if (selectedJob && selectedJob.id === jobId) { setSelectedJob(null); } } catch (error) { alert('Failed to delete job: ' + error.message); } }; const getStatusColor = (status) => { const colors = { pending: 'bg-yellow-400/20 text-yellow-400', running: 'bg-orange-400/20 text-orange-400', completed: 'bg-green-400/20 text-green-400', failed: 'bg-red-400/20 text-red-400', cancelled: 'bg-gray-500/20 text-gray-400', }; return colors[status] || colors.pending; }; if (loading) { return (
); } if (jobList.length === 0) { return (

No jobs yet. Submit a job to get started!

); } return ( <>
{jobList.map((job) => (

{job.name}

{job.status}

Frames: {job.frame_start} - {job.frame_end}

Format: {job.output_format}

Created: {new Date(job.created_at).toLocaleString()}

Progress {job.progress.toFixed(1)}%
{(job.status === 'pending' || job.status === 'running') && ( )} {(job.status === 'completed' || job.status === 'failed' || job.status === 'cancelled') && ( )}
))}
{selectedJob && ( setSelectedJob(null)} onUpdate={loadJobs} /> )} ); }