diff options
| author | Rafi Zadanly <zadanlyr@gmail.com> | 2023-03-18 10:17:16 +0700 |
|---|---|---|
| committer | Rafi Zadanly <zadanlyr@gmail.com> | 2023-03-18 10:17:16 +0700 |
| commit | 62efd1afc02422545579c529cd954d0c157889ee (patch) | |
| tree | 09fa6a45b1b0f31af4e019ac6c4437721774e1cf | |
| parent | ff9e6c43f451ed933b0cb8d35623bf3b6a1de1c4 (diff) | |
navbar user dropdown, add to cart
| -rw-r--r-- | src/core/components/elements/Navbar/NavbarDesktop.jsx | 47 | ||||
| -rw-r--r-- | src/core/components/elements/Navbar/NavbarUserDropdown.jsx | 16 | ||||
| -rw-r--r-- | src/lib/product/components/Product.jsx | 4 | ||||
| -rw-r--r-- | src/lib/product/components/ProductDesktop.jsx | 36 | ||||
| -rw-r--r-- | src/pages/_app.jsx | 2 | ||||
| -rw-r--r-- | src/styles/globals.css | 39 |
6 files changed, 123 insertions, 21 deletions
diff --git a/src/core/components/elements/Navbar/NavbarDesktop.jsx b/src/core/components/elements/Navbar/NavbarDesktop.jsx index fa620eb2..3ee9dc1e 100644 --- a/src/core/components/elements/Navbar/NavbarDesktop.jsx +++ b/src/core/components/elements/Navbar/NavbarDesktop.jsx @@ -11,11 +11,14 @@ import dynamic from 'next/dynamic' import IndoteknikLogo from '@/images/logo.png' import Category from '@/lib/category/components/Category' import { useState } from 'react' +import useAuth from '@/core/hooks/useAuth' +import NavbarUserDropdown from './NavbarUserDropdown' const Search = dynamic(() => import('./Search')) const NavbarDesktop = () => { const [isOpenCategory, setIsOpenCategory] = useState(false) + const auth = useAuth() return ( <DesktopView> @@ -82,7 +85,7 @@ const NavbarDesktop = () => { > <div>Kategori Produk</div> <ChevronDownIcon className={`ml-auto w-6 ${isOpenCategory ? 'rotate-180' : ''}`} /> - + <div className={`category-mega-box-wrapper ${isOpenCategory ? 'show' : ''}`}> <Category /> </div> @@ -113,19 +116,35 @@ const NavbarDesktop = () => { Blog Indoteknik </Link> </div> - <div className='w-3/12 flex gap-x-1'> - <Link - href='/login' - className='flex-1 flex justify-center items-center bg-red_r-11 !text-gray_r-1 rounded-none' - > - Masuk - </Link> - <Link - href='/register' - className='flex-1 flex justify-center items-center bg-red_r-11 !text-gray_r-1 rounded-none rounded-tr-xl' - > - Daftar - </Link> + + <div className='w-3/12 flex gap-x-1 relative'> + {!auth && ( + <> + <Link + href='/login' + className='flex-1 flex justify-center items-center bg-red_r-11 !text-gray_r-1 rounded-none' + > + Masuk + </Link> + <Link + href='/register' + className='flex-1 flex justify-center items-center bg-red_r-11 !text-gray_r-1 rounded-none rounded-tr-xl' + > + Daftar + </Link> + </> + )} + {auth && ( + <> + <Link href='/' className='navbar-user-dropdown-button'> + <span>Halo, {auth?.name}</span> + <div className='ml-auto'> + <ChevronDownIcon className='w-6' /> + </div> + </Link> + <NavbarUserDropdown /> + </> + )} </div> </div> </div> diff --git a/src/core/components/elements/Navbar/NavbarUserDropdown.jsx b/src/core/components/elements/Navbar/NavbarUserDropdown.jsx new file mode 100644 index 00000000..fb95c593 --- /dev/null +++ b/src/core/components/elements/Navbar/NavbarUserDropdown.jsx @@ -0,0 +1,16 @@ +import Link from '../Link/Link' + +const NavbarUserDropdown = () => { + return ( + <div className='navbar-user-dropdown-wrapper'> + <div className='navbar-user-dropdown'> + <Link href='/'>Daftar Transaksi</Link> + <Link href='/'>Invoice & Faktur Pajak</Link> + <Link href='/'>Wishlist</Link> + <Link href='/'>Pengaturan Akun</Link> + </div> + </div> + ) +} + +export default NavbarUserDropdown diff --git a/src/lib/product/components/Product.jsx b/src/lib/product/components/Product.jsx index d1586ef9..9b41f5c3 100644 --- a/src/lib/product/components/Product.jsx +++ b/src/lib/product/components/Product.jsx @@ -18,10 +18,10 @@ const Product = ({ product }) => { } const data = { product_id: product.id } await createOrDeleteWishlistApi({ data }) - if (wishlist.data.productTotal > 0) { + if (wishlist?.data?.productTotal > 0) { toast.success('Berhasil menghapus dari wishlist') } else { - toast.success('Berhasil menambahkan ke wishlist') + toast.error('Terjadi kesalahan internal, gagal menambahkan ke wishlist') } wishlist.refetch() } diff --git a/src/lib/product/components/ProductDesktop.jsx b/src/lib/product/components/ProductDesktop.jsx index 1272237b..f37d900c 100644 --- a/src/lib/product/components/ProductDesktop.jsx +++ b/src/lib/product/components/ProductDesktop.jsx @@ -6,6 +6,8 @@ import { HeartIcon } from '@heroicons/react/24/outline' import { Fragment, useEffect, useRef, useState } from 'react' import LazyLoad from 'react-lazy-load' import ProductSimilar from './ProductSimilar' +import { toast } from 'react-hot-toast' +import { updateItemCart } from '@/core/utils/cart' const ProductDesktop = ({ product, wishlist, toggleWishlist }) => { const [variantQuantity, setVariantQuantity] = useState(null) @@ -34,6 +36,28 @@ const ProductDesktop = ({ product, wishlist, toggleWishlist }) => { } } + const validAction = (variantId) => { + let isValid = true + if ( + !variantQuantity[variantId] || + variantQuantity[variantId] < 1 || + isNaN(parseInt(variantQuantity[variantId])) + ) { + toast.error('Jumlah barang minimal 1') + isValid = false + } + return isValid + } + + const handleAddToCart = (variantId) => { + if (!validAction(variantId)) return + updateItemCart({ + productId: variantId, + quantity: variantQuantity[variantId] + }) + toast.success('Berhasil menambahkan ke keranjang') + } + const productSimilarQuery = [ product?.name.replace(/[()/"&]/g, ''), `fq=-product_id:${product.id}`, @@ -168,8 +192,16 @@ const ProductDesktop = ({ product, wishlist, toggleWishlist }) => { /> </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> + <button + type='button' + onClick={() => handleAddToCart(variant.id)} + className='flex-1 py-2 btn-yellow' + > + Keranjang + </button> + <button type='button' className='flex-1 py-2 btn-solid-red'> + Beli + </button> </td> </tr> ))} diff --git a/src/pages/_app.jsx b/src/pages/_app.jsx index 8b13cc0b..7b04fea2 100644 --- a/src/pages/_app.jsx +++ b/src/pages/_app.jsx @@ -15,7 +15,7 @@ function MyApp({ Component, pageProps }) { return ( <> <Toaster - position='top-center' + position={isMobile ? 'top-center' : 'bottom-center'} toastOptions={{ duration: 3000, className: 'border border-gray_r-8' diff --git a/src/styles/globals.css b/src/styles/globals.css index 63fa729e..06a9420c 100644 --- a/src/styles/globals.css +++ b/src/styles/globals.css @@ -425,7 +425,40 @@ button { @apply odd:bg-gray_r-3 even:bg-gray_r-1; } -.category-mega-box-wrapper { +.navbar-user-dropdown-button { + @apply flex-1 + flex + gap-x-2 + p-4 + items-center + bg-red_r-11 + !text-gray_r-1 + rounded-none + rounded-tr-xl; +} + +.navbar-user-dropdown-button span { + @apply line-clamp-1; +} + +.navbar-user-dropdown-wrapper a { + @apply text-gray_r-12/80 hover:text-red_r-11 font-medium; +} + +.navbar-user-dropdown { + @apply bg-white + border + border-gray_r-6 + p-4 + w-full + flex + flex-col + gap-y-3 + shadow; +} + +.category-mega-box-wrapper, +.navbar-user-dropdown-wrapper { @apply absolute opacity-0 left-0 @@ -440,7 +473,9 @@ button { text-left; } -.category-mega-box-wrapper.show { +.category-mega-box-wrapper.show, +.navbar-user-dropdown-button:hover ~ .navbar-user-dropdown-wrapper, +.navbar-user-dropdown-wrapper:hover { @apply top-[100%] opacity-100 pointer-events-auto; |
