From 5e4686bdd4a7092ac7f6aaa380616540a24af4c6 Mon Sep 17 00:00:00 2001 From: Belen Curcio <curciobelen@gmail.com> Date: Fri, 16 Oct 2020 13:16:55 -0300 Subject: [PATCH] Dynamic Sizes and Colors --- .../product/ProductView/ProductView.tsx | 67 +++++++++---------- components/product/Swatch/Swatch.tsx | 35 ++++++---- components/product/helpers.ts | 10 +++ 3 files changed, 64 insertions(+), 48 deletions(-) create mode 100644 components/product/helpers.ts diff --git a/components/product/ProductView/ProductView.tsx b/components/product/ProductView/ProductView.tsx index 46614bfa6..c4c8fccbb 100644 --- a/components/product/ProductView/ProductView.tsx +++ b/components/product/ProductView/ProductView.tsx @@ -7,6 +7,8 @@ import { Button, Container } from '@components/ui' import { Swatch, ProductSlider } from '@components/product' import useAddItem from '@lib/bigcommerce/cart/use-add-item' import type { Product } from '@lib/bigcommerce/api/operations/get-product' +import { getProductOptions } from '../helpers' + interface Props { className?: string children?: any @@ -22,6 +24,9 @@ const COLORS: Colors[] = ['pink', 'black', 'white'] const SIZES = ['s', 'm', 'l', 'xl', 'xxl'] const ProductView: FC<Props> = ({ product, className }) => { + const options = getProductOptions(product) + console.log(options) + const addItem = useAddItem() const { openSidebar } = useUI() @@ -100,41 +105,33 @@ const ProductView: FC<Props> = ({ product, className }) => { <div className={s.squareBg}></div> </div> - <div className="flex-1 flex flex-col"> - <section className="pt-24"> - <h2 className="uppercase font-medium">Color</h2> - <div className="flex flex-row py-4"> - {COLORS.map((color) => ( - <Swatch - key={color} - color={color} - active={color === activeColor} - onClick={() => - setChoices((choices) => { - return { ...choices, color } - }) - } - /> - ))} - </div> - </section> - <section className="pb-4"> - <h2 className="uppercase font-medium">Size</h2> - <div className="flex flex-row py-4"> - {SIZES.map((size) => { - return ( - <Swatch - size={size.toUpperCase()} - key={`size-${size}`} - active={size === activeSize} - onClick={() => - setChoices((choices) => ({ ...choices, size })) - } - /> - ) - })} - </div> - </section> + + <div className="flex-1 flex flex-col pt-24"> + {options?.map((opt) => ( + <section className="pb-4"> + <h2 className="uppercase font-medium">{opt.displayName}</h2> + <div className="flex flex-row py-4"> + {opt.values.map((v: any) => { + return ( + <Swatch + key={v.entityId} + label={v.label} + active={v.label === activeColor} + variant={opt.displayName} + onClick={() => + setChoices((choices) => { + return { + ...choices, + [opt.displayName.toLowerCase()]: v.label, + } + }) + } + /> + ) + })} + </div> + </section> + ))} <section className="pb-12"> <div className="break-words" diff --git a/components/product/Swatch/Swatch.tsx b/components/product/Swatch/Swatch.tsx index 5940bc9a4..ef1bc223b 100644 --- a/components/product/Swatch/Swatch.tsx +++ b/components/product/Swatch/Swatch.tsx @@ -9,37 +9,46 @@ interface Props extends ButtonProps { className?: string children?: any active?: boolean - color?: Colors - size?: string + label?: string + variant?: 'size' | 'color' | string } -const Swatch: FC<Props> = ({ className, size, color, active, ...props }) => { +const Swatch: FC<Props> = ({ + className, + label, + variant = 'size', + active, + ...props +}) => { + variant = variant?.toLowerCase() + label = label?.toLowerCase() + const rootClassName = cn( s.root, { [s.active]: active, - [s.size]: size, - [s.colorPink]: color === 'pink', - [s.colorWhite]: color === 'white', - [s.colorBlack]: color === 'black', - [s.colorViolet]: color === 'violet', + [s.size]: variant === 'size', + [s.colorPink]: label === 'pink', + [s.colorWhite]: label === 'white', + [s.colorBlack]: label === 'black', + [s.colorViolet]: label === 'violet', }, className ) return ( - <Button className={rootClassName} {...props}> - {color && active && ( + <Button className={rootClassName}> + {variant === 'color' && active && ( <span className={cn('absolute', { - 'text-white': color !== 'white', - 'text-black': color === 'white', + 'text-white': label !== 'white', + 'text-black': label === 'white', })} > <Check /> </span> )} - {size} + {variant === 'size' ? label : null} </Button> ) } diff --git a/components/product/helpers.ts b/components/product/helpers.ts new file mode 100644 index 000000000..a67266b07 --- /dev/null +++ b/components/product/helpers.ts @@ -0,0 +1,10 @@ +import type { Product } from '@lib/bigcommerce/api/operations/get-product' + +export function getProductOptions(product: Product) { + const options = product.options.edges?.map(({ node }: any) => ({ + displayName: node.displayName, + values: node.values.edges?.map(({ node }: any) => node), + })) + + return options +}