- Glocke im Backoffice-Header (ungelesen-Zähler, letzte 10, alle gelesen), mobil einbindbar über variant="mobile". - /notifications mit Filter gelesen/ungelesen/Art, Öffnen markiert gelesen (nur relative Links), Pagination. - /account Abschnitt Benachrichtigungen: E-Mail-Opt-out je Typ, Notdienst Pflicht. - /settings/email (tenant:manage): Absendername, Antwortadresse, Empfänger Notdienst und Abrechnung; Validierung gegen Header-Injection, max. 20 Adressen, Audit. - Actions unter actions/notifications mit moduleGuard + guard; Navigation ergänzt. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
24 lines
922 B
TypeScript
24 lines
922 B
TypeScript
"use server";
|
|
|
|
import { revalidatePath } from "next/cache";
|
|
import { moduleGuard } from "@/server/action-guard";
|
|
import { ctxFromGuard } from "@/server/services/context";
|
|
import { setPreferences } from "@/server/services/notifications/preferences";
|
|
|
|
const guard = moduleGuard("notifications");
|
|
|
|
export type PreferencesState = { status: "idle" | "saved" | "error" };
|
|
|
|
/** Save the current user's e-mail opt-outs (checked boxes = e-mail on). */
|
|
export async function saveNotificationPreferences(_prev: PreferencesState, formData: FormData): Promise<PreferencesState> {
|
|
const g = await guard("notification:read");
|
|
try {
|
|
await setPreferences(ctxFromGuard(g), { emailOn: formData.getAll("emailOn").map(String) });
|
|
} catch (err) {
|
|
console.error("[notifications] saving preferences failed:", (err as Error).message);
|
|
return { status: "error" };
|
|
}
|
|
revalidatePath("/account");
|
|
return { status: "saved" };
|
|
}
|