ledgerone_frontend/components/export-download-button.tsx
2026-02-24 21:47:18 +00:00

57 lines
1.6 KiB
TypeScript

"use client";
import { useState } from "react";
type ApiResponse<T> = {
data: T;
meta: { timestamp: string; version: "v1" };
error: null | { message: string; code?: string };
};
type ExportData = { status?: string; url?: string; csv?: string };
async function getJson<T>(path: string) {
const res = await fetch(path);
if (!res.ok) {
throw new Error("Request failed");
}
const payload = (await res.json()) as ApiResponse<T>;
return payload.data;
}
export function ExportDownloadButton() {
const [status, setStatus] = useState<string>("");
const onDownload = async () => {
setStatus("Building export...");
try {
const userId = localStorage.getItem("ledgerone_user_id");
const query = userId ? `?user_id=${encodeURIComponent(userId)}` : "";
const data = await getJson<ExportData>(`/api/exports/csv${query}`);
if (data.csv) {
const blob = new Blob([data.csv], { type: "text/csv" });
const url = URL.createObjectURL(blob);
window.open(url, "_blank", "noopener,noreferrer");
setStatus("Download opened.");
} else {
setStatus("Export ready.");
}
} catch {
setStatus("Unable to download export.");
}
};
return (
<div className="space-y-2">
<button
type="button"
onClick={onDownload}
className="w-full rounded-xl bg-ink px-4 py-2 text-sm font-semibold text-haze"
>
Download export
</button>
{status ? <p className="text-xs text-muted">{status}</p> : null}
</div>
);
}