summaryrefslogtreecommitdiff
path: root/src/lib/home/components
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/home/components')
-rw-r--r--src/lib/home/components/CategoryDynamic.jsx108
-rw-r--r--src/lib/home/components/CategoryDynamicMobile.jsx101
-rw-r--r--src/lib/home/components/CategoryPilihan.jsx120
-rw-r--r--src/lib/home/components/PreferredBrand.jsx46
-rw-r--r--src/lib/home/components/PromotionProgram.jsx5
-rw-r--r--src/lib/home/components/Skeleton/BannerPromoSkeleton.jsx16
6 files changed, 16 insertions, 380 deletions
diff --git a/src/lib/home/components/CategoryDynamic.jsx b/src/lib/home/components/CategoryDynamic.jsx
deleted file mode 100644
index 0cc43d91..00000000
--- a/src/lib/home/components/CategoryDynamic.jsx
+++ /dev/null
@@ -1,108 +0,0 @@
-import React, { useEffect, useState } from 'react';
-import useCategoryManagement from '../hooks/useCategoryManagement';
-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'
-
-const CategoryDynamic = () => {
- const { categoryManagement } = useCategoryManagement();
- 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]);
-
- return (
- <div>
- {categoryManagement && categoryManagement.data?.map((category) => {
- const countLevel1 = categoryData[category.categoryIdI] || 0;
-
- return (
- <Skeleton key={category.id} isLoaded={categoryManagement}>
- <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?.categoryIdI)} className="!text-red-500 font-semibold">Lihat Semua</Link>
- </div>
- <div className='grid grid-cols-3 gap-2'>
- {category.categories.map((subCategory) => {
- const countLevel2 = subCategoryData[subCategory.idLevel2] || 0;
-
- return (
- <div key={subCategory.id} 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'
- />
- <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?.idLevel2)} 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]'>
- {subCategory.childFrontendIdI.map((childCategory) => (
- <div key={childCategory.id}>
- <Link href={createSlug('/shop/category/', childCategory?.name, childCategory?.idLevel3)} 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}
- 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>
- );
- })}
- </div>
- </div>
- </Skeleton>
- );
- })}
- </div>
- );
-};
-
-export default CategoryDynamic;
diff --git a/src/lib/home/components/CategoryDynamicMobile.jsx b/src/lib/home/components/CategoryDynamicMobile.jsx
deleted file mode 100644
index c1433a2d..00000000
--- a/src/lib/home/components/CategoryDynamicMobile.jsx
+++ /dev/null
@@ -1,101 +0,0 @@
-import React, { useEffect, useState } from 'react';
-import useCategoryManagement from '../hooks/useCategoryManagement';
-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';
-
-const CategoryDynamicMobile = () => {
- const { categoryManagement } = useCategoryManagement()
- const [selectedCategory, setSelectedCategory] = useState({});
-
- useEffect(() => {
- const loadPromo = async () => {
- try {
- if (categoryManagement.data?.length > 0) {
- const initialSelections = categoryManagement.data.reduce((acc, category) => {
- if (category.categories.length > 0) {
- acc[category.id] = category.categories[0].idLevel2;
- }
- return acc;
- }, {});
- setSelectedCategory(initialSelections);
- }
- } catch (loadError) {
- // console.error("Error loading promo items:", loadError);
- }
- };
-
- loadPromo();
- }, [categoryManagement.data]);
-
- const handleCategoryLevel2Click = (categoryIdI, idLevel2) => {
- setSelectedCategory(prev => ({
- ...prev,
- [categoryIdI]: idLevel2
- }));
- };
-
- return (
- <div className='p-4'>
- {categoryManagement.data && categoryManagement.data.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?.categoryIdI)} 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?.idLevel2)}
- className={`border flex justify-start items-center max-w-48 max-h-16 rounded ${selectedCategory[category.id] === index?.idLevel2 ? '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='object-'
- />
- <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>
- <p className='text-gray_r-10 text-[10px]'>999 rb+ Produk</p>
- </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?.idLevel2 && index.childFrontendIdI.map((x) => (
- <div key={x.id}>
- <Link href={createSlug('/shop/category/', x?.name, x?.idLevel3)} 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}
- />
- <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
deleted file mode 100644
index 6568621c..00000000
--- a/src/lib/home/components/CategoryPilihan.jsx
+++ /dev/null
@@ -1,120 +0,0 @@
-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 (
- <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 ae12505d..6b64a444 100644
--- a/src/lib/home/components/PreferredBrand.jsx
+++ b/src/lib/home/components/PreferredBrand.jsx
@@ -1,5 +1,4 @@
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'
@@ -39,23 +38,7 @@ const PreferredBrand = () => {
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'>
@@ -65,21 +48,24 @@ const PreferredBrand = () => {
Lihat Semua
</Link>
)}
- </div>
- <div className='border rounded border-gray_r-6'>
- {manufactures.isLoading && <PreferredBrandSkeleton />}
- {!manufactures.isLoading && (
- <Swiper {...swiperBanner}>
- {preferredBrandsData.map((manufacture) => (
- <SwiperSlide key={manufacture.id}>
- <BrandCard brand={manufacture} />
- </SwiperSlide>
- ))}
- </Swiper>
+ {isMobile && (
+ <Link href='/shop/brands' className='!text-red-500 font-semibold sm:text-h-sm'>
+ Lihat Semua
+ </Link>
)}
</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 \ 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 c2f76069..99258d94 100644
--- a/src/lib/home/components/PromotionProgram.jsx
+++ b/src/lib/home/components/PromotionProgram.jsx
@@ -3,16 +3,11 @@ import Image from 'next/image'
import { bannerApi } from '@/api/bannerApi';
import useDevice from '@/core/hooks/useDevice'
import { Swiper, SwiperSlide } from 'swiper/react';
-import BannerPromoSkeleton from '../components/Skeleton/BannerPromoSkeleton';
const { useQuery } = require('react-query')
const BannerSection = () => {
const promotionProgram = useQuery('promotionProgram', bannerApi({ type: 'banner-promotion' }));
const { isMobile, isDesktop } = useDevice()
- if (promotionProgram.isLoading) {
- return <BannerPromoSkeleton />;
- }
-
return (
<div className='px-4 sm:px-0'>
<div className='flex justify-between items-center mb-4 '>
diff --git a/src/lib/home/components/Skeleton/BannerPromoSkeleton.jsx b/src/lib/home/components/Skeleton/BannerPromoSkeleton.jsx
deleted file mode 100644
index c5f39f19..00000000
--- a/src/lib/home/components/Skeleton/BannerPromoSkeleton.jsx
+++ /dev/null
@@ -1,16 +0,0 @@
-import useDevice from '@/core/hooks/useDevice'
-import Skeleton from 'react-loading-skeleton'
-
-const BannerPromoSkeleton = () => {
- const { isDesktop } = useDevice()
-
- return (
- <div className='grid grid-cols-1 md:grid-cols-3 gap-x-3'>
- {Array.from({ length: isDesktop ? 3 : 1.2 }, (_, index) => (
- <Skeleton count={1} height={isDesktop ? 60 : 36} key={index} />
- ))}
- </div>
- )
-}
-
-export default BannerPromoSkeleton