import { Card, CardHeader, CardTitle, CardDescription, CardContent, StatBox, ProgressBar } from "@/app/components/ui"; import type { TranslateFunction } from "@/lib/i18n/dictionaries"; interface JobProgressCardProps { job: { type: string; status: string; started_at: string | null; finished_at: string | null; total_files: number | null; processed_files: number | null; progress_percent: number | null; current_file: string | null; stats_json: { scanned_files: number; indexed_files: number; removed_files: number; errors: number; warnings: number; } | null; }; isThumbnailOnly: boolean; progressTitle: string; progressDescription: string | undefined; t: TranslateFunction; formatDuration: (start: string, end: string | null) => string; formatSpeed: (count: number, durationMs: number) => string; } export function JobProgressCard({ job, isThumbnailOnly, progressTitle, progressDescription, t }: JobProgressCardProps) { const isCompleted = job.status === "success"; const isPhase2 = job.status === "extracting_pages" || job.status === "generating_thumbnails"; const showProgressCard = (isCompleted || job.status === "failed" || job.status === "running" || isPhase2) && (job.total_files != null || !!job.current_file); if (!showProgressCard) return null; return ( {progressTitle} {progressDescription && {progressDescription}} {job.total_files != null && job.total_files > 0 && ( <> > )} {job.current_file && ( {t("jobDetail.currentFile")} {job.current_file} )} ); } export function IndexStatsCard({ job, t, formatDuration, formatSpeed, durationMs }: { job: JobProgressCardProps["job"]; t: TranslateFunction; formatDuration: (start: string, end: string | null) => string; formatSpeed: (count: number, durationMs: number) => string; durationMs: number; }) { if (!job.stats_json) return null; const speedCount = job.stats_json.scanned_files; return ( {t("jobDetail.indexStats")} {job.started_at && ( {formatDuration(job.started_at, job.finished_at)} {speedCount > 0 && ` · ${formatSpeed(speedCount, durationMs)} scan rate`} )} 0 ? "warning" : "default"} /> 0 ? "error" : "default"} /> ); } export function ThumbnailStatsCard({ job, t, formatDuration, formatSpeed, durationMs }: { job: JobProgressCardProps["job"]; t: TranslateFunction; formatDuration: (start: string, end: string | null) => string; formatSpeed: (count: number, durationMs: number) => string; durationMs: number; }) { if (job.total_files == null) return null; const speedCount = job.processed_files ?? 0; return ( {t("jobDetail.thumbnailStats")} {job.started_at && ( {formatDuration(job.started_at, job.finished_at)} {speedCount > 0 && ` · ${formatSpeed(speedCount, durationMs)} thumbnails/s`} )} ); }
{job.current_file}