147 lines
5.3 KiB
TypeScript
147 lines
5.3 KiB
TypeScript
import type { GlobalConfig } from "payload";
|
|
import { isAdmin } from "@/access";
|
|
|
|
const WEEKDAYS = [
|
|
{ label: "Montag", value: "Monday" },
|
|
{ label: "Dienstag", value: "Tuesday" },
|
|
{ label: "Mittwoch", value: "Wednesday" },
|
|
{ label: "Donnerstag", value: "Thursday" },
|
|
{ label: "Freitag", value: "Friday" },
|
|
{ label: "Samstag", value: "Saturday" },
|
|
{ label: "Sonntag", value: "Sunday" },
|
|
] as const;
|
|
|
|
/**
|
|
* Central SEO settings, edited once by Anna, applied automatically across
|
|
* the whole website (see lib/seo/*). Everything here is optional - nothing
|
|
* is invented if a field is left blank (see lib/seo/jsonld.ts, which only
|
|
* emits LocalBusiness structured data once real address data exists).
|
|
*/
|
|
export const SEOSettings: GlobalConfig = {
|
|
slug: "seo-settings",
|
|
label: "SEO-Einstellungen",
|
|
admin: {
|
|
description: "Globale SEO-Vorgaben für die gesamte Website - greift automatisch überall dort, wo eine Seite keine eigenen SEO-Angaben hat.",
|
|
group: "SEO",
|
|
},
|
|
access: {
|
|
read: () => true,
|
|
update: isAdmin,
|
|
},
|
|
fields: [
|
|
{
|
|
type: "tabs",
|
|
tabs: [
|
|
{
|
|
label: "Allgemein",
|
|
fields: [
|
|
{
|
|
name: "siteUrl",
|
|
type: "text",
|
|
label: "Website-URL",
|
|
admin: {
|
|
description: "Nur bei Bedarf setzen (z. B. https://anouma.org) - überschreibt die Server-Konfiguration. Leer lassen, um die technische Standardeinstellung zu verwenden.",
|
|
},
|
|
validate: (value: string | null | undefined) => {
|
|
if (!value) return true;
|
|
return /^https?:\/\/.+/.test(value) || "Bitte eine vollständige URL angeben (z. B. https://anouma.org).";
|
|
},
|
|
},
|
|
{
|
|
name: "defaultDescription",
|
|
type: "textarea",
|
|
label: "Standard-Beschreibung",
|
|
maxLength: 300,
|
|
admin: { description: "Wird verwendet, wenn eine Seite keine eigene Meta-Beschreibung hat." },
|
|
},
|
|
{
|
|
name: "defaultOgImage",
|
|
type: "upload",
|
|
relationTo: "media",
|
|
label: "Standardbild für soziale Netzwerke",
|
|
admin: { description: "Wird verwendet, wenn eine Seite kein eigenes Bild für soziale Netzwerke hat." },
|
|
},
|
|
{
|
|
name: "robotsIndexable",
|
|
type: "checkbox",
|
|
label: "Website für Suchmaschinen sichtbar",
|
|
defaultValue: true,
|
|
admin: {
|
|
description: "Deaktivieren, um die gesamte öffentliche Website vorübergehend für Suchmaschinen zu sperren (z. B. während des Aufbaus). Betrifft nicht Admin/Konto - die sind ohnehin immer gesperrt.",
|
|
},
|
|
},
|
|
],
|
|
},
|
|
{
|
|
label: "Lokale Informationen",
|
|
admin: { description: "Werden nur verwendet, wenn tatsächlich ausgefüllt - es werden keine Angaben erfunden." },
|
|
fields: [
|
|
{
|
|
name: "businessName",
|
|
type: "text",
|
|
label: "Geschäfts-/Markenname",
|
|
defaultValue: "Anouma",
|
|
},
|
|
{
|
|
name: "businessDescription",
|
|
type: "textarea",
|
|
label: "Kurzbeschreibung",
|
|
admin: { description: "Kurzer, sachlicher Beschreibungstext für strukturierte Daten (nicht der Website-Text)." },
|
|
},
|
|
{
|
|
type: "row",
|
|
fields: [
|
|
{ name: "latitude", type: "number", label: "Breitengrad (optional)", admin: { width: "50%" } },
|
|
{ name: "longitude", type: "number", label: "Längengrad (optional)", admin: { width: "50%" } },
|
|
],
|
|
},
|
|
{
|
|
name: "openingHours",
|
|
type: "array",
|
|
label: "Öffnungs-/Erreichbarkeitszeiten",
|
|
admin: { description: "Optional - nur für tatsächlich feste Zeiten (z. B. Sprechzeiten)." },
|
|
fields: [
|
|
{
|
|
type: "row",
|
|
fields: [
|
|
{
|
|
name: "days",
|
|
type: "select",
|
|
label: "Tage",
|
|
hasMany: true,
|
|
required: true,
|
|
options: [...WEEKDAYS],
|
|
admin: { width: "50%" },
|
|
},
|
|
{ name: "opens", type: "text", label: "Von (z. B. 09:00)", required: true, admin: { width: "25%" } },
|
|
{ name: "closes", type: "text", label: "Bis (z. B. 17:00)", required: true, admin: { width: "25%" } },
|
|
],
|
|
},
|
|
],
|
|
},
|
|
],
|
|
},
|
|
{
|
|
label: "Social Media",
|
|
fields: [
|
|
{
|
|
name: "socialLinks",
|
|
type: "array",
|
|
label: "Profile",
|
|
fields: [
|
|
{
|
|
type: "row",
|
|
fields: [
|
|
{ name: "platform", type: "text", label: "Plattform (z. B. Instagram)", required: true, admin: { width: "35%" } },
|
|
{ name: "url", type: "text", label: "Link", required: true, admin: { width: "65%" } },
|
|
],
|
|
},
|
|
],
|
|
},
|
|
],
|
|
},
|
|
],
|
|
},
|
|
],
|
|
};
|