'use client'; import { Dialog, DialogPanel, Transition, TransitionChild } from '@headlessui/react'; import { XMarkIcon } from '@heroicons/react/24/outline'; import clsx from 'clsx'; import Price from 'components/price'; import { CORE_VARIANT_ID_KEY, CORE_WAIVER } from 'lib/constants'; import { CoreChargeOption, Money, ProductOption, ProductVariant } from 'lib/shopify/types'; import { createUrl } from 'lib/utils'; import { usePathname, useRouter, useSearchParams } from 'next/navigation'; import { Fragment, useEffect, useState } from 'react'; type Combination = { id: string; availableForSale: boolean; [key: string]: string | boolean; // ie. { color: 'Red', size: 'Large', ... } }; export function VariantSelector({ options, variants, minPrice }: { options: ProductOption[]; variants: ProductVariant[]; minPrice: Money; }) { const router = useRouter(); const pathname = usePathname(); const searchParams = useSearchParams(); const [isOpen, setIsOpen] = useState(false); const combinations: Combination[] = variants.map((variant) => ({ id: variant.id, availableForSale: variant.availableForSale, // Adds key / value pairs for each variant (ie. "color": "Black" and "size": 'M"). ...variant.selectedOptions.reduce( (accumulator, option) => ({ ...accumulator, [option.name.toLowerCase()]: option.value }), {} ) })); const variantsById: Record = variants.reduce((acc, variant) => { return { ...acc, [variant.id]: variant }; }, {}); // If a variant is not selected, we want to select the first available for sale variant as default useEffect(() => { const hasSelectedVariant = Array.from(searchParams.entries()).some(([key, value]) => { return combinations.some((combination) => combination[key] === value); }); if (!hasSelectedVariant) { const defaultVariant = variants.find((variant) => variant.availableForSale); if (defaultVariant) { const optionSearchParams = new URLSearchParams(searchParams.toString()); defaultVariant.selectedOptions.forEach((option) => { optionSearchParams.set(option.name.toLowerCase(), option.value); }); const defaultUrl = createUrl(pathname, optionSearchParams); router.replace(defaultUrl, { scroll: false }); } } // eslint-disable-next-line react-hooks/exhaustive-deps }, []); const hasNoOptionsOrJustOneOption = !options.length || (options.length === 1 && options[0]?.values.length === 1); if (hasNoOptionsOrJustOneOption) { return null; } const openModal = () => setIsOpen(true); const closeModal = () => setIsOpen(false); return (
See more Remanufactured and Used Options{' '}
); }