diff options
| author | IT Fixcomart <it@fixcomart.co.id> | 2024-08-20 09:14:52 +0000 |
|---|---|---|
| committer | IT Fixcomart <it@fixcomart.co.id> | 2024-08-20 09:14:52 +0000 |
| commit | 7388f27d1778aaa66191b44d725ce7c3e3e4ddd8 (patch) | |
| tree | 7fdef4f99f0f42e2d99a40bfd5b81f1ca5f4ef30 /src/lib/category | |
| parent | 6d302bb338e26810a7f90326b84086217f1f4ae0 (diff) | |
| parent | 5c5eef9d62efd83f52f7c37dacb94d50ff7cb915 (diff) | |
Merged in Feature/category-management (pull request #248)
Feature/category management
Diffstat (limited to 'src/lib/category')
| -rw-r--r-- | src/lib/category/api/popularProduct.js | 31 | ||||
| -rw-r--r-- | src/lib/category/components/Category.jsx | 88 | ||||
| -rw-r--r-- | src/lib/category/components/PopularBrand.jsx | 83 |
3 files changed, 184 insertions, 18 deletions
diff --git a/src/lib/category/api/popularProduct.js b/src/lib/category/api/popularProduct.js new file mode 100644 index 00000000..48f8a2a0 --- /dev/null +++ b/src/lib/category/api/popularProduct.js @@ -0,0 +1,31 @@ + +export const fetchPopulerProductSolr = async (category_id_ids) => { + let sort ='sort=qty_sold_f desc'; + try { + const queryParams = new URLSearchParams({ q: category_id_ids }); + const response = await fetch(`/solr/product/select?${queryParams.toString()}&rows=2000&fl=manufacture_name_s,manufacture_id_i,id,display_name_s,qty_sold_f&${sort}`); + 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) => { + const result = []; + for (const promotion of promotions) { + const data = { + id: promotion.id, + name: promotion.display_name_s, + manufacture_name: promotion.manufacture_name_s, + manufacture_id: promotion.manufacture_id_i, + }; + result.push(data); + } + return result; + };
\ No newline at end of file diff --git a/src/lib/category/components/Category.jsx b/src/lib/category/components/Category.jsx index e6ea5acf..374cdf78 100644 --- a/src/lib/category/components/Category.jsx +++ b/src/lib/category/components/Category.jsx @@ -2,11 +2,21 @@ import odooApi from '@/core/api/odooApi' import Link from '@/core/components/elements/Link/Link' import DesktopView from '@/core/components/views/DesktopView' import { createSlug } from '@/core/utils/slug' +import { ChevronRightIcon } from '@heroicons/react/24/outline' +import Image from 'next/image' import { useEffect, useState } from 'react' +import PopularBrand from './PopularBrand' +import { bannerApi } from '@/api/bannerApi'; +const { useQuery } = require('react-query') const Category = () => { const [categories, setCategories] = useState([]) + const [openCategories, setOpenCategory] = useState([]); + const [banner, setBanner] = useState([]); + const promotionProgram = useQuery('banner-promo-category-card', bannerApi({ type: 'banner-promo-category-card' })); + // const promotionProgram = useQuery('promotionProgram', bannerApi({ type: 'banner-promotion' })); + useEffect(() => { const loadCategories = async () => { let dataCategories = await odooApi('GET', '/api/v1/category/tree') @@ -27,45 +37,87 @@ const Category = () => { loadCategories() }, []) + // useEffect(() => { + // const loadCategories = async () => { + // let dataCategories = await odooApi('GET', '/api/v1/category/tree') + // dataCategories = dataCategories?.map((category) => { + // category.childs = category.childs.map((child1Category) => { + // return { + // ...child1Category, + // isOpen: false + // } + // }) + // return { + // ...category, + // isOpen: false + // } + // }) + // setCategories(dataCategories) + // } + // loadCategories() + // }, []) + // console.log("categories",categories) + return ( <DesktopView> <div className='category-mega-box'> {categories?.map((category) => ( - <div key={category.id}> + <div key={category.id} className='flex'> <Link href={createSlug('/shop/category/', category.name, category.id)} - className='category-mega-box__parent' + className='category-mega-box__parent flex items-center' > + <div className='w-6 h-6 border mr-2 rounded-full flex justify-center items-center'> + <Image src={category.image} alt='' width={16} height={16} /> + </div> {category.name} </Link> <div className='category-mega-box__child-wrapper'> - <div className='grid grid-cols-3 gap-x-4 gap-y-6 max-h-full overflow-auto'> + <div className='grid grid-cols-3 gap-x-4 gap-y-6 max-h-full !w-[590px] overflow-auto'> {category.childs.map((child1Category) => ( - <div key={child1Category.id}> + <div key={child1Category.id} className='w-full'> <Link href={createSlug('/shop/category/', child1Category.name, child1Category.id)} - className='category-mega-box__child-one mb-4' + className='category-mega-box__child-one mb-4 w-full h-8 flex justify-center line-clamp-2' > {child1Category.name} </Link> - <div className='flex flex-col gap-y-3'> - {child1Category.childs.map((child2Category) => ( - <Link - href={createSlug( - '/shop/category/', - child2Category.name, - child2Category.id - )} - className='category-mega-box__child-two' - key={child2Category.id} - > - {child2Category.name} - </Link> + <div className='flex flex-col gap-y-3 w-full'> + {child1Category.childs.map((child2Category, index) => ( + (index < 4) && ( + <Link + href={createSlug('/shop/category/', child2Category.name, child2Category.id)} + className='category-mega-box__child-two truncate' + key={child2Category.id} + > + {child2Category.name} + </Link> + ) ))} + {child1Category.childs.length > 5 && ( + <div className='flex hover:bg-gray_r-8/35 rounded-10'> + <Link + href={createSlug('/shop/category/', child1Category.name, child1Category.id)} + className='category-mega-box__child-one flex items-center gap-4 font-bold hover:ml-4' + > + <p className='mt-2 mb-0 text-danger-500 font-semibold'>Lihat Semua</p> + <ChevronRightIcon className='w-4 text-danger-500 font-bold' /> + </Link> + </div> + )} </div> </div> ))} </div> + <div className='category-mega-box__child-wrapper !w-[260px] !flex !flex-col !gap-4'> + <PopularBrand category={category} /> + {promotionProgram?.data[0]?.map((banner, index)=>( + <div key={index} className='flex w-60 h-20 object-cover'> + {/* <Image src='https://erp.indoteknik.com/api/image/x_banner.banner/x_banner_image/397' alt='' width={275} height={4} /> */} + <Image src={`${banner.image}`} alt={`${banner.name}`} width={275} height={4} /> + </div> + ))} + </div> </div> </div> ))} diff --git a/src/lib/category/components/PopularBrand.jsx b/src/lib/category/components/PopularBrand.jsx new file mode 100644 index 00000000..f0b12e2c --- /dev/null +++ b/src/lib/category/components/PopularBrand.jsx @@ -0,0 +1,83 @@ +import odooApi from '@/core/api/odooApi' +import React, { useEffect, useState } from 'react' +import axios from 'axios'; +import { useQuery } from 'react-query' +import Link from '@/core/components/elements/Link/Link' +import { createSlug } from '@/core/utils/slug' +import Image from 'next/image' +import { ChevronRightIcon } from '@heroicons/react/24/outline' +import useProductSearch from '../../../lib/product/hooks/useProductSearch'; +import { SolrResponse } from "~/types/solr"; +import { fetchPopulerProductSolr } from '../api/popularProduct' + +const SOLR_HOST = process.env.SOLR_HOST + +const PopularBrand = ({ category }) => { + const [topBrands, setTopBrands] = useState([]); + + const fetchTopBrands = async () => { + try { + const items = await fetchPopulerProductSolr(`category_id_ids:(${category?.categoryDataIds?.join(' OR ')})`); + // console.log("id",items) + // Fungsi untuk deduplikasi dan mengambil 12 nama brand teratas + const getTop12UniqueBrands = (prod) => { + const brandSet = new Set(); + const topBrands = []; + + for (const product of prod) { + if (!brandSet.has(product.manufacture_name)) { + brandSet.add(product.manufacture_name); + topBrands.push({ name: product.manufacture_name, id: product.manufacture_id }); + }else{ + } + if (topBrands.length === 18) break; + } + return topBrands; + } + + // Menggunakan hasil pencarian produk + const products = items; + const top12UniqueBrands = getTop12UniqueBrands(products); + + // console.log('top12UniqueBrands', top12UniqueBrands); + setTopBrands(top12UniqueBrands); + } catch (error) { + console.error("Error fetching data from Solr", error); + throw error; + } + } + + useEffect(() => { + fetchTopBrands(); + }, [category]); + + return ( + <div className='flex flex-col'> + <div className='grid grid-cols-3 max-h-full w-full gap-2'> + {topBrands.map((brand, index) => ( + <div key={index} className='w-full flex items-center justify-center pb-2'> + <Link + href={createSlug('/shop/brands/', brand.name, brand.id)} + className='category-mega-box__child-one w-8 h-full flex items-center justify-center ' + > + <Image src={`https://erp.indoteknik.com/api/image/x_manufactures/x_logo_manufacture/${brand.id}` } alt={`${brand.name}`} width={104} height={44} objectFit='cover' /> + </Link> + </div> + ))} + </div> + {/* {topBrands.length > 8 && ( + <div className='flex hover:bg-gray_r-8/35 rounded-10'> + <Link + href={createSlug('/shop/category/', category.name, category.id)} + className='category-mega-box__child-one flex items-center gap-4 font-bold hover:ml-4' + > + <p className='mt-2 mb-0 text-danger-500 font-semibold'>Lihat Semua Brand</p> + <ChevronRightIcon className='w-4 text-danger-500 font-bold' /> + </Link> + </div> + )} */} + </div> + ) +} + +export default PopularBrand; |
