diff --git a/components/product/variant-selector.tsx b/components/product/variant-selector.tsx index a50d42d8b..b87788fc7 100644 --- a/components/product/variant-selector.tsx +++ b/components/product/variant-selector.tsx @@ -127,139 +127,151 @@ export function VariantSelector({ -
-
- {options.map((option) => { - return ( -
    - {option.values.map((value) => { - const optionNameLowerCase = option.name.toLowerCase(); - const optionSearchParams = new URLSearchParams(searchParams.toString()); +
    + {options.map((option) => { + return ( +
      + {option.values.map((value) => { + const optionNameLowerCase = option.name.toLowerCase(); + const optionSearchParams = new URLSearchParams(searchParams.toString()); - optionSearchParams.set(optionNameLowerCase, value); + optionSearchParams.set(optionNameLowerCase, value); - // In order to determine if an option is available for sale, we need to: - // - // 1. Filter out all other param state - // 2. Filter out invalid options - // 3. Check if the option combination is available for sale - // - // This is the "magic" that will cross check possible variant combinations and preemptively - // disable combinations that are not available. For example, if the color gray is only available in size medium, - // then all other sizes should be disabled. - const filtered = Array.from(optionSearchParams.entries()).filter( - ([key, value]) => - options.find( - (option) => - option.name.toLowerCase() === key && option.values.includes(value) - ) - ); - - const isAvailableForSale = combinations.find((combination) => - filtered.every( - ([key, value]) => - combination[key] === value && combination.availableForSale + // In order to determine if an option is available for sale, we need to: + // + // 1. Filter out all other param state + // 2. Filter out invalid options + // 3. Check if the option combination is available for sale + // + // This is the "magic" that will cross check possible variant combinations and preemptively + // disable combinations that are not available. For example, if the color gray is only available in size medium, + // then all other sizes should be disabled. + const filtered = Array.from(optionSearchParams.entries()).filter( + ([key, value]) => + options.find( + (option) => + option.name.toLowerCase() === key && option.values.includes(value) ) - ); + ); - const variant = isAvailableForSale - ? variantsById[isAvailableForSale.id] - : undefined; + const isAvailableForSale = combinations.find((combination) => + filtered.every( + ([key, value]) => + combination[key] === value && combination.availableForSale + ) + ); - const coreChargeOptions = [ - variant?.waiverAvailable && { - label: 'Core Waiver', - value: CORE_WAIVER, - price: { amount: 0, currencyCode: variant?.price.currencyCode } - }, - variant?.coreVariantId && - variant.coreCharge && { - label: 'Core Charge', - value: variant.coreVariantId, - price: variant.coreCharge - } - ].filter(Boolean) as CoreChargeOption[]; + const variant = isAvailableForSale + ? variantsById[isAvailableForSale.id] + : undefined; - // preset the first core charge option if not set - coreChargeOptions[0] && - optionSearchParams.set(CORE_VARIANT_ID_KEY, coreChargeOptions[0].value); + const coreChargeOptions = [ + variant?.waiverAvailable && { + label: 'Core Waiver', + value: CORE_WAIVER, + price: { amount: 0, currencyCode: variant?.price.currencyCode } + }, + variant?.coreVariantId && + variant.coreCharge && { + label: 'Core Charge', + value: variant.coreVariantId, + price: variant.coreCharge + } + ].filter(Boolean) as CoreChargeOption[]; - const optionUrl = createUrl(pathname, optionSearchParams); + // preset the first core charge option if not set + coreChargeOptions[0] && + optionSearchParams.set(CORE_VARIANT_ID_KEY, coreChargeOptions[0].value); - // The option is active if it's in the url params. - const isActive = searchParams.get(optionNameLowerCase) === value; + const optionUrl = createUrl(pathname, optionSearchParams); - return ( -
    • + - ))} + {!isAvailableForSale ? Out of Stock : null} +
    +
    + {coreChargeOptions.map((option) => ( + + ))} +
    +
    +
    + Condition: + {variant?.condition || 'N/A'}
    - - - ); - })} -
- ); - })} -
+
+ Estimated Delivery: + {variant?.estimatedDelivery || 'N/A'} +
+
+ Mileage: + {variant?.mileage || 'N/A'} +
+
+ + + ); + })} + + ); + })} diff --git a/lib/shopify/fragments/product.ts b/lib/shopify/fragments/product.ts index 1680db310..d098b39c0 100644 --- a/lib/shopify/fragments/product.ts +++ b/lib/shopify/fragments/product.ts @@ -55,6 +55,15 @@ const productFragment = /* GraphQL */ ` coreVariantId: metafield(namespace: "custom", key: "coreVariant") { value } + estimatedDelivery: metafield(namespace: "custom", key: "delivery") { + value + } + mileage: metafield(namespace: "custom", key: "mileage") { + value + } + condition: metafield(namespace: "custom", key: "condition") { + value + } } } } diff --git a/lib/shopify/index.ts b/lib/shopify/index.ts index 1f2fa79cf..3e039edb4 100644 --- a/lib/shopify/index.ts +++ b/lib/shopify/index.ts @@ -185,7 +185,10 @@ const reshapeVariants = (variants: ShopifyProductVariant[]): ProductVariant[] => ...variant, waiverAvailable: parseMetaFieldValue(variant.waiverAvailable), coreVariantId: variant.coreVariantId?.value || null, - coreCharge: parseMetaFieldValue(variant.coreCharge) + coreCharge: parseMetaFieldValue(variant.coreCharge), + mileage: variant.mileage?.value ?? null, + estimatedDelivery: variant.estimatedDelivery?.value || null, + condition: variant.condition?.value || null })); }; diff --git a/lib/shopify/types.ts b/lib/shopify/types.ts index 3d54660cd..ca8b4cc0b 100644 --- a/lib/shopify/types.ts +++ b/lib/shopify/types.ts @@ -87,15 +87,21 @@ export type ProductVariant = { barcode: string | null; sku: string | null; coreVariantId: string | null; + mileage: number | null; + estimatedDelivery: string | null; + condition: string | null; }; export type ShopifyProductVariant = Omit< ProductVariant, - 'coreCharge' | 'waiverAvailable' | 'coreVariantId' + 'coreCharge' | 'waiverAvailable' | 'coreVariantId' | 'mileage' | 'estimatedDelivery' | 'condition' > & { waiverAvailable: { value: string }; coreVariantId: { value: string } | null; coreCharge: { value: string } | null; + mileage: { value: number } | null; + estimatedDelivery: { value: string } | null; + condition: { value: string } | null; }; export type SEO = {