Files
EpicNext-Cms/src/components/admin/studio/use-studio-translations.ts
T
Simo 3ae4f21217
CI / check (push) Successful in 1m40s
CI / deploy (push) Successful in 1m26s
CI / e2e (push) Successful in 24s
refactor(catalog): separate Studio data hooks and presentation
2026-09-05 18:15:29 +02:00

97 lines
2.6 KiB
TypeScript

"use client";
import { useState } from "react";
import { toast } from "sonner";
import { setFurnidataTranslateEnabled } from "@/actions/import-furni";
import { adminFetch } from "@/lib/admin-fetch";
// Language codes that get a FurnitureData_<lang>.json file. Mirrors
// FURNIDATA_LANGUAGES in furni-data-i18n (kept client-safe here so we don't pull
// server-only fs modules into the browser bundle).
const TRANSLATE_LANGS = [
"nl",
"en",
"de",
"fr",
"es",
"tr",
"it",
"pt",
"fi",
"pl",
"ru",
"ar",
"ja",
] as const;
export function useStudioTranslations(defaultTranslate: boolean) {
// Translation controls (per-import toggle + language selection, plus a global
// default that persists to the site setting and seeds the per-import toggle).
const ALL_LANGS = TRANSLATE_LANGS as readonly string[];
const [translate, setTranslate] = useState<boolean>(defaultTranslate);
const [translateLangs, setTranslateLangs] = useState<string[]>([
...ALL_LANGS,
]);
const [langPickerOpen, setLangPickerOpen] = useState(false);
const [buildingLanguages, setBuildingLanguages] = useState(false);
const [globalTranslate, setGlobalTranslate] =
useState<boolean>(defaultTranslate);
// Build every language for the whole catalog at once (used to translate
// everything after importing with translation disabled for speed).
const buildAllLanguages = async () => {
setBuildingLanguages(true);
try {
const res = await adminFetch(
"/api/admin/import/furni?action=build-languages",
);
const data = (await res.json()) as {
languages?: Array<{ lang: string; ok: boolean }>;
error?: string;
};
if (res.ok) {
const langs = data.languages ?? [];
const okCount = langs.filter((l) => l.ok).length;
toast.success(
`Languages translated (${okCount}/${langs.length} completed)`,
);
} else {
toast.error(data.error ?? "Translation failed");
}
} catch {
toast.error("Network error while translating languages");
} finally {
setBuildingLanguages(false);
}
};
const toggleLang = (lang: string) =>
setTranslateLangs((prev) =>
prev.includes(lang) ? prev.filter((l) => l !== lang) : [...prev, lang],
);
const onGlobalTranslateChange = async (next: boolean) => {
setGlobalTranslate(next);
setTranslate(next);
try {
await setFurnidataTranslateEnabled({ enabled: next });
} catch {
toast.error("Could not save the default translation setting");
}
};
return {
ALL_LANGS,
translate,
setTranslate,
translateLangs,
setTranslateLangs,
langPickerOpen,
setLangPickerOpen,
buildingLanguages,
globalTranslate,
buildAllLanguages,
toggleLang,
onGlobalTranslateChange,
};
}