diff options
| author | Rafi Zadanly <zadanlyr@gmail.com> | 2023-03-11 13:37:29 +0700 |
|---|---|---|
| committer | Rafi Zadanly <zadanlyr@gmail.com> | 2023-03-11 13:37:29 +0700 |
| commit | d26133d39e7d9cd510fdc72d239303f4ba918bdd (patch) | |
| tree | ac3266dbd2d949c6cfc230183e18014d7df0552b /src | |
| parent | 1218d8109380488ab7d15538fe3f828883dbc822 (diff) | |
create useDevice hooks, optimize DesktopView and MobileView, and show category API data
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/components/views/DesktopView.jsx | 21 | ||||
| -rw-r--r-- | src/core/components/views/MobileView.jsx | 21 | ||||
| -rw-r--r-- | src/core/hooks/useDevice.js | 36 | ||||
| -rw-r--r-- | src/lib/category/components/Category.jsx | 77 | ||||
| -rw-r--r-- | src/lib/home/components/HeroBanner.jsx | 67 | ||||
| -rw-r--r-- | src/pages/index.jsx | 3 | ||||
| -rw-r--r-- | src/styles/globals.css | 58 |
7 files changed, 192 insertions, 91 deletions
diff --git a/src/core/components/views/DesktopView.jsx b/src/core/components/views/DesktopView.jsx index 08c4b310..9042a766 100644 --- a/src/core/components/views/DesktopView.jsx +++ b/src/core/components/views/DesktopView.jsx @@ -1,24 +1,17 @@ +import useDevice from '@/core/hooks/useDevice' import { useEffect, useState } from 'react' const DesktopView = ({ children }) => { + const { isDesktop } = useDevice() const [view, setView] = useState(<></>) useEffect(() => { - const handleResize = () => { - if (window.innerWidth >= 768) { - setView(children) - } else { - setView(<></>) - } + if (isDesktop) { + setView(children) + } else { + setView(<></>) } - - handleResize() - window.addEventListener('resize', handleResize) - - return () => { - window.removeEventListener('resize', handleResize) - } - }, [children]) + }, [isDesktop, children]) return view } diff --git a/src/core/components/views/MobileView.jsx b/src/core/components/views/MobileView.jsx index 348572c6..0c8a806c 100644 --- a/src/core/components/views/MobileView.jsx +++ b/src/core/components/views/MobileView.jsx @@ -1,24 +1,17 @@ +import useDevice from '@/core/hooks/useDevice' import { useEffect, useState } from 'react' const MobileView = ({ children }) => { + const { isMobile } = useDevice() const [view, setView] = useState(<></>) useEffect(() => { - const handleResize = () => { - if (window.innerWidth < 768) { - setView(children) - } else { - setView(<></>) - } + if (isMobile) { + setView(children) + } else { + setView(<></>) } - - handleResize() - window.addEventListener('resize', handleResize) - - return () => { - window.removeEventListener('resize', handleResize) - } - }, [children]) + }, [isMobile, children]) return view } diff --git a/src/core/hooks/useDevice.js b/src/core/hooks/useDevice.js new file mode 100644 index 00000000..ca11610d --- /dev/null +++ b/src/core/hooks/useDevice.js @@ -0,0 +1,36 @@ +const { useState, useEffect } = require('react') + +const useDevice = () => { + const [isMobile, setIsMobile] = useState(false) + const [isDesktop, setIsDesktop] = useState(false) + + useEffect(() => { + const handleResize = () => { + if (window.innerWidth < 768) { + setIsMobile(true) + } else { + setIsMobile(false) + } + + if (window.innerWidth >= 768) { + setIsDesktop(true) + } else { + setIsDesktop(false) + } + } + + handleResize() + window.addEventListener('resize', handleResize) + + return () => { + window.removeEventListener('resize', handleResize) + } + }, []) + + return { + isMobile, + isDesktop + } +} + +export default useDevice diff --git a/src/lib/category/components/Category.jsx b/src/lib/category/components/Category.jsx index 21e2ec6f..5ba45cc7 100644 --- a/src/lib/category/components/Category.jsx +++ b/src/lib/category/components/Category.jsx @@ -1,28 +1,69 @@ +import odooApi from '@/core/api/odooApi' import Link from '@/core/components/elements/Link/Link' import DesktopView from '@/core/components/views/DesktopView' +import { useEffect, useState } from 'react' const Category = () => { + const [categories, setCategories] = useState([]) + + useEffect(() => { + const loadCategories = async () => { + let dataCategories = await odooApi('GET', '/api/v1/category/tree') + dataCategories = dataCategories.map((category) => { + category.childs = category.childs.map((child1Category) => { + return { + ...child1Category, + isOpen: false + } + }) + return { + ...category, + isOpen: false + } + }) + setCategories(dataCategories) + } + loadCategories() + }, []) + return ( <DesktopView> - <div className='category-box'> - <div> - <Link href='/'>Alat Potong & Pelengkap Mesin</Link> - <div> - <div className='font-medium'>Alat Potong & Pelengkap Mesin</div> - </div> - </div> - <div> - <Link href='/'>Alat Ukur & Instrument</Link> - <div> - <div className='font-medium'>Alat Ukur & Instrument</div> - </div> - </div> - <div> - <Link href='/'>Komponen Mekanikal & Hardware</Link> - <div> - <div className='font-medium'>Komponen Mekanikal & Hardware</div> + <div className='category-mega-box'> + {categories.map((category) => ( + <div key={category.id}> + <Link + href='/' + className='category-mega-box__parent' + > + {category.name} + </Link> + <div className='category-mega-box__child-wrapper'> + <div className='grid grid-cols-3 gap-x-4 gap-y-6 max-h-full overflow-auto'> + {category.childs.map((child1Category) => ( + <div key={child1Category.id}> + <Link + href='/' + className='category-mega-box__child-one mb-4' + > + {child1Category.name} + </Link> + <div className='flex flex-col gap-y-3'> + {child1Category.childs.map((child2Category) => ( + <Link + href='/' + className='category-mega-box__child-two' + key={child2Category.id} + > + {child2Category.name} + </Link> + ))} + </div> + </div> + ))} + </div> + </div> </div> - </div> + ))} </div> </DesktopView> ) diff --git a/src/lib/home/components/HeroBanner.jsx b/src/lib/home/components/HeroBanner.jsx index e6690c01..95f590fc 100644 --- a/src/lib/home/components/HeroBanner.jsx +++ b/src/lib/home/components/HeroBanner.jsx @@ -1,7 +1,6 @@ import ImageSkeleton from '@/core/components/elements/Skeleton/ImageSkeleton' import useHeroBanner from '../hooks/useHeroBanner' import Image from '@/core/components/elements/Image/Image' -import MobileView from '@/core/components/views/MobileView' // Swiper import { Swiper, SwiperSlide } from 'swiper/react' @@ -9,44 +8,44 @@ import { Pagination, Autoplay } from 'swiper' import 'swiper/css' import 'swiper/css/pagination' import 'swiper/css/autoplay' - -const swiperBanner = { - pagination: { dynamicBullets: true }, - autoplay: { - delay: 6000, - disableOnInteraction: false - }, - modules: [Pagination, Autoplay] -} +import useDevice from '@/core/hooks/useDevice' const HeroBanner = () => { + const { isMobile } = useDevice() const { heroBanners } = useHeroBanner() + const swiperBanner = { + pagination: { dynamicBullets: isMobile ? true : false, clickable: true }, + autoplay: { + delay: 6000, + disableOnInteraction: false + }, + modules: [Pagination, Autoplay] + } + return ( - <MobileView> - <div className='min-h-[200px]'> - {heroBanners.isLoading && <ImageSkeleton />} - {!heroBanners.isLoading && ( - <Swiper - slidesPerView={1} - pagination={swiperBanner.pagination} - modules={swiperBanner.modules} - autoplay={swiperBanner.autoplay} - className='border-b border-gray_r-6' - > - {heroBanners.data?.map((banner, index) => ( - <SwiperSlide key={index}> - <Image - src={banner.image} - alt={banner.name} - className='w-full h-auto' - /> - </SwiperSlide> - ))} - </Swiper> - )} - </div> - </MobileView> + <div className='min-h-[200px]'> + {heroBanners.isLoading && <ImageSkeleton />} + {!heroBanners.isLoading && ( + <Swiper + slidesPerView={1} + pagination={swiperBanner.pagination} + modules={swiperBanner.modules} + autoplay={swiperBanner.autoplay} + className='border border-gray_r-6' + > + {heroBanners.data?.map((banner, index) => ( + <SwiperSlide key={index}> + <Image + src={banner.image} + alt={banner.name} + className='w-full h-auto' + /> + </SwiperSlide> + ))} + </Swiper> + )} + </div> ) } diff --git a/src/pages/index.jsx b/src/pages/index.jsx index 2c63e772..70231f7e 100644 --- a/src/pages/index.jsx +++ b/src/pages/index.jsx @@ -34,6 +34,9 @@ export default function Home() { <div className='w-3/12'> <Category /> </div> + <div className='w-6/12 px-1'> + <HeroBanner /> + </div> </div> </div> </DesktopView> diff --git a/src/styles/globals.css b/src/styles/globals.css index f551f9f7..12589e7d 100644 --- a/src/styles/globals.css +++ b/src/styles/globals.css @@ -381,23 +381,59 @@ button { @apply !border-yellow_r-9; } -.category-box { - @apply py-2 border border-gray_r-6; +.category-mega-box { + @apply relative py-2 border border-gray_r-6 h-full; } -.category-box > div { - @apply relative text-gray_r-12/80; +.category-mega-box > div { + @apply text-gray_r-12/80; } -.category-box a { - @apply py-2.5 px-4 idt-transition text-gray_r-12/80 hover:bg-gray_r-4; +.category-mega-box > div:hover .category-mega-box__parent { + @apply bg-yellow_r-4; } -.category-box a + div { - @apply absolute left-[100%] top-0 w-[40vw] bg-gray_r-1 border border-gray_r-6 p-4 hidden; +.category-mega-box > div:hover .category-mega-box__child-wrapper { + @apply block; } -.category-box a:hover + div, -.category-box a + div:hover { - @apply block; +.category-mega-box .category-mega-box__parent { + @apply py-2.5 + px-4 + idt-transition + text-gray_r-12/80 + font-normal +} + +.category-mega-box__child-wrapper { + @apply absolute + left-[100%] + top-0 + w-[50vw] + bg-gray_r-1/90 + backdrop-blur-md + border + border-gray_r-6 + p-6 + hidden + h-full + z-50; +} + +.category-mega-box__child-one { + @apply text-gray_r-12/80 + hover:text-red_r-11 + transition-colors + ease-linear + duration-100 + font-semibold; +} + +.category-mega-box__child-two { + @apply text-gray_r-12/80 + hover:text-red_r-11 + transition-colors + ease-linear + duration-100 + font-normal; } |
