+
+
+
+ {Children.map(children, (child) => {
+ // Add the keen-slider__slide className to children
+ if (isValidElement(child)) {
+ return {
+ ...child,
+ props: {
+ ...child.props,
+ className: `${
+ child.props.className ? `${child.props.className} ` : ''
+ }keen-slider__slide`,
+ },
+ }
+ }
+ return child
+ })}
+
+ {slider && (
+
+ {[...Array(slider.details().size).keys()].map((idx) => {
+ return (
+
+ )
+ })}
+
+ )}
+
+ )
+}
+
+export default ProductSlider
diff --git a/components/product/ProductSlider/index.ts b/components/product/ProductSlider/index.ts
new file mode 100644
index 00000000..50444041
--- /dev/null
+++ b/components/product/ProductSlider/index.ts
@@ -0,0 +1 @@
+export { default } from './ProductSlider'
diff --git a/components/product/ProductView/ProductView.module.css b/components/product/ProductView/ProductView.module.css
new file mode 100644
index 00000000..6545d611
--- /dev/null
+++ b/components/product/ProductView/ProductView.module.css
@@ -0,0 +1,96 @@
+.root {
+ @apply relative grid items-start gap-8 grid-cols-1 overflow-x-hidden;
+
+ @screen lg {
+ @apply grid-cols-12;
+ }
+}
+
+.productDisplay {
+ @apply relative flex px-0 pb-0 box-border col-span-1 bg-violet;
+ min-height: 600px;
+
+ @screen md {
+ min-height: 700px;
+ }
+
+ @screen lg {
+ margin-right: -2rem;
+ margin-left: -2rem;
+ @apply mx-0 col-span-6;
+ min-height: 100%;
+ height: 100%;
+ }
+}
+
+.squareBg {
+ @apply absolute inset-0 bg-violet z-0 h-full;
+}
+
+.nameBox {
+ @apply absolute top-6 left-0 z-20 pr-16;
+
+ @screen lg {
+ @apply left-6 pr-16;
+ }
+
+ & .name {
+ @apply px-6 py-2 bg-primary text-primary font-bold;
+ font-size: 2rem;
+ letter-spacing: 0.4px;
+ }
+
+ & .price {
+ @apply px-6 py-2 pb-4 bg-primary text-primary font-bold inline-block tracking-wide;
+ }
+
+ @screen lg {
+ & .name,
+ & .price {
+ @apply bg-violet-light text-white;
+ }
+ }
+}
+
+.sidebar {
+ @apply flex flex-col col-span-1 mx-auto max-w-8xl px-6 w-full h-full;
+
+ @screen lg {
+ @apply col-span-6 py-24 justify-between;
+ }
+}
+
+.sliderContainer {
+ @apply absolute z-10 inset-0 flex items-center justify-center overflow-x-hidden;
+}
+
+.imageContainer {
+ & > div {
+ @apply h-full;
+ & > div {
+ @apply h-full;
+ }
+ }
+}
+
+.img {
+ @apply w-full h-auto max-h-full object-cover;
+}
+
+.button {
+ text-align: center;
+ width: 100%;
+ max-width: 300px;
+
+ @screen sm {
+ min-width: 300px;
+ }
+}
+
+.wishlistButton {
+ @apply absolute z-30 top-6 right-0 bg-primary text-primary w-10 h-10 flex items-center justify-center font-semibold leading-6 cursor-pointer;
+
+ @screen lg {
+ @apply right-12 text-white bg-violet;
+ }
+}
diff --git a/components/product/ProductView/ProductView.tsx b/components/product/ProductView/ProductView.tsx
new file mode 100644
index 00000000..d38da352
--- /dev/null
+++ b/components/product/ProductView/ProductView.tsx
@@ -0,0 +1,174 @@
+import cn from 'classnames'
+import Image from 'next/image'
+import { NextSeo } from 'next-seo'
+import { FC, useEffect, useState } from 'react'
+import s from './ProductView.module.css'
+import { Swatch, ProductSlider } from '@components/product'
+import { Button, Container, Text, useUI } from '@components/ui'
+import type { Product } from '@commerce/types'
+import usePrice from '@framework/product/use-price'
+import { useAddItem } from '@framework/cart'
+import { getVariant, SelectedOptions } from '../helpers'
+import WishlistButton from '@components/wishlist/WishlistButton'
+
+interface Props {
+ children?: any
+ product: Product
+ className?: string
+}
+
+const ProductView: FC