From 1ef538546c0bdd9351baaed90b837f399584b460 Mon Sep 17 00:00:00 2001 From: Rafi Zadanly Date: Mon, 13 Mar 2023 16:20:18 +0700 Subject: category, brand, product popular, product category in desktop home page --- src/core/components/elements/Navbar/Navbar.jsx | 192 +-------------------- .../components/elements/Navbar/NavbarDesktop.jsx | 170 ++++++++++++++++++ .../components/elements/Navbar/NavbarMobile.jsx | 48 ++++++ src/lib/brand/components/BrandCard.jsx | 6 +- src/lib/home/components/CategoryHome.jsx | 2 +- src/lib/home/components/PopularProduct.jsx | 51 ++++-- src/lib/home/components/PreferredBrand.jsx | 21 ++- src/lib/product/components/ProductCard.jsx | 91 ++++++++-- src/lib/product/components/ProductSlider.jsx | 8 +- src/pages/index.jsx | 35 +++- src/styles/globals.css | 49 +++++- 11 files changed, 438 insertions(+), 235 deletions(-) create mode 100644 src/core/components/elements/Navbar/NavbarDesktop.jsx create mode 100644 src/core/components/elements/Navbar/NavbarMobile.jsx (limited to 'src') diff --git a/src/core/components/elements/Navbar/Navbar.jsx b/src/core/components/elements/Navbar/Navbar.jsx index 1c559faf..57904498 100644 --- a/src/core/components/elements/Navbar/Navbar.jsx +++ b/src/core/components/elements/Navbar/Navbar.jsx @@ -1,197 +1,13 @@ import dynamic from 'next/dynamic' -import Image from 'next/image' -import IndoteknikLogo from '@/images/logo.png' -import { - Bars3Icon, - ChevronDownIcon, - DocumentCheckIcon, - HeartIcon, - ShoppingCartIcon -} from '@heroicons/react/24/outline' -import Link from '../Link/Link' -import useSidebar from '@/core/hooks/useSidebar' -import MobileView from '../../views/MobileView' -import DesktopView from '../../views/DesktopView' -const Search = dynamic(() => import('./Search')) +const NavbarDesktop = dynamic(() => import('./NavbarDesktop')) +const NavbarMobile = dynamic(() => import('./NavbarMobile')) const Navbar = () => { - const { Sidebar, open } = useSidebar() return ( <> - - - {Sidebar} - - - -
-
- - Tentang Indoteknik.com - -
- - Pembayaran Tempo - - - F.A.Q - - - Fitur Layanan - -
-
-
- - - -
-
-
-
Kategori Produk
- -
-
- - Promo Produk - - - Semua Brand - - - Ready Stock - - - Blog Indoteknik - -
-
- - Masuk - - - Daftar - -
-
-
-
+ + ) } diff --git a/src/core/components/elements/Navbar/NavbarDesktop.jsx b/src/core/components/elements/Navbar/NavbarDesktop.jsx new file mode 100644 index 00000000..2f7a6e23 --- /dev/null +++ b/src/core/components/elements/Navbar/NavbarDesktop.jsx @@ -0,0 +1,170 @@ +import { + ChevronDownIcon, + HeartIcon, + ShoppingCartIcon, + DocumentCheckIcon +} from '@heroicons/react/24/outline' +import Link from '../Link/Link' +import Image from 'next/image' +import DesktopView from '../../views/DesktopView' +import dynamic from 'next/dynamic' +import IndoteknikLogo from '@/images/logo.png' +import Category from '@/lib/category/components/Category' +import { useState } from 'react' + +const Search = dynamic(() => import('./Search')) + +const NavbarDesktop = () => { + const [isOpenCategory, setIsOpenCategory] = useState(false) + + return ( + +
+
+ + Tentang Indoteknik.com + +
+ + Pembayaran Tempo + + + F.A.Q + + + Fitur Layanan + +
+
+
+ + + +
+
+
+
Kategori Produk
+ +
+ +
+
+
+ + Promo Produk + + + Semua Brand + + + Ready Stock + + + Blog Indoteknik + +
+
+ + Masuk + + + Daftar + +
+
+
+
+ ) +} + +export default NavbarDesktop diff --git a/src/core/components/elements/Navbar/NavbarMobile.jsx b/src/core/components/elements/Navbar/NavbarMobile.jsx new file mode 100644 index 00000000..3998875b --- /dev/null +++ b/src/core/components/elements/Navbar/NavbarMobile.jsx @@ -0,0 +1,48 @@ +import Image from 'next/image' +import MobileView from '../../views/MobileView' +import Link from '../Link/Link' +import { Bars3Icon, HeartIcon, ShoppingCartIcon } from '@heroicons/react/24/outline' +import useSidebar from '@/core/hooks/useSidebar' +import dynamic from 'next/dynamic' +import IndoteknikLogo from '@/images/logo.png' + +const Search = dynamic(() => import('./Search')) + +const NavbarMobile = () => { + const { Sidebar, open } = useSidebar() + + return ( + + + {Sidebar} + + ) +} + +export default NavbarMobile diff --git a/src/lib/brand/components/BrandCard.jsx b/src/lib/brand/components/BrandCard.jsx index 1bcdb5ab..984a9fa6 100644 --- a/src/lib/brand/components/BrandCard.jsx +++ b/src/lib/brand/components/BrandCard.jsx @@ -1,18 +1,20 @@ import Image from '@/core/components/elements/Image/Image' import Link from '@/core/components/elements/Link/Link' +import useDevice from '@/core/hooks/useDevice' import { createSlug } from '@/core/utils/slug' const BrandCard = ({ brand }) => { + const { isMobile } = useDevice() return ( {brand.logo && ( {brand.name} )} {!brand.logo && ( diff --git a/src/lib/home/components/CategoryHome.jsx b/src/lib/home/components/CategoryHome.jsx index ac43e2bc..05f0ca28 100644 --- a/src/lib/home/components/CategoryHome.jsx +++ b/src/lib/home/components/CategoryHome.jsx @@ -6,7 +6,7 @@ const CategoryHome = ({ id }) => { const { categoryHome } = useCategoryHome({ id }) return ( -
+
{categoryHome.data ? ( { const { popularProducts } = usePopularProduct() return ( -
-
Produk Populer
- {popularProducts.isLoading && } - {!popularProducts.isLoading && ( - - )} -
+ <> + +
+
Produk Banyak Dilihat
+ {popularProducts.isLoading && } + {!popularProducts.isLoading && ( + + )} +
+
+ + +
+
+ Produk Banyak Dilihat +
+
+ {popularProducts.data && + popularProducts.data.products.map((product) => ( +
+ +
+ ))} +
+
+
+ ) } diff --git a/src/lib/home/components/PreferredBrand.jsx b/src/lib/home/components/PreferredBrand.jsx index 3df3cdb7..7edd0730 100644 --- a/src/lib/home/components/PreferredBrand.jsx +++ b/src/lib/home/components/PreferredBrand.jsx @@ -2,18 +2,31 @@ import { Swiper, SwiperSlide } from 'swiper/react' import usePreferredBrand from '../hooks/usePreferredBrand' import PreferredBrandSkeleton from './Skeleton/PreferredBrandSkeleton' import BrandCard from '@/lib/brand/components/BrandCard' +import useDevice from '@/core/hooks/useDevice' +import Link from '@/core/components/elements/Link/Link' const PreferredBrand = () => { const { preferredBrands } = usePreferredBrand() + const { isMobile, isDesktop } = useDevice() return ( -
-
Brand Pilihan
+
+
+
Brand Pilihan
+ {isDesktop && ( + + Lihat Semua + + )} +
{preferredBrands.isLoading && } {!preferredBrands.isLoading && ( {preferredBrands.data?.manufactures.map((brand) => ( diff --git a/src/lib/product/components/ProductCard.jsx b/src/lib/product/components/ProductCard.jsx index 6b88a3bd..0c11137d 100644 --- a/src/lib/product/components/ProductCard.jsx +++ b/src/lib/product/components/ProductCard.jsx @@ -3,9 +3,9 @@ import Link from '@/core/components/elements/Link/Link' import currencyFormat from '@/core/utils/currencyFormat' import { createSlug } from '@/core/utils/slug' -const ProductCard = ({ product, simpleTitle }) => { - return ( - <> +const ProductCard = ({ product, simpleTitle, variant = 'vertical' }) => { + if (variant == 'vertical') { + return (
{ {product?.name} {product.variantTotal > 1 && (
@@ -22,7 +22,7 @@ const ProductCard = ({ product, simpleTitle }) => {
)} -
+
{product?.manufacture?.name ? ( { product?.manufacture?.name, product?.manufacture.id )} - className='mb-1' + className='mb-1 font-normal' > {product.manufacture.name} @@ -39,7 +39,7 @@ const ProductCard = ({ product, simpleTitle }) => { )} @@ -47,7 +47,7 @@ const ProductCard = ({ product, simpleTitle }) => { {product?.lowestPrice?.discountPercentage > 0 && (
-
+
{currencyFormat(product?.lowestPrice?.price)}
{product?.lowestPrice?.discountPercentage}%
@@ -69,8 +69,79 @@ const ProductCard = ({ product, simpleTitle }) => { )}
- - ) + ) + } + + if (variant == 'horizontal') { + return ( +
+
+ + {product?.name} + {product.variantTotal > 1 && ( +
+ {product.variantTotal} Varian +
+ )} + +
+
+ {product?.manufacture?.name ? ( + + {product.manufacture.name} + + ) : ( +
-
+ )} + + {product?.name} + + + {product?.lowestPrice?.discountPercentage > 0 && ( +
+
{product?.lowestPrice?.discountPercentage}%
+
+ {currencyFormat(product?.lowestPrice?.price)} +
+
+ )} + +
+ {product?.lowestPrice?.priceDiscount > 0 ? ( + currencyFormat(product?.lowestPrice?.priceDiscount) + ) : ( + Call for price + )} +
+ {product?.stockTotal > 0 && ( +
+
Ready Stock
+
{product?.stockTotal > 5 ? '> 5' : '< 5'}
+
+ )} +
+
+ ) + } } export default ProductCard diff --git a/src/lib/product/components/ProductSlider.jsx b/src/lib/product/components/ProductSlider.jsx index 060d4638..ed7db486 100644 --- a/src/lib/product/components/ProductSlider.jsx +++ b/src/lib/product/components/ProductSlider.jsx @@ -5,12 +5,14 @@ import 'swiper/css' import Image from '@/core/components/elements/Image/Image' import Link from '@/core/components/elements/Link/Link' import { useRef } from 'react' +import useDevice from '@/core/hooks/useDevice' const bannerClassName = - 'absolute rounded-r top-0 left-0 h-full max-w-[52%] idt-transition border border-gray_r-6' + 'absolute rounded-r top-0 left-0 h-full w-auto md:w-[20%] idt-transition border border-gray_r-6' const ProductSlider = ({ products, simpleTitle = false, bannerMode = false }) => { const bannerRef = useRef('') + const { isMobile } = useDevice() const changeBannerOpacity = (swiper) => { if (!bannerMode) return @@ -32,8 +34,8 @@ const ProductSlider = ({ products, simpleTitle = false, bannerMode = false }) => )} import('@/core/components/layouts/BasicLayout')) @@ -25,18 +25,39 @@ const CategoryHomeId = dynamic(() => import('@/lib/home/components/CategoryHomeI }) export default function Home() { + const bannerRef = useRef(null) + const wrapperRef = useRef(null) + + const handleOnLoad = () => { + wrapperRef.current.style.height = + bannerRef.current.querySelector(':first-child').clientHeight + 'px' + } + return ( -
-
-
- -
-
+
+
+
+
+
+ +
+
+ +
+ +
diff --git a/src/styles/globals.css b/src/styles/globals.css index 12589e7d..b482aa30 100644 --- a/src/styles/globals.css +++ b/src/styles/globals.css @@ -134,6 +134,7 @@ button { .btn-yellow { @apply bg-yellow_r-9 border-yellow_r-9 + hover:bg-yellow_r-10 disabled:text-gray_r-10 disabled:bg-yellow_r-7 disabled:border-yellow_r-7; @@ -381,8 +382,34 @@ button { @apply !border-yellow_r-9; } +.category-mega-box-wrapper { + @apply absolute + opacity-0 + left-0 + top-[125%] + flex + w-full + z-10 + transition-all + ease-in + duration-200 + pointer-events-none; +} + +.category-mega-box-wrapper.show { + @apply top-[100%] + opacity-100 + pointer-events-auto; +} + .category-mega-box { - @apply relative py-2 border border-gray_r-6 h-full; + @apply relative + py-2 + border + border-t-0 + border-gray_r-6 + h-full + w-full; } .category-mega-box > div { @@ -394,29 +421,34 @@ button { } .category-mega-box > div:hover .category-mega-box__child-wrapper { - @apply block; + @apply opacity-100 + top-0 + pointer-events-auto; } .category-mega-box .category-mega-box__parent { @apply py-2.5 px-4 - idt-transition text-gray_r-12/80 - font-normal + font-normal; } .category-mega-box__child-wrapper { @apply absolute left-[100%] - top-0 - w-[50vw] + top-12 + w-[40vw] bg-gray_r-1/90 backdrop-blur-md border border-gray_r-6 p-6 - hidden - h-full + opacity-0 + h-full + transition-all + ease-in + duration-200 + pointer-events-none z-50; } @@ -437,3 +469,4 @@ button { duration-100 font-normal; } + -- cgit v1.2.3