diff options
| author | Rafi Zadanly <zadanlyr@gmail.com> | 2023-03-14 17:18:16 +0700 |
|---|---|---|
| committer | Rafi Zadanly <zadanlyr@gmail.com> | 2023-03-14 17:18:16 +0700 |
| commit | 3b19ddcd0051f094b4659a35107646d678c2fd0c (patch) | |
| tree | b1a431e1fdab08414e81c898a2d0d69fce992d5e /src | |
| parent | a69ae4d893300ca9a22b65393f8beecf94c223a5 (diff) | |
product detail
Diffstat (limited to 'src')
| -rw-r--r-- | src/lib/product/components/Product.jsx | 300 | ||||
| -rw-r--r-- | src/lib/product/components/ProductCard.jsx | 2 | ||||
| -rw-r--r-- | src/lib/product/components/ProductDesktop.jsx | 160 | ||||
| -rw-r--r-- | src/lib/product/components/ProductMobile.jsx | 280 | ||||
| -rw-r--r-- | src/styles/globals.css | 33 |
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, - <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, + <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, + <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; } - |
