summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRafi Zadanly <zadanlyr@gmail.com>2023-03-14 17:18:16 +0700
committerRafi Zadanly <zadanlyr@gmail.com>2023-03-14 17:18:16 +0700
commit3b19ddcd0051f094b4659a35107646d678c2fd0c (patch)
treeb1a431e1fdab08414e81c898a2d0d69fce992d5e
parenta69ae4d893300ca9a22b65393f8beecf94c223a5 (diff)
product detail
-rw-r--r--src/lib/product/components/Product.jsx300
-rw-r--r--src/lib/product/components/ProductCard.jsx2
-rw-r--r--src/lib/product/components/ProductDesktop.jsx160
-rw-r--r--src/lib/product/components/ProductMobile.jsx280
-rw-r--r--src/styles/globals.css33
5 files changed, 478 insertions, 297 deletions
diff --git a/src/lib/product/components/Product.jsx b/src/lib/product/components/Product.jsx
index ae476b80..d1586ef9 100644
--- a/src/lib/product/components/Product.jsx
+++ b/src/lib/product/components/Product.jsx
@@ -1,105 +1,15 @@
-import Badge from '@/core/components/elements/Badge/Badge'
-import Divider from '@/core/components/elements/Divider/Divider'
-import Image from '@/core/components/elements/Image/Image'
-import Link from '@/core/components/elements/Link/Link'
-import currencyFormat from '@/core/utils/currencyFormat'
-import { useEffect, useState } from 'react'
-import Select from 'react-select'
-import ProductSimilar from './ProductSimilar'
-import LazyLoad from 'react-lazy-load'
import { toast } from 'react-hot-toast'
-import { updateItemCart } from '@/core/utils/cart'
import useWishlist from '@/lib/wishlist/hooks/useWishlist'
-import { HeartIcon } from '@heroicons/react/24/outline'
+import createOrDeleteWishlistApi from '@/lib/wishlist/api/createOrDeleteWishlistApi'
+import ProductDesktop from './ProductDesktop'
import useAuth from '@/core/hooks/useAuth'
+import ProductMobile from './ProductMobile'
import { useRouter } from 'next/router'
-import createOrDeleteWishlistApi from '@/lib/wishlist/api/createOrDeleteWishlistApi'
-
-const informationTabOptions = [
- { value: 'specification', label: 'Spesifikasi' },
- { value: 'description', label: 'Deskripsi' },
- { value: 'important', label: 'Info Penting' }
-]
const Product = ({ product }) => {
const auth = useAuth()
const router = useRouter()
const { wishlist } = useWishlist({ productId: product?.id })
- const [quantity, setQuantity] = useState('1')
- const [selectedVariant, setSelectedVariant] = useState(null)
- const [informationTab, setInformationTab] = useState(null)
-
- const [activeVariant, setActiveVariant] = useState({
- id: product.id,
- code: product.code,
- name: product.name,
- price: product.lowestPrice,
- stock: product.stockTotal,
- weight: product.weight
- })
-
- const variantOptions = product.variants?.map((variant) => ({
- value: variant.id,
- label:
- (variant.code ? `[${variant.code}] ` : '') +
- (variant.attributes.length > 0 ? variant.attributes.join(', ') : product.name)
- }))
-
- useEffect(() => {
- if (!selectedVariant && variantOptions.length == 1) {
- setSelectedVariant(variantOptions[0])
- }
- }, [selectedVariant, variantOptions])
-
- useEffect(() => {
- if (selectedVariant) {
- const variant = product.variants.find((variant) => variant.id == selectedVariant.value)
- const variantAttributes =
- variant.attributes.length > 0 ? ' - ' + variant.attributes.join(', ') : ''
-
- setActiveVariant({
- id: variant.id,
- code: variant.code,
- name: variant.parent.name + variantAttributes,
- price: variant.price,
- stock: variant.stock,
- weight: variant.weight
- })
- }
- }, [selectedVariant, product])
-
- useEffect(() => {
- if (!informationTab) {
- setInformationTab(informationTabOptions[0].value)
- }
- }, [informationTab])
-
- const validAction = () => {
- let isValid = true
- if (!selectedVariant) {
- toast.error('Pilih varian terlebih dahulu')
- isValid = false
- }
- if (!quantity || quantity < 1 || isNaN(parseInt(quantity))) {
- toast.error('Jumlah barang minimal 1')
- isValid = false
- }
- return isValid
- }
-
- const handleClickCart = () => {
- if (!validAction()) return
- updateItemCart({
- productId: activeVariant.id,
- quantity
- })
- toast.success('Berhasil menambahkan ke keranjang')
- }
-
- const handleClickBuy = () => {
- if (!validAction()) return
- router.push(`/shop/checkout?productId=${activeVariant.id}&quantity=${quantity}`)
- }
const toggleWishlist = async () => {
if (!auth) {
@@ -118,210 +28,10 @@ const Product = ({ product }) => {
return (
<>
- <Image
- src={product.image}
- alt={product.name}
- className='h-72 object-contain object-center w-full border-b border-gray_r-4'
- />
-
- <div className='p-4'>
- <div className='flex items-end mb-2'>
- {product.manufacture?.name ? (
- <Link href='/'>{product.manufacture?.name}</Link>
- ) : (
- <div>-</div>
- )}
- <button
- type='button'
- className='ml-auto'
- onClick={toggleWishlist}
- >
- {wishlist.data?.productTotal > 0 ? (
- <HeartIcon className='w-6 fill-red_r-11 text-red_r-11' />
- ) : (
- <HeartIcon className='w-6' />
- )}
- </button>
- </div>
- <h1 className='leading-6 font-medium'>{activeVariant?.name}</h1>
- {activeVariant?.price?.discountPercentage > 0 && (
- <div className='flex gap-x-1 items-center mt-2'>
- <div className='text-gray_r-11 line-through text-caption-1'>
- {currencyFormat(activeVariant?.price?.price)}
- </div>
- <Badge type='solid-red'>{activeVariant?.price?.discountPercentage}%</Badge>
- </div>
- )}
- <h3 className='text-red_r-11 font-semibold mt-1'>
- {activeVariant?.price?.priceDiscount > 0 ? (
- currencyFormat(activeVariant?.price?.priceDiscount)
- ) : (
- <span className='text-gray_r-11 leading-6 font-normal'>
- Hubungi kami untuk dapatkan harga terbaik,&nbsp;
- <a
- href='https://wa.me/'
- className='text-red_r-11 underline'
- >
- klik disini
- </a>
- </span>
- )}
- </h3>
- </div>
-
- <Divider />
-
- <div className='p-4'>
- <div>
- <label className='flex justify-between'>
- Pilih Varian:
- <span className='text-gray_r-11'>{product?.variantTotal} Varian</span>
- </label>
- <Select
- name='variant'
- classNamePrefix='form-select'
- options={variantOptions}
- className='mt-2'
- value={selectedVariant}
- onChange={(option) => setSelectedVariant(option)}
- isSearchable={product.variantTotal > 10}
- />
- </div>
- <div className='mt-4 mb-2'>Jumlah</div>
- <div className='flex gap-x-3'>
- <div className='w-2/12'>
- <input
- name='quantity'
- type='number'
- className='form-input'
- value={quantity}
- onChange={(e) => setQuantity(e.target.value)}
- />
- </div>
- <button
- type='button'
- className='btn-yellow flex-1'
- onClick={handleClickCart}
- >
- Keranjang
- </button>
- <button
- type='button'
- className='btn-solid-red flex-1'
- onClick={handleClickBuy}
- >
- Beli
- </button>
- </div>
- </div>
-
- <Divider />
-
- <div className='p-4'>
- <h2 className='font-semibold'>Informasi Produk</h2>
- <div className='flex gap-x-4 mt-4 mb-3'>
- {informationTabOptions.map((option) => (
- <TabButton
- value={option.value}
- key={option.value}
- active={informationTab == option.value}
- onClick={() => setInformationTab(option.value)}
- >
- {option.label}
- </TabButton>
- ))}
- </div>
-
- <TabContent
- active={informationTab == 'specification'}
- className='rounded border border-gray_r-6 divide-y divide-gray_r-6'
- >
- <SpecificationContent label='Jumlah Varian'>
- <span>{product?.variantTotal} Varian</span>
- </SpecificationContent>
- <SpecificationContent label='Nomor SKU'>
- <span>SKU-{product?.id}</span>
- </SpecificationContent>
- <SpecificationContent label='Part Number'>
- <span>{activeVariant?.code || '-'}</span>
- </SpecificationContent>
- <SpecificationContent label='Stok'>
- {activeVariant?.stock > 0 && (
- <span className='flex gap-x-1.5'>
- <div className='badge-solid-red'>Ready Stock</div>
- <div className='badge-gray'>{activeVariant?.stock > 5 ? '> 5' : '< 5'}</div>
- </span>
- )}
- {activeVariant?.stock == 0 && (
- <a
- href='https://wa.me'
- className='text-red_r-11 font-medium'
- >
- Tanya Stok
- </a>
- )}
- </SpecificationContent>
- <SpecificationContent label='Berat Barang'>
- {activeVariant?.weight > 0 && <span>{activeVariant?.weight} KG</span>}
- {activeVariant?.weight == 0 && (
- <a
- href='https://wa.me'
- className='text-red_r-11 font-medium'
- >
- Tanya Berat
- </a>
- )}
- </SpecificationContent>
- </TabContent>
-
- <TabContent
- active={informationTab == 'description'}
- className='leading-6 text-gray_r-11'
- dangerouslySetInnerHTML={{
- __html: product.description != '' ? product.description : 'Belum ada deskripsi produk.'
- }}
- />
- </div>
-
- <Divider />
-
- <div className='p-4'>
- <h2 className='font-semibold mb-4'>Kamu Mungkin Juga Suka</h2>
- <LazyLoad>
- <ProductSimilar query={product?.name.split(' ').slice(1, 3).join(' ')} />
- </LazyLoad>
- </div>
+ <ProductMobile product={product} wishlist={wishlist} toggleWishlist={toggleWishlist} />
+ <ProductDesktop product={product} wishlist={wishlist} toggleWishlist={toggleWishlist} />
</>
)
}
-const TabButton = ({ children, active, ...props }) => {
- const activeClassName = active ? 'text-red_r-11 underline underline-offset-4' : 'text-gray_r-11'
- return (
- <button
- {...props}
- type='button'
- className={`font-medium pb-1 ${activeClassName}`}
- >
- {children}
- </button>
- )
-}
-
-const TabContent = ({ children, active, className, ...props }) => (
- <div
- {...props}
- className={`${active ? 'block' : 'hidden'} ${className}`}
- >
- {children}
- </div>
-)
-
-const SpecificationContent = ({ children, label }) => (
- <div className='flex justify-between p-3'>
- <span className='text-gray_r-11'>{label}</span>
- {children}
- </div>
-)
-
export default Product
diff --git a/src/lib/product/components/ProductCard.jsx b/src/lib/product/components/ProductCard.jsx
index 0c11137d..3454d4fd 100644
--- a/src/lib/product/components/ProductCard.jsx
+++ b/src/lib/product/components/ProductCard.jsx
@@ -39,7 +39,7 @@ const ProductCard = ({ product, simpleTitle, variant = 'vertical' }) => {
)}
<Link
href={createSlug('/shop/product/', product?.name, product?.id)}
- className={`font-normal mb-2 !text-gray_r-12 ${
+ className={`font-normal mb-2 !text-gray_r-12 leading-6 ${
simpleTitle ? 'line-clamp-2' : 'line-clamp-3'
}`}
>
diff --git a/src/lib/product/components/ProductDesktop.jsx b/src/lib/product/components/ProductDesktop.jsx
new file mode 100644
index 00000000..dc733eac
--- /dev/null
+++ b/src/lib/product/components/ProductDesktop.jsx
@@ -0,0 +1,160 @@
+import Image from '@/core/components/elements/Image/Image'
+import Link from '@/core/components/elements/Link/Link'
+import DesktopView from '@/core/components/views/DesktopView'
+import currencyFormat from '@/core/utils/currencyFormat'
+import { HeartIcon } from '@heroicons/react/24/outline'
+import { useEffect, useState } from 'react'
+
+const ProductDesktop = ({ product, wishlist, toggleWishlist }) => {
+ const [variantQuantity, setVariantQuantity] = useState(null)
+
+ useEffect(() => {
+ const mapVariantQuantity = product.variants.reduce((acc, cur) => {
+ acc[cur.id] = 1
+ return acc
+ }, {})
+ setVariantQuantity(mapVariantQuantity)
+ }, [product])
+
+ const changeQuantity = (variantId, quantity) => {
+ setVariantQuantity((variantQuantity) => ({ ...variantQuantity, [variantId]: quantity }))
+ }
+
+ return (
+ <DesktopView>
+ <div className='container mx-auto mt-10'>
+ <div className='flex'>
+ <div className='w-3/12'>
+ <Image
+ src={product.image}
+ alt={product.name}
+ className='h-96 object-contain object-center w-full border border-gray_r-4'
+ />
+ </div>
+ <div className='w-6/12 px-4'>
+ <h1 className='text-title-md leading-8 font-medium'>{product?.name}</h1>
+ <div className='mt-6 flex flex-col gap-y-4'>
+ <div className='flex'>
+ <div className='w-1/4 text-gray_r-12/60'>Nomor SKU</div>
+ <div className='w-3/4'>SKU-{product.id}</div>
+ </div>
+ <div className='flex'>
+ <div className='w-1/4 text-gray_r-12/60'>Part Number</div>
+ <div className='w-3/4'>{product.code || '-'}</div>
+ </div>
+ <div className='flex'>
+ <div className='w-1/4 text-gray_r-12/60'>Manufacture</div>
+ <div className='w-3/4'>
+ {product.manufacture?.name ? (
+ <Link href='/'>{product.manufacture?.name}</Link>
+ ) : (
+ <div>-</div>
+ )}
+ </div>
+ </div>
+ <div className='flex'>
+ <div className='w-1/4 text-gray_r-12/60'>Berat Barang</div>
+ <div className='w-3/4'>
+ {product?.weight > 0 && <span>{product?.weight} KG</span>}
+ {product?.weight == 0 && (
+ <a href='https://wa.me' className='text-red_r-11 font-medium'>
+ Tanya Berat
+ </a>
+ )}
+ </div>
+ </div>
+ </div>
+ </div>
+ <div className='w-3/12'>
+ {product.variants.length > 1 && product.lowestPrice.priceDiscount > 0 && (
+ <div className='text-gray_r-12/80'>Harga mulai dari: </div>
+ )}
+ {product?.lowestPrice.discountPercentage > 0 && (
+ <div className='flex gap-x-1 items-center mt-2'>
+ <div className='badge-solid-red text-caption-1'>
+ {product?.lowestPrice.discountPercentage}%
+ </div>
+ <div className='text-gray_r-11 line-through text-caption-1'>
+ {currencyFormat(product?.lowestPrice.price)}
+ </div>
+ </div>
+ )}
+ <h3 className='text-red_r-11 font-semibold mt-1 text-title-lg'>
+ {product?.lowestPrice.priceDiscount > 0 ? (
+ currencyFormat(product?.lowestPrice.priceDiscount)
+ ) : (
+ <span className='text-gray_r-11 leading-6 font-normal'>
+ Hubungi kami untuk dapatkan harga terbaik,&nbsp;
+ <a href='https://wa.me/' className='text-red_r-11 underline'>
+ klik disini
+ </a>
+ </span>
+ )}
+ </h3>
+ <button type='button' className='btn-solid-red w-full mt-6'>
+ Lihat Varian
+ </button>
+
+ <div className='flex mt-4'>
+ <button className='flex items-center gap-x-1' onClick={toggleWishlist}>
+ {wishlist.data?.productTotal > 0 ? (
+ <HeartIcon className='w-6 fill-red_r-11 text-red_r-11' />
+ ) : (
+ <HeartIcon className='w-6' />
+ )}
+ Wishlist
+ </button>
+ </div>
+ </div>
+ </div>
+
+ <div className='mt-12'>
+ <div className='text-h-lg font-semibold mb-6'>Varian Produk</div>
+ <div className='table-specification'>
+ <table>
+ <thead>
+ <tr>
+ <th>No. SKU</th>
+ <th>Harga</th>
+ <th>Jumlah</th>
+ <th>Action</th>
+ </tr>
+ </thead>
+ <tbody>
+ {product.variants.map((variant) => (
+ <tr key={variant.id}>
+ <td>{variant.code}</td>
+ <td>
+ {variant.price.discountPercentage > 0 && (
+ <>
+ <span className='line-through text-caption-1 text-gray_r-11'>
+ {currencyFormat(variant.price.price)}
+ </span>{' '}
+ </>
+ )}
+ {currencyFormat(variant.price.priceDiscount)}
+ </td>
+ <td>
+ <input
+ type='number'
+ className='form-input w-16 text-center'
+ value={variantQuantity[variant.id]}
+ onChange={(e) => changeQuantity(variant.id, e.target.value)}
+ />
+ </td>
+ <td className='flex gap-x-3'>
+ <button className='flex-1 py-2 btn-yellow'>Keranjang</button>
+ <button className='flex-1 py-2 btn-solid-red'>Beli</button>
+ </td>
+ </tr>
+ ))}
+ </tbody>
+ </table>
+ </div>
+ </div>
+ </div>
+ </DesktopView>
+ )
+}
+
+export default ProductDesktop
diff --git a/src/lib/product/components/ProductMobile.jsx b/src/lib/product/components/ProductMobile.jsx
new file mode 100644
index 00000000..790fcd57
--- /dev/null
+++ b/src/lib/product/components/ProductMobile.jsx
@@ -0,0 +1,280 @@
+import Divider from '@/core/components/elements/Divider/Divider'
+import Image from '@/core/components/elements/Image/Image'
+import Link from '@/core/components/elements/Link/Link'
+import currencyFormat from '@/core/utils/currencyFormat'
+import { useEffect, useState } from 'react'
+import Select from 'react-select'
+import ProductSimilar from './ProductSimilar'
+import LazyLoad from 'react-lazy-load'
+import { updateItemCart } from '@/core/utils/cart'
+import { HeartIcon } from '@heroicons/react/24/outline'
+import { useRouter } from 'next/router'
+import MobileView from '@/core/components/views/MobileView'
+import { toast } from 'react-hot-toast'
+
+const ProductMobile = ({ product, wishlist, toggleWishlist }) => {
+ const router = useRouter()
+
+ const [quantity, setQuantity] = useState('1')
+ const [selectedVariant, setSelectedVariant] = useState(null)
+ const [informationTab, setInformationTab] = useState(null)
+
+ const [activeVariant, setActiveVariant] = useState({
+ id: product.id,
+ code: product.code,
+ name: product.name,
+ price: product.lowestPrice,
+ stock: product.stockTotal,
+ weight: product.weight
+ })
+
+ const variantOptions = product.variants?.map((variant) => ({
+ value: variant.id,
+ label:
+ (variant.code ? `[${variant.code}] ` : '') +
+ (variant.attributes.length > 0 ? variant.attributes.join(', ') : product.name)
+ }))
+
+ useEffect(() => {
+ if (!selectedVariant && variantOptions.length == 1) {
+ setSelectedVariant(variantOptions[0])
+ }
+ }, [selectedVariant, variantOptions])
+
+ useEffect(() => {
+ if (selectedVariant) {
+ const variant = product.variants.find((variant) => variant.id == selectedVariant.value)
+ const variantAttributes =
+ variant.attributes.length > 0 ? ' - ' + variant.attributes.join(', ') : ''
+
+ setActiveVariant({
+ id: variant.id,
+ code: variant.code,
+ name: variant.parent.name + variantAttributes,
+ price: variant.price,
+ stock: variant.stock,
+ weight: variant.weight
+ })
+ }
+ }, [selectedVariant, product])
+
+ useEffect(() => {
+ if (!informationTab) {
+ setInformationTab(informationTabOptions[0].value)
+ }
+ }, [informationTab])
+
+ const validAction = () => {
+ let isValid = true
+ if (!selectedVariant) {
+ toast.error('Pilih varian terlebih dahulu')
+ isValid = false
+ }
+ if (!quantity || quantity < 1 || isNaN(parseInt(quantity))) {
+ toast.error('Jumlah barang minimal 1')
+ isValid = false
+ }
+ return isValid
+ }
+
+ const handleClickCart = () => {
+ if (!validAction()) return
+ updateItemCart({
+ productId: activeVariant.id,
+ quantity
+ })
+ toast.success('Berhasil menambahkan ke keranjang')
+ }
+
+ const handleClickBuy = () => {
+ if (!validAction()) return
+ router.push(`/shop/checkout?productId=${activeVariant.id}&quantity=${quantity}`)
+ }
+
+ return (
+ <MobileView>
+ <Image
+ src={product.image}
+ alt={product.name}
+ className='h-72 object-contain object-center w-full border-b border-gray_r-4'
+ />
+
+ <div className='p-4'>
+ <div className='flex items-end mb-2'>
+ {product.manufacture?.name ? (
+ <Link href='/'>{product.manufacture?.name}</Link>
+ ) : (
+ <div>-</div>
+ )}
+ <button type='button' className='ml-auto' onClick={toggleWishlist}>
+ {wishlist.data?.productTotal > 0 ? (
+ <HeartIcon className='w-6 fill-red_r-11 text-red_r-11' />
+ ) : (
+ <HeartIcon className='w-6' />
+ )}
+ </button>
+ </div>
+ <h1 className='leading-6 font-medium'>{activeVariant?.name}</h1>
+ {activeVariant?.price?.discountPercentage > 0 && (
+ <div className='flex gap-x-1 items-center mt-2'>
+ <div className='text-gray_r-11 line-through text-caption-1'>
+ {currencyFormat(activeVariant?.price?.price)}
+ </div>
+ <div className='badge-solid-red'>{activeVariant?.price?.discountPercentage}%</div>
+ </div>
+ )}
+ <h3 className='text-red_r-11 font-semibold mt-1'>
+ {activeVariant?.price?.priceDiscount > 0 ? (
+ currencyFormat(activeVariant?.price?.priceDiscount)
+ ) : (
+ <span className='text-gray_r-11 leading-6 font-normal'>
+ Hubungi kami untuk dapatkan harga terbaik,&nbsp;
+ <a href='https://wa.me/' className='text-red_r-11 underline'>
+ klik disini
+ </a>
+ </span>
+ )}
+ </h3>
+ </div>
+
+ <Divider />
+
+ <div className='p-4'>
+ <div>
+ <label className='flex justify-between'>
+ Pilih Varian:
+ <span className='text-gray_r-11'>{product?.variantTotal} Varian</span>
+ </label>
+ <Select
+ name='variant'
+ classNamePrefix='form-select'
+ options={variantOptions}
+ className='mt-2'
+ value={selectedVariant}
+ onChange={(option) => setSelectedVariant(option)}
+ isSearchable={product.variantTotal > 10}
+ />
+ </div>
+ <div className='mt-4 mb-2'>Jumlah</div>
+ <div className='flex gap-x-3'>
+ <div className='w-2/12'>
+ <input
+ name='quantity'
+ type='number'
+ className='form-input'
+ value={quantity}
+ onChange={(e) => setQuantity(e.target.value)}
+ />
+ </div>
+ <button type='button' className='btn-yellow flex-1' onClick={handleClickCart}>
+ Keranjang
+ </button>
+ <button type='button' className='btn-solid-red flex-1' onClick={handleClickBuy}>
+ Beli
+ </button>
+ </div>
+ </div>
+
+ <Divider />
+
+ <div className='p-4'>
+ <h2 className='font-semibold'>Informasi Produk</h2>
+ <div className='flex gap-x-4 mt-4 mb-3'>
+ {informationTabOptions.map((option) => (
+ <TabButton
+ value={option.value}
+ key={option.value}
+ active={informationTab == option.value}
+ onClick={() => setInformationTab(option.value)}
+ >
+ {option.label}
+ </TabButton>
+ ))}
+ </div>
+
+ <TabContent
+ active={informationTab == 'specification'}
+ className='rounded border border-gray_r-6 divide-y divide-gray_r-6'
+ >
+ <SpecificationContent label='Jumlah Varian'>
+ <span>{product?.variantTotal} Varian</span>
+ </SpecificationContent>
+ <SpecificationContent label='Nomor SKU'>
+ <span>SKU-{product?.id}</span>
+ </SpecificationContent>
+ <SpecificationContent label='Part Number'>
+ <span>{activeVariant?.code || '-'}</span>
+ </SpecificationContent>
+ <SpecificationContent label='Stok'>
+ {activeVariant?.stock > 0 && (
+ <span className='flex gap-x-1.5'>
+ <div className='badge-solid-red'>Ready Stock</div>
+ <div className='badge-gray'>{activeVariant?.stock > 5 ? '> 5' : '< 5'}</div>
+ </span>
+ )}
+ {activeVariant?.stock == 0 && (
+ <a href='https://wa.me' className='text-red_r-11 font-medium'>
+ Tanya Stok
+ </a>
+ )}
+ </SpecificationContent>
+ <SpecificationContent label='Berat Barang'>
+ {activeVariant?.weight > 0 && <span>{activeVariant?.weight} KG</span>}
+ {activeVariant?.weight == 0 && (
+ <a href='https://wa.me' className='text-red_r-11 font-medium'>
+ Tanya Berat
+ </a>
+ )}
+ </SpecificationContent>
+ </TabContent>
+
+ <TabContent
+ active={informationTab == 'description'}
+ className='leading-6 text-gray_r-11'
+ dangerouslySetInnerHTML={{
+ __html: product.description != '' ? product.description : 'Belum ada deskripsi produk.'
+ }}
+ />
+ </div>
+
+ <Divider />
+
+ <div className='p-4'>
+ <h2 className='font-semibold mb-4'>Kamu Mungkin Juga Suka</h2>
+ <LazyLoad>
+ <ProductSimilar query={product?.name.split(' ').slice(1, 3).join(' ')} />
+ </LazyLoad>
+ </div>
+ </MobileView>
+ )
+}
+
+const informationTabOptions = [
+ { value: 'specification', label: 'Spesifikasi' },
+ { value: 'description', label: 'Deskripsi' },
+ { value: 'important', label: 'Info Penting' }
+]
+
+const TabButton = ({ children, active, ...props }) => {
+ const activeClassName = active ? 'text-red_r-11 underline underline-offset-4' : 'text-gray_r-11'
+ return (
+ <button {...props} type='button' className={`font-medium pb-1 ${activeClassName}`}>
+ {children}
+ </button>
+ )
+}
+
+const TabContent = ({ children, active, className, ...props }) => (
+ <div {...props} className={`${active ? 'block' : 'hidden'} ${className}`}>
+ {children}
+ </div>
+)
+
+const SpecificationContent = ({ children, label }) => (
+ <div className='flex justify-between p-3'>
+ <span className='text-gray_r-11'>{label}</span>
+ {children}
+ </div>
+)
+
+export default ProductMobile
diff --git a/src/styles/globals.css b/src/styles/globals.css
index b482aa30..b9dfbe38 100644
--- a/src/styles/globals.css
+++ b/src/styles/globals.css
@@ -382,6 +382,37 @@ button {
@apply !border-yellow_r-9;
}
+.table-specification {
+ @apply max-h-[500px] overflow-y-auto border border-gray_r-6;
+}
+
+.table-specification > table {
+ @apply table-fixed
+ border-collapse
+ w-full;
+}
+
+.table-specification > table > thead {
+ @apply sticky top-0 border-b;
+}
+
+.table-specification > table > thead > tr {
+ @apply bg-gray_r-1/80 backdrop-blur-lg;
+}
+
+.table-specification th {
+ @apply font-semibold;
+}
+
+.table-specification th,
+.table-specification td {
+ @apply py-4 px-2 text-center;
+}
+
+.table-specification > table > tbody > tr {
+ @apply odd:bg-gray_r-3 even:bg-gray_r-1;
+}
+
.category-mega-box-wrapper {
@apply absolute
opacity-0
@@ -407,6 +438,7 @@ button {
py-2
border
border-t-0
+ bg-white
border-gray_r-6
h-full
w-full;
@@ -469,4 +501,3 @@ button {
duration-100
font-normal;
}
-