--- import Layout from "../../layouts/Layout.astro"; import ProductCard from "../../components/ProductCard.astro"; import { products, getProduct } from "../../data/products"; import type { Locale } from "../../i18n/config"; import { useTranslations } from "../../i18n/ui"; import { formatPrice } from "../../i18n/format"; import { ABO_STUFEN, aboStufenKonfig, aboStufeName, aboStufeVorteil, type AboStufe } from "../../data/abo"; const lang: Locale = "de"; const t = useTranslations(lang); // Bestellungen sind weiterhin Beispieldaten (siehe previewNote) — ECHT sind ab jetzt aber // Anmeldung, Profil (Benutzername/Foto) und Rezensionen, gespeichert im localStorage dieses // Geräts (siehe scripts/account.ts, scripts/reviews.ts). Jede Bestellposition referenziert // einen echten Produkt-Slug — der Name kommt live aus den Produktdaten (mehrsprachig, immer // konsistent mit dem Shop), damit "Rezension schreiben" wirklich zur passenden Seite führt. const beispielBestellungenRoh = [ { nummer: "VDB-2026-0184", datum: "28.07.2026", status: "versendet" as const, tracking: "00340434161094015791", artikel: [ { slug: "hasidog-plushie-blaueroverall", menge: 1 }, { slug: "perlen-armband-hellblau", menge: 1 }, ], }, { nummer: "VDB-2026-0157", datum: "12.07.2026", status: "abgeschlossen" as const, tracking: null, artikel: [{ slug: "haekelnadel-set-ergonomisch", menge: 1 }], }, ]; const beispielBestellungen = beispielBestellungenRoh.map((b) => { const artikel = b.artikel.map((a) => { const p = getProduct(a.slug); return { ...a, name: p?.name[lang] ?? a.slug, preis: p?.preis ?? 0 }; }); return { ...b, artikel, summe: artikel.reduce((s, a) => s + a.preis * a.menge, 0) }; }); const statusLabel = { bezahlt: t.accountDash.statusBezahlt, bearbeitung: t.accountDash.statusBearbeitung, versandVorbereitet: t.accountDash.statusVersandVorbereitet, versendet: t.accountDash.statusVersendet, abgeschlossen: t.accountDash.statusAbgeschlossen, } as const; // Abo-Pläne: Namen/Vorteilstexte UND Preis/Rabatt kommen komplett aus den admin-editierbaren // Einstellungen (src/content/abo-einstellungen.json) — VanVan kann im CMS alles zum Abo selbst // pflegen. Reihenfolge fest klein → mittel → groß. const aboPlanLabels: Record = { klein: { name: aboStufeName("klein", lang), vorteil: aboStufeVorteil("klein", lang) }, mittel: { name: aboStufeName("mittel", lang), vorteil: aboStufeVorteil("mittel", lang) }, gross: { name: aboStufeName("gross", lang), vorteil: aboStufeVorteil("gross", lang) }, }; // Eigenes Icon je Stufe (rein optisch, nicht admin-editierbar) — soll auf einen Blick erkennbar // machen, dass es sich um eine aufsteigende Reihe handelt (Keimling → Blatt → Krone). const aboPlanIcon: Record = { klein: "🌱", mittel: "🌿", gross: "👑" }; // "Zuletzt angesehen" zeigt in dieser Vorschau einfach die ersten echten Produkte aus dem Shop — // in Phase 2 kommt hier die tatsächliche Verlaufs-Historie der angemeldeten Person hin. const zuletztAngesehen = products.slice(0, 3); // "Offene Sendungen" = alles außer abgeschlossen (bezahlt/bearbeitung/versandVorbereitet/ // versendet), damit die Zahl exakt zu dem passt, was der "Offene Sendungen"-Tab tatsächlich // zeigt. "Bestellungen" zählt entsprechend nur die schon angekommenen (abgeschlossenen). const offeneSendungen = beispielBestellungen.filter((b) => b.status !== "abgeschlossen").length; const angekommeneBestellungen = beispielBestellungen.filter((b) => b.status === "abgeschlossen").length; ---

{t.accountDash.previewNote}

{/* Schnellnavigation: eine zusammenhängende Leiste direkt über "Meine Bestellungen" / "Meine Wunschliste" statt drei loser Kästchen — jedes Segment springt zum passenden Abschnitt weiter unten, Icon und Akzentfarbe passen zur jeweiligen Überschrift. */}

{t.accountDash.ordersTitle}

{beispielBestellungen.map((b) => (
{t.accountDash.orderNo} {b.nummer} {t.accountDash.orderDate} {b.datum}
{statusLabel[b.status]}
    {b.artikel.map((a) => (
  • {a.menge}× {a.name} {formatPrice(a.preis * a.menge, lang)} {/* Zustand (Button vs. "✓ Bewertet") hängt vom localStorage ab — wird per JS beim Laden gesetzt (siehe Script unten), Grundzustand ist der Button. */} {t.accountDash.reviewBtn}
  • ))}
{t.accountDash.orderTotal}: {formatPrice(b.summe, lang)}
{b.tracking && {t.accountDash.trackingBtn}} {t.accountDash.reorderBtn}
{b.tracking && (

{t.accountDash.trackingLabel}: {b.tracking}

)} {/* Rechnung direkt auf der Seite ansehen (natives , siehe Skript unten) — kein Download nötig. Empfängername wird beim Öffnen live aus dem Konto befüllt (siehe .invoice-billto-name), Adresse ist bewusst dieselbe Platzhalter-Adresse wie oben unter "Meine Daten". */}

{t.accountDash.invoiceTitle}

{t.accountDash.invoiceNumberLabel}: {b.nummer}

{t.accountDash.invoiceDateLabel}: {b.datum}

{t.accountDash.invoiceSellerLabel}

Van's DIY & Bastelbedarf

{t.accountDash.invoiceBillToLabel}


Musterstraße 1
10115 Berlin
Deutschland

{b.artikel.map((a) => ( ))}
{t.accountDash.invoiceItemLabel} {t.accountDash.invoiceQtyLabel} {t.accountDash.invoiceUnitPriceLabel} {t.accountDash.invoiceSumLabel}
{a.name} {a.menge} {formatPrice(a.preis, lang)} {formatPrice(a.preis * a.menge, lang)}
{t.accountDash.orderTotal} {formatPrice(b.summe, lang)}

{t.common.vatNote}

))}

{t.accountDash.wishlistTitle}

{t.accountDash.wishlistEmpty}

{zuletztAngesehen.length > 0 && (

{t.accountDash.recentTitle}

{zuletztAngesehen.map((p) => )}
)}

{t.accountDash.profileTitle}

{t.accountDash.photoLabel}
{/* Optionaler Spitzname zuerst (Bonus, wird bevorzugt angezeigt), darunter der feste Pflicht-Name (z.B. für Bestellungen/Lieferadresse). */}
{t.accountDash.usernameHint}
{/* Name, E-Mail und Lieferadresse sind fest (wie bei einer echten Bestellung) — nur der Spitzname oben ist änderbar. */}
{t.accountDash.profileName}
{t.accountDash.profileEmail}
{t.accountDash.profileAddress}Musterstraße 1
10115 Berlin
Deutschland
{/* Treuebonus: 10 gültige, abgeschlossene Bestellungen → 20% auf einen frei wählbaren Artikel (siehe scripts/account.ts). Fortschritt/Status kommen komplett aus dem Konto und werden per JS befüllt (siehe Skript unten) — hier nur das Gerüst mit sinnvollen Leerzuständen. */}

{t.accountDash.loyaltyTitle}

{/* Treuebonus ist an ein aktives Abo gekoppelt (soll als Zusatzanreiz fürs Abo wirken) — ohne aktives Abo wird dieser gesperrte Hinweis statt des Fortschritts gezeigt (siehe renderLoyalty() im Skript unten, treueFortschritt().gesperrt). */}

{t.accountDash.loyaltyExplainer}

{/* Abosystem: drei Mitgliedschaftsstufen mit dauerhaftem Rabatt + Teddy-Prämien. Preise/Rabatte kommen aus src/content/abo-einstellungen.json (admin-editierbar via Decap CMS), Status/ Fortschritt/Benachrichtigungen komplett aus dem Konto (siehe scripts/account.ts) und werden per JS befüllt (Skript unten) — hier nur das Gerüst mit sinnvollen Leerzuständen. */}

{t.accountDash.aboTitle}

{t.accountDash.aboIntro}

{ABO_STUFEN.map((stufe) => { const cfg = aboStufenKonfig(stufe); const labels = aboPlanLabels[stufe]; return (

{labels.name}

{formatPrice(cfg.preis, lang)} {t.accountDash.aboPreisSuffix}

💰 −{cfg.rabattProzent}%
{cfg.kleinIntervallMonate > 0 && ( 🧸 {t.accountDash.aboRewardEveryLabel.replace("{n}", String(cfg.kleinIntervallMonate))} )} {cfg.grossIntervallMonate > 0 && ( 🧸🧸 {t.accountDash.aboRewardEveryLabel.replace("{n}", String(cfg.grossIntervallMonate))} )}

{labels.vorteil}

); })}

{t.accountDash.aboBenachrichtigungenTitle}

  • {t.accountDash.aboKeineBenachrichtigungen}

{t.accountDash.aboExplainer}