import { useEffect, useMemo, useState } from "react"; import { Link, useNavigate, useParams } from "react-router"; import perfumes from "../data/perfumes"; import SharedNavbar from "./SharedNavbar"; import { formatChf } from "../shop/money"; import { useShop } from "../shop/useShop"; import "./ProductDetailPage.css"; const priceToCents = (price) => { const match = String(price).match(/(\d+)/); return match ? Number(match[1]) * 100 : 0; }; function ProductDetailContent({ perfumeSlug }) { const navigate = useNavigate(); const { addToCart, subscribeToProduct, user } = useShop(); const perfume = useMemo( () => perfumes.find((item) => item.slug === perfumeSlug) || perfumes[0], [perfumeSlug] ); const [selectedImage, setSelectedImage] = useState( perfume.gallery?.[0] || perfume.image ); const [selectedSize, setSelectedSize] = useState("sample"); const [showReviewDetails, setShowReviewDetails] = useState(false); const [commentPage, setCommentPage] = useState(0); const [isStructureOpen, setIsStructureOpen] = useState(false); const [isMoodOpen, setIsMoodOpen] = useState(false); const selectedProductId = `${perfume.slug}-${selectedSize === "sample" ? "sample" : "full"}`; const selectedProductLabel = selectedSize === "sample" ? "Sample" : "Full Size"; const selectedPriceCents = priceToCents(perfume.prices[selectedSize]); const sampleCredit = user?.sampleCredits?.find( (credit) => credit.slug === perfume.slug && credit.status === "available" ); const discountPreviewCents = selectedSize === "full" ? Math.min( selectedPriceCents, (user?.discoveryStatus === "Discount available" ? 4800 : 0) + (sampleCredit?.amount_cents || 0) ) : 0; const sizeOptions = [ { key: "sample", title: "Sample 2ml", price: perfume.prices.sample, note: "Zum Testen · ca. 20 Anwendungen", }, { key: "full", title: "Full Size 50ml", price: perfume.prices.full, note: "Nachkauf · 500+ Anwendungen", }, ]; const reviewSummary = perfume.reviews || { score: 0, total: 0, metrics: [], }; const reviewComments = perfume.commentSpotlight || []; const commentPages = []; for (let i = 0; i < reviewComments.length; i += 2) { commentPages.push(reviewComments.slice(i, i + 2)); } const safeCommentPages = commentPages.length > 0 ? commentPages : [ [ { id: "fallback-1", name: "Atelier", title: "Noch keine Stimmen", text: "Für diesen Duft sind aktuell noch keine Kommentare hinterlegt.", }, ], ]; useEffect(() => { const interval = window.setInterval(() => { setCommentPage((prev) => (prev + 1) % safeCommentPages.length); }, 5000); return () => window.clearInterval(interval); }, [safeCommentPages.length]); return (
DUFTDETAIL {perfume.name}
{perfume.name}
{[perfume.image, ...(perfume.gallery || [])] .slice(0, 3) .map((img, index) => ( ))}
TRAGEHINWEIS

{perfume.dosage}

HALTBARKEIT

{perfume.longevity}

ANLASS

{perfume.occasion}

{/* --- Accordion Group Start --- */}
{/* Dropdown: Duftstruktur */}
{isStructureOpen && (
PHASE 1: TOP NOTES (0–1 H)
{perfume.phases.top.map((note) => ( {note} ))}
PHASE 2: HEART NOTES (1–4 H)
{perfume.phases.heart.map((note) => ( {note} ))}
PHASE 3: BASE NOTES (4 H+)
{perfume.phases.base.map((note) => ( {note} ))}
)}
{/* Dropdown: Moodsetting */}
{isMoodOpen && (

{perfume.mood}

)}
{/* --- Accordion Group End --- */}
Edition 04

{perfume.name}

{perfume.shortText}

MATERIAL-KOMPOSITION
{perfume.materialTags.map((tag) => ( {tag} ))}
GRÖSSE WÄHLEN
{sizeOptions.map((option) => ( ))}
Discovery Set wird einmalig angerechnet

Nur das erste Discovery Set erzeugt CHF 48 Guthaben. Es wird einmal bei einem späteren Full-Size-Kauf automatisch abgezogen.

{discountPreviewCents > 0 && (

Erwarteter Preis mit Rabatt:{" "} {formatChf(selectedPriceCents - discountPreviewCents)}

)}
Zum Set
BESCHREIBUNG
PARFÜMERIE / STUDIO

{perfume.description}

HERKUNFT

{perfume.origin}

KONZENTRATION

{perfume.concentration}

EDITION

{perfume.edition}

LIEFERUNG CH
VERSAND

Innerhalb von 1–2 Werktagen

ZUSTELLUNG

In der Regel in 5–6 Tagen bei dir

HINWEIS

Sorgfältig verpackt und geschützt versendet.

STIMMEN ZUM DUFT
{safeCommentPages.map((_, index) => (
{safeCommentPages[commentPage].map((comment) => (
{comment.title}

{comment.text}

{comment.name}
))}
RESONANZ

Verdichtete Wahrnehmung aus bisherigen Stimmen zu Charakter, Haltbarkeit, Sillage und Originalität.

{reviewSummary.score.toFixed(1)}
★★★★★ {reviewSummary.total} Stimmen
{showReviewDetails && (
{reviewSummary.metrics.map((metric) => (
{metric.label}
{metric.value.toFixed(1)}
))}
)}

Lieber erst testen?

Bestelle ein 2ml Sample für CHF 12 oder das komplette Discovery Set mit allen 6 Düften für CHF 48. Beide werden beim späteren Full-Size-Kauf vollständig angerechnet.

); } function ProductDetailPage() { const { perfumeSlug = "kalter-beton" } = useParams(); return ; } export default ProductDetailPage;