import { useEffect, useState } from "react"; import { useParams } from "react-router"; import type { ShopifyProduct } from "@reacteditor/field-shopify"; import { useProduct } from "@/hooks/use-shopify-products"; import { useShopifyCart } from "@/hooks/use-shopify-cart"; import { Typography } from "@/components/Typography"; import { cn } from "@/lib/utils"; import { Skeleton } from "@/components/ui/skeleton"; export type ProductDetailsProps = { product: ShopifyProduct | null; }; export function ProductDetailsView({ product: selected }: ProductDetailsProps) { const { handle: paramHandle } = useParams<{ handle?: string }>(); const handle = selected?.handle ?? paramHandle ?? null; const { product, loading } = useProduct(handle); const cart = useShopifyCart(); const [activeImage, setActiveImage] = useState(0); const [variant, setVariant] = useState(null); const [quantity, setQuantity] = useState(1); const [adding, setAdding] = useState(false); useEffect(() => { if (product?.variants?.edges?.length) { setVariant(product.variants.edges[0].node); } }, [product]); if (!handle || loading || !product) { return (
{Array.from({ length: 4 }).map((_, i) => ( ))}
); } const images = product.images?.edges?.map((e: any) => e.node) ?? []; const main = images[activeImage]; const price = variant?.price ?? product.priceRange?.minVariantPrice; const formatted = price ? new Intl.NumberFormat("en-US", { style: "currency", currency: price.currencyCode, }).format(parseFloat(price.amount)) : null; const onAdd = async () => { if (!variant) return; setAdding(true); try { await cart.addItem(variant.id, quantity); cart.openCart(); } finally { setAdding(false); } }; return (
{main ? ( {main.altText ) : null}
{images.length > 1 ? (
{images.map((img: any, i: number) => ( ))}
) : null}
{product.title} {formatted ? ( {formatted} ) : null}
{(product.options ?? []).map((opt: any) => (

{opt.name}

{opt.values.map((val: string) => { const matching = product.variants.edges.find((e: any) => e.node.selectedOptions?.some( (o: any) => o.name === opt.name && o.value === val, ), ); const selected = variant?.selectedOptions?.some( (o: any) => o.name === opt.name && o.value === val, ); return ( ); })}
))}
{quantity}
{product.description ? (

Details

{product.description}

) : null}
); }