1import React, { useEffect, useState } from "react";
2import { useSearchParams } from "react-router-dom";
3import { apiFetch } from '../lib/api';
4import "./DownloadStatusCard.css";
6export default function DownloadStatus() {
7 const [searchParams] = useSearchParams();
8 const jobId = searchParams.get("job"); // <-- FIXED
9 const os = searchParams.get("os");
10 const [status, setStatus] = useState(null);
11 const [filePath, setFilePath] = useState(null);
12 const [error, setError] = useState(null);
13 const [step, setStep] = useState(0);
15 // Poll backend for job status
18 setError("No job ID provided.");
22 let timer = setInterval(async () => {
24 const res = await api.get(`/builder/status/${jobId}`);
28 setStatus(res.status);
29 if (res.status === "queued") setStep(1);
30 if (res.status === "building") setStep(2);
31 if (res.status === "complete") setStep(3);
32 if (res.status === "failed") setStep(-1);
35 setFilePath(res.filePath);
38 if (res.status === "complete" && res.filePath) {
42 window.location.href = res.filePath;
45 if (res.status === "failed") {
47 setError("Build failed. Please try again.");
50 setError("Status check failed.");
55 return () => clearInterval(timer);
58 // Progress bar width by step
59 const progressWidth = step === 1 ? "33%" : step === 2 ? "66%" : step === 3 ? "100%" : "0%";
60 const statusText = step === 1 ? "Queued" : step === 2 ? "Building" : step === 3 ? "Ready" : step === -1 ? "Failed" : "Loading…";
63 <div className="download-status-page" style={{ display: "flex", justifyContent: "center", alignItems: "center", minHeight: "80vh" }}>
64 <div className="download-status-card">
65 <div className="download-status-title">Agent Installer Status</div>
66 <div className="download-status-progress">
67 <div className="download-status-bar" style={{ width: progressWidth }}></div>
69 <div className="download-status-step">{statusText}</div>
70 <div className="download-status-meta">
71 <span><b>Job ID:</b> {jobId}</span>
72 <span><b>Device:</b> {os ? os.toUpperCase() : "-"}</span>
74 {error && <div className="download-status-error">{error}</div>}
75 {step === 3 && filePath && (
76 <div className="download-status-ready">
77 <a className="download-status-btn" href={filePath} download>
80 <div style={{ marginTop: "0.5rem" }}>
81 <span>Installer is ready. If your download didn't start, click above.</span>
86 <div className="download-status-error">
87 Build failed. <button className="download-status-btn" onClick={() => window.location.reload()}>Retry</button>