From 33da0fcb718335eb1d077af4321ac65e0146a2d6 Mon Sep 17 00:00:00 2001 From: Rafi Zadanly Date: Mon, 22 May 2023 11:58:05 +0700 Subject: Refactoring hero banner feature --- src/api/BannerApi.js | 5 +++ src/components/skeleton/BannerSkeleton.jsx | 20 +++++++++ src/components/ui/HeroBanner.jsx | 64 +++++++++++++++++++++++++++ src/components/ui/HeroBannerSecondary.jsx | 35 +++++++++++++++ src/lib/home/components/HeroBanner.jsx | 70 ------------------------------ src/lib/home/hooks/useHeroBanner.js | 13 ------ src/pages/index.jsx | 25 +++-------- src/utils/getRandomInt.js | 3 ++ 8 files changed, 132 insertions(+), 103 deletions(-) create mode 100644 src/api/BannerApi.js create mode 100644 src/components/skeleton/BannerSkeleton.jsx create mode 100644 src/components/ui/HeroBanner.jsx create mode 100644 src/components/ui/HeroBannerSecondary.jsx delete mode 100644 src/lib/home/components/HeroBanner.jsx delete mode 100644 src/lib/home/hooks/useHeroBanner.js create mode 100644 src/utils/getRandomInt.js (limited to 'src') diff --git a/src/api/BannerApi.js b/src/api/BannerApi.js new file mode 100644 index 00000000..8ebecd26 --- /dev/null +++ b/src/api/BannerApi.js @@ -0,0 +1,5 @@ +import odooApi from '@/core/api/odooApi' + +export const BannerApi = ({ type }) => { + return async () => await odooApi('GET', `/api/v1/banner?type=${type}`) +} diff --git a/src/components/skeleton/BannerSkeleton.jsx b/src/components/skeleton/BannerSkeleton.jsx new file mode 100644 index 00000000..3de9c027 --- /dev/null +++ b/src/components/skeleton/BannerSkeleton.jsx @@ -0,0 +1,20 @@ +const HeroBannerSkeleton = () => { + return ( +
+
+ +
+ Loading... +
+ ) +} + +export { HeroBannerSkeleton } diff --git a/src/components/ui/HeroBanner.jsx b/src/components/ui/HeroBanner.jsx new file mode 100644 index 00000000..1b5bf165 --- /dev/null +++ b/src/components/ui/HeroBanner.jsx @@ -0,0 +1,64 @@ +import DesktopView from '@/core/components/views/DesktopView' +import MobileView from '@/core/components/views/MobileView' +import { Swiper, SwiperSlide } from 'swiper/react' +import { Pagination, Autoplay } from 'swiper' +import 'swiper/css' +import 'swiper/css/pagination' +import 'swiper/css/autoplay' +import { useMemo } from 'react' +import Link from '@/core/components/elements/Link/Link' +import Image from '@/core/components/elements/Image/Image' +import { useQuery } from 'react-query' +import { BannerApi } from '@/api/BannerApi' +import { HeroBannerSkeleton } from '../skeleton/BannerSkeleton' + +const swiperBanner = { + autoplay: { + delay: 6000, + disableOnInteraction: false + }, + modules: [Pagination, Autoplay], + loop: true, + className: 'border border-gray_r-6', + slidesPerView: 1 +} + +const HeroBanner = () => { + const heroBanner = useQuery('heroBanner', BannerApi({ type: 'index-a-1' })) + + const swiperBannerMobile = { + ...swiperBanner, + pagination: { dynamicBullets: true, clickable: true } + } + + const swiperBannerDesktop = { + ...swiperBanner, + pagination: { dynamicBullets: false, clickable: true } + } + + const BannerComponent = useMemo(() => { + return heroBanner.data?.map((banner, index) => ( + + + {banner.name} + + + )) + }, [heroBanner.data]) + + if (heroBanner.isLoading) return + + return ( + <> + + {BannerComponent} + + + + {BannerComponent} + + + ) +} + +export default HeroBanner diff --git a/src/components/ui/HeroBannerSecondary.jsx b/src/components/ui/HeroBannerSecondary.jsx new file mode 100644 index 00000000..a3227002 --- /dev/null +++ b/src/components/ui/HeroBannerSecondary.jsx @@ -0,0 +1,35 @@ +import Link from '@/core/components/elements/Link/Link' +import { getRandomInt } from '@/utils/getRandomInt' +import Image from 'next/image' +import { useMemo } from 'react' +import { useQuery } from 'react-query' +import { HeroBannerSkeleton } from '../skeleton/BannerSkeleton' +import { BannerApi } from '@/api/BannerApi' + +const HeroBannerSecondary = () => { + const heroBannerSecondary = useQuery('heroBannerSecondary', BannerApi({ type: 'index-a-2' })) + + const randomIndex = useMemo(() => { + if (!heroBannerSecondary.data) return null + const length = heroBannerSecondary.data?.length + return getRandomInt(length) + }, [heroBannerSecondary.data]) + + if (heroBannerSecondary.isLoading) return + + return ( + heroBannerSecondary.data && ( + + {heroBannerSecondary.data[randomIndex].name} + + ) + ) +} + +export default HeroBannerSecondary diff --git a/src/lib/home/components/HeroBanner.jsx b/src/lib/home/components/HeroBanner.jsx deleted file mode 100644 index 889bb2ce..00000000 --- a/src/lib/home/components/HeroBanner.jsx +++ /dev/null @@ -1,70 +0,0 @@ -import ImageSkeleton from '@/core/components/elements/Skeleton/ImageSkeleton' -import useHeroBanner from '../hooks/useHeroBanner' -import Image from '@/core/components/elements/Image/Image' - -// Swiper -import { Swiper, SwiperSlide } from 'swiper/react' -import { Pagination, Autoplay } from 'swiper' -import 'swiper/css' -import 'swiper/css/pagination' -import 'swiper/css/autoplay' -import MobileView from '@/core/components/views/MobileView' -import DesktopView from '@/core/components/views/DesktopView' -import Link from '@/core/components/elements/Link/Link' - -const HeroBanner = () => { - const { heroBanners } = useHeroBanner() - - const swiperBanner = { - autoplay: { - delay: 6000, - disableOnInteraction: false - }, - modules: [Pagination, Autoplay], - loop: true - } - - const swiperBannerMobile = { - ...swiperBanner, - pagination: { dynamicBullets: true, clickable: true } - } - - const swiperBannerDesktop = { - ...swiperBanner, - pagination: { dynamicBullets: false, clickable: true } - } - - return ( -
- {heroBanners.isLoading && } - {!heroBanners.isLoading && ( - <> - - - {heroBanners.data?.map((banner, index) => ( - - - {banner.name} - - - ))} - - - - - {heroBanners.data?.map((banner, index) => ( - - - {banner.name} - - - ))} - - - - )} -
- ) -} - -export default HeroBanner diff --git a/src/lib/home/hooks/useHeroBanner.js b/src/lib/home/hooks/useHeroBanner.js deleted file mode 100644 index 5d2b0512..00000000 --- a/src/lib/home/hooks/useHeroBanner.js +++ /dev/null @@ -1,13 +0,0 @@ -import heroBannerApi from '../api/heroBannerApi' -import { useQuery } from 'react-query' - -const useHeroBanner = () => { - const fetchHeroBanner = async () => await heroBannerApi() - const { isLoading, data } = useQuery('heroBanner', fetchHeroBanner) - - return { - heroBanners: { data, isLoading } - } -} - -export default useHeroBanner diff --git a/src/pages/index.jsx b/src/pages/index.jsx index d83bc990..ea4949b2 100644 --- a/src/pages/index.jsx +++ b/src/pages/index.jsx @@ -5,17 +5,15 @@ import MobileView from '@/core/components/views/MobileView' import DesktopView from '@/core/components/views/DesktopView' import { useRef } from 'react' import Seo from '@/core/components/Seo' -import { useQuery } from 'react-query' -import odooApi from '@/core/api/odooApi' -import Image from 'next/image' import DelayRender from '@/core/components/elements/DelayRender/DelayRender' -import Link from '@/core/components/elements/Link/Link' +import HeroBannerSecondary from '@/components/ui/HeroBannerSecondary' +import { HeroBannerSkeleton } from '@/components/skeleton/BannerSkeleton' const BasicLayout = dynamic(() => import('@/core/components/layouts/BasicLayout')) const FlashSale = dynamic(() => import('@/lib/flashSale/components/FlashSale')) const BannerSection = dynamic(() => import('@/lib/home/components/BannerSection')) -const HeroBanner = dynamic(() => import('@/lib/home/components/HeroBanner'), { - loading: () => +const HeroBanner = dynamic(() => import('@/components/ui/HeroBanner'), { + loading: () => }) const PreferredBrand = dynamic(() => import('@/lib/home/components/PreferredBrand'), { loading: () => @@ -29,9 +27,6 @@ const CategoryHomeId = dynamic(() => import('@/lib/home/components/CategoryHomeI const CustomerReviews = dynamic(() => import('@/lib/review/components/CustomerReviews')) export default function Home() { - const fetchSecondHeroBanner = async () => await odooApi('GET', '/api/v1/banner?type=index-a-2') - const secondHeroBanner = useQuery('secondHeroBanner', fetchSecondHeroBanner) - const bannerRef = useRef(null) const wrapperRef = useRef(null) @@ -58,17 +53,7 @@ export default function Home() {
- {secondHeroBanner.isFetched && ( - - {secondHeroBanner.data[0].name} - - )} +
diff --git a/src/utils/getRandomInt.js b/src/utils/getRandomInt.js new file mode 100644 index 00000000..900e55f8 --- /dev/null +++ b/src/utils/getRandomInt.js @@ -0,0 +1,3 @@ +export const getRandomInt = (max) => { + return Math.floor(Math.random() * max); +} \ No newline at end of file -- cgit v1.2.3