Bisher war jeder Charakter (HasiDog, Frieda, Sam, ...) eine eigene Unterkategorie mit eigener Seite. Das passte nicht mehr, sobald eine Familie mehrere Charaktere bekommt (HasiDog, HasiGott, Mama Hase) — die sollten alle auf EINER Seite erscheinen, nicht auf drei getrennten. Neues Modell: - Unterkategorie = die ganze Tier-Familie (z.B. "hase", "kuh", "wal"), nicht mehr ein einzelner Charakter. - Jede Familie hat jetzt ein "characters"-Array (categories.ts, config.yml) — beliebig viele Charaktere, jeder mit eigenem Namen, Vorstellungstext und optionalem "Mehr über mich"-Link. - Produkte bekommen ein neues optionales Feld "charakter", das sie einem bestimmten Charakter innerhalb der Unterkategorie zuordnet (Product. charakter in products.ts + Adminbereich-Feld). - Die Unterkategorie-Seite zeigt jetzt JEDEN Charakter als eigene Box untereinander, mit automatisch abwechselnder Foto-/Text-Seite (1. links, 2. rechts, 3. wieder links, ...). Ein Charakter ohne zugeordnetes Produkt zeigt trotzdem schon seine Box (nur ohne Foto) — die Seite "wächst" mit, sobald neue Charaktere/Produkte dazukommen, für jede Tier-Familie (Hase, Kuh, Wal, Oktopus, Schildkröte, Pinguin). - "Hase" hat jetzt drei Charaktere (HasiDog mit echtem Produkt, HasiGott und Mama Hase als Platzhalter-Boxen). - Unterkategorien-Chips zeigen jetzt sauber die Familiennamen (Kuh, Hase, Wal, ...) statt "Kuh „Frieda"" etc. - Alte, verwaiste /hasidog/-Seite entfernt (war durch die Umstellung kaputt und nirgends mehr verlinkt). Verifiziert per Puppeteer gegen den echten Build: /shop/diy-plushies/hase/ zeigt alle drei Charaktere korrekt alternierend, Ein-Charakter-Familien (Kuh etc.) funktionieren unverändert, Adminbereich lädt ohne Konfigurationsfehler, alte Hase-URLs geben korrekt 404.
305 lines
15 KiB
YAML
305 lines
15 KiB
YAML
backend:
|
||
name: github
|
||
repo: vans-diy-bastelbedarf/website
|
||
branch: main
|
||
base_url: https://vans-diy-bastelbedarf-cms-auth.dogfather1608.workers.dev
|
||
|
||
logo:
|
||
src: /logo.png
|
||
|
||
app_title: "Van's Shop – Adminbereich"
|
||
|
||
# Bilder, die VanVan hier hochlädt, landen automatisch hier im Projekt und sind danach
|
||
# unter /img/products/<dateiname> auf der Website erreichbar.
|
||
media_folder: "public/img/products"
|
||
public_folder: "/img/products"
|
||
|
||
collections:
|
||
- name: products
|
||
label: Produkte
|
||
label_singular: Produkt
|
||
icon: shopping_bag
|
||
folder: src/content/products
|
||
create: true
|
||
delete: true
|
||
slug: "{{fields.slug}}"
|
||
identifier_field: slug
|
||
extension: json
|
||
format: json
|
||
summary: "{{name.de}} — {{preis}} €"
|
||
fields:
|
||
- label: "📷 Fotos"
|
||
name: bilder
|
||
widget: list
|
||
required: false
|
||
hint: "Hier Fotos hochladen oder per Drag & Drop reinziehen. Das erste Foto ist das Hauptbild, das überall zuerst angezeigt wird."
|
||
field: { label: Foto, name: bild, widget: image }
|
||
- label: Name
|
||
name: name
|
||
widget: object
|
||
fields:
|
||
- { label: Deutsch, name: de, widget: string }
|
||
- { label: Englisch, name: en, widget: string }
|
||
- { label: "Schweizerdeutsch", name: ch, widget: string }
|
||
- { label: Französisch, name: fr, widget: string }
|
||
- label: Beschreibung
|
||
name: beschreibung
|
||
widget: object
|
||
fields:
|
||
- { label: Deutsch, name: de, widget: text }
|
||
- { label: Englisch, name: en, widget: text }
|
||
- { label: "Schweizerdeutsch", name: ch, widget: text }
|
||
- { label: Französisch, name: fr, widget: text }
|
||
- label: "Preis (€)"
|
||
name: preis
|
||
widget: number
|
||
value_type: float
|
||
step: 0.01
|
||
hint: "Der ganz normale Verkaufspreis, z.B. 19.99"
|
||
- label: "Reduzierter Preis? (nur ausfüllen, wenn im Sale)"
|
||
name: preisAlt
|
||
widget: number
|
||
value_type: float
|
||
step: 0.01
|
||
required: false
|
||
hint: "Hier den ALTEN, höheren Preis eintragen — er wird dann durchgestrichen neben dem neuen Preis angezeigt. Leer lassen, wenn kein Sale."
|
||
- label: "🏷️ Rabatte (optional — alles leer lassen, wenn kein automatischer Rabatt gelten soll)"
|
||
name: rabatt
|
||
widget: object
|
||
required: false
|
||
hint: "Zusätzlich zum 'Reduzierten Preis' oben kannst du hier einen automatischen Rabatt einrichten, der von selbst wieder abläuft, sowie einen Mengenrabatt (z.B. ab 3 Stück günstiger). Du musst nichts selbst ausrechnen — sobald du oben rechts auf 'Speichern' klickst, berechnet die Website den neuen Preis automatisch und zeigt ihn den Kund:innen sofort an."
|
||
fields:
|
||
- { label: "Rabatt in Prozent (z.B. 20 für 20%)", name: prozent, widget: number, value_type: int, required: false, hint: "Nur ausfüllen ODER den Betrag unten — nicht beides." }
|
||
- { label: "ODER: Rabatt als fester Betrag (€)", name: betrag, widget: number, value_type: float, step: 0.01, required: false }
|
||
- { label: "Rabatt gültig bis (leer = läuft nicht automatisch ab)", name: bis, widget: datetime, format: "YYYY-MM-DD", date_format: "YYYY-MM-DD", time_format: false, required: false, hint: "Nach diesem Datum verschwindet der Rabatt automatisch — ohne dass du etwas tun musst." }
|
||
- label: "Mengenrabatt-Staffel (z.B. ab 3 Stück 10% Rabatt)"
|
||
name: mengenrabatt
|
||
widget: list
|
||
required: false
|
||
summary: "ab {{fields.abMenge}} Stück → -{{fields.prozent}}%"
|
||
hint: "Gilt automatisch im Warenkorb, wenn jemand mehrere Stück dieses Produkts kauft."
|
||
fields:
|
||
- { label: "Ab wie vielen Stück", name: abMenge, widget: number, value_type: int }
|
||
- { label: "Rabatt in Prozent", name: prozent, widget: number, value_type: int }
|
||
- label: "Auf Lager"
|
||
name: bestand
|
||
widget: number
|
||
value_type: int
|
||
hint: "Wie viele Stück hast du vorrätig? 0 = ausverkauft (Artikel bleibt trotzdem sichtbar)."
|
||
- label: Kategorie
|
||
name: kategorie
|
||
widget: relation
|
||
collection: categories
|
||
search_fields: ["name.de"]
|
||
value_field: "slug"
|
||
display_fields: ["name.de"]
|
||
- label: "Unterkategorie (optional)"
|
||
name: unterkategorie
|
||
widget: string
|
||
required: false
|
||
hint: "Interner Code der Unterkategorie eintragen, z.B. hase (siehe Bereich Kategorien)"
|
||
- label: "Charakter innerhalb der Unterkategorie (optional)"
|
||
name: charakter
|
||
widget: string
|
||
required: false
|
||
hint: "Nur nötig, wenn die Unterkategorie mehrere Charaktere hat (z.B. 'hase' hat HasiDog, HasiGott, Mama Hase) — dann hier den Charakter-Code eintragen, z.B. hasidog (siehe Bereich Kategorien)."
|
||
- label: Auszeichnungen
|
||
name: badges
|
||
widget: select
|
||
multiple: true
|
||
required: false
|
||
hint: "Erscheinen als kleine Sticker auf dem Produktbild"
|
||
options:
|
||
- { label: "✨ Neu", value: neu }
|
||
- { label: "🔥 Bestseller", value: bestseller }
|
||
- { label: "🏷️ Im Sale", value: sale }
|
||
- { label: "🧶 Handgemacht", value: handgemacht }
|
||
- { label: Artikelnummer, name: artikelnummer, widget: string, required: false }
|
||
- { label: Material, name: material, widget: string, required: false }
|
||
- { label: "Größe / Maße", name: groesse, widget: string, required: false }
|
||
- label: Farben
|
||
name: farben
|
||
widget: list
|
||
required: false
|
||
hint: "Eine Farbe pro Zeile, z.B. Lavendel"
|
||
- { label: Lieferumfang, name: lieferumfang, widget: string, required: false }
|
||
- { label: Pflegehinweise, name: pflegehinweise, widget: string, required: false }
|
||
- { label: Lieferzeit, name: lieferzeit, widget: string, required: false }
|
||
- label: "🚚 Eigene Versandkosten (nur für Einzelkauf dieses Produkts)"
|
||
name: versand
|
||
widget: object
|
||
required: false
|
||
hint: "Gilt NUR, wenn jemand genau 1 Stück von genau diesem Produkt kauft. Bei mehreren Produkten/Stück im Warenkorb gilt automatisch die allgemeine Versandkosten-Staffel (siehe Bereich 'Versandkosten-Staffel'). Leer lassen = Staffel gilt auch beim Einzelkauf."
|
||
fields:
|
||
- { label: "Deutschland (€)", name: de, widget: number, value_type: float, step: 0.01, required: false }
|
||
- { label: "Österreich (€)", name: at, widget: number, value_type: float, step: 0.01, required: false }
|
||
- { label: "Schweiz (€)", name: ch, widget: number, value_type: float, step: 0.01, required: false }
|
||
- { label: "Luxemburg (€)", name: lu, widget: number, value_type: float, step: 0.01, required: false }
|
||
- label: "Interner Code (URL) — nach Veröffentlichung nicht mehr ändern!"
|
||
name: slug
|
||
widget: string
|
||
hint: "Nur Kleinbuchstaben, Zahlen und Bindestriche, z.B. wolke-plushie-lavendel"
|
||
|
||
- name: categories
|
||
label: Kategorien
|
||
label_singular: Kategorie
|
||
icon: category
|
||
folder: src/content/categories
|
||
create: true
|
||
delete: false
|
||
slug: "{{fields.slug}}"
|
||
identifier_field: slug
|
||
extension: json
|
||
format: json
|
||
summary: "{{name.de}}"
|
||
fields:
|
||
- label: "Icon (Emoji)"
|
||
name: icon
|
||
widget: string
|
||
hint: "z.B. 🧸"
|
||
- label: Name
|
||
name: name
|
||
widget: object
|
||
fields:
|
||
- { label: Deutsch, name: de, widget: string }
|
||
- { label: Englisch, name: en, widget: string }
|
||
- { label: "Schweizerdeutsch", name: ch, widget: string }
|
||
- { label: Französisch, name: fr, widget: string }
|
||
- label: Beschreibung
|
||
name: description
|
||
widget: object
|
||
fields:
|
||
- { label: Deutsch, name: de, widget: text }
|
||
- { label: Englisch, name: en, widget: text }
|
||
- { label: "Schweizerdeutsch", name: ch, widget: text }
|
||
- { label: Französisch, name: fr, widget: text }
|
||
- label: Unterkategorien
|
||
name: subcategories
|
||
widget: list
|
||
required: false
|
||
summary: "{{fields.name.de}}"
|
||
fields:
|
||
- { label: "Interner Code (URL)", name: slug, widget: string, hint: "z.B. hase — steht für die ganze Tier-Serie, nicht nur einen einzelnen Charakter." }
|
||
- label: Name
|
||
name: name
|
||
widget: object
|
||
fields:
|
||
- { label: Deutsch, name: de, widget: string }
|
||
- { label: Englisch, name: en, widget: string }
|
||
- { label: "Schweizerdeutsch", name: ch, widget: string }
|
||
- { label: Französisch, name: fr, widget: string }
|
||
- label: "Charaktere dieser Serie (z.B. mehrere Hasen-Varianten)"
|
||
name: characters
|
||
widget: list
|
||
required: false
|
||
summary: "{{fields.name.de}}"
|
||
hint: "Jeder Charakter bekommt auf der Unterkategorie-Seite seine eigene Box — die Foto-Seite wechselt automatisch ab (1. links, 2. rechts, 3. wieder links, usw.). Trage beim passenden Produkt weiter oben unter 'Charakter innerhalb der Unterkategorie' genau denselben Code ein, damit Foto und Text zusammenfinden."
|
||
fields:
|
||
- { label: "Interner Code", name: slug, widget: string, hint: "z.B. hasidog — muss beim Produkt unter 'Charakter' genau so eingetragen werden." }
|
||
- label: Name
|
||
name: name
|
||
widget: object
|
||
fields:
|
||
- { label: Deutsch, name: de, widget: string }
|
||
- { label: Englisch, name: en, widget: string }
|
||
- { label: "Schweizerdeutsch", name: ch, widget: string }
|
||
- { label: Französisch, name: fr, widget: string }
|
||
- label: "Persönliche Vorstellung (1. Zeile 'Hallo, ich bin ...', 2. Zeile Persönlichkeit)"
|
||
name: vorstellung
|
||
widget: object
|
||
required: false
|
||
fields:
|
||
- { label: Deutsch, name: de, widget: text }
|
||
- { label: Englisch, name: en, widget: text }
|
||
- { label: "Schweizerdeutsch", name: ch, widget: text }
|
||
- { label: Französisch, name: fr, widget: text }
|
||
- { label: "Link zu einer externen 'Mehr über mich'-Seite (optional)", name: mehrLink, widget: string, required: false }
|
||
- label: "Reihenfolge (0 = zuerst)"
|
||
name: order
|
||
widget: number
|
||
value_type: int
|
||
- label: "Interner Code (URL) — nach Veröffentlichung nicht mehr ändern!"
|
||
name: slug
|
||
widget: string
|
||
|
||
- name: versandkosten
|
||
label: "🚚 Versandkosten-Staffel"
|
||
icon: local_shipping
|
||
files:
|
||
- name: staffel
|
||
label: "Versandkosten-Staffel nach Warenwert"
|
||
file: src/content/versandstaffel.json
|
||
description: >
|
||
Gilt automatisch im Warenkorb/an der Kasse, sobald jemand mehrere Produkte oder
|
||
mehrere Stück kauft (bei genau 1 Stück von 1 Produkt gilt stattdessen der eigene
|
||
Versandpreis am Produkt, falls dort einer eingetragen ist). Ab 75 € Warenwert ist der
|
||
Versand immer kostenlos, unabhängig von dieser Tabelle.
|
||
fields:
|
||
- label: Deutschland
|
||
name: de
|
||
widget: list
|
||
summary: "ab {{fields.abWarenwert}} € → {{fields.kosten}} €"
|
||
fields:
|
||
- { label: "Ab Warenwert (€)", name: abWarenwert, widget: number, value_type: float, step: 0.01 }
|
||
- { label: "Versandkosten (€)", name: kosten, widget: number, value_type: float, step: 0.01 }
|
||
- label: Österreich
|
||
name: at
|
||
widget: list
|
||
summary: "ab {{fields.abWarenwert}} € → {{fields.kosten}} €"
|
||
fields:
|
||
- { label: "Ab Warenwert (€)", name: abWarenwert, widget: number, value_type: float, step: 0.01 }
|
||
- { label: "Versandkosten (€)", name: kosten, widget: number, value_type: float, step: 0.01 }
|
||
- label: Schweiz
|
||
name: ch
|
||
widget: list
|
||
summary: "ab {{fields.abWarenwert}} € → {{fields.kosten}} €"
|
||
fields:
|
||
- { label: "Ab Warenwert (€)", name: abWarenwert, widget: number, value_type: float, step: 0.01 }
|
||
- { label: "Versandkosten (€)", name: kosten, widget: number, value_type: float, step: 0.01 }
|
||
- label: Luxemburg
|
||
name: lu
|
||
widget: list
|
||
summary: "ab {{fields.abWarenwert}} € → {{fields.kosten}} €"
|
||
fields:
|
||
- { label: "Ab Warenwert (€)", name: abWarenwert, widget: number, value_type: float, step: 0.01 }
|
||
- { label: "Versandkosten (€)", name: kosten, widget: number, value_type: float, step: 0.01 }
|
||
|
||
- name: gutscheine
|
||
label: "🎟️ Gutscheincodes"
|
||
icon: local_offer
|
||
files:
|
||
- name: codes
|
||
label: "Gutscheincodes"
|
||
file: src/content/gutscheine.json
|
||
description: >
|
||
Codes, die Kund:innen im Warenkorb/an der Kasse eingeben können, um Rabatt auf den
|
||
gesamten Warenwert zu bekommen (z.B. für Aktionen, Newsletter, Stammkund:innen).
|
||
fields:
|
||
- label: Gutscheincodes
|
||
name: codes
|
||
widget: list
|
||
summary: "{{fields.code}}"
|
||
fields:
|
||
- { label: "Code (z.B. WILLKOMMEN10)", name: code, widget: string, hint: "Groß-/Kleinschreibung ist egal — wird automatisch angepasst." }
|
||
- { label: "Rabatt in Prozent (z.B. 10 für 10%)", name: prozent, widget: number, value_type: int, required: false }
|
||
- { label: "ODER: Rabatt als fester Betrag (€)", name: betrag, widget: number, value_type: float, step: 0.01, required: false }
|
||
- { label: "Gültig bis (leer = unbegrenzt)", name: bis, widget: datetime, format: "YYYY-MM-DD", date_format: "YYYY-MM-DD", time_format: false, required: false }
|
||
|
||
- name: bankverbindung
|
||
label: "🏦 Bankverbindung"
|
||
icon: account_balance
|
||
files:
|
||
- name: konto
|
||
label: "Bankverbindung für Vorkasse"
|
||
file: src/content/bankverbindung.json
|
||
description: >
|
||
Wird Kund:innen direkt im Checkout angezeigt, sobald sie "Banküberweisung (Vorkasse)"
|
||
als Zahlungsart wählen — sie überweisen dann selbst auf dieses Konto. Bitte einmal mit
|
||
deinen echten Kontodaten ausfüllen, sonst bekommen Kund:innen nur einen Platzhalter
|
||
angezeigt.
|
||
fields:
|
||
- { label: Kontoinhaber:in, name: kontoinhaber, widget: string, required: false }
|
||
- { label: IBAN, name: iban, widget: string, required: false, hint: "z.B. DE12 3456 7890 1234 5678 90" }
|
||
- { label: BIC, name: bic, widget: string, required: false }
|
||
- { label: Bank (Name), name: bank, widget: string, required: false }
|