diff --git a/app/cart/components/CartContent.tsx b/app/cart/components/CartContent.tsx index 26fccdb..610dd40 100644 --- a/app/cart/components/CartContent.tsx +++ b/app/cart/components/CartContent.tsx @@ -5,7 +5,7 @@ import Link from "next/link"; import Image from "next/image"; import { useCart, removeFromCart, setQuantity } from "../../lib/cart"; import { useProducts } from "../../lib/products"; -import { formatPrice } from "../../lib/format"; +import { formatPrice, discountPercent } from "../../lib/format"; import { Reveal } from "../../components/Reveal"; import { VersandModal } from "../../components/VersandModal"; import { FreeShippingBanner } from "./FreeShippingBanner"; @@ -96,7 +96,9 @@ export function CartContent({ have had room for a real 2-column layout at Tablet widths anyway). */} - {items.map(({ entry, product }, i) => ( + {items.map(({ entry, product }, i) => { + const discount = discountPercent(product.price, product.compareAtPrice); + return (
{i > 0 &&
}
@@ -114,6 +116,9 @@ export function CartContent({

Einzelpreis

+ {discount !== null && ( + {formatPrice(product.compareAtPrice!)} + )} {formatPrice(product.price)} inkl. MwSt.

@@ -147,7 +152,8 @@ export function CartContent({
- ))} + ); + })}
diff --git a/app/components/ProductSpotlight.tsx b/app/components/ProductSpotlight.tsx index 3185401..958d777 100644 --- a/app/components/ProductSpotlight.tsx +++ b/app/components/ProductSpotlight.tsx @@ -3,7 +3,7 @@ import Link from "next/link"; import { AddToCartButton } from "./AddToCartButton"; import { Reveal } from "./Reveal"; import { getSpotlightProduct } from "../lib/payload"; -import { formatPrice } from "../lib/format"; +import { formatPrice, discountPercent } from "../lib/format"; /** * Product teaser for whichever product is marked `spotlight` in Payload @@ -26,6 +26,7 @@ export async function ProductSpotlight() { if (!product) return null; const image = product.spotlightImage || product.image; + const discount = discountPercent(product.price, product.compareAtPrice); return (
@@ -38,6 +39,11 @@ export async function ProductSpotlight() { sizes="(min-width: 768px) 380px, 100vw" className="object-cover transition-transform duration-500 group-hover:scale-105" /> + {discount !== null && ( + + -{discount}% + + )}
@@ -51,9 +57,9 @@ export async function ProductSpotlight() {

{product.spotlightText || product.description}

-
- {product.compareAtPrice && product.compareAtPrice > product.price && ( -

{formatPrice(product.compareAtPrice)}

+
+ {discount !== null && ( +

{formatPrice(product.compareAtPrice!)}

)}

{formatPrice(product.price)}

inkl. MwSt. zzgl. Versand

diff --git a/app/lib/format.ts b/app/lib/format.ts index b9f625b..811601f 100644 --- a/app/lib/format.ts +++ b/app/lib/format.ts @@ -10,6 +10,15 @@ export function formatPrice(value: number): string { return `${value.toFixed(2).replace(".", ",")} €`; } +// null when there's nothing to advertise — compareAtPrice unset, or set +// but not actually higher than price (e.g. cleared back down without +// nulling the field). Callers use this both to gate whether to render +// strikethrough/badge UI at all and to fill in the "-XX%" label. +export function discountPercent(price: number, compareAtPrice: number | null): number | null { + if (compareAtPrice === null || compareAtPrice <= price) return null; + return Math.round((1 - price / compareAtPrice) * 100); +} + const MONTHS_DE = [ "Januar", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember", diff --git a/app/shop/components/ProductGrid.tsx b/app/shop/components/ProductGrid.tsx index 1749bf4..4979559 100644 --- a/app/shop/components/ProductGrid.tsx +++ b/app/shop/components/ProductGrid.tsx @@ -1,7 +1,7 @@ import Link from "next/link"; import Image from "next/image"; import { getProducts } from "../../lib/payload"; -import { formatPrice } from "../../lib/format"; +import { formatPrice, discountPercent } from "../../lib/format"; import { RevealGroup, RevealItem } from "../../components/Reveal"; import { AddToCartInlineButton } from "../../components/AddToCartInlineButton"; @@ -22,7 +22,9 @@ export async function ProductGrid() { return (
- {products.map((product) => ( + {products.map((product) => { + const discount = discountPercent(product.price, product.compareAtPrice); + return ( + {discount !== null && ( + + -{discount}% + + )}

+ {discount !== null && ( + {formatPrice(product.compareAtPrice!)} + )} {formatPrice(product.price)} inkl. MwSt.

@@ -66,7 +76,8 @@ export async function ProductGrid() {
- ))} + ); + })} ); diff --git a/app/todo-cards/components/Pricing.tsx b/app/todo-cards/components/Pricing.tsx index e2d5d97..ab4c31c 100644 --- a/app/todo-cards/components/Pricing.tsx +++ b/app/todo-cards/components/Pricing.tsx @@ -55,7 +55,7 @@ export async function Pricing() {
-
+

{formatPrice(product.price)}

inkl. MwSt. zzgl. Versand