import { useState } from "react"; import { FileCheck, FileWarning, HardDrive, Loader2, Server, } from "lucide-react"; import { DownloadStatus, DownloadTask, useSession } from "../../context/session-context"; import { formatBytes, formatSpeed } from "../../lib/utils"; import { Button } from "../ui/Button"; import { Card, CardContent } from "../ui/Card"; import { Progress } from "../ui/ProgressBar"; const API_URL = import.meta.env.VITE_API_URL || ""; const createdAtFormatter = new Intl.DateTimeFormat(undefined, { hour: "2-digit", minute: "2-digit", }); interface DownloadItemProps { item: DownloadTask; } const statusLabel: Record = { queued: "Queued", downloading: "Transferring", completed: "Ready", error: "Issue", }; function getDownloadErrorMessage(error: unknown): string { if (error instanceof Error && error.message) { return error.message; } return "Failed to download file."; } export function DownloadItem({ item }: DownloadItemProps) { const { sessionId } = useSession(); const [downloadError, setDownloadError] = useState(null); const [isSaving, setIsSaving] = useState(false); const isCompleted = item.status === "completed"; const isError = item.status === "error"; const isQueued = item.status === "queued"; const statusBadgeClass = isCompleted ? "border-emerald-400/20 bg-emerald-400/10 text-emerald-300" : isError ? "border-destructive/30 bg-destructive/10 text-destructive" : isQueued ? "border-amber-400/20 bg-amber-400/10 text-amber-300" : "border-primary/20 bg-primary/10 text-primary"; const statusDetail = isCompleted ? "File cached and ready to be saved locally." : isError ? "The transfer stopped before completion." : isQueued ? "Waiting for the server to start processing." : "Receiving data from the source URL."; const handleDownloadFile = async (): Promise => { try { setDownloadError(null); setIsSaving(true); const response = await fetch(`${API_URL}/api/download/${item.id}`, { headers: { "x-session-id": sessionId }, }); if (!response.ok) { throw new Error("Failed to fetch the stored file."); } const blob = await response.blob(); const url = window.URL.createObjectURL(blob); const anchor = document.createElement("a"); anchor.href = url; anchor.download = item.filename; document.body.appendChild(anchor); anchor.click(); window.URL.revokeObjectURL(url); document.body.removeChild(anchor); } catch (error: unknown) { setDownloadError(getDownloadErrorMessage(error)); } finally { setIsSaving(false); } }; return (
{isCompleted ? (
) : isError ? (
) : isQueued ? (
) : (
)}
{statusLabel[item.status]} Created at {createdAtFormatter.format(item.createdAt)}

{item.filename || item.url}

{item.url}

{isCompleted ? ( ) : null}

Status

{statusDetail}

Size

{item.totalBytes ? formatBytes(item.totalBytes) : "Unknown until available"}

Throughput

{item.speed ? formatSpeed(item.speed) : "Waiting for activity"}

{!isCompleted && !isError ? (
{isQueued ? "Waiting on server" : "Transfer progress"} {item.progress ? `${Math.round(item.progress)}%` : "0%"}
{formatBytes(item.receivedBytes || 0)} / {item.totalBytes ? formatBytes(item.totalBytes) : "Unknown"} {item.speed ? formatSpeed(item.speed) : "No transfer speed yet"}
) : null} {isCompleted ? (

Transfer completed successfully

The file is ready in the current session and can be saved to disk at any time before expiration.

) : null} {downloadError ? (

Unable to save file

{downloadError}

) : null} {isError ? (

Transfer failed

{item.error || "Unknown error occurred during the transfer."}

) : null}
); }