L6 Benachrichtigungen & Audit: Glocke, Posteingang, Nutzer-Einstellungen, Mailkonfiguration
- 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>
This commit is contained in:
@@ -0,0 +1,23 @@
|
||||
"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" };
|
||||
}
|
||||
Reference in New Issue
Block a user