summaryrefslogtreecommitdiff
path: root/src/lib/home
diff options
context:
space:
mode:
authorit-fixcomart <it@fixcomart.co.id>2024-09-20 16:52:16 +0700
committerit-fixcomart <it@fixcomart.co.id>2024-09-20 16:52:16 +0700
commita784f4623448ff846dbc5c8259405e6cce8fffb7 (patch)
tree016da331ea5a18ef2c3c1264728b1199b5e9172a /src/lib/home
parent1db54e16f970b4e09df89d432efd5a66ac775eb6 (diff)
parentb7e7696d675d0c2e36364f7cbedb0483a343048d (diff)
Merge branch 'release' into Feature/new-register
Diffstat (limited to 'src/lib/home')
-rw-r--r--src/lib/home/api/CategoryPilihanApi.js8
-rw-r--r--src/lib/home/api/categoryManagementApi.js40
-rw-r--r--src/lib/home/components/CategoryDynamic.jsx143
-rw-r--r--src/lib/home/components/CategoryDynamicMobile.jsx114
-rw-r--r--src/lib/home/components/CategoryPilihan.jsx123
-rw-r--r--src/lib/home/components/PreferredBrand.jsx56
-rw-r--r--src/lib/home/components/PromotionProgram.jsx2
-rw-r--r--src/lib/home/hooks/useCategoryPilihan.js13
8 files changed, 477 insertions, 22 deletions
diff --git a/src/lib/home/api/CategoryPilihanApi.js b/src/lib/home/api/CategoryPilihanApi.js
new file mode 100644
index 00000000..8a0b38d3
--- /dev/null
+++ b/src/lib/home/api/CategoryPilihanApi.js
@@ -0,0 +1,8 @@
+import odooApi from '@/core/api/odooApi'
+
+const categoryPilihanApi = async () => {
+ const dataCategoryPilihan = await odooApi('GET', '/api/v1/lob_homepage')
+ return dataCategoryPilihan
+}
+
+export default categoryPilihanApi
diff --git a/src/lib/home/api/categoryManagementApi.js b/src/lib/home/api/categoryManagementApi.js
new file mode 100644
index 00000000..0aeb2aac
--- /dev/null
+++ b/src/lib/home/api/categoryManagementApi.js
@@ -0,0 +1,40 @@
+export const fetchCategoryManagementSolr = async () => {
+ let sort ='sort=sequence_i asc';
+ try {
+ const response = await fetch(`/solr/category_management/query?q=*:*&q.op=OR&indent=true&${sort}&&rows=20`);
+ if (!response.ok) {
+ throw new Error(`HTTP error! status: ${response.status}`);
+ }
+ const data = await response.json();
+ const promotions = await map(data.response.docs);
+ return promotions;
+ } catch (error) {
+ console.error("Error fetching promotion data:", error);
+ return [];
+ }
+ };
+
+ const map = async (promotions) => {
+ return promotions.map((promotion) =>{
+ let parsedCategories = promotion.categories.map(category => {
+ // Parse string JSON utama
+ let parsedCategory = JSON.parse(category);
+
+ // Parse setiap elemen di child_frontend_id_i jika ada
+ if (parsedCategory.child_frontend_id_i) {
+ parsedCategory.child_frontend_id_i = parsedCategory.child_frontend_id_i.map(child => JSON.parse(child));
+ }
+
+ return parsedCategory;
+ });
+ let productMapped = {
+ id: promotion.id,
+ name: promotion.name_s,
+ image: promotion.image_s,
+ sequence: promotion.sequence_i,
+ numFound: promotion.numFound_i,
+ categories: parsedCategories
+ };
+ return productMapped;
+ })
+ }; \ No newline at end of file
diff --git a/src/lib/home/components/CategoryDynamic.jsx b/src/lib/home/components/CategoryDynamic.jsx
new file mode 100644
index 00000000..ca104ada
--- /dev/null
+++ b/src/lib/home/components/CategoryDynamic.jsx
@@ -0,0 +1,143 @@
+import React, { useEffect, useState, useCallback } from 'react';
+import {fetchCategoryManagementSolr} from '../api/categoryManagementApi'
+import NextImage from 'next/image';
+import Link from "next/link";
+import { createSlug } from '@/core/utils/slug';
+import odooApi from '@/core/api/odooApi';
+import { Skeleton } from '@chakra-ui/react';
+import { Swiper, SwiperSlide } from 'swiper/react';
+import 'swiper/css';
+import 'swiper/css/navigation';
+import 'swiper/css/pagination';
+import { Navigation, Pagination, Autoplay } 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)
+ }, [])
+
+ useEffect(() => {
+ loadBrand()
+ }, [loadBrand])
+
+ // const [categoryData, setCategoryData] = useState({});
+ // const [subCategoryData, setSubCategoryData] = useState({});
+
+ // useEffect(() => {
+ // const fetchCategoryData = async () => {
+ // if (categoryManagement && categoryManagement.data) {
+ // const updatedCategoryData = {};
+ // const updatedSubCategoryData = {};
+
+ // 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]);
+
+ const swiperBanner = {
+ modules: [Pagination, ],
+ classNames:'mySwiper',
+ slidesPerView: 3,
+ spaceBetween:10,
+ pagination: {
+ dynamicBullets: true,
+ clickable: true,
+ }
+ };
+
+ 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'>
+ <div className='font-semibold sm:text-h-lg mr-2'>{category.name}</div>
+ {/* <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?.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;
+
+ 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'>
+ <div className='font-semibold text-lg mr-2'>{subCategory?.name}</div>
+ {/* <Skeleton isLoaded={countLevel2 != 0}>
+ <p className={`text-gray_r-10 text-sm`}>
+ {countLevel2} Produk tersedia
+ </p>
+ </Skeleton> */}
+ <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/', 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'>
+ <div className='font-semibold line-clamp-2 group-hover:text-red-500 text-sm mr-2'>{childCategory.name}</div>
+ </div>
+ </Link>
+ </div>
+ ))}
+ </div>
+ </div>
+ </div>
+ </SwiperSlide>
+ );
+ })}
+ </Swiper>
+ </div>
+ </Skeleton>
+ );
+ })}
+ </div>
+ );
+};
+
+export default CategoryDynamic;
diff --git a/src/lib/home/components/CategoryDynamicMobile.jsx b/src/lib/home/components/CategoryDynamicMobile.jsx
new file mode 100644
index 00000000..1061f3e4
--- /dev/null
+++ b/src/lib/home/components/CategoryDynamicMobile.jsx
@@ -0,0 +1,114 @@
+import React, { useEffect, useState, useCallback } from 'react';
+import NextImage from 'next/image';
+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'
+
+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();
+
+ setIsLoading(false)
+ setCategoryManagement(items)
+ }, [])
+
+ 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);
+ }
+ } catch (loadError) {
+ // console.error("Error loading promo items:", loadError);
+ }
+ };
+
+ loadPromo();
+ }, [categoryManagement]);
+
+ const handleCategoryLevel2Click = (categoryIdI, idLevel2) => {
+ setSelectedCategory(prev => ({
+ ...prev,
+ [categoryIdI]: idLevel2
+ }));
+ };
+
+ return (
+ <div className='p-4'>
+ {categoryManagement && categoryManagement?.map((category) => (
+ <div key={category.id}>
+ <div className='bagian-judul flex flex-row justify-between items-center gap-3 mb-4 mt-4'>
+ <div className='font-semibold sm:text-h-sm mr-2'>{category?.name}</div>
+ <Link href={createSlug('/shop/category/', category?.name, category?.id)} className="!text-red-500 font-semibold text-sm">Lihat Semua</Link>
+ </div>
+ <Swiper slidesPerView={2.3} spaceBetween={10}>
+ {category.categories.map((index) => (
+ <SwiperSlide key={index.id}>
+ <div
+ onClick={() => handleCategoryLevel2Click(category.id, index?.id_level_2)}
+ className={`border flex justify-start items-center max-w-48 max-h-16 rounded ${selectedCategory[category.id] === index?.id_level_2 ? 'bg-red-50 border-red-500 text-red-500' : 'border-gray-200 text-gray-900'}`}
+ >
+ <div className='p-1 flex justify-start items-center'>
+ <div className='flex flex-row justify-center items-center'>
+ <NextImage
+ src={index.image ? index.image : "/images/noimage.jpeg"}
+ alt={index.name}
+ width={30}
+ height={30}
+ className=''
+ />
+ <div className='bagian-judul flex flex-col justify-center items-start gap-1 ml-2'>
+ <div className='font-semibold text-[10px] line-clamp-1'>{index?.name}</div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </SwiperSlide>
+ ))}
+ </Swiper>
+ <div className='p-3 mt-2 border'>
+ <div className='grid grid-cols-2 gap-2 overflow-y-auto max-h-[240px]'>
+ {category.categories.map((index) => (
+ selectedCategory[category.id] === index?.id_level_2 && index?.child_frontend_id_i.map((x) => (
+ <div key={x.id}>
+ <Link href={createSlug('/shop/category/', x?.name, x?.id_level_3)} className="flex flex-row gap-1 border rounded group hover:border-red-500">
+ <NextImage
+ src={x.image ? x.image : "/images/noimage.jpeg"}
+ alt={x.name}
+ width={40}
+ height={40}
+ className='p-2'
+ />
+ <div className='bagian-judul flex flex-col justify-center items-start gap-1 break-words line-clamp-2 group-hover:text-red-500'>
+ <div className='font-semibold line-clamp-2 group-hover:text-red-500 text-[10px]'>{x?.name}</div>
+ </div>
+ </Link>
+ </div>
+ ))
+ ))}
+ </div>
+ </div>
+ </div>
+ ))}
+ </div>
+ );
+};
+
+export default CategoryDynamicMobile;
diff --git a/src/lib/home/components/CategoryPilihan.jsx b/src/lib/home/components/CategoryPilihan.jsx
new file mode 100644
index 00000000..6dbf771e
--- /dev/null
+++ b/src/lib/home/components/CategoryPilihan.jsx
@@ -0,0 +1,123 @@
+import Image from 'next/image'
+import useCategoryHome from '../hooks/useCategoryHome'
+import Link from '@/core/components/elements/Link/Link'
+import { createSlug } from '@/core/utils/slug'
+import { useEffect, useState } from 'react';
+import { bannerApi } from '../../../api/bannerApi';
+const { useQuery } = require('react-query')
+import { HeroBannerSkeleton } from '../../../components/skeleton/BannerSkeleton';
+import useCategoryPilihan from '../hooks/useCategoryPilihan';
+import useDevice from '@/core/hooks/useDevice'
+import { Swiper, SwiperSlide } from 'swiper/react';
+import 'swiper/css';
+
+const CategoryPilihan = ({ id, categories }) => {
+ const { isDesktop, isMobile } = useDevice()
+ const { categoryPilihan } = useCategoryPilihan();
+ const heroBanner = useQuery('categoryPilihan', bannerApi({ type: 'banner-category-list' }));
+ return (
+ categoryPilihan.length > 0 && (
+ <section>
+ {isDesktop && (
+ <div>
+ <div className='flex flex-row items-center mb-4'>
+ <div className='font-semibold sm:text-h-lg mr-2'>LOB Kategori Pilihan</div>
+ <p className='text-gray_r-10 text-sm'>200 Rb+ Produk Unggulan & 800+ Brand Rekomendasi tersedia!</p>
+ </div>
+ {heroBanner.data &&
+ heroBanner.data?.length > 0 && (
+ <div className='flex w-full h-full justify-center mb-4 bg-cover bg-center'>
+ <Link key={heroBanner.data[0].id} href={heroBanner.data[0].url}>
+ <Image
+ width={1260}
+ height={170}
+ quality={100}
+ src={heroBanner.data[0].image}
+ alt={heroBanner.data[0].name}
+ className='h-full object-cover w-full'
+ />
+ </Link>
+ </div>
+ )}
+ <div className="group/item grid grid-cols-6 gap-y-2 w-full h-full col-span-2 ">
+ {categoryPilihan?.data?.map((category) => (
+ <div key={category.id} className="KartuInti h-48 w-60 max-w-sm lg:max-w-full flex flex-col border-[1px] border-gray-200 relative group">
+ <div className='KartuB absolute h-48 w-60 inset-0 flex items-center justify-center '>
+ <div className="group/edit flex items-center justify-end h-48 w-60 flex-col group-hover/item:visible">
+ <div className=' h-36 flex justify-end items-end'>
+ <Image className='group-hover:scale-105 transition-transform duration-300 ' src={category?.image? category?.image : '/images/noimage.jpeg'} width={120} height={120} alt={category?.name} />
+ </div>
+ <h2 className="text-gray-700 content-center h-12 border-t-[1px] px-1 w-60 border-gray-200 font-normal text-sm text-center">{category?.industries}</h2>
+ </div>
+ </div>
+ <div className='KartuA relative inset-0 flex h-36 w-60 items-center justify-center opacity-0 group-hover:opacity-75 group-hover:bg-[#E20613] transition-opacity '>
+ <Link
+ href={createSlug('/shop/lob/', category?.industries, category?.id)}
+ className='category-mega-box__parent text-white rounded-lg'
+ >
+ Lihat semua
+ </Link>
+ </div>
+ </div>
+ ))}
+ </div>
+ </div>
+ )}
+ {isMobile && (
+ <div className='p-4'>
+ <div className='flex flex-row items-center mb-4'>
+ <div className='font-semibold sm:text-h-md mr-2'>LOB Kategori Pilihan</div>
+ {/* <p className='text-gray_r-10 text-sm'>200 Rb+ Produk Unggulan & 800+ Brand Rekomendasi tersedia!</p> */}
+ </div>
+ <div className='flex'>
+ {heroBanner.data &&
+ heroBanner.data?.length > 0 && (
+ <div className=' object-fill '>
+ <Link key={heroBanner.data[0].id} href={heroBanner.data[0].url}>
+ <Image
+ width={439}
+ height={150}
+ quality={100}
+ src={heroBanner.data[0].image}
+ alt={heroBanner.data[0].name}
+ className='object-cover'
+ />
+ </Link>
+ </div>
+ )}
+ </div>
+ <Swiper slidesPerView={2.1} spaceBetween={10}>
+ {categoryPilihan?.data?.map((category) => (
+ <SwiperSlide key={category.id}>
+ <div key={category.id} className="KartuInti mt-2 h-48 w-48 max-w-sm lg:max-w-full flex flex-col border-[1px] border-gray-200 relative group">
+ <div className='KartuB absolute h-48 w-48 inset-0 flex items-center justify-center '>
+ <div className="group/edit flex items-center justify-end h-48 w-48 flex-col group-hover/item:visible">
+ <div className=' h-36 flex justify-end items-end'>
+ <Image className='group-hover:scale-105 transition-transform duration-300 ' src={category?.image? category?.image : '/images/noimage.jpeg'} width={120} height={120} alt={category?.name} />
+ </div>
+ <h2 className="text-gray-700 content-center h-12 border-t-[1px] px-1 w-48 border-gray-200 font-normal text-sm text-center">{category?.industries}</h2>
+ </div>
+ </div>
+ <div className='KartuA relative inset-0 flex h-36 w-48 items-center justify-center opacity-0 group-hover:opacity-75 group-hover:bg-[#E20613] transition-opacity '>
+ <Link
+ href={createSlug('/shop/lob/', category?.industries, category?.id)}
+ className='category-mega-box__parent text-white rounded-lg'
+ >
+ Lihat semua
+ </Link>
+ </div>
+ </div>
+ </SwiperSlide>
+ ))}
+
+ </Swiper>
+
+ </div>
+ )}
+ </section>
+
+ )
+ )
+}
+
+export default CategoryPilihan
diff --git a/src/lib/home/components/PreferredBrand.jsx b/src/lib/home/components/PreferredBrand.jsx
index 6b64a444..eefced60 100644
--- a/src/lib/home/components/PreferredBrand.jsx
+++ b/src/lib/home/components/PreferredBrand.jsx
@@ -1,4 +1,5 @@
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'
@@ -8,7 +9,7 @@ import Link from '@/core/components/elements/Link/Link'
import axios from 'axios'
const PreferredBrand = () => {
- let query = 'level_s'
+ let query = ''
let params = 'prioritas'
const [isLoading, setIsLoading] = useState(true)
const [startWith, setStartWith] = useState(null)
@@ -17,7 +18,7 @@ const PreferredBrand = () => {
const loadBrand = useCallback(async () => {
setIsLoading(true)
const name = startWith ? `${startWith}*` : ''
- const result = await axios(`${process.env.NEXT_PUBLIC_SELF_HOST}/api/shop/brands?params=${name}`)
+ const result = await axios(`${process.env.NEXT_PUBLIC_SELF_HOST}/api/shop/brands?rows=20`)
setIsLoading(false)
setManufactures((manufactures) => [...result.data])
@@ -34,38 +35,51 @@ const PreferredBrand = () => {
useEffect(() => {
loadBrand()
- }, [loadBrand])
+ }, [])
- const { preferredBrands } = usePreferredBrand(query)
+ // const { preferredBrands } = usePreferredBrand(query)
const { isMobile, isDesktop } = useDevice()
-
+ const swiperBanner = {
+ modules:[Navigation, Pagination, Autoplay],
+ autoplay: {
+ delay: 4000,
+ disableOnInteraction: false
+ },
+ loop: true,
+ className: 'h-[70px] md:h-[100px] w-full',
+ slidesPerView: isMobile ? 4 : 8,
+ spaceBetween: isMobile ? 12 : 0,
+ pagination: {
+ dynamicBullets: true,
+ dynamicMainBullets: isMobile ? 6 : 8,
+ clickable: true,
+ }
+ }
+ const preferredBrandsData = manufactures ? manufactures.slice(0, 20) : []
return (
<div className='px-4 sm:px-0'>
<div className='flex justify-between items-center mb-4'>
- <div className='font-semibold sm:text-h-lg'>Brand Pilihan</div>
+ <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
</Link>
)}
- {isMobile && (
- <Link href='/shop/brands' className='!text-red-500 font-semibold sm:text-h-sm'>
- Lihat Semua
- </Link>
+ </div>
+ <div className=''>
+ {manufactures.isLoading && <PreferredBrandSkeleton />}
+ {!manufactures.isLoading && (
+ <Swiper {...swiperBanner}>
+ {preferredBrandsData.map((manufacture) => (
+ <SwiperSlide key={manufacture.id}>
+ <BrandCard brand={manufacture} />
+ </SwiperSlide>
+ ))}
+ </Swiper>
)}
</div>
- {manufactures.isLoading && <PreferredBrandSkeleton />}
- {!manufactures.isLoading && (
- <Swiper slidesPerView={isMobile ? 3.5 : 7.5} spaceBetween={isMobile ? 12 : 24} freeMode>
- {manufactures.map((manufacture) => (
- <SwiperSlide key={manufacture.id}>
- <BrandCard brand={manufacture} />
- </SwiperSlide>
- ))}
- </Swiper>
- )}
</div>
)
}
-export default PreferredBrand
+export default PreferredBrand \ No newline at end of file
diff --git a/src/lib/home/components/PromotionProgram.jsx b/src/lib/home/components/PromotionProgram.jsx
index c2f76069..ae8d5d6f 100644
--- a/src/lib/home/components/PromotionProgram.jsx
+++ b/src/lib/home/components/PromotionProgram.jsx
@@ -16,7 +16,7 @@ const BannerSection = () => {
return (
<div className='px-4 sm:px-0'>
<div className='flex justify-between items-center mb-4 '>
- <div className='font-semibold sm:text-h-lg'>Promo Tersedia</div>
+ <h1 className='font-semibold text-[14px] sm:text-h-lg'> <Link href='/shop/promo' className='!text-black font-semibold' >Promo Tersedia</Link></h1>
{isDesktop && (
<Link href='/shop/promo' className='!text-red-500 font-semibold'>
Lihat Semua
diff --git a/src/lib/home/hooks/useCategoryPilihan.js b/src/lib/home/hooks/useCategoryPilihan.js
new file mode 100644
index 00000000..12a86f7e
--- /dev/null
+++ b/src/lib/home/hooks/useCategoryPilihan.js
@@ -0,0 +1,13 @@
+import categoryPilihanApi from '../api/CategoryPilihanApi'
+import { useQuery } from 'react-query'
+
+const useCategoryPilihan = () => {
+ const fetchCategoryPilihan = async () => await categoryPilihanApi()
+ const { isLoading, data } = useQuery('categoryPilihanApi', fetchCategoryPilihan)
+
+ return {
+ categoryPilihan: { data, isLoading }
+ }
+}
+
+export default useCategoryPilihan \ No newline at end of file