import { useEffect, useState } from "react"; import { useParams, Link, useNavigate } from "react-router-dom"; import { getProject, deleteProject, listTrackers, listProcessedTickets } from "../../lib/api"; import type { Project, WatchedTracker, ProcessedTicket } from "../../lib/types"; import TrackerList from "../trackers/TrackerList"; export default function ProjectDashboard() { const { projectId } = useParams(); const navigate = useNavigate(); const [project, setProject] = useState(null); const [trackers, setTrackers] = useState([]); const [tickets, setTickets] = useState([]); async function loadData() { if (!projectId) return; const [proj, trks, tkts] = await Promise.all([ getProject(projectId), listTrackers(projectId), listProcessedTickets(projectId), ]); setProject(proj); setTrackers(trks); setTickets(tkts); } useEffect(() => { loadData(); }, [projectId]); async function handleDelete() { if (!projectId) return; if (!window.confirm(`Delete project "${project?.name}"?`)) return; await deleteProject(projectId); window.dispatchEvent(new Event("orchai:refresh-projects")); navigate("/"); } function statusBadgeClass(status: string): string { switch (status) { case "Pending": return "bg-yellow-100 text-yellow-700"; case "Done": return "bg-green-100 text-green-700"; case "Error": return "bg-red-100 text-red-700"; default: return "bg-blue-100 text-blue-700"; } } if (!project) { return
Loading...
; } const recentTickets = tickets.slice(-10).reverse(); return (

{project.name}

Edit
Path: {project.path}
{project.cloned_from && (
Cloned from: {project.cloned_from}
)}
Base branch: {project.base_branch}
Created: {new Date(project.created_at).toLocaleDateString()}

Watched Trackers

Recent Tickets

{recentTickets.length === 0 ? (
No tickets processed yet.
) : (
{recentTickets.map((ticket) => (
#{ticket.artifact_id} {ticket.artifact_title}
{ticket.status}
))}
)}
); }