--- import type { Product } from "../data/products"; import type { Locale } from "../i18n/config"; import { localePrefix } from "../i18n/config"; import { useTranslations } from "../i18n/ui"; import { formatPrice } from "../i18n/format"; import { effektiverPreis, rabattLabel, hatAktivenRabatt } from "../data/rabatt"; import { durchschnittsbewertung, anzahlBewertungen } from "../data/products"; import HeartRating from "./HeartRating.astro"; interface Props { product: Product; lang: Locale } const { product, lang } = Astro.props; const t = useTranslations(lang); const finalPrice = effektiverPreis(product); const discountBadge = rabattLabel(product); const showOldAsPreis = !product.preisAlt && hatAktivenRabatt(product); const bewertungSchnitt = durchschnittsbewertung(product); const bewertungAnzahl = anzahlBewertungen(product); const badgeLabel: Record = { neu: t.badge.neu, bestseller: t.badge.bestseller, sale: t.badge.sale, handgemacht: t.badge.handgemacht, }; const name = product.name[lang]; const desc = product.beschreibung[lang]; ---
{product.bilder && product.bilder.length > 0 ? ( <> {product.bilder.map((bild, i) => ( {name} ))} {product.bilder.length > 1 && ( <> )} ) : ( )}
{product.badges.map((b) => ( {badgeLabel[b]} ))} {product.bestand === 0 && {t.badge.ausverkauft}} {discountBadge && {discountBadge}}

{name}

{/* Immer gerendert (auch ohne Server-Bewertungen), aber standardmäßig versteckt — ein gemeinsames Skript (siehe unten) blendet die Zeile automatisch ein, sobald auf diesem Gerät lokal gespeicherte Kundenrezensionen für dieses Produkt dazukommen (siehe scripts/reviews.ts), egal auf welcher Seite die Karte gerade angezeigt wird. */} {bewertungSchnitt !== null && ( )}

{desc.slice(0, 78)}{desc.length > 78 ? "…" : ""}

{product.preisAlt && {formatPrice(product.preisAlt, lang)}} {showOldAsPreis && {formatPrice(product.preis, lang)}} {formatPrice(finalPrice, lang)}