Adminbereich für VanVan: Produkte/Kategorien als bearbeitbare JSON-Dateien + Sveltia-CMS-Login unter /admin/

This commit is contained in:
qcigano
2026-08-02 13:36:04 +02:00
parent 2e340f7a8a
commit 81b1a50158
19 changed files with 677 additions and 292 deletions
+145
View File
@@ -0,0 +1,145 @@
backend:
name: github
repo: vans-diy-bastelbedarf/website
branch: main
base_url: https://vans-diy-bastelbedarf-cms-auth.dogfather1608.workers.dev
# 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"
locale: de
collections:
- name: products
label: Produkte
label_singular: Produkt
folder: src/content/products
create: true
delete: true
slug: "{{fields.slug}}"
identifier_field: slug
extension: json
format: json
summary: "{{name.de}} — {{preis}} €"
fields:
- 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"
- 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: Artikelnummer
name: artikelnummer
widget: string
required: false
- label: Kategorie
name: kategorie
widget: relation
collection: categories
search_fields: ["name.de"]
value_field: "slug"
display_fields: ["name.de"]
- { label: "Preis (in Euro)", name: preis, widget: number, value_type: float, step: 0.01 }
- label: "Alter Preis (nur ausfüllen, wenn im Sale)"
name: preisAlt
widget: number
value_type: float
step: 0.01
required: false
- { label: "Bestand (Anzahl auf Lager)", name: bestand, widget: number, value_type: int }
- 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: 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: Auszeichnungen
name: badges
widget: select
multiple: true
required: false
options:
- { label: Neu, value: neu }
- { label: Bestseller, value: bestseller }
- { label: "Im Sale", value: sale }
- { label: Handgemacht, value: handgemacht }
- label: Fotos
name: bilder
widget: list
required: false
field: { label: Foto, name: bild, widget: image }
- name: categories
label: Kategorien
label_singular: Kategorie
folder: src/content/categories
create: true
delete: false
slug: "{{fields.slug}}"
identifier_field: slug
extension: json
format: json
summary: "{{name.de}}"
fields:
- label: "Interner Code (URL) — nach Veröffentlichung nicht mehr ändern!"
name: slug
widget: string
- label: "Reihenfolge (0 = zuerst)"
name: order
widget: number
value_type: int
- 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: "Icon (Emoji)"
name: icon
widget: string
hint: "z.B. 🧸"
- label: Unterkategorien
name: subcategories
widget: list
required: false
summary: "{{fields.name.de}}"
fields:
- { label: "Interner Code (URL)", name: slug, widget: string }
- 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 }
+16
View File
@@ -0,0 +1,16 @@
<!doctype html>
<html lang="de">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="robots" content="noindex" />
<title>Van's DIY & Bastelbedarf Admin</title>
<link rel="icon" href="/favicon.svg" />
</head>
<body>
<!-- Sveltia CMS: quelloffen (MIT), läuft komplett im Browser, bearbeitet die Inhalte
direkt im GitHub-Repo. Kein eigener Server nötig — siehe config.yml für die
Feld-Definitionen (Produkte, Kategorien). -->
<script src="https://unpkg.com/@sveltia/cms/dist/sveltia-cms.js" type="module"></script>
</body>
</html>
@@ -0,0 +1,37 @@
{
"slug": "bastelzubehoer",
"order": 4,
"name": {
"de": "Bastelzubehör",
"en": "Craft Supplies",
"ch": "Bastelzubehör",
"fr": "Fournitures créatives"
},
"description": {
"de": "Grundausstattung und kleine Helfer für kreative DIY-Projekte.",
"en": "Essentials and handy little helpers for creative DIY projects.",
"ch": "Grundusstattig und chlini Helfer für kreativi DIY-Projäkt.",
"fr": "L'essentiel et de petits accessoires pour vos projets créatifs."
},
"icon": "✂️",
"subcategories": [
{
"slug": "holzknoepfe",
"name": {
"de": "Holzknöpfe",
"en": "Wooden Buttons",
"ch": "Holzchnöpf",
"fr": "Boutons en bois"
}
},
{
"slug": "kunststoffknoepfe",
"name": {
"de": "Kunststoffknöpfe",
"en": "Plastic Buttons",
"ch": "Kunststoffchnöpf",
"fr": "Boutons en plastique"
}
}
]
}
@@ -0,0 +1,17 @@
{
"slug": "diy-haekelwerke",
"order": 1,
"name": {
"de": "DIY Häkelwerke",
"en": "DIY Crochet",
"ch": "DIY Häkelwerke",
"fr": "Crochet DIY"
},
"description": {
"de": "Gehäkelte Deko, Accessoires und kleine Kunstwerke aus feiner Wolle.",
"en": "Crocheted décor, accessories and small works of art made from fine yarn.",
"ch": "Ghäkleti Deko, Accessoires und chlini Kunstwerch us feiner Wolle.",
"fr": "Décorations, accessoires et petites œuvres crochetés en laine fine."
},
"icon": "🧶"
}
+73
View File
@@ -0,0 +1,73 @@
{
"slug": "diy-plushies",
"order": 0,
"name": {
"de": "DIY Plushies",
"en": "DIY Plushies",
"ch": "DIY Plushies",
"fr": "Peluches DIY"
},
"description": {
"de": "Handgenähte Kuscheltiere und Plüschfiguren jedes Stück ein Unikat.",
"en": "Hand-sewn stuffed animals and plush figures every piece a one-of-a-kind.",
"ch": "Vo Hang gnähti Kuscheltier und Plüschfigure jedes Sächeli es Unikat.",
"fr": "Peluches et figurines cousues à la main chaque pièce est unique."
},
"icon": "🧸",
"subcategories": [
{
"slug": "kuh-frieda",
"name": {
"de": "Kuh „Frieda”",
"en": "Cow \"Frieda\"",
"ch": "Kuh „Frieda”",
"fr": "Vache « Frieda »"
}
},
{
"slug": "hase-hasidog",
"name": {
"de": "Hase „HasiDog”",
"en": "Bunny \"HasiDog\"",
"ch": "Hase „HasiDog”",
"fr": "Lapin « HasiDog »"
}
},
{
"slug": "wal-sam",
"name": {
"de": "Wal „Sam”",
"en": "Whale \"Sam\"",
"ch": "Wal „Sam”",
"fr": "Baleine « Sam »"
}
},
{
"slug": "oktopus-siggi",
"name": {
"de": "Oktopus „Siggi”",
"en": "Octopus \"Siggi\"",
"ch": "Oktopus „Siggi”",
"fr": "Poulpe « Siggi »"
}
},
{
"slug": "schildkroete-gaby",
"name": {
"de": "Schildkröte „Gaby”",
"en": "Turtle \"Gaby\"",
"ch": "Schildchröte „Gaby”",
"fr": "Tortue « Gaby »"
}
},
{
"slug": "pinguin-pingi",
"name": {
"de": "Pinguin „Pingi”",
"en": "Penguin \"Pingi\"",
"ch": "Pinguin „Pingi”",
"fr": "Pingouin « Pingi »"
}
}
]
}
@@ -0,0 +1,28 @@
{
"slug": "haekelzubehoer",
"order": 3,
"name": {
"de": "Häkelzubehör",
"en": "Crochet Supplies",
"ch": "Häkelzubehör",
"fr": "Fournitures de crochet"
},
"description": {
"de": "Nadeln, Garne und alles, was dein nächstes Häkelprojekt braucht.",
"en": "Hooks, yarn and everything your next crochet project needs.",
"ch": "Nadle, Garn und alles, wo's für dis nächschte Häkelprojekt bruucht.",
"fr": "Crochets, fils et tout ce qu'il faut pour votre prochain projet."
},
"icon": "🪡",
"subcategories": [
{
"slug": "maschenmarkierer",
"name": {
"de": "Maschenmarkierer",
"en": "Stitch Markers",
"ch": "Masche-Markierer",
"fr": "Marqueurs de mailles"
}
}
]
}
@@ -0,0 +1,55 @@
{
"slug": "modeschmuck-accessoires",
"order": 2,
"name": {
"de": "DIY Modeschmuck & Accessoires",
"en": "DIY Jewelry & Accessories",
"ch": "DIY Modeschmuck & Accessoires",
"fr": "Bijoux & accessoires DIY"
},
"description": {
"de": "Selbstgemachter Schmuck und Accessoires für den besonderen Auftritt.",
"en": "Handmade jewelry and accessories for that special touch.",
"ch": "Sälber gmachte Schmuck und Accessoires für dr bsundere Uftritt.",
"fr": "Bijoux et accessoires faits main pour une touche unique."
},
"icon": "📿",
"subcategories": [
{
"slug": "glasperlenarmbaender",
"name": {
"de": "Glasperlenarmbänder",
"en": "Glass Bead Bracelets",
"ch": "Glasperle-Armbändel",
"fr": "Bracelets en perles de verre"
}
},
{
"slug": "kunststoffperlenarmbaender",
"name": {
"de": "Kunststoffperlenarmbänder",
"en": "Plastic Bead Bracelets",
"ch": "Kunststoffperle-Armbändel",
"fr": "Bracelets en perles plastique"
}
},
{
"slug": "edelstahlhalsketten",
"name": {
"de": "Edelstahlhalsketten",
"en": "Stainless Steel Necklaces",
"ch": "Edelstahl-Halschette",
"fr": "Colliers en acier inoxydable"
}
},
{
"slug": "polyesterhalsketten",
"name": {
"de": "Polyesterhalsketten",
"en": "Polyester Necklaces",
"ch": "Polyester-Halschette",
"fr": "Colliers en polyester"
}
}
]
}
@@ -0,0 +1,26 @@
{
"slug": "bastel-starterset",
"name": {
"de": "DIY Bastel-Starterset",
"en": "DIY Craft Starter Kit",
"ch": "DIY Bastel-Starterset",
"fr": "Kit créatif de démarrage DIY"
},
"artikelnummer": "BAS-050",
"kategorie": "bastelzubehoer",
"preis": 34,
"preisAlt": 42,
"bestand": 8,
"beschreibung": {
"de": "Alles für den Einstieg: Schere, Kleber, Knöpfe, Bänder und eine kleine Anleitung mit drei Projekten.",
"en": "Everything to get started: scissors, glue, buttons, ribbon and a little guide with three projects.",
"ch": "Alles für dr Iistig: Schere, Chläber, Chnöpf, Bändel und e chlini Aaleitig mit drei Projäkt.",
"fr": "Tout pour débuter : ciseaux, colle, boutons, rubans et un petit guide avec trois projets."
},
"lieferumfang": "1 Set (siehe Beschreibung)",
"lieferzeit": "24 Werktage",
"badges": [
"sale"
],
"bilder": []
}
@@ -0,0 +1,28 @@
{
"slug": "baumwollgarn-bundle",
"name": {
"de": "Baumwollgarn-Bundle „Pastell” (6 Knäuel)",
"en": "Cotton Yarn Bundle \"Pastel\" (6 skeins)",
"ch": "Baumwollgarn-Bundle „Pastell” (6 Knäuel)",
"fr": "Lot de fil coton « Pastel » (6 pelotes)"
},
"artikelnummer": "ZUB-205",
"kategorie": "haekelzubehoer",
"preis": 24.9,
"bestand": 17,
"beschreibung": {
"de": "Sechs Knäuel weiches Baumwollgarn in aufeinander abgestimmten Pastelltönen.",
"en": "Six skeins of soft cotton yarn in coordinated pastel shades.",
"ch": "Sächs Chnöiel weichs Baumwollgarn i aufenand abgstimmte Pastelltöne.",
"fr": "Six pelotes de fil coton doux dans des tons pastel assortis."
},
"material": "100 % Baumwolle",
"farben": [
"Pastellmix"
],
"lieferzeit": "24 Werktage",
"badges": [
"neu"
],
"bilder": []
}
@@ -0,0 +1,26 @@
{
"slug": "fuchs-plushie-mini",
"name": {
"de": "Mini-Fuchs Plushie",
"en": "Mini Fox Plushie",
"ch": "Mini-Fuchs Plushie",
"fr": "Peluche mini renard"
},
"artikelnummer": "PLU-002",
"kategorie": "diy-plushies",
"preis": 19.9,
"bestand": 0,
"beschreibung": {
"de": "Kleiner handgenähter Fuchs für die Tasche oder als Deko im Kinderzimmer.",
"en": "A small hand-sewn fox to take along or as décor for a kid's room.",
"ch": "Chline, vo Hang gnähte Fuchs für d'Täsche oder als Deko im Chinderzimmer.",
"fr": "Petit renard cousu à la main, pour le sac ou pour décorer une chambre d'enfant."
},
"material": "Baumwollstoff, Füllwatte OEKO-TEX",
"groesse": "ca. 14 cm",
"lieferzeit": "24 Werktage",
"badges": [
"handgemacht"
],
"bilder": []
}
@@ -0,0 +1,26 @@
{
"slug": "haekel-untersetzer-set",
"name": {
"de": "Häkel-Untersetzer Set (4er)",
"en": "Crochet Coaster Set (4-pack)",
"ch": "Häkel-Untersetzer Set (4er)",
"fr": "Set de 4 sous-verres au crochet"
},
"artikelnummer": "HAE-004",
"kategorie": "diy-haekelwerke",
"preis": 16,
"bestand": 14,
"beschreibung": {
"de": "Vier runde Untersetzer im Granny-Square-Stil, mixbar in vielen Farben.",
"en": "Four round coasters in granny-square style, mix and match in many colors.",
"ch": "Vier rundi Untersetzer im Granny-Square-Stil, mixbar i viel Farbe.",
"fr": "Quatre sous-verres ronds façon granny square, à combiner dans de nombreuses couleurs."
},
"material": "Baumwollgarn",
"lieferumfang": "4 Untersetzer",
"lieferzeit": "24 Werktage",
"badges": [
"neu"
],
"bilder": []
}
@@ -0,0 +1,34 @@
{
"slug": "haekeldecke-boho",
"name": {
"de": "Häkeldecke „Boho Sonnenuntergang”",
"en": "Crochet Blanket \"Boho Sunset\"",
"ch": "Häkeldecke „Boho Sonnenuntergang”",
"fr": "Plaid au crochet « Coucher de soleil bohème »"
},
"artikelnummer": "HAE-010",
"kategorie": "diy-haekelwerke",
"preis": 89,
"preisAlt": 109,
"bestand": 3,
"beschreibung": {
"de": "Großformatige Häkeldecke in warmen Terracotta- und Lila-Tönen, komplett handgehäkelt.",
"en": "A large crochet blanket in warm terracotta and purple tones, entirely hand-crocheted.",
"ch": "Grossformatigi Häkeldecki i warme Terracotta- und Lila-Töne, komplett vo Hang ghäkelt.",
"fr": "Grand plaid au crochet dans des tons chauds terracotta et violet, entièrement fait main."
},
"material": "100 % Baumwollgarn",
"groesse": "ca. 130 × 160 cm",
"farben": [
"Terracotta",
"Lila",
"Sandbeige"
],
"pflegehinweise": "Handwäsche empfohlen, liegend trocknen.",
"lieferzeit": "57 Werktage (Sonderanfertigung)",
"badges": [
"sale",
"handgemacht"
],
"bilder": []
}
@@ -0,0 +1,26 @@
{
"slug": "haekelnadel-set-ergonomisch",
"name": {
"de": "Ergonomisches Häkelnadel-Set (9-teilig)",
"en": "Ergonomic Crochet Hook Set (9-piece)",
"ch": "Ergonomisches Häkelnadel-Set (9-teilig)",
"fr": "Set de 9 crochets ergonomiques"
},
"artikelnummer": "ZUB-101",
"kategorie": "haekelzubehoer",
"preis": 22,
"bestand": 21,
"beschreibung": {
"de": "Griffige, ergonomische Häkelnadeln in 9 gängigen Stärken, inkl. Aufbewahrungsrolle.",
"en": "Comfortable, ergonomic crochet hooks in 9 common sizes, incl. a storage roll.",
"ch": "Griffigi, ergonomischi Häkelnadle i 9 gängige Stärche, inkl. Ufbewahrigsrolle.",
"fr": "Crochets ergonomiques et faciles à tenir en 9 tailles courantes, avec pochette de rangement."
},
"material": "Aluminium, Softgrip-Griff",
"lieferumfang": "9 Nadeln + Stoffrolle",
"lieferzeit": "24 Werktage",
"badges": [
"bestseller"
],
"bilder": []
}
@@ -0,0 +1,25 @@
{
"slug": "makramee-ohrringe",
"name": {
"de": "Makramee-Ohrringe „Terra”",
"en": "Macramé Earrings \"Terra\"",
"ch": "Makramee-Ohrringe „Terra”",
"fr": "Boucles d'oreilles macramé « Terra »"
},
"artikelnummer": "SCH-014",
"kategorie": "modeschmuck-accessoires",
"preis": 12,
"bestand": 0,
"beschreibung": {
"de": "Leichte, geknüpfte Ohrringe aus Makramee-Garn mit Holzperle.",
"en": "Lightweight knotted earrings made from macramé cord with a wooden bead.",
"ch": "Lychti, gknüpfti Ohrringe us Makramee-Garn mit Holzperle.",
"fr": "Boucles d'oreilles légères, nouées en fil macramé, avec perle en bois."
},
"material": "Makramee-Garn, Holzperle, Edelstahlhaken",
"lieferzeit": "24 Werktage",
"badges": [
"handgemacht"
],
"bilder": []
}
@@ -0,0 +1,30 @@
{
"slug": "perlen-armband-hellblau",
"name": {
"de": "Perlenarmband „Himmelblau”",
"en": "Beaded Bracelet \"Sky Blue\"",
"ch": "Perlenarmband „Himmelblau”",
"fr": "Bracelet de perles « Bleu ciel »"
},
"artikelnummer": "SCH-021",
"kategorie": "modeschmuck-accessoires",
"preis": 14.5,
"bestand": 9,
"beschreibung": {
"de": "Zartes, handgefädeltes Perlenarmband mit vergoldetem Verschluss.",
"en": "A delicate, hand-strung beaded bracelet with a gold-plated clasp.",
"ch": "Zarts, vo Hang gfädlets Perlearmband mit vergoldetem Verschluss.",
"fr": "Bracelet de perles délicat, enfilé à la main, avec fermoir plaqué or."
},
"material": "Glasperlen, vergoldeter Edelstahl-Verschluss",
"farben": [
"Hellblau",
"Silber"
],
"lieferzeit": "24 Werktage",
"badges": [
"handgemacht",
"neu"
],
"bilder": []
}
@@ -0,0 +1,23 @@
{
"slug": "stoffreste-bundle",
"name": {
"de": "Stoffreste-Bundle „Bunte Mischung”",
"en": "Fabric Scraps Bundle \"Colorful Mix\"",
"ch": "Stoffreste-Bundle „Bunte Mischung”",
"fr": "Lot de chutes de tissu « Mélange coloré »"
},
"artikelnummer": "BAS-018",
"kategorie": "bastelzubehoer",
"preis": 9.9,
"bestand": 25,
"beschreibung": {
"de": "Restestoffe in verschiedenen Mustern und Farben ideal für kleine Nähprojekte.",
"en": "Leftover fabrics in various patterns and colors perfect for small sewing projects.",
"ch": "Restestoff i verschiedene Muster und Farbe ideal für chlini Nöihprojäkt.",
"fr": "Chutes de tissu aux motifs et couleurs variés idéales pour de petits projets de couture."
},
"material": "Baumwollmix",
"lieferzeit": "24 Werktage",
"badges": [],
"bilder": []
}
@@ -0,0 +1,33 @@
{
"slug": "wolke-plushie-lavendel",
"name": {
"de": "Wolke-Plushie „Lavendel”",
"en": "Cloud Plushie \"Lavender\"",
"ch": "Wolke-Plushie „Lavendel”",
"fr": "Peluche nuage « Lavande »"
},
"artikelnummer": "PLU-001",
"kategorie": "diy-plushies",
"preis": 28.5,
"bestand": 6,
"beschreibung": {
"de": "Weiche, handgenähte Wolke zum Kuscheln aus kuscheligem Plüschstoff mit dezenter Lavendel-Stickerei.",
"en": "A soft, hand-sewn cloud made for cuddling plush fabric with subtle lavender embroidery.",
"ch": "Weichi, vo Hang gnähti Wolke zum Kuschle us kuschlige Plüschstoff mit dezenter Lavendel-Stickerei.",
"fr": "Nuage doux cousu à la main, parfait à câliner tissu peluche avec une broderie lavande discrète."
},
"material": "Plüschstoff (Polyester), Füllwatte OEKO-TEX",
"groesse": "ca. 24 × 16 cm",
"farben": [
"Lavendel",
"Cremeweiß"
],
"lieferumfang": "1 Plushie",
"pflegehinweise": "Handwäsche bei 30°C, nicht bügeln.",
"lieferzeit": "24 Werktage",
"badges": [
"handgemacht",
"bestseller"
],
"bilder": []
}
+14 -87
View File
@@ -1,14 +1,10 @@
import type { Locale } from "../i18n/config"; import type { Locale } from "../i18n/config";
// Hauptkategorien laut Pflichtenheft (Abschnitt 6 "Shop & Kategorien"). // Kategoriedaten kommen seit 02.08.2026 aus src/content/categories/*.json — eine Datei pro
// Neue Kategorien/Unterkategorien einfach hier ergänzen — alle Shop-Routen lesen aus dieser Datei, // Hauptkategorie, inkl. verschachtelter Unterkategorien. Im Admin-Bereich (/admin/, Sveltia
// nichts ist fest verdrahtet ("beliebig viele Unterkategorien ... müssen möglich sein"). // CMS) kann VanVan Name/Beschreibung ändern und neue Unterkategorien ergänzen, ohne Code
// name/description sind je Sprache hinterlegt (DE/EN/CH/FR) für die Mehrsprachigkeit. // anzufassen. `order` bestimmt die Reihenfolge (Dateien in einem Ordner haben von sich aus
// // keine garantierte Reihenfolge).
// Unterkategorien (seit 02.08.2026, auf VanVans Wunsch): bereits vollständig angelegt, auch
// ohne dass schon Produkte zugeordnet sind — "damit später Produkte direkt den entsprechenden
// Bereichen zugeordnet werden können" (siehe Dokument1.pdf). Zeigen bis dahin einen
// "noch keine Produkte"-Hinweis auf ihrer eigenen Seite.
type LocalizedText = Record<Locale, string>; type LocalizedText = Record<Locale, string>;
@@ -19,90 +15,21 @@ export interface Subcategory {
export interface Category { export interface Category {
slug: string; slug: string;
order: number;
name: LocalizedText; name: LocalizedText;
description: LocalizedText; description: LocalizedText;
icon: string; // dezentes Emoji als Platzhalter-Icon, bis es echte Icons/Fotos gibt icon: string; // dezentes Emoji als Platzhalter-Icon, bis es echte Icons/Fotos gibt
subcategories?: Subcategory[]; subcategories?: Subcategory[];
} }
export const categories: Category[] = [ const modules = import.meta.glob("/src/content/categories/*.json", { eager: true }) as Record<
{ string,
slug: "diy-plushies", { default: Category }
name: { de: "DIY Plushies", en: "DIY Plushies", ch: "DIY Plushies", fr: "Peluches DIY" }, >;
description: {
de: "Handgenähte Kuscheltiere und Plüschfiguren jedes Stück ein Unikat.", export const categories: Category[] = Object.values(modules)
en: "Hand-sewn stuffed animals and plush figures every piece a one-of-a-kind.", .map((m) => m.default)
ch: "Vo Hang gnähti Kuscheltier und Plüschfigure jedes Sächeli es Unikat.", .sort((a, b) => a.order - b.order);
fr: "Peluches et figurines cousues à la main chaque pièce est unique.",
},
icon: "🧸",
subcategories: [
{ slug: "kuh-frieda", name: { de: "Kuh „Frieda”", en: "Cow \"Frieda\"", ch: "Kuh „Frieda”", fr: "Vache « Frieda »" } },
{ slug: "hase-hasidog", name: { de: "Hase „HasiDog”", en: "Bunny \"HasiDog\"", ch: "Hase „HasiDog”", fr: "Lapin « HasiDog »" } },
{ slug: "wal-sam", name: { de: "Wal „Sam”", en: "Whale \"Sam\"", ch: "Wal „Sam”", fr: "Baleine « Sam »" } },
{ slug: "oktopus-siggi", name: { de: "Oktopus „Siggi”", en: "Octopus \"Siggi\"", ch: "Oktopus „Siggi”", fr: "Poulpe « Siggi »" } },
{ slug: "schildkroete-gaby", name: { de: "Schildkröte „Gaby”", en: "Turtle \"Gaby\"", ch: "Schildchröte „Gaby”", fr: "Tortue « Gaby »" } },
{ slug: "pinguin-pingi", name: { de: "Pinguin „Pingi”", en: "Penguin \"Pingi\"", ch: "Pinguin „Pingi”", fr: "Pingouin « Pingi »" } },
],
},
{
slug: "diy-haekelwerke",
name: { de: "DIY Häkelwerke", en: "DIY Crochet", ch: "DIY Häkelwerke", fr: "Crochet DIY" },
description: {
de: "Gehäkelte Deko, Accessoires und kleine Kunstwerke aus feiner Wolle.",
en: "Crocheted décor, accessories and small works of art made from fine yarn.",
ch: "Ghäkleti Deko, Accessoires und chlini Kunstwerch us feiner Wolle.",
fr: "Décorations, accessoires et petites œuvres crochetés en laine fine.",
},
icon: "🧶",
},
{
slug: "modeschmuck-accessoires",
name: { de: "DIY Modeschmuck & Accessoires", en: "DIY Jewelry & Accessories", ch: "DIY Modeschmuck & Accessoires", fr: "Bijoux & accessoires DIY" },
description: {
de: "Selbstgemachter Schmuck und Accessoires für den besonderen Auftritt.",
en: "Handmade jewelry and accessories for that special touch.",
ch: "Sälber gmachte Schmuck und Accessoires für dr bsundere Uftritt.",
fr: "Bijoux et accessoires faits main pour une touche unique.",
},
icon: "📿",
subcategories: [
{ slug: "glasperlenarmbaender", name: { de: "Glasperlenarmbänder", en: "Glass Bead Bracelets", ch: "Glasperle-Armbändel", fr: "Bracelets en perles de verre" } },
{ slug: "kunststoffperlenarmbaender", name: { de: "Kunststoffperlenarmbänder", en: "Plastic Bead Bracelets", ch: "Kunststoffperle-Armbändel", fr: "Bracelets en perles plastique" } },
{ slug: "edelstahlhalsketten", name: { de: "Edelstahlhalsketten", en: "Stainless Steel Necklaces", ch: "Edelstahl-Halschette", fr: "Colliers en acier inoxydable" } },
{ slug: "polyesterhalsketten", name: { de: "Polyesterhalsketten", en: "Polyester Necklaces", ch: "Polyester-Halschette", fr: "Colliers en polyester" } },
],
},
{
slug: "haekelzubehoer",
name: { de: "Häkelzubehör", en: "Crochet Supplies", ch: "Häkelzubehör", fr: "Fournitures de crochet" },
description: {
de: "Nadeln, Garne und alles, was dein nächstes Häkelprojekt braucht.",
en: "Hooks, yarn and everything your next crochet project needs.",
ch: "Nadle, Garn und alles, wo's für dis nächschte Häkelprojekt bruucht.",
fr: "Crochets, fils et tout ce qu'il faut pour votre prochain projet.",
},
icon: "🪡",
subcategories: [
{ slug: "maschenmarkierer", name: { de: "Maschenmarkierer", en: "Stitch Markers", ch: "Masche-Markierer", fr: "Marqueurs de mailles" } },
],
},
{
slug: "bastelzubehoer",
name: { de: "Bastelzubehör", en: "Craft Supplies", ch: "Bastelzubehör", fr: "Fournitures créatives" },
description: {
de: "Grundausstattung und kleine Helfer für kreative DIY-Projekte.",
en: "Essentials and handy little helpers for creative DIY projects.",
ch: "Grundusstattig und chlini Helfer für kreativi DIY-Projäkt.",
fr: "L'essentiel et de petits accessoires pour vos projets créatifs.",
},
icon: "✂️",
subcategories: [
{ slug: "holzknoepfe", name: { de: "Holzknöpfe", en: "Wooden Buttons", ch: "Holzchnöpf", fr: "Boutons en bois" } },
{ slug: "kunststoffknoepfe", name: { de: "Kunststoffknöpfe", en: "Plastic Buttons", ch: "Kunststoffchnöpf", fr: "Boutons en plastique" } },
],
},
];
export function getCategory(slug: string): Category | undefined { export function getCategory(slug: string): Category | undefined {
return categories.find((c) => c.slug === slug); return categories.find((c) => c.slug === slug);
+15 -205
View File
@@ -1,18 +1,11 @@
import type { Locale } from "../i18n/config"; import type { Locale } from "../i18n/config";
// Platzhalter-Produktdaten für Phase 1 (rein clientseitige Demo-Daten). // Produktdaten kommen seit 02.08.2026 aus src/content/products/*.json — eine Datei pro
// Struktur folgt bewusst den optionalen Feldern aus dem Pflichtenheft (Abschnitt 7 // Produkt. Diese JSON-Dateien werden im Admin-Bereich (/admin/, Sveltia CMS) von VanVan
// "Produktverwaltung") — nicht gesetzte Felder werden auf den Seiten automatisch // bearbeitet: neues Foto hochladen, Text ändern, Preis anpassen, fertig — kein Code nötig.
// ausgeblendet ("nicht benötigte Felder müssen deaktivierbar sein"). // `import.meta.glob(..., { eager: true })` lädt sie zur Build-Zeit synchron ein, damit sich
// // an der bestehenden API dieser Datei (products-Array + Helper-Funktionen) nichts ändert —
// Mehrsprachigkeit: `name` und `beschreibung` sind je Sprache hinterlegt (DE/EN/CH/FR). // alle Seiten, die von hier importieren, funktionieren unverändert weiter.
// Die technischen Detail-Felder (material, groesse, farben, ...) bleiben bewusst nur auf
// Deutsch — das sind ohnehin Platzhalterdaten, die in Phase 2 durch VanVans echte
// Produktangaben ersetzt werden. Die zugehörigen LABEL-Texte (z.B. "Material") kommen aus
// src/i18n/ui.ts und sind bereits übersetzt.
//
// TODO Phase 2: diese Datei durch echte Daten aus Cloudflare D1 + Worker-API ersetzen.
// TODO VanVan: echte Produktfotos, Texte und Preise liefern — alles hier ist Platzhalter.
export type Badge = "neu" | "bestseller" | "sale" | "handgemacht"; export type Badge = "neu" | "bestseller" | "sale" | "handgemacht";
@@ -34,200 +27,17 @@ export interface Product {
pflegehinweise?: string; pflegehinweise?: string;
lieferzeit?: string; lieferzeit?: string;
badges: Badge[]; badges: Badge[];
bilder?: string[]; // Pfade zu Produktfotos, von VanVan im Admin-Bereich hochgeladen
} }
export const products: Product[] = [ const modules = import.meta.glob("/src/content/products/*.json", { eager: true }) as Record<
{ string,
slug: "wolke-plushie-lavendel", { default: Product }
name: { >;
de: "Wolke-Plushie „Lavendel”", en: "Cloud Plushie \"Lavender\"",
ch: "Wolke-Plushie „Lavendel”", fr: "Peluche nuage « Lavande »", export const products: Product[] = Object.values(modules)
}, .map((m) => m.default)
artikelnummer: "PLU-001", .sort((a, b) => a.slug.localeCompare(b.slug));
kategorie: "diy-plushies",
preis: 28.5,
bestand: 6,
beschreibung: {
de: "Weiche, handgenähte Wolke zum Kuscheln aus kuscheligem Plüschstoff mit dezenter Lavendel-Stickerei.",
en: "A soft, hand-sewn cloud made for cuddling plush fabric with subtle lavender embroidery.",
ch: "Weichi, vo Hang gnähti Wolke zum Kuschle us kuschlige Plüschstoff mit dezenter Lavendel-Stickerei.",
fr: "Nuage doux cousu à la main, parfait à câliner tissu peluche avec une broderie lavande discrète.",
},
material: "Plüschstoff (Polyester), Füllwatte OEKO-TEX",
groesse: "ca. 24 × 16 cm",
farben: ["Lavendel", "Cremeweiß"],
lieferumfang: "1 Plushie",
pflegehinweise: "Handwäsche bei 30°C, nicht bügeln.",
lieferzeit: "24 Werktage",
badges: ["handgemacht", "bestseller"],
},
{
slug: "fuchs-plushie-mini",
name: { de: "Mini-Fuchs Plushie", en: "Mini Fox Plushie", ch: "Mini-Fuchs Plushie", fr: "Peluche mini renard" },
artikelnummer: "PLU-002",
kategorie: "diy-plushies",
preis: 19.9,
bestand: 0,
beschreibung: {
de: "Kleiner handgenähter Fuchs für die Tasche oder als Deko im Kinderzimmer.",
en: "A small hand-sewn fox to take along or as décor for a kid's room.",
ch: "Chline, vo Hang gnähte Fuchs für d'Täsche oder als Deko im Chinderzimmer.",
fr: "Petit renard cousu à la main, pour le sac ou pour décorer une chambre d'enfant.",
},
material: "Baumwollstoff, Füllwatte OEKO-TEX",
groesse: "ca. 14 cm",
lieferzeit: "24 Werktage",
badges: ["handgemacht"],
},
{
slug: "haekeldecke-boho",
name: {
de: "Häkeldecke „Boho Sonnenuntergang”", en: "Crochet Blanket \"Boho Sunset\"",
ch: "Häkeldecke „Boho Sonnenuntergang”", fr: "Plaid au crochet « Coucher de soleil bohème »",
},
artikelnummer: "HAE-010",
kategorie: "diy-haekelwerke",
preis: 89,
preisAlt: 109,
bestand: 3,
beschreibung: {
de: "Großformatige Häkeldecke in warmen Terracotta- und Lila-Tönen, komplett handgehäkelt.",
en: "A large crochet blanket in warm terracotta and purple tones, entirely hand-crocheted.",
ch: "Grossformatigi Häkeldecki i warme Terracotta- und Lila-Töne, komplett vo Hang ghäkelt.",
fr: "Grand plaid au crochet dans des tons chauds terracotta et violet, entièrement fait main.",
},
material: "100 % Baumwollgarn",
groesse: "ca. 130 × 160 cm",
farben: ["Terracotta", "Lila", "Sandbeige"],
pflegehinweise: "Handwäsche empfohlen, liegend trocknen.",
lieferzeit: "57 Werktage (Sonderanfertigung)",
badges: ["sale", "handgemacht"],
},
{
slug: "haekel-untersetzer-set",
name: { de: "Häkel-Untersetzer Set (4er)", en: "Crochet Coaster Set (4-pack)", ch: "Häkel-Untersetzer Set (4er)", fr: "Set de 4 sous-verres au crochet" },
artikelnummer: "HAE-004",
kategorie: "diy-haekelwerke",
preis: 16,
bestand: 14,
beschreibung: {
de: "Vier runde Untersetzer im Granny-Square-Stil, mixbar in vielen Farben.",
en: "Four round coasters in granny-square style, mix and match in many colors.",
ch: "Vier rundi Untersetzer im Granny-Square-Stil, mixbar i viel Farbe.",
fr: "Quatre sous-verres ronds façon granny square, à combiner dans de nombreuses couleurs.",
},
material: "Baumwollgarn",
lieferumfang: "4 Untersetzer",
lieferzeit: "24 Werktage",
badges: ["neu"],
},
{
slug: "perlen-armband-hellblau",
name: { de: "Perlenarmband „Himmelblau”", en: "Beaded Bracelet \"Sky Blue\"", ch: "Perlenarmband „Himmelblau”", fr: "Bracelet de perles « Bleu ciel »" },
artikelnummer: "SCH-021",
kategorie: "modeschmuck-accessoires",
preis: 14.5,
bestand: 9,
beschreibung: {
de: "Zartes, handgefädeltes Perlenarmband mit vergoldetem Verschluss.",
en: "A delicate, hand-strung beaded bracelet with a gold-plated clasp.",
ch: "Zarts, vo Hang gfädlets Perlearmband mit vergoldetem Verschluss.",
fr: "Bracelet de perles délicat, enfilé à la main, avec fermoir plaqué or.",
},
material: "Glasperlen, vergoldeter Edelstahl-Verschluss",
farben: ["Hellblau", "Silber"],
lieferzeit: "24 Werktage",
badges: ["handgemacht", "neu"],
},
{
slug: "makramee-ohrringe",
name: { de: "Makramee-Ohrringe „Terra”", en: "Macramé Earrings \"Terra\"", ch: "Makramee-Ohrringe „Terra”", fr: "Boucles d'oreilles macramé « Terra »" },
artikelnummer: "SCH-014",
kategorie: "modeschmuck-accessoires",
preis: 12,
bestand: 0,
beschreibung: {
de: "Leichte, geknüpfte Ohrringe aus Makramee-Garn mit Holzperle.",
en: "Lightweight knotted earrings made from macramé cord with a wooden bead.",
ch: "Lychti, gknüpfti Ohrringe us Makramee-Garn mit Holzperle.",
fr: "Boucles d'oreilles légères, nouées en fil macramé, avec perle en bois.",
},
material: "Makramee-Garn, Holzperle, Edelstahlhaken",
lieferzeit: "24 Werktage",
badges: ["handgemacht"],
},
{
slug: "haekelnadel-set-ergonomisch",
name: { de: "Ergonomisches Häkelnadel-Set (9-teilig)", en: "Ergonomic Crochet Hook Set (9-piece)", ch: "Ergonomisches Häkelnadel-Set (9-teilig)", fr: "Set de 9 crochets ergonomiques" },
artikelnummer: "ZUB-101",
kategorie: "haekelzubehoer",
preis: 22,
bestand: 21,
beschreibung: {
de: "Griffige, ergonomische Häkelnadeln in 9 gängigen Stärken, inkl. Aufbewahrungsrolle.",
en: "Comfortable, ergonomic crochet hooks in 9 common sizes, incl. a storage roll.",
ch: "Griffigi, ergonomischi Häkelnadle i 9 gängige Stärche, inkl. Ufbewahrigsrolle.",
fr: "Crochets ergonomiques et faciles à tenir en 9 tailles courantes, avec pochette de rangement.",
},
material: "Aluminium, Softgrip-Griff",
lieferumfang: "9 Nadeln + Stoffrolle",
lieferzeit: "24 Werktage",
badges: ["bestseller"],
},
{
slug: "baumwollgarn-bundle",
name: { de: "Baumwollgarn-Bundle „Pastell” (6 Knäuel)", en: "Cotton Yarn Bundle \"Pastel\" (6 skeins)", ch: "Baumwollgarn-Bundle „Pastell” (6 Knäuel)", fr: "Lot de fil coton « Pastel » (6 pelotes)" },
artikelnummer: "ZUB-205",
kategorie: "haekelzubehoer",
preis: 24.9,
bestand: 17,
beschreibung: {
de: "Sechs Knäuel weiches Baumwollgarn in aufeinander abgestimmten Pastelltönen.",
en: "Six skeins of soft cotton yarn in coordinated pastel shades.",
ch: "Sächs Chnöiel weichs Baumwollgarn i aufenand abgstimmte Pastelltöne.",
fr: "Six pelotes de fil coton doux dans des tons pastel assortis.",
},
material: "100 % Baumwolle",
farben: ["Pastellmix"],
lieferzeit: "24 Werktage",
badges: ["neu"],
},
{
slug: "bastel-starterset",
name: { de: "DIY Bastel-Starterset", en: "DIY Craft Starter Kit", ch: "DIY Bastel-Starterset", fr: "Kit créatif de démarrage DIY" },
artikelnummer: "BAS-050",
kategorie: "bastelzubehoer",
preis: 34,
preisAlt: 42,
bestand: 8,
beschreibung: {
de: "Alles für den Einstieg: Schere, Kleber, Knöpfe, Bänder und eine kleine Anleitung mit drei Projekten.",
en: "Everything to get started: scissors, glue, buttons, ribbon and a little guide with three projects.",
ch: "Alles für dr Iistig: Schere, Chläber, Chnöpf, Bändel und e chlini Aaleitig mit drei Projäkt.",
fr: "Tout pour débuter : ciseaux, colle, boutons, rubans et un petit guide avec trois projets.",
},
lieferumfang: "1 Set (siehe Beschreibung)",
lieferzeit: "24 Werktage",
badges: ["sale"],
},
{
slug: "stoffreste-bundle",
name: { de: "Stoffreste-Bundle „Bunte Mischung”", en: "Fabric Scraps Bundle \"Colorful Mix\"", ch: "Stoffreste-Bundle „Bunte Mischung”", fr: "Lot de chutes de tissu « Mélange coloré »" },
artikelnummer: "BAS-018",
kategorie: "bastelzubehoer",
preis: 9.9,
bestand: 25,
beschreibung: {
de: "Restestoffe in verschiedenen Mustern und Farben ideal für kleine Nähprojekte.",
en: "Leftover fabrics in various patterns and colors perfect for small sewing projects.",
ch: "Restestoff i verschiedene Muster und Farbe ideal für chlini Nöihprojäkt.",
fr: "Chutes de tissu aux motifs et couleurs variés idéales pour de petits projets de couture.",
},
material: "Baumwollmix",
lieferzeit: "24 Werktage",
badges: [],
},
];
export function getProduct(slug: string): Product | undefined { export function getProduct(slug: string): Product | undefined {
return products.find((p) => p.slug === slug); return products.find((p) => p.slug === slug);