import React, { useEffect, useState } from "react"; import { useNavigate } from "react-router"; interface Props { ticker: string; } export default function JobHistory({ ticker }: Props) { const [jobs, setJobs] = useState([]); const [loading, setLoading] = useState(false); const [selected, setSelected] = useState(null); const fetchJobs = async () => { setLoading(true); try { const res = await fetch(`/api/jobs?ticker=${encodeURIComponent(ticker)}`); if (!res.ok) { setJobs([]); } else { const data = await res.json(); setJobs(data.jobs || []); } } catch (e) { console.warn("Failed to fetch jobs:", e); setJobs([]); } finally { setLoading(false); } }; useEffect(() => { fetchJobs(); const id = setInterval(fetchJobs, 8000); return () => clearInterval(id); // eslint-disable-next-line react-hooks/exhaustive-deps }, [ticker]); const fetchDetails = async (jobId: string) => { try { const res = await fetch(`/api/jobs/${jobId}`); if (!res.ok) { setSelected({ id: jobId, error: true }); return; } const data = await res.json(); setSelected(data); } catch (e) { console.warn("Failed to fetch job details:", e); setSelected({ id: jobId, error: true }); } }; return (

Job History

{loading ? "Loading..." : `${jobs.length} jobs`}
{jobs.length === 0 ? (

No recent jobs for {ticker}

) : ( jobs.map((j: any) => (
Job: {j.id}
State: {j.state}
API
{selected?.id === j.id && (
{JSON.stringify(selected, null, 2)}
)}
)) )}
); }