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
+}