Files
Wabenhain/src/lib/settings-tabs.ts
T
Nick SzaunigandClaude Opus 5.5 de82ad0233
Docker Image bauen und veroeffentlichen / build-and-push (push) Successful in 2m26s
feat(admin): settings page with tabs, system checks and email test
"Inhalte" becomes Admin -> Einstellungen, grouped into tabs so each
area stands on its own: Firma & Versand, Marke, Startseite, Seiten,
Social Media, Rechtstexte and System & Tests. Tabs are plain links
(?reiter=...), bookmarkable and usable without JavaScript; saving
returns to the same tab.

System & Tests brings everything that checks the running shop into one
place:
- integration overview (Stripe, Stripe webhook, Microsoft 365 mail,
  Microsoft sign-in, Turnstile, Google reviews, DHL, ApiCore): only
  whether each is set up and the names of missing variables, never a
  value; warns when Stripe runs on test keys or mixes test/live
- the email test, now with the IPv4 network checks for
  smtp.office365.com:587 and login.microsoftonline.com:443

/admin/inhalte and /admin/e-mail-test redirect to the new page; the
separate "E-Mail-Test" menu entry is gone. The tab parameter and the
saved group are validated against a fixed list before they are used in
a redirect. Docs point to the new location and cover the ENETUNREACH
(IPv6) case.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
2026-09-27 00:07:34 +02:00

37 lines
1.5 KiB
TypeScript

import type { ContentFieldDef } from "@/lib/content-registry";
/**
* Reiter von Admin → Einstellungen und welche Inhaltsgruppen
* (lib/content-registry.ts) sie tragen. "system" hat keine Inhaltsfelder,
* sondern Anbindungsstatus und E-Mail-Test.
*/
export const SETTINGS_TABS = [
{ id: "firma", groups: ["company", "shipping"] },
{ id: "marke", groups: ["brand"] },
{ id: "startseite", groups: ["home"] },
{ id: "seiten", groups: ["pages"] },
{ id: "social", groups: ["social"] },
{ id: "recht", groups: ["legal"] },
{ id: "system", groups: [] },
] as const satisfies readonly { id: string; groups: readonly ContentFieldDef["group"][] }[];
export type SettingsTabId = (typeof SETTINGS_TABS)[number]["id"];
export const SETTINGS_PATH = "/admin/einstellungen";
/** Reiter aus ?reiter=…; alles Unbekannte (auch Mehrfachwerte) faellt auf den ersten Reiter zurueck. */
export function parseSettingsTab(value: string | string[] | undefined): SettingsTabId {
const match = SETTINGS_TABS.find((tab) => tab.id === value);
return match ? match.id : SETTINGS_TABS[0].id;
}
/**
* Ziel nach dem Speichern: derselbe Reiter. Der group-Wert kommt aus dem
* Formular und ist damit Nutzereingabe — nur bekannte Gruppen fuehren zu
* einem Reiter, alles andere zur Uebersicht.
*/
export function settingsPathForGroup(group: string): string {
const tab = SETTINGS_TABS.find((t) => (t.groups as readonly string[]).includes(group));
return tab ? `${SETTINGS_PATH}?reiter=${tab.id}` : SETTINGS_PATH;
}