summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/core/components/views/DesktopView.jsx21
-rw-r--r--src/core/components/views/MobileView.jsx21
-rw-r--r--src/core/hooks/useDevice.js36
-rw-r--r--src/lib/category/components/Category.jsx77
-rw-r--r--src/lib/home/components/HeroBanner.jsx67
-rw-r--r--src/pages/index.jsx3
-rw-r--r--src/styles/globals.css58
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;
}