121 lines
4.3 KiB
TypeScript
121 lines
4.3 KiB
TypeScript
"use server";
|
|
|
|
import { revalidatePath } from "next/cache";
|
|
import { getSqliteConnection } from "@/server/db/client";
|
|
import { DomainError } from "@/server/domain/errors";
|
|
import { I18nService } from "@/server/i18n/service";
|
|
import { requireFreelancerBackend } from "@/server/web/freelancer";
|
|
import { cleanText } from "@/server/web/form-data";
|
|
|
|
export async function updateLanguageMetadataAction(
|
|
localeCode: string,
|
|
formData: FormData,
|
|
) {
|
|
const name = cleanText(formData.get("name")) ?? "";
|
|
const nativeName = cleanText(formData.get("nativeName")) ?? "";
|
|
const fallbackLocale = cleanText(formData.get("fallbackLocale")) ?? "";
|
|
const textDirection = cleanText(formData.get("textDirection")) ?? "";
|
|
|
|
if (!name || name.length > 80) {
|
|
return { errorKey: "settings.languageDetail.errors.name" };
|
|
}
|
|
if (!nativeName || nativeName.length > 80) {
|
|
return { errorKey: "settings.languageDetail.errors.nativeName" };
|
|
}
|
|
if (textDirection !== "ltr" && textDirection !== "rtl") {
|
|
return { errorKey: "settings.languageDetail.errors.direction" };
|
|
}
|
|
if (fallbackLocale === localeCode) {
|
|
return { errorKey: "settings.languageDetail.errors.selfFallback" };
|
|
}
|
|
|
|
try {
|
|
const { actor } = await requireFreelancerBackend();
|
|
const service = new I18nService(getSqliteConnection().db);
|
|
const current = service
|
|
.listLocales(actor)
|
|
.find((locale) => locale.code === localeCode);
|
|
if (!current) return { errorKey: "settings.languageDetail.errors.notFound" };
|
|
if (current.builtIn) {
|
|
return { errorKey: "settings.languageDetail.errors.builtInMetadata" };
|
|
}
|
|
|
|
const locale = service.updateLocale(actor, localeCode, {
|
|
name,
|
|
nativeName,
|
|
fallbackLocale,
|
|
textDirection,
|
|
});
|
|
revalidateLanguage(locale.code);
|
|
return { success: true };
|
|
} catch (error) {
|
|
console.error("Language metadata update failed", error);
|
|
if (error instanceof DomainError) {
|
|
if (error.details?.reason === "fallback_loop") {
|
|
return { errorKey: "settings.languageDetail.errors.fallbackLoop" };
|
|
}
|
|
if (error.details?.reason === "self_fallback") {
|
|
return { errorKey: "settings.languageDetail.errors.selfFallback" };
|
|
}
|
|
}
|
|
return { errorKey: "settings.languageDetail.errors.metadataFailed" };
|
|
}
|
|
}
|
|
|
|
export async function activateLanguageAction(localeCode: string) {
|
|
try {
|
|
const { actor } = await requireFreelancerBackend();
|
|
const service = new I18nService(getSqliteConnection().db);
|
|
const readiness = service.getLocaleReadiness(actor, localeCode);
|
|
if (!readiness.canActivate) {
|
|
return {
|
|
errorKey: "settings.languageDetail.errors.notReady",
|
|
missingCriticalCount: readiness.missingCriticalKeys.length,
|
|
};
|
|
}
|
|
service.updateLocale(actor, localeCode, { status: "active" });
|
|
revalidateLanguage(localeCode);
|
|
return { success: true };
|
|
} catch (error) {
|
|
console.error("Language activation failed", error);
|
|
return { errorKey: "settings.languageDetail.errors.activateFailed" };
|
|
}
|
|
}
|
|
|
|
export async function setDetailDefaultLocaleAction(localeCode: string) {
|
|
try {
|
|
const { actor } = await requireFreelancerBackend();
|
|
const service = new I18nService(getSqliteConnection().db);
|
|
service.setDefaultLocale(actor, localeCode);
|
|
revalidateLanguage(localeCode);
|
|
return { success: true };
|
|
} catch (error) {
|
|
console.error("Detail default locale update failed", error);
|
|
return { errorKey: "settings.languageDetail.errors.defaultFailed" };
|
|
}
|
|
}
|
|
|
|
export async function archiveLanguageAction(localeCode: string) {
|
|
try {
|
|
const { actor } = await requireFreelancerBackend();
|
|
const service = new I18nService(getSqliteConnection().db);
|
|
const readiness = service.getLocaleReadiness(actor, localeCode);
|
|
if (!readiness.canArchive) {
|
|
return { errorKey: "settings.languageDetail.errors.archiveBlocked" };
|
|
}
|
|
service.archiveLocale(actor, localeCode);
|
|
revalidateLanguage(localeCode);
|
|
return { success: true };
|
|
} catch (error) {
|
|
console.error("Language archive failed", error);
|
|
return { errorKey: "settings.languageDetail.errors.archiveFailed" };
|
|
}
|
|
}
|
|
|
|
function revalidateLanguage(localeCode: string) {
|
|
revalidatePath("/", "layout");
|
|
revalidatePath("/settings/language");
|
|
revalidatePath("/settings/languages");
|
|
revalidatePath(`/settings/languages/${localeCode}`);
|
|
}
|