"use client"; import { useState, useCallback, useEffect } from "react"; import { motion, AnimatePresence } from "framer-motion"; import { IoChevronForward, IoDiscOutline, IoPulseOutline } from "react-icons/io5"; import { useCart } from "@/components/cart/CartContext"; import type { MatchedGroup, MatchedSubgroup, MatchedVariant } from "@/lib/variants"; const FORMAT_PREF_KEY = "trptk_format_pref"; const DISC_FALLBACKS: Record = { cd: "sacd", sacd: "cd" }; type FormatPref = { groupSlug: string; subgroupSlug: string | null; variantSlug: string; }; type Props = { groups: MatchedGroup[]; releaseDate?: string; }; const groupIcons: Record = { physical: , digital: , }; /** Strip the subgroup prefix (e.g. "Stereo " / "Surround ") from a variant title when redundant. */ function shortVariantTitle(title: string, subgroup: MatchedSubgroup | null): string { if (!subgroup) return title; const prefix = subgroup.label + " "; return title.startsWith(prefix) ? title.slice(prefix.length) : title; } function formatPrice(amount: number, currencyCode: string) { return new Intl.NumberFormat("en-US", { style: "currency", currency: currencyCode, minimumFractionDigits: 2, }).format(amount); } const fadeVariants = { initial: { opacity: 0, y: 6 }, animate: { opacity: 1, y: 0, transition: { type: "tween" as const, ease: "easeInOut" as const, duration: 0.25 }, }, exit: { opacity: 0, y: -6, transition: { type: "tween" as const, ease: "easeInOut" as const, duration: 0.15 }, }, }; const optionBase = "relative z-10 w-full rounded-xl border bg-lightbg p-4 shadow-lg text-center transition-all hover:border-lightline-hover hover:text-trptkblue dark:bg-darkbg dark:hover:border-darkline-hover dark:hover:text-white duration-200 border-lightline dark:border-darkline text-lighttext dark:text-darktext ease-in-out"; const optionSelected = "relative z-10 w-full border-trptkblue bg-[oklch(0.921_0.012_252.4)] text-trptkblue dark:border-white dark:bg-[oklch(0.335_0.021_262.52)] dark:text-white rounded-xl border p-4 shadow-lg text-center transition-all duration-200 ease-in-out text-lighttext dark:text-darktext"; export function FormatSelector({ groups, releaseDate }: Props) { const { addItem, isAdding } = useCart(); const isPreorder = releaseDate ? new Date(releaseDate) > new Date() : false; // Navigation state const [selectedGroup, setSelectedGroup] = useState(null); const [selectedSubgroup, setSelectedSubgroup] = useState(null); const [selectedVariant, setSelectedVariant] = useState(null); const reset = useCallback(() => { setSelectedGroup(null); setSelectedSubgroup(null); setSelectedVariant(null); }, []); // Restore last-used format preference on mount useEffect(() => { try { const raw = localStorage.getItem(FORMAT_PREF_KEY); if (!raw) return; const pref: FormatPref = JSON.parse(raw); const group = groups.find((g) => g.slug === pref.groupSlug); if (!group) return; if (pref.subgroupSlug && group.subgroups) { const subgroup = group.subgroups.find((sg) => sg.slug === pref.subgroupSlug); if (!subgroup) return; const variant = subgroup.variants.find((v) => v.slug === pref.variantSlug); if (!variant) return; setSelectedGroup(group); setSelectedSubgroup(subgroup); setSelectedVariant(variant); } else if (group.variants) { const variant = group.variants.find((v) => v.slug === pref.variantSlug) ?? group.variants.find((v) => v.slug === DISC_FALLBACKS[pref.variantSlug]); if (!variant) return; setSelectedGroup(group); setSelectedVariant(variant); } } catch {} }, [groups]); const goToGroup = useCallback((group: MatchedGroup) => { setSelectedGroup(group); setSelectedSubgroup(null); setSelectedVariant(null); // If the group has direct variants (Physical) and only one, auto-select if (group.variants && group.variants.length === 1) { setSelectedVariant(group.variants[0]); } }, []); const goToSubgroup = useCallback((subgroup: MatchedSubgroup) => { setSelectedSubgroup(subgroup); setSelectedVariant(null); if (subgroup.variants.length === 1) { setSelectedVariant(subgroup.variants[0]); } }, []); const handleAddToCart = useCallback(async () => { if (!selectedVariant) return; await addItem(selectedVariant.medusaVariantId); // Save selection path so the next release page pre-selects the same format const pref: FormatPref = { groupSlug: selectedGroup?.slug ?? groups[0]?.slug ?? "", subgroupSlug: selectedSubgroup?.slug ?? null, variantSlug: selectedVariant.slug, }; try { localStorage.setItem(FORMAT_PREF_KEY, JSON.stringify(pref)); } catch {} }, [selectedVariant, selectedGroup, selectedSubgroup, groups, addItem]); if (groups.length === 0) return null; // Auto-select if only one group const effectiveGroup = groups.length === 1 ? groups[0] : selectedGroup; const showGroupStep = groups.length > 1 && !selectedGroup; // Determine current step for breadcrumb const breadcrumbs: { label: string; onClick?: () => void }[] = []; if (groups.length > 1) { breadcrumbs.push({ label: "Format", onClick: selectedGroup ? reset : undefined, }); } if (effectiveGroup) { breadcrumbs.push({ label: effectiveGroup.label, onClick: selectedSubgroup ? () => { setSelectedSubgroup(null); setSelectedVariant(null); } : undefined, }); } if (selectedSubgroup) { breadcrumbs.push({ label: selectedSubgroup.label }); } // Determine what to show const showPhysicalVariants = effectiveGroup && effectiveGroup.variants && !showGroupStep; const showSubgroups = effectiveGroup && effectiveGroup.subgroups && !selectedSubgroup && !showGroupStep; const showDigitalVariants = selectedSubgroup != null; // Which variants to display? const displayVariants = showPhysicalVariants ? effectiveGroup!.variants! : showDigitalVariants ? selectedSubgroup!.variants : null; // Subgroups to display const displaySubgroups = showSubgroups ? effectiveGroup!.subgroups! : null; return (
{/* Breadcrumbs */} {breadcrumbs.length > 0 && ( )} {/* Step 1: Group selection (Physical / Digital) */} {showGroupStep && ( {groups.map((group) => ( ))} )} {/* Subgroups (Stereo, Surround, Immersive, Video) */} {displaySubgroups && ( {displaySubgroups.map((sg) => ( ))} )} {/* Variant selection (final step — pick a specific format) */} {displayVariants && ( {displayVariants.map((v) => ( ))} )} {/* Add to Cart */} {selectedVariant && ( {isPreorder && releaseDate && (

Available{" "} {new Intl.DateTimeFormat("en-US", { month: "long", day: "numeric", year: "numeric", }).format(new Date(releaseDate))}

)}
)}
); }