diff options
| author | it-fixcomart <it@fixcomart.co.id> | 2024-07-23 09:42:57 +0700 |
|---|---|---|
| committer | it-fixcomart <it@fixcomart.co.id> | 2024-07-23 09:42:57 +0700 |
| commit | aed8055fbef665984574bc98bb6223c1c54a821a (patch) | |
| tree | fe795d141fb8d7e9404949e77c367f5a8a405937 /src/lib/home | |
| parent | d628ae7e520f01186e7ede2e06118d869ee7282f (diff) | |
<iman> marged develompent & category management
Diffstat (limited to 'src/lib/home')
| -rw-r--r-- | src/lib/home/api/categoryManagementApi.js | 8 | ||||
| -rw-r--r-- | src/lib/home/components/CategoryDynamic.jsx | 65 | ||||
| -rw-r--r-- | src/lib/home/components/CategoryDynamicMobile.jsx | 101 | ||||
| -rw-r--r-- | src/lib/home/components/CategoryPilihan.jsx | 66 | ||||
| -rw-r--r-- | src/lib/home/components/PreferredBrand.jsx | 42 | ||||
| -rw-r--r-- | src/lib/home/hooks/useCategoryManagement.js | 13 |
6 files changed, 283 insertions, 12 deletions
diff --git a/src/lib/home/api/categoryManagementApi.js b/src/lib/home/api/categoryManagementApi.js new file mode 100644 index 00000000..b70d60ce --- /dev/null +++ b/src/lib/home/api/categoryManagementApi.js @@ -0,0 +1,8 @@ +import odooApi from '@/core/api/odooApi' + +const categoryManagementApi = async () => { + const dataCategoryManagement = await odooApi('GET', '/api/v1/categories_management') + return dataCategoryManagement +} + +export default categoryManagementApi diff --git a/src/lib/home/components/CategoryDynamic.jsx b/src/lib/home/components/CategoryDynamic.jsx new file mode 100644 index 00000000..cac8a138 --- /dev/null +++ b/src/lib/home/components/CategoryDynamic.jsx @@ -0,0 +1,65 @@ +import React, { useEffect, useState } from 'react'; +import useCategoryManagement from '../hooks/useCategoryManagement'; +import NextImage from 'next/image'; +import Link from "next/link" +import router from 'next/router'; +import { createSlug } from '@/core/utils/slug' + +const CategoryDynamic = () => { + const { categoryManagement } = useCategoryManagement() + + return ( + <div> + {categoryManagement && categoryManagement.data?.map((category) => ( + <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> + <p className='text-gray_r-10 text-sm'>999 rb+ Produk tersedia</p> + <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((index)=> ( + <div key={index.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={index.image? index.image : "/images/noimage.jpeg"} + alt={index.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'>{index.name}</div> + <p className='text-gray_r-10 text-sm'>999 rb+ Produk</p> + <Link href={createSlug('/shop/category/', index?.name, index?.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]' > + {index.childFrontendIdI.map((x)=> ( + <div key={x.id}> + <Link href={createSlug('/shop/category/', x?.name, x?.idLevel3)} className="flex flex-row gap-2 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-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'>{x.name}</div> + </div> + </Link> + </div> + ))} + </div> + </div> + </div> + ))} + </div> + </div> + ))} + </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..c1433a2d --- /dev/null +++ b/src/lib/home/components/CategoryDynamicMobile.jsx @@ -0,0 +1,101 @@ +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 new file mode 100644 index 00000000..7b9f0094 --- /dev/null +++ b/src/lib/home/components/CategoryPilihan.jsx @@ -0,0 +1,66 @@ +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'; + + +const CategoryPilihan = ({ id, categories }) => { + const heroBanner = useQuery('categoryPilihan', bannerApi({ type: 'index-a-1' })); + + return ( + <section> + <div className='flex flex-row items-center mb-4'> + <div className='font-semibold sm:text-h-lg mr-2'>Kategori Pilihan</div> + <p className='text-gray_r-10 text-sm'>200 Rb+ Produk Unggulan & 800+ Brand Rekomendasi tersedia!</p> + </div> + <div className='flex w-full h-48 bg-red-300 mb-4'> + {heroBanner.data && + heroBanner.data?.length > 0 && ( + <div className='px-4 sm:px-0 object-fill '> + {/* {heroBanner.data?.map((banner) => ( */} + <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='h-48 object-fill w-full rounded hover:scale-105 transition duration-500 ease-in-out' + /> + </Link> + {/* ))} */} + </div> + + )} + </div> + <div className="group/item grid grid-cols-6 gap-y-2 w-full h-full col-span-2 "> + {categories.map((category) => ( + <div 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-center h-48 w-60 flex-col group-hover/item:visible"> + <div className=' h-36'> + <Image className='group-hover:scale-110 transition-transform duration-300' src={category?.image1920? category?.image1920 : '/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?.name}</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/category/', category?.name, category?.id)} + className='category-mega-box__parent text-white rounded-lg' + > + Lihat semua + </Link> + </div> + </div> + ))} + </div> + </section> + ) +} + +export default CategoryPilihan diff --git a/src/lib/home/components/PreferredBrand.jsx b/src/lib/home/components/PreferredBrand.jsx index 6b64a444..1aa9746b 100644 --- a/src/lib/home/components/PreferredBrand.jsx +++ b/src/lib/home/components/PreferredBrand.jsx @@ -1,5 +1,5 @@ -import { Swiper, SwiperSlide } from 'swiper/react' -import { useCallback, useEffect, useState } from 'react' +import { Swiper, SwiperProps, SwiperSlide } from 'swiper/react'; +import { Navigation, Pagination, Autoplay } from 'swiper'; import usePreferredBrand from '../hooks/usePreferredBrand' import PreferredBrandSkeleton from './Skeleton/PreferredBrandSkeleton' import BrandCard from '@/lib/brand/components/BrandCard' @@ -38,6 +38,22 @@ 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, + } + } return ( <div className='px-4 sm:px-0'> @@ -54,16 +70,18 @@ const PreferredBrand = () => { </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 className='border rounded border-gray_r-6'> + {preferredBrands.isLoading && <PreferredBrandSkeleton />} + {!preferredBrands.isLoading && ( + <Swiper {...swiperBanner}> + {preferredBrands.data?.data.map((brand) => ( + <SwiperSlide key={brand.id}> + <BrandCard brand={brand} /> + </SwiperSlide> + ))} + </Swiper> + )} + </div> </div> ) } diff --git a/src/lib/home/hooks/useCategoryManagement.js b/src/lib/home/hooks/useCategoryManagement.js new file mode 100644 index 00000000..c1dda585 --- /dev/null +++ b/src/lib/home/hooks/useCategoryManagement.js @@ -0,0 +1,13 @@ +import categoryManagementApi from '../api/categoryManagementApi' +import { useQuery } from 'react-query' + +const useCategoryManagement = () => { + const fetchCategoryManagement = async () => await categoryManagementApi() + const { isLoading, data } = useQuery('categoryManagementApi', fetchCategoryManagement) + + return { + categoryManagement: { data, isLoading } + } +} + +export default useCategoryManagement
\ No newline at end of file |
