import "server-only"; import { query } from "@/lib/db"; // Gemeinsame Zugriffsschicht für die vier Übersetzungstabellen aus // db/migrations/0006_content_translations.sql. Die Wert-Spalte heißt // in allen vieren bewusst einheitlich "name" (auch bei // section_translations, obwohl sections.label selbst anders heißt) – // vereinfacht diese generischen Helfer, statt zusätzlich eine Spalten- // Namens-Zuordnung pflegen zu müssen. export type TranslationTable = | "dish_translations" | "section_translations" | "allergen_translations" | "additive_translations" | "closed_day_translations"; const ID_COLUMN: Record = { dish_translations: "dish_id", section_translations: "section_key", allergen_translations: "allergen_code", additive_translations: "additive_code", closed_day_translations: "closed_date", }; /** Alle Übersetzungen einer Tabelle, gruppiert nach Eltern-ID. */ export async function loadTranslations( table: TranslationTable ): Promise>> { const idCol = ID_COLUMN[table]; const rows = await query<{ id: string; language_code: string; name: string }>( `select ${idCol} as id, language_code, name from ${table}` ); return groupByParent(rows); } /** Übersetzungen nur für eine Teilmenge von Eltern-IDs laden (z. B. die * Gerichte des aktuell angezeigten Wochenplan-Zeitraums). */ export async function loadTranslationsFor( table: TranslationTable, ids: string[] ): Promise>> { if (ids.length === 0) return new Map(); const idCol = ID_COLUMN[table]; const rows = await query<{ id: string; language_code: string; name: string }>( `select ${idCol} as id, language_code, name from ${table} where ${idCol} = any($1)`, [ids] ); return groupByParent(rows); } function groupByParent( rows: { id: string; language_code: string; name: string }[] ): Map> { const map = new Map>(); for (const r of rows) { if (!map.has(r.id)) map.set(r.id, {}); map.get(r.id)![r.language_code] = r.name; } return map; } /** Übersetzungen eines Eintrags für die übergebenen Sprachen setzen – * ein leerer/nur-Leerzeichen-Wert löscht die Zeile für diese Sprache * wieder (z. B. wenn ein Formularfeld geleert wird), statt eine leere * Übersetzung zu speichern. */ export async function replaceTranslations( table: TranslationTable, id: string, translations: Record ): Promise { const idCol = ID_COLUMN[table]; for (const [languageCode, rawValue] of Object.entries(translations)) { const value = rawValue?.trim(); if (!value) { await query(`delete from ${table} where ${idCol} = $1 and language_code = $2`, [ id, languageCode, ]); continue; } await query( `insert into ${table} (${idCol}, language_code, name) values ($1, $2, $3) on conflict (${idCol}, language_code) do update set name = excluded.name`, [id, languageCode, value] ); } }