diff options
| author | it-fixcomart <it@fixcomart.co.id> | 2024-11-28 10:47:43 +0700 |
|---|---|---|
| committer | it-fixcomart <it@fixcomart.co.id> | 2024-11-28 10:47:43 +0700 |
| commit | 5bc7a6807847610b190ea9d5046021d2db15afc5 (patch) | |
| tree | e895b02c65bf97e3c6c970bb8d777922120f4570 /src/lib/home/components | |
| parent | 7ed3fd96322d08bd91434b8ec4dcbc542a610998 (diff) | |
| parent | 952421c810b53ec4d25ad5ef605bae1bd1d5d616 (diff) | |
Merge branch 'new-release' into Feature/switch-account
Diffstat (limited to 'src/lib/home/components')
| -rw-r--r-- | src/lib/home/components/BannerSection.jsx | 40 | ||||
| -rw-r--r-- | src/lib/home/components/CategoryDynamic.jsx | 236 | ||||
| -rw-r--r-- | src/lib/home/components/CategoryDynamicMobile.jsx | 56 | ||||
| -rw-r--r-- | src/lib/home/components/PreferredBrand.jsx | 81 | ||||
| -rw-r--r-- | src/lib/home/components/PromotionProgram.jsx | 87 | ||||
| -rw-r--r-- | src/lib/home/components/ServiceList.jsx | 4 |
6 files changed, 266 insertions, 238 deletions
diff --git a/src/lib/home/components/BannerSection.jsx b/src/lib/home/components/BannerSection.jsx index f83c36fc..303b5c4b 100644 --- a/src/lib/home/components/BannerSection.jsx +++ b/src/lib/home/components/BannerSection.jsx @@ -1,18 +1,48 @@ import Link from '@/core/components/elements/Link/Link'; import Image from 'next/image'; +import { useEffect, useState } from 'react'; +import { bannerApi } from '../../../api/bannerApi'; const { useQuery } = require('react-query'); const { default: bannerSectionApi } = require('../api/bannerSectionApi'); const BannerSection = () => { - const fetchBannerSection = async () => await bannerSectionApi(); - const bannerSection = useQuery('bannerSection', fetchBannerSection); + const [data, setData] = useState(null); + const [shouldFetch, setShouldFetch] = useState(false); + useEffect(() => { + const fetchCategoryData = async () => { + const res = await fetch('/api/banner-section'); + const { data } = await res.json(); + if (data) { + setData(data); + } + }; + + fetchCategoryData(); + }, []); + + // const fetchBannerSection = async () => await bannerSectionApi(); + const getBannerSection = useQuery( + 'bannerSection', + bannerApi({ type: 'home-banner' }), + { + enabled: shouldFetch, + onSuccess: (data) => { + if (data) { + localStorage.setItem('Homepage_bannerSection', JSON.stringify(data)); + setData(data); + } + }, + } + ); + + const bannerSection = data; return ( - bannerSection.data && - bannerSection.data?.length > 0 && ( + bannerSection && + bannerSection?.length > 0 && ( <div className='grid grid-cols-1 sm:grid-cols-2 gap-4'> - {bannerSection.data?.map((banner) => ( + {bannerSection?.map((banner) => ( <Link key={banner.id} href={banner.url}> <Image width={1024} diff --git a/src/lib/home/components/CategoryDynamic.jsx b/src/lib/home/components/CategoryDynamic.jsx index 49a9a93f..cc4f42b7 100644 --- a/src/lib/home/components/CategoryDynamic.jsx +++ b/src/lib/home/components/CategoryDynamic.jsx @@ -1,9 +1,9 @@ -import React, { useEffect, useState, useCallback } from 'react'; +import React, { useEffect, useState } from 'react'; import { fetchCategoryManagementSolr } from '../api/categoryManagementApi'; +import { Skeleton } from '@chakra-ui/react'; import NextImage from 'next/image'; import Link from 'next/link'; import { createSlug } from '@/core/utils/slug'; -import { Skeleton } from '@chakra-ui/react'; import { Swiper, SwiperSlide } from 'swiper/react'; import 'swiper/css'; import 'swiper/css/navigation'; @@ -12,45 +12,21 @@ import { Pagination } from 'swiper'; const CategoryDynamic = () => { const [categoryManagement, setCategoryManagement] = useState([]); - const [isLoading, setIsLoading] = useState(false); - const loadBrand = useCallback(async () => { - setIsLoading(true); - const items = await fetchCategoryManagementSolr(); - - setIsLoading(false); - setCategoryManagement(items); - }, []); + const [isLoading, setIsLoading] = useState(true); useEffect(() => { - loadBrand(); - }, [loadBrand]); - - // const [categoryData, setCategoryData] = useState({}); - // const [subCategoryData, setSubCategoryData] = useState({}); - - // useEffect(() => { - // const fetchCategoryData = async () => { - // if (categoryManagement && categoryManagement.data) { - // const updatedCategoryData = {}; - // const updatedSubCategoryData = {}; + const fetchCategoryData = async () => { + setIsLoading(true); + const res = await fetch('/api/category-management'); + const { data } = await res.json(); + if (data) { + setCategoryManagement(data); + } + setIsLoading(false); + }; - // for (const category of categoryManagement.data) { - // const countLevel1 = await odooApi('GET', `/api/v1/category/numFound?parent_id=${category.categoryIdI}`); - - // updatedCategoryData[category.categoryIdI] = countLevel1?.numFound; - - // for (const subCategory of countLevel1?.children) { - // updatedSubCategoryData[subCategory.id] = subCategory?.numFound; - // } - // } - - // setCategoryData(updatedCategoryData); - // setSubCategoryData(updatedSubCategoryData); - // } - // }; - - // fetchCategoryData(); - // }, [categoryManagement.isLoading]); + fetchCategoryData(); + }, []); const swiperBanner = { modules: [Pagination], @@ -66,115 +42,99 @@ const CategoryDynamic = () => { return ( <div> {categoryManagement && - categoryManagement?.map((category) => { - // const countLevel1 = categoryData[category.categoryIdI] || 0; - return ( - <Skeleton key={category.id} isLoaded={!isLoading}> - <div key={category.id}> - <div className='bagian-judul flex flex-row justify-start items-center gap-3 mb-4 mt-4'> - <h1 className='font-semibold text-[14px] sm:text-h-lg mr-2'> - {category.name} - </h1> - {/* <Skeleton isLoaded={countLevel1 != 0}> - <p className={`text-gray_r-10 text-sm`}>{countLevel1} Produk tersedia</p> - </Skeleton> */} - <Link - href={createSlug( - '/shop/category/', - category?.name, - category?.category_id - )} - className='!text-red-500 font-semibold' - > - Lihat Semua - </Link> - </div> - - {/* Swiper for SubCategories */} - <Swiper {...swiperBanner}> - {category.categories.map((subCategory) => { - // const countLevel2 = subCategoryData[subCategory.idLevel2] || 0; + categoryManagement.map((category) => ( + <Skeleton key={category.id} isLoaded={!isLoading}> + <div key={category.id}> + <div className='bagian-judul flex flex-row justify-start items-center gap-3 mb-4 mt-4'> + <h1 className='font-semibold text-[14px] sm:text-h-lg mr-2'> + {category.name} + </h1> + <Link + href={createSlug( + '/shop/category/', + category?.name, + category?.category_id + )} + className='!text-red-500 font-semibold' + > + Lihat Semua + </Link> + </div> - return ( - <SwiperSlide key={subCategory.id}> - <div className='border rounded justify-start items-start '> - <div className='p-3'> - <div className='flex flex-row border rounded mb-2 justify-start items-center'> - <NextImage - src={ - subCategory.image - ? subCategory.image - : '/images/noimage.jpeg' - } - alt={subCategory.name} - width={90} - height={30} - className='object-fit p-4' - /> - <div className='bagian-judul flex flex-col justify-center items-start gap-2 ml-2'> - <h2 className='font-semibold text-lg mr-2'> - {subCategory?.name} - </h2> - {/* <Skeleton isLoaded={countLevel2 != 0}> - <p className={`text-gray_r-10 text-sm`}> - {countLevel2} Produk tersedia - </p> - </Skeleton> */} + <Swiper {...swiperBanner}> + {category?.categories?.map((subCategory) => ( + <SwiperSlide key={subCategory.id}> + <div className='border rounded justify-start items-start '> + <div className='p-3'> + <div className='flex flex-row border rounded mb-2 justify-start items-center'> + <NextImage + src={ + subCategory.image + ? subCategory.image + : '/images/noimage.jpeg' + } + alt={subCategory.name} + width={90} + height={30} + className='object-fit p-4' + /> + <div className='bagian-judul flex flex-col justify-center items-start gap-2 ml-2'> + <h2 className='font-semibold text-lg mr-2'> + {subCategory?.name} + </h2> + <Link + href={createSlug( + '/shop/category/', + subCategory?.name, + subCategory?.id_level_2 + )} + className='!text-red-500 font-semibold' + > + Lihat Semua + </Link> + </div> + </div> + <div className='grid grid-cols-2 gap-2 overflow-y-auto max-h-[240px] min-h-[240px] content-start'> + {subCategory.child_frontend_id_i.map( + (childCategory) => ( + <div key={childCategory.id} className=''> <Link href={createSlug( '/shop/category/', - subCategory?.name, - subCategory?.id_level_2 + childCategory?.name, + childCategory?.id_level_3 )} - className='!text-red-500 font-semibold' + className='flex flex-row gap-2 border rounded group hover:border-red-500' > - Lihat Semua + <NextImage + src={ + childCategory.image + ? childCategory.image + : '/images/noimage.jpeg' + } + alt={childCategory.name} + className='p-2 ml-1' + width={40} + height={40} + /> + <div className='bagian-judul flex flex-col justify-center items-center gap-2 break-words line-clamp-2 group-hover:text-red-500'> + <h3 className='font-semibold line-clamp-2 group-hover:text-red-500 text-sm mr-2'> + {childCategory.name} + </h3> + </div> </Link> </div> - </div> - <div className='grid grid-cols-2 gap-2 overflow-y-auto max-h-[240px] min-h-[240px] content-start'> - {subCategory.child_frontend_id_i.map( - (childCategory) => ( - <div key={childCategory.id} className=''> - <Link - href={createSlug( - '/shop/category/', - childCategory?.name, - childCategory?.id_level_3 - )} - className='flex flex-row gap-2 border rounded group hover:border-red-500' - > - <NextImage - src={ - childCategory.image - ? childCategory.image - : '/images/noimage.jpeg' - } - alt={childCategory.name} - className='p-2 ml-1' - width={40} - height={40} - /> - <div className='bagian-judul flex flex-col justify-center items-center gap-2 break-words line-clamp-2 group-hover:text-red-500'> - <h3 className='font-semibold line-clamp-2 group-hover:text-red-500 text-sm mr-2'> - {childCategory.name} - </h3> - </div> - </Link> - </div> - ) - )} - </div> - </div> + ) + )} </div> - </SwiperSlide> - ); - })} - </Swiper> - </div> - </Skeleton> - ); - })} + </div> + </div> + </SwiperSlide> + ))} + </Swiper> + </div> + </Skeleton> + ))} </div> ); }; diff --git a/src/lib/home/components/CategoryDynamicMobile.jsx b/src/lib/home/components/CategoryDynamicMobile.jsx index 4a8f13cf..67ae6f5f 100644 --- a/src/lib/home/components/CategoryDynamicMobile.jsx +++ b/src/lib/home/components/CategoryDynamicMobile.jsx @@ -4,52 +4,46 @@ import Link from 'next/link'; import { createSlug } from '@/core/utils/slug'; import { Swiper, SwiperSlide } from 'swiper/react'; import 'swiper/css'; -import { fetchCategoryManagementSolr } from '../api/categoryManagementApi'; +import { + fetchCategoryManagementSolr, + fetchCategoryManagementVersion, +} from '../api/categoryManagementApi'; const CategoryDynamicMobile = () => { const [selectedCategory, setSelectedCategory] = useState({}); const [categoryManagement, setCategoryManagement] = useState([]); const [isLoading, setIsLoading] = useState(false); - const loadBrand = useCallback(async () => { - setIsLoading(true); - const items = await fetchCategoryManagementSolr(); + useEffect(() => { + const fetchCategoryData = async () => { + setIsLoading(true); + const res = await fetch('/api/category-management'); + const { data } = await res.json(); + if (data) { + setCategoryManagement(data); + } + setIsLoading(false); + }; - setIsLoading(false); - setCategoryManagement(items); + fetchCategoryData(); }, []); useEffect(() => { - loadBrand(); - }, [loadBrand]); - - useEffect(() => { - const loadPromo = async () => { - try { - if (categoryManagement?.length > 0) { - const initialSelections = categoryManagement.reduce( - (acc, category) => { - if (category.categories.length > 0) { - acc[category.id] = category.categories[0].id_level_2; - } - return acc; - }, - {} - ); - setSelectedCategory(initialSelections); + if (categoryManagement?.length > 0) { + const initialSelections = categoryManagement.reduce((acc, category) => { + if (category.categories.length > 0) { + acc[category.id] = category.categories[0].id_level_2; } - } catch (loadError) { - // console.error("Error loading promo items:", loadError); - } - }; - - loadPromo(); + return acc; + }, {}); + setSelectedCategory(initialSelections); + } }, [categoryManagement]); - const handleCategoryLevel2Click = (categoryIdI, idLevel2) => { + const handleCategoryLevel2Click = (categoryId, idLevel2) => { setSelectedCategory((prev) => ({ ...prev, - [categoryIdI]: idLevel2, + [categoryId]: idLevel2, })); }; diff --git a/src/lib/home/components/PreferredBrand.jsx b/src/lib/home/components/PreferredBrand.jsx index eefced60..b7a30503 100644 --- a/src/lib/home/components/PreferredBrand.jsx +++ b/src/lib/home/components/PreferredBrand.jsx @@ -1,49 +1,50 @@ -import { Swiper, SwiperSlide } from 'swiper/react' -import { Navigation, Pagination, Autoplay } from 'swiper'; -import { useCallback, useEffect, useState } from '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' -import axios from 'axios' +import { Swiper, SwiperSlide } from 'swiper/react'; +import { Navigation, Pagination, Autoplay } from 'swiper'; +import { useCallback, useEffect, useState } from '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'; +import axios from 'axios'; const PreferredBrand = () => { - let query = '' - let params = 'prioritas' - const [isLoading, setIsLoading] = useState(true) - const [startWith, setStartWith] = useState(null) - const [manufactures, setManufactures] = useState([]) + let query = ''; + let params = 'prioritas'; + const [isLoading, setIsLoading] = useState(true); + const [startWith, setStartWith] = useState(null); + const [manufactures, setManufactures] = useState([]); const loadBrand = useCallback(async () => { - setIsLoading(true) - const name = startWith ? `${startWith}*` : '' - const result = await axios(`${process.env.NEXT_PUBLIC_SELF_HOST}/api/shop/brands?rows=20`) - - setIsLoading(false) - setManufactures((manufactures) => [...result.data]) - }, [startWith]) + setIsLoading(true); + const name = startWith ? `${startWith}*` : ''; + const result = await axios( + `${process.env.NEXT_PUBLIC_SELF_HOST}/api/shop/preferredBrand?rows=20` + ); + setIsLoading(false); + setManufactures((manufactures) => [...result.data]); + }, [startWith]); const toggleStartWith = (alphabet) => { - setManufactures([]) + setManufactures([]); if (alphabet == startWith) { - setStartWith(null) - return + setStartWith(null); + return; } - setStartWith(alphabet) - } + setStartWith(alphabet); + }; useEffect(() => { - loadBrand() - }, []) + loadBrand(); + }, []); // const { preferredBrands } = usePreferredBrand(query) - const { isMobile, isDesktop } = useDevice() + const { isMobile, isDesktop } = useDevice(); const swiperBanner = { - modules:[Navigation, Pagination, Autoplay], + modules: [Navigation, Pagination, Autoplay], autoplay: { delay: 4000, - disableOnInteraction: false + disableOnInteraction: false, }, loop: true, className: 'h-[70px] md:h-[100px] w-full', @@ -53,13 +54,17 @@ const PreferredBrand = () => { dynamicBullets: true, dynamicMainBullets: isMobile ? 6 : 8, clickable: true, - } - } - const preferredBrandsData = manufactures ? manufactures.slice(0, 20) : [] + }, + }; + const preferredBrandsData = manufactures ? manufactures.slice(0, 20) : []; return ( <div className='px-4 sm:px-0'> <div className='flex justify-between items-center mb-4'> - <h1 className='font-semibold text-[14px] sm:text-h-lg'><Link href='/shop/brands' className='!text-black font-semibold'>Brand Pilihan</Link></h1> + <h1 className='font-semibold text-[14px] sm:text-h-lg'> + <Link href='/shop/brands' className='!text-black font-semibold'> + Brand Pilihan + </Link> + </h1> {isDesktop && ( <Link href='/shop/brands' className='!text-red-500 font-semibold'> Lihat Semua @@ -79,7 +84,7 @@ const PreferredBrand = () => { )} </div> </div> - ) -} + ); +}; -export default PreferredBrand
\ No newline at end of file +export default PreferredBrand; diff --git a/src/lib/home/components/PromotionProgram.jsx b/src/lib/home/components/PromotionProgram.jsx index ae06bd4d..562fa138 100644 --- a/src/lib/home/components/PromotionProgram.jsx +++ b/src/lib/home/components/PromotionProgram.jsx @@ -4,15 +4,56 @@ import { bannerApi } from '@/api/bannerApi'; import useDevice from '@/core/hooks/useDevice'; import { Swiper, SwiperSlide } from 'swiper/react'; import BannerPromoSkeleton from '../components/Skeleton/BannerPromoSkeleton'; +import { useEffect, useState } from 'react'; const { useQuery } = require('react-query'); const BannerSection = () => { - const promotionProgram = useQuery( - 'promotionProgram', - bannerApi({ type: 'banner-promotion' }) - ); const { isMobile, isDesktop } = useDevice(); + const [data, setData] = useState(null); + const [shouldFetch, setShouldFetch] = useState(false); + useEffect(() => { + const fetchData = async () => { + const res = await fetch(`/api/hero-banner?type=banner-promotion`); + const { data } = await res.json(); + if (data) { + setData(data); + } + }; + + fetchData(); + }, []); + + // useEffect(() => { + // const localData = localStorage.getItem('Homepage_promotionProgram'); + // if (localData) { + // setData(JSON.parse(localData)); + // } else { + // setShouldFetch(true); + // } + // }, []); + + // const getPromotionProgram = useQuery( + // 'promotionProgram', + // bannerApi({ type: 'banner-promotion' }), + // { + // enabled: shouldFetch, + // onSuccess: (data) => { + // if (data) { + // localStorage.setItem( + // 'Homepage_promotionProgram', + // JSON.stringify(data) + // ); + // setData(data); + // } + // }, + // } + // ); + + const promotionProgram = data; - if (promotionProgram.isLoading) { + // if (getPromotionProgram?.isLoading && !data) { + // return <BannerPromoSkeleton />; + // } + if (!data) { return <BannerPromoSkeleton />; } @@ -39,28 +80,26 @@ const BannerSection = () => { </Link> )} </div> - {isDesktop && - promotionProgram.data && - promotionProgram.data?.length > 0 && ( - <div className='grid grid-cols-3 sm:grid-cols-3 gap-4 rounded-md'> - {promotionProgram.data?.map((banner) => ( - <Link key={banner.id} href={banner.url}> - <Image - width={439} - height={150} - quality={85} - src={banner.image} - alt={banner.name} - className='h-auto w-full rounded hover:scale-105 transition duration-500 ease-in-out' - /> - </Link> - ))} - </div> - )} + {isDesktop && promotionProgram && promotionProgram?.length > 0 && ( + <div className='grid grid-cols-3 sm:grid-cols-3 gap-4 rounded-md'> + {promotionProgram?.map((banner) => ( + <Link key={banner.id} href={banner.url}> + <Image + width={439} + height={150} + quality={85} + src={banner.image} + alt={banner.name} + className='h-auto w-full rounded hover:scale-105 transition duration-500 ease-in-out' + /> + </Link> + ))} + </div> + )} {isMobile && ( <Swiper slidesPerView={1.1} spaceBetween={8} freeMode> - {promotionProgram.data?.map((banner) => ( + {promotionProgram?.map((banner) => ( <SwiperSlide key={banner.id}> <Link key={banner.id} href={banner.url}> <Image diff --git a/src/lib/home/components/ServiceList.jsx b/src/lib/home/components/ServiceList.jsx index 5b16915d..b3cc8fe5 100644 --- a/src/lib/home/components/ServiceList.jsx +++ b/src/lib/home/components/ServiceList.jsx @@ -32,7 +32,7 @@ const ServiceList = () => { </div> <div className='w-full'> <Link - href='/tentang-kami' + href='/garansi-resmi' className='border border-gray-200 p-2 flex items-center gap-x-2 rounded-lg' > <div className=''> @@ -57,7 +57,7 @@ const ServiceList = () => { </div> <div className='w-full '> <Link - href='/tentang-kami' + href='/pembayaran-tempo' className='border border-gray-200 p-2 flex items-center gap-x-2 rounded-lg' > <div className=''> |
