diff --git a/app/product/[name]/page.tsx b/app/product/[name]/page.tsx index 192b60225..38e6c236d 100644 --- a/app/product/[name]/page.tsx +++ b/app/product/[name]/page.tsx @@ -100,7 +100,7 @@ export default async function ProductPage(props: { params: Promise<{ name: strin )} - + diff --git a/components/cart/add-to-cart.tsx b/components/cart/add-to-cart.tsx index 85cba14cd..6a46fa5e2 100644 --- a/components/cart/add-to-cart.tsx +++ b/components/cart/add-to-cart.tsx @@ -4,7 +4,6 @@ import { PlusIcon } from '@heroicons/react/24/outline'; import clsx from 'clsx'; import { useProduct } from 'components/product/product-context'; import { Product, ProductVariations } from 'lib/woocomerce/models/product'; -import { useMemo } from 'react'; import { useCart } from './cart-context'; function SubmitButton({disabled = false}: {disabled: boolean}) { @@ -23,22 +22,10 @@ function SubmitButton({disabled = false}: {disabled: boolean}) { export function AddToCart({ product, variations }: { product: Product, variations?: ProductVariations[] }) { const { setNewCart } = useCart(); - const {state} = useProduct(); + const { state } = useProduct(); + const productVariant = variations?.find((variation) => variation.id.toString() === state.variation); + const variation = productVariant?.attributes.map((attr) => ({ attribute: attr.name, value: attr.option })) || []; - - const productVariant = useMemo(() => { - const keys = Object.keys(state).filter((key) => key !== 'id' && key !== 'image').map((key) => ({ - attribute: key.toLowerCase(), - value: state[key] - })); - const productExist = variations?.find((variation) => { - const attributes = variation.attributes.map((attr) => ({name: attr.name, option: attr.option})) || []; - return attributes.every((attribute) => attribute.option === keys.find((key) => key.attribute === attribute.name)?.value); - }); - - return productExist ? keys : []; - }, [state, variations]); - return (
{ @@ -46,7 +33,7 @@ export function AddToCart({ product, variations }: { product: Product, variation const cart = await ( await fetch('/api/cart', { method: 'POST', - body: JSON.stringify({ id: product.id, quantity: 1, variation: productVariant }) + body: JSON.stringify({ id: product.id, quantity: 1, variation }) }) ).json(); setNewCart(cart); @@ -55,7 +42,7 @@ export function AddToCart({ product, variations }: { product: Product, variation } }} > - + ); } diff --git a/components/product/product-context.tsx b/components/product/product-context.tsx index 755e262ad..8dc2dfc83 100644 --- a/components/product/product-context.tsx +++ b/components/product/product-context.tsx @@ -7,12 +7,15 @@ type ProductState = { [key: string]: string; } & { image?: string; -}; +} & { + variation?: string; +} type ProductContextType = { state: ProductState; updateOption: (name: string, value: string) => ProductState; updateImage: (index: string) => ProductState; + updateVariation: (variation: string) => ProductState; }; const ProductContext = createContext(undefined); @@ -48,11 +51,18 @@ export function ProductProvider({ children }: { children: React.ReactNode }) { return { ...state, ...newState }; }; + const updateVariation = (variation: string) => { + const newState = { variation }; + setOptimisticState(newState); + return { ...state, ...newState }; + } + const value = useMemo( () => ({ state, updateOption, updateImage, + updateVariation }), [state] ); diff --git a/components/product/product-description.tsx b/components/product/product-description.tsx index 99cc41e8d..9072585db 100644 --- a/components/product/product-description.tsx +++ b/components/product/product-description.tsx @@ -1,14 +1,19 @@ +'use client'; import Price from 'components/price'; import Prose from 'components/prose'; -import { Product } from 'lib/woocomerce/models/product'; +import { Product, ProductVariations } from 'lib/woocomerce/models/product'; +import { useProduct } from './product-context'; -export function ProductDescription({ product }: { product: Product }) { +export function ProductDescription({ product, variations }: { product: Product, variations?: ProductVariations[] }) { + const { state } = useProduct(); + const productVariant = variations?.find((variation) => variation.id.toString() === state.variation); + return ( <>

{product.name}

- +
{product.description ? ( diff --git a/components/product/variant-selector.tsx b/components/product/variant-selector.tsx index 943b6a8f0..e9ba3647e 100644 --- a/components/product/variant-selector.tsx +++ b/components/product/variant-selector.tsx @@ -35,12 +35,19 @@ export function VariantSelector({ const optionNameLowerCase = option?.name?.toLowerCase(); // The option is active if it's in the selected options. const isActive = optionNameLowerCase ? state[optionNameLowerCase] === value : false; - if (!optionNameLowerCase) return null; return (