import type { MetadataBatchReportDto, MetadataRefreshReportDto, ReadingStatusMatchReportDto, ReadingStatusPushReportDto, DownloadDetectionReportDto } from "@/lib/api";
import type { TranslateFunction } from "@/lib/i18n/dictionaries";
interface JobSummaryBannerProps {
job: {
type: string;
status: string;
started_at: string | null;
finished_at: string | null;
error_opt: string | null;
stats_json: {
scanned_files: number;
indexed_files: number;
removed_files: number;
errors: number;
warnings: number;
} | null;
total_files: number | null;
processed_files: number | null;
};
batchReport: MetadataBatchReportDto | null;
refreshReport: MetadataRefreshReportDto | null;
readingStatusReport: ReadingStatusMatchReportDto | null;
readingStatusPushReport: ReadingStatusPushReportDto | null;
downloadDetectionReport: DownloadDetectionReportDto | null;
t: TranslateFunction;
formatDuration: (start: string, end: string | null) => string;
}
export function JobSummaryBanner({
job, batchReport, refreshReport, readingStatusReport, readingStatusPushReport, downloadDetectionReport, t, formatDuration,
}: JobSummaryBannerProps) {
const isCompleted = job.status === "success";
const isFailed = job.status === "failed";
const isCancelled = job.status === "cancelled";
const isMetadataBatch = job.type === "metadata_batch";
const isMetadataRefresh = job.type === "metadata_refresh";
const isReadingStatusMatch = job.type === "reading_status_match";
const isReadingStatusPush = job.type === "reading_status_push";
const isDownloadDetection = job.type === "download_detection";
const isThumbnailOnly = job.type === "thumbnail_rebuild" || job.type === "thumbnail_regenerate";
if (isCompleted && job.started_at) {
return (
{t("jobDetail.completedIn", { duration: formatDuration(job.started_at, job.finished_at) })}
{isMetadataBatch && batchReport && (
— {batchReport.auto_matched} {t("jobDetail.autoMatched").toLowerCase()}, {batchReport.already_linked} {t("jobDetail.alreadyLinked").toLowerCase()}, {batchReport.no_results} {t("jobDetail.noResults").toLowerCase()}, {batchReport.errors} {t("jobDetail.errors").toLowerCase()}
)}
{isMetadataRefresh && refreshReport && (
— {refreshReport.refreshed} {t("jobDetail.refreshed").toLowerCase()}, {refreshReport.unchanged} {t("jobDetail.unchanged").toLowerCase()}, {refreshReport.errors} {t("jobDetail.errors").toLowerCase()}
)}
{isReadingStatusMatch && readingStatusReport && (
— {readingStatusReport.linked} {t("jobDetail.linked").toLowerCase()}, {readingStatusReport.no_results} {t("jobDetail.noResults").toLowerCase()}, {readingStatusReport.ambiguous} {t("jobDetail.ambiguous").toLowerCase()}, {readingStatusReport.errors} {t("jobDetail.errors").toLowerCase()}
)}
{isReadingStatusPush && readingStatusPushReport && (
— {readingStatusPushReport.pushed} {t("jobDetail.pushed").toLowerCase()}, {readingStatusPushReport.no_books} {t("jobDetail.noBooks").toLowerCase()}, {readingStatusPushReport.errors} {t("jobDetail.errors").toLowerCase()}
)}
{isDownloadDetection && downloadDetectionReport && (
— {downloadDetectionReport.found} {t("jobDetail.downloadFound").toLowerCase()}, {downloadDetectionReport.not_found} {t("jobDetail.downloadNotFound").toLowerCase()}, {downloadDetectionReport.errors} {t("jobDetail.errors").toLowerCase()}
)}
{!isMetadataBatch && !isMetadataRefresh && !isReadingStatusMatch && !isReadingStatusPush && !isDownloadDetection && job.stats_json && (
— {job.stats_json.scanned_files} {t("jobDetail.scanned").toLowerCase()}, {job.stats_json.indexed_files} {t("jobDetail.indexed").toLowerCase()}
{job.stats_json.removed_files > 0 && `, ${job.stats_json.removed_files} ${t("jobDetail.removed").toLowerCase()}`}
{(job.stats_json.warnings ?? 0) > 0 && `, ${job.stats_json.warnings} ${t("jobDetail.warnings").toLowerCase()}`}
{job.stats_json.errors > 0 && `, ${job.stats_json.errors} ${t("jobDetail.errors").toLowerCase()}`}
{job.total_files != null && job.total_files > 0 && `, ${job.total_files} ${t("jobType.thumbnail_rebuild").toLowerCase()}`}
)}
{!isMetadataBatch && !isMetadataRefresh && !isReadingStatusMatch && !isReadingStatusPush && !job.stats_json && isThumbnailOnly && job.total_files != null && (
— {job.processed_files ?? job.total_files} {t("jobDetail.generated").toLowerCase()}
)}
);
}
if (isFailed) {
return (
{t("jobDetail.jobFailed")}
{job.started_at && (
{t("jobDetail.failedAfter", { duration: formatDuration(job.started_at, job.finished_at) })}
)}
{job.error_opt && (
{job.error_opt}
)}
);
}
if (isCancelled) {
return (
{t("jobDetail.cancelled")}
{job.started_at && (
{t("jobDetail.failedAfter", { duration: formatDuration(job.started_at, job.finished_at) })}
)}
);
}
return null;
}