import type { CollectionConfig } from "payload"; import { isAdmin } from "@/access"; function normalizePath(value: string): string { const trimmed = value.trim(); const withSlash = trimmed.startsWith("/") ? trimmed : `/${trimmed}`; return withSlash.length > 1 ? withSlash.replace(/\/+$/, "") : withSlash; } /** * Simple slug-change redirect table (see lib/seo/redirects.ts). Deliberately * scoped to the three dynamic [slug] detail routes (Angebote/Termine/ * Aktuelles) — that's the only place slugs actually live and can change, so * looking this up only there avoids adding a database lookup to every * single request the way a catch-all middleware would. */ export const Redirects: CollectionConfig = { slug: "redirects", labels: { singular: "Weiterleitung", plural: "Weiterleitungen", }, admin: { useAsTitle: "fromPath", defaultColumns: ["fromPath", "toPath", "type", "enabled"], group: "SEO", description: "Leitet eine alte URL (z. B. nach einer Slug-Änderung bei Angeboten, Terminen oder Aktuelles) dauerhaft auf eine neue weiter.", }, access: { read: () => true, create: isAdmin, update: isAdmin, delete: isAdmin, }, fields: [ { name: "fromPath", type: "text", label: "Alte URL (Pfad)", required: true, unique: true, index: true, admin: { description: "Nur der Pfad, z. B. /angebote/doula (ohne Domain)." }, hooks: { beforeValidate: [({ value }) => (typeof value === "string" && value ? normalizePath(value) : value)], }, }, { name: "toPath", type: "text", label: "Neue URL (Pfad)", required: true, admin: { description: "Ziel-Pfad, z. B. /angebote/doula-begleitung." }, hooks: { beforeValidate: [({ value }) => (typeof value === "string" && value ? normalizePath(value) : value)], }, }, { name: "type", type: "select", label: "Art der Weiterleitung", required: true, defaultValue: "permanent", options: [ { label: "301 – Dauerhaft", value: "permanent" }, { label: "302 – Vorübergehend", value: "temporary" }, ], }, { name: "enabled", type: "checkbox", label: "Aktiv", defaultValue: true, }, ], };