Gerichtnamen, Essenszeiten und Allergen-/Zusatzstoff-Bezeichnungen sind jetzt genauso dynamisch mehrsprachig wie die Bedienoberfläche aus v1.10.0, statt fest auf Englisch/Polnisch begrenzt zu sein. Neue Übersetzungstabellen ersetzen die alten name_en/name_pl-Spalten, DeepL-Auto-Übersetzung und CSV-Import/-Export unterstützen jetzt beliebig viele aktive Sprachen.
49 lines
1.4 KiB
TypeScript
49 lines
1.4 KiB
TypeScript
import { query } from "@/lib/db";
|
|
import { loadTranslationsFor } from "@/lib/db/translations";
|
|
import { listActiveLanguageCodes } from "@/lib/db/languages";
|
|
import { authErrorResponse, requireRole } from "@/lib/auth/session";
|
|
import { toCsv } from "@/lib/csv";
|
|
|
|
interface DishRow {
|
|
id: string;
|
|
name: string;
|
|
price: string;
|
|
allergens: string[];
|
|
additives: string[];
|
|
}
|
|
|
|
export async function GET() {
|
|
try {
|
|
await requireRole(["staff", "admin"]);
|
|
const [dishes, activeCodes] = await Promise.all([
|
|
query<DishRow>("select id, name, price, allergens, additives from dishes order by name"),
|
|
listActiveLanguageCodes(),
|
|
]);
|
|
const langCodes = activeCodes.filter((c) => c !== "de");
|
|
const translations = await loadTranslationsFor(
|
|
"dish_translations",
|
|
dishes.map((d) => d.id)
|
|
);
|
|
const rows = [
|
|
["name", ...langCodes.map((c) => `name_${c}`), "price", "allergens", "additives"],
|
|
...dishes.map((d) => [
|
|
d.name,
|
|
...langCodes.map((c) => translations.get(d.id)?.[c] ?? ""),
|
|
d.price,
|
|
(d.allergens ?? []).join(";"),
|
|
(d.additives ?? []).join(";"),
|
|
]),
|
|
];
|
|
return new Response(toCsv(rows), {
|
|
headers: {
|
|
"Content-Type": "text/csv; charset=utf-8",
|
|
"Content-Disposition": 'attachment; filename="gerichte.csv"',
|
|
},
|
|
});
|
|
} catch (err) {
|
|
const res = authErrorResponse(err);
|
|
if (res) return res;
|
|
throw err;
|
|
}
|
|
}
|