"use client"; import { useI18n } from "@/components/I18nProvider"; import { useEffect, useState } from "react"; import { processingStage, type ProcessingJob, } from "@/shared/processing-progress"; const completionDeadlines = new Map(); export function ProcessingProgress({ job }: { job: ProcessingJob | null }) { const { t } = useI18n(); const [now, setNow] = useState(null); const [visibleCompletion, setVisibleCompletion] = useState( null, ); const complete = job?.kind === "map" && job.state === "complete"; const completionKey = complete ? `minegeo:map-refresh-notice:${job.id ?? job.updated_at}` : null; useEffect(() => { setVisibleCompletion(null); if (!completionKey) return; let deadline = completionDeadlines.get(completionKey); try { const saved = Number(localStorage.getItem(completionKey)); if (Number.isFinite(saved) && saved > 0) deadline = saved; } catch { // Keep the same deadline during navigation if browser storage is blocked. } deadline ??= Date.now() + 10_000; completionDeadlines.set(completionKey, deadline); try { localStorage.setItem(completionKey, String(deadline)); } catch {} const remaining = deadline - Date.now(); if (remaining <= 0) return; setVisibleCompletion(completionKey); const timer = setTimeout(() => setVisibleCompletion(null), remaining); return () => clearTimeout(timer); }, [completionKey]); useEffect(() => { setNow(Date.now()); if (job?.state !== "running") return; const timer = setInterval(() => setNow(Date.now()), 5000); return () => clearInterval(timer); }, [job?.state]); if ( !job || (complete ? visibleCompletion !== completionKey : !["queued", "running"].includes(job.state)) ) return null; const progress = complete ? 100 : Math.max(0, Math.min(100, job.progress)); const stopped = now !== null && job.state === "running" && (!job.lease_until || Date.parse(job.lease_until) < now); return (

{complete ? `100% · ${t("Guessing map refreshed successfully")}` : job.state === "queued" ? t("Waiting for a processing worker") : `${progress}% · ${job.kind === "map" ? t("Refreshing guessing map") : t(processingStage(progress))}`}

{complete ? t("The updated guessing map is ready to preview.") : stopped ? t( "The worker has stopped reporting. Check its terminal and restart it if necessary. Your uploaded export is saved.", ) : job.state === "running" ? t( "Worker connected. Large exports can take a while; progress measures completed work.", ) : t("Processing will start when a worker is available.")}

); }