feat: Umschaltbarer Hinweismodus für Allergene/Zusatzstoffe
Neue Migration 0002_labeling_notice.sql: settings.labeling_mode
("detailed"/"notice") + labeling_notice(_en/_pl). Auf der Seite
"Allergene & Zusatzstoffe" (LabelingNoticeEditor) kann zwischen der
detaillierten Auswahl je Gericht und einem editierbaren Hinweistext
umgeschaltet werden. Im Hinweismodus entfällt auf der öffentlichen
Speisekarte (Desktop + Mobile) die Legende und die Kürzel an den
Gerichten, in der Gerichte-Verwaltung wird die Chip-Auswahl beim
Bearbeiten ausgeblendet. Umschalten/Bearbeiten ist für staff und admin
freigegeben, Farben in /api/settings bleiben admin-only.
Version 1.8.0.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import { NextResponse } from "next/server";
|
||||
import { query } from "@/lib/db";
|
||||
import { getSettings } from "@/lib/db/settings";
|
||||
import { getSettings, type LabelingMode } from "@/lib/db/settings";
|
||||
import { authErrorResponse, requireRole } from "@/lib/auth/session";
|
||||
import { isSameOrigin } from "@/lib/origin";
|
||||
|
||||
@@ -8,14 +8,58 @@ export async function GET() {
|
||||
return NextResponse.json(await getSettings());
|
||||
}
|
||||
|
||||
interface SettingsPatchBody {
|
||||
colors?: Record<string, string>;
|
||||
labeling_mode?: LabelingMode;
|
||||
labeling_notice?: string;
|
||||
labeling_notice_en?: string | null;
|
||||
labeling_notice_pl?: string | null;
|
||||
}
|
||||
|
||||
export async function PATCH(request: Request) {
|
||||
if (!isSameOrigin(request)) {
|
||||
return NextResponse.json({ error: "Nicht erlaubt." }, { status: 403 });
|
||||
}
|
||||
try {
|
||||
await requireRole(["admin"]);
|
||||
const { colors } = (await request.json()) as { colors: Record<string, string> };
|
||||
await query("update settings set colors = $1 where id = 1", [JSON.stringify(colors)]);
|
||||
// Farben bleiben admin-only wie bisher; die Allergen-/Zusatzstoff-
|
||||
// Anzeige darf auch Kantinenpersonal umschalten/bearbeiten.
|
||||
const session = await requireRole(["staff", "admin"]);
|
||||
const body = (await request.json()) as SettingsPatchBody;
|
||||
|
||||
const sets: string[] = [];
|
||||
const params: unknown[] = [];
|
||||
|
||||
if (body.colors !== undefined) {
|
||||
if (session.user.role !== "admin") {
|
||||
return NextResponse.json({ error: "forbidden" }, { status: 403 });
|
||||
}
|
||||
params.push(JSON.stringify(body.colors));
|
||||
sets.push(`colors = $${params.length}`);
|
||||
}
|
||||
if (body.labeling_mode !== undefined) {
|
||||
if (body.labeling_mode !== "detailed" && body.labeling_mode !== "notice") {
|
||||
return NextResponse.json({ error: "invalid_input" }, { status: 400 });
|
||||
}
|
||||
params.push(body.labeling_mode);
|
||||
sets.push(`labeling_mode = $${params.length}`);
|
||||
}
|
||||
if (body.labeling_notice !== undefined) {
|
||||
params.push(body.labeling_notice);
|
||||
sets.push(`labeling_notice = $${params.length}`);
|
||||
}
|
||||
if (body.labeling_notice_en !== undefined) {
|
||||
params.push(body.labeling_notice_en);
|
||||
sets.push(`labeling_notice_en = $${params.length}`);
|
||||
}
|
||||
if (body.labeling_notice_pl !== undefined) {
|
||||
params.push(body.labeling_notice_pl);
|
||||
sets.push(`labeling_notice_pl = $${params.length}`);
|
||||
}
|
||||
|
||||
if (sets.length === 0) {
|
||||
return NextResponse.json({ error: "invalid_input" }, { status: 400 });
|
||||
}
|
||||
await query(`update settings set ${sets.join(", ")} where id = 1`, params);
|
||||
return NextResponse.json({ ok: true });
|
||||
} catch (err) {
|
||||
const res = authErrorResponse(err);
|
||||
|
||||
Reference in New Issue
Block a user