"use client";
import * as React from "react";
import { CheckCircle2, CircleSlash, Loader2, XCircle } from "lucide-react";
import type { Job } from "@/lib/api";
import { api } from "@/lib/api";
import { Sheet } from "@/components/ui/sheet";
import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
import { Progress } from "@/components/ui/progress";
import { useToast } from "@/components/toast";
/**
* Why a request is where it is.
*
* Previously a failure was a red word in a list plus a three-second toast, and
* the reason was raw text — "transfer Completed, Errored" — joined with a dot
* after the album name in 13px dim type. Since the backend now walks a ladder
* of candidates instead of giving up on the first peer, there is an actual
* story to tell: who was tried, what each one said, and what is left.
*/
export function JobSheet({
job,
onClose,
onChanged,
}: {
job: Job | null;
onClose: () => void;
onChanged: () => void;
}) {
const toast = useToast();
const [busy, setBusy] = React.useState(false);
const retry = async () => {
if (!job) return;
setBusy(true);
try {
await api.retry(job.id);
toast("Requeued");
onChanged();
onClose();
} catch (e) {
toast((e as Error).message, true);
}
setBusy(false);
};
const conf = job?.confidence;
return (
!v && onClose()}
title={job ? job.title : ""}
description={job ? [job.artist, job.album].filter(Boolean).join(" · ") : undefined}
footer={
job?.state === "failed" ? (
) : null
}
>
{job && (