Files
EpicNext-Cms/src/app/admin/studio/sync/catalog-export-client.tsx
T
Simo 9ec9ab31ad
CI / check (pull_request) Failing after 1m21s
CI / deploy (pull_request) Skipped
CI / e2e (pull_request) Skipped
feat: export Catalog Studio assets and SQL to catalog repository
2026-09-05 11:49:00 +02:00

103 lines
2.8 KiB
TypeScript

"use client";
import { useCallback, useEffect, useState } from "react";
import { adminFetch } from "@/lib/admin-fetch";
type ExportStatus = {
enabled: boolean;
pending: number;
active: number;
running?: boolean;
commit?: string;
finishedAt?: string;
error?: string;
};
export function CatalogExportClient() {
const [status, setStatus] = useState<ExportStatus | null>(null);
const [error, setError] = useState("");
const [busy, setBusy] = useState(false);
const refresh = useCallback(async () => {
try {
const response = await adminFetch("/api/admin/catalog-export", {
cache: "no-store",
});
if (!response.ok) throw new Error("Unable to load export status");
setStatus(await response.json());
setError("");
} catch {
setError("Unable to load export status");
}
}, []);
useEffect(() => {
void refresh();
const timer = setInterval(() => {
void refresh();
}, 15_000);
return () => clearInterval(timer);
}, [refresh]);
async function retry() {
setBusy(true);
try {
const response = await adminFetch("/api/admin/catalog-export", {
method: "POST",
});
if (!response.ok) throw new Error("Unable to queue export");
await refresh();
} catch {
setError("Unable to queue export");
} finally {
setBusy(false);
}
}
return (
<section className="space-y-3 rounded-lg border border-[var(--admin-border)] p-4">
<h2 className="text-lg font-semibold">Catalog repository export</h2>
<p className="text-sm text-muted-foreground">
Automatically publishes bundles, icons, gamedata, translations and
catalog SQL to Epicnabbo-Catalogus-Updated-Daily (Beta-3).
</p>
<div role="status" className="text-sm" aria-live="polite">
{!status
? "Loading…"
: !status.enabled
? "Not configured on this server."
: status.active
? `Waiting for ${status.active} operation(s) to finish.`
: status.running
? "Export in progress…"
: status.pending
? `${status.pending} update(s) queued for the worker.`
: "No pending updates."}
{status?.commit && (
<p>
Last published commit:{" "}
<a
className="underline"
href={`https://gitlab.epicnabbo.nl/remco/Epicnabbo-Catalogus-Updated-Daily/commit/${status.commit}`}
target="_blank"
rel="noreferrer"
>
{status.commit.slice(0, 12)}
</a>
</p>
)}
{status?.finishedAt && <p>Last attempt: {status.finishedAt}</p>}
</div>
{(error || status?.error) && (
<p role="alert" className="text-sm">
{error || status?.error}
</p>
)}
<button
type="button"
disabled={!status?.enabled || busy}
onClick={retry}
className="rounded-md border border-[var(--admin-border)] px-3 py-2 text-sm disabled:opacity-50"
>
{busy ? "Queuing…" : "Export now / retry"}
</button>
</section>
);
}