"use client"; import { useTranslations } from "next-intl"; import { useState } from "react"; import { Button } from "@/components/ui/button"; import { adminFetch } from "@/lib/admin-fetch"; export function NitroScale32Generator({ classname, disabled, onChanged, }: { classname: string; disabled: boolean; onChanged: (metadata: Record) => void; }) { const t = useTranslations("admin.studio.scale32"); const [preview, setPreview] = useState<{ hash: string; before: string; after: string; count: number; skipped?: number; } | null>(null), [undo, setUndo] = useState<{ hash: string; backupHash: string } | null>( null, ), [busy, setBusy] = useState(false), [error, setError] = useState(""); async function run(action: "preview" | "apply" | "restore") { setBusy(true); setError(""); try { const response = await adminFetch("/api/admin/studio/nitro-scale32", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ classname, action, expectedHash: action === "restore" ? undo?.hash : preview?.hash, backupHash: undo?.backupHash, }), }); const data = await response.json(); if (!response.ok) throw Error(data.error || t("generationFailed")); if (action === "preview") setPreview(data); else { setPreview(null); setUndo( action === "apply" ? { hash: data.hash, backupHash: data.backupHash } : null, ); onChanged(data.metadata); } } catch (e) { setError(e instanceof Error ? e.message : t("generationFailed")); } finally { setBusy(false); } } return (

{t("title")}

{t("intro")}

{disabled &&

{t("saveFirst")}

} {preview && ( <>

{t("previewCount", { count: preview.count })}

{preview.skipped ? (

{t("skipped", { count: preview.skipped })}

) : null}
{[ [t("original64"), preview.before], [t("derived32"), preview.after], ].map(([label, src]) => (
{label}
{label}
))}
)} {undo && (

{t("saved")}

)} {error && (

{error}

)}
); }