refactoring out variant specific details

This commit is contained in:
Samantha Kellow 2023-11-24 08:53:57 +00:00
parent 5cfc48cdec
commit 4e33afc9dc
3 changed files with 42 additions and 15 deletions

View File

@ -1,24 +1,16 @@
import { AddToCart } from 'components/cart/add-to-cart';
import Price from 'components/price';
import { Product } from 'lib/shopify/types';
import { DescriptionContent } from './description-content';
import { SustainabilityInfo } from './sustainability-info';
import { VariantSelector } from './variant-selector';
import { VariantDetails } from './variant-details';
export function ProductDescription({ product }: { product: Product }) {
const filterDeterminedOptions = product.options.filter(option => option.name !== 'Wrap')
return (
<>
<div className="mb-6 flex flex-col border-b pb-6 dark:border-neutral-700">
<div className="flex flex-col">
<h1 className="mb-2 text-2xl md:text-3xl font-medium">{product.title}</h1>
<div className="place-self-end mr-auto w-auto rounded-full bg-gray-600 p-2 text-sm text-white">
<Price
amount={product.priceRange.maxVariantPrice.amount}
currencyCode={product.priceRange.maxVariantPrice.currencyCode}
/>
</div>
</div>
<VariantSelector options={filterDeterminedOptions} variants={product.variants} />
<VariantDetails product={product} />
<AddToCart variants={product.variants} availableForSale={product.availableForSale} />
<DescriptionContent product={product} />

View File

@ -0,0 +1,26 @@
'use client'
import Price from "components/price";
import { Product } from "lib/shopify/types";
import { useState } from "react";
import { VariantSelector } from "./variant-selector";
export function VariantDetails({ product }: { product: Product }) {
const filterDeterminedOptions = product.options.filter(option => option.name !== 'Wrap');
const [selectedVariant, setSelectedVariant] = useState(product.variants[0]);
return (
<>
<div className='flex flex-col border-b mb-6 dark:border-neutral-700'>
<div className="place-self-end mr-auto w-auto rounded-full bg-gray-600 p-2 text-sm text-white mb-6">
<Price
amount={selectedVariant?.price.amount || product.variants[0]!.price.amount}
currencyCode={product.priceRange.maxVariantPrice.currencyCode}
/>
</div>
</div>
<VariantSelector options={filterDeterminedOptions} variants={product.variants} setSelectedVariant={setSelectedVariant} />
</>
)
}

View File

@ -1,10 +1,11 @@
'use client';
import clsx from 'clsx';
import { ProductOption, ProductVariant } from 'lib/shopify/types';
import { Money, ProductOption, ProductVariant } from 'lib/shopify/types';
import { createUrl } from 'lib/utils';
import Link from 'next/link';
import { usePathname, useRouter, useSearchParams } from 'next/navigation';
import { useEffect } from 'react';
type ParamsMap = {
[key: string]: string; // ie. { color: 'Red', size: 'Large', ... }
@ -14,15 +15,18 @@ type OptimizedVariant = {
id: string;
availableForSale: boolean;
params: URLSearchParams;
[key: string]: string | boolean | URLSearchParams; // ie. { color: 'Red', size: 'Large', ... }
price: Money;
[key: string]: string | boolean | URLSearchParams | Money; // ie. { color: 'Red', size: 'Large', ... }
};
export function VariantSelector({
options,
variants
variants,
setSelectedVariant,
}: {
options: ProductOption[];
variants: ProductVariant[];
setSelectedVariant: (newVariant: ProductVariant) => void,
}) {
const pathname = usePathname();
const currentParams = useSearchParams();
@ -46,7 +50,8 @@ export function VariantSelector({
const optimized: OptimizedVariant = {
id: variant.id,
availableForSale: variant.availableForSale,
params: new URLSearchParams()
params: new URLSearchParams(),
price: variant.price,
};
variant.selectedOptions.forEach((selectedOption) => {
@ -79,6 +84,10 @@ export function VariantSelector({
const currentUrl = createUrl(pathname, currentParams);
const selectedVariantUrl = createUrl(pathname, selectedVariantParams);
useEffect(() => {
setSelectedVariant(selectedVariant);
}, [selectedVariantUrl]);
if (currentUrl !== selectedVariantUrl) {
router.replace(selectedVariantUrl);
}