diff options
| -rw-r--r-- | src/pages/shop/promo/[slug].jsx | 350 |
1 files changed, 191 insertions, 159 deletions
diff --git a/src/pages/shop/promo/[slug].jsx b/src/pages/shop/promo/[slug].jsx index cfb2c841..a0ffecea 100644 --- a/src/pages/shop/promo/[slug].jsx +++ b/src/pages/shop/promo/[slug].jsx @@ -1,16 +1,16 @@ -import dynamic from 'next/dynamic' +import dynamic from 'next/dynamic'; import NextImage from 'next/image'; -import { useEffect, useState } from 'react' -import { useRouter } from 'next/router' -import Seo from '../../../core/components/Seo.jsx' -import Promocrumb from '../../../lib/promo/components/Promocrumb.jsx' -import LogoSpinner from '../../../core/components/elements/Spinner/LogoSpinner.jsx' -import ProductPromoCard from '../../../../src-migrate/modules/product-promo/components/Card.tsx' -import React from 'react' +import { useEffect, useState } from 'react'; +import { useRouter } from 'next/router'; +import Seo from '../../../core/components/Seo.jsx'; +import Promocrumb from '../../../lib/promo/components/Promocrumb.jsx'; +import LogoSpinner from '../../../core/components/elements/Spinner/LogoSpinner.jsx'; +import ProductPromoCard from '../../../../src-migrate/modules/product-promo/components/Card.tsx'; +import React from 'react'; import DesktopView from '../../../core/components/views/DesktopView.jsx'; import MobileView from '../../../core/components/views/MobileView.jsx'; import 'swiper/swiper-bundle.css'; -import useDevice from '../../../core/hooks/useDevice.js' +import useDevice from '../../../core/hooks/useDevice.js'; import ProductFilterDesktop from '../../../lib/product/components/ProductFilterDesktopPromotion.jsx'; import ProductFilter from '../../../lib/product/components/ProductFilter.jsx'; import { HStack, Image, Tag, TagCloseButton, TagLabel } from '@chakra-ui/react'; @@ -21,15 +21,17 @@ import _ from 'lodash'; import useActive from '../../../core/hooks/useActive.js'; import useProductSearch from '../../../lib/promo/hooks/usePromotionSearch.js'; -const BasicLayout = dynamic(() => import('../../../core/components/layouts/BasicLayout.jsx')) +const BasicLayout = dynamic(() => + import('../../../core/components/layouts/BasicLayout.jsx') +); export default function PromoDetail() { - const router = useRouter() - const { slug = '', brand ='', category='', page = '1' } = router.query + const router = useRouter(); + const { slug = '', brand = '', category = '', page = '1' } = router.query; const [currentPage, setCurrentPage] = useState(parseInt(10) || 1); const [orderBy, setOrderBy] = useState(router.query?.orderBy); const popup = useActive(); - const prefixUrl = `/shop/promo/${slug}` + const prefixUrl = `/shop/promo/${slug}`; const [queryFinal, setQueryFinal] = useState({}); const [limit, setLimit] = useState(30); const [q, setQ] = useState('*'); @@ -42,38 +44,55 @@ export default function PromoDetail() { : [] : [] ); - + const [categoryValues, setCategory] = useState( router.query?.category?.split(',') || router.query?.category?.split(',') ); - + const [priceFrom, setPriceFrom] = useState(router.query?.priceFrom || null); const [priceTo, setPriceTo] = useState(router.query?.priceTo || null); - useEffect(() => { const newQuery = { fq: `type_value_s:${slug}`, - page : router.query.page? router.query.page : 1, - brand : router.query.brand? router.query.brand : '', - category : router.query.category? router.query.category : '', - priceFrom : router.query.priceFrom? router.query.priceFrom : '', - priceTo : router.query.priceTo? router.query.priceTo : '', - limit : router.query.limit? router.query.limit : '', - orderBy : router.query.orderBy? router.query.orderBy : '' + page: router.query.page ? router.query.page : 1, + brand: router.query.brand ? router.query.brand : '', + category: router.query.category ? router.query.category : '', + priceFrom: router.query.priceFrom ? router.query.priceFrom : '', + priceTo: router.query.priceTo ? router.query.priceTo : '', + limit: router.query.limit ? router.query.limit : '', + orderBy: router.query.orderBy ? router.query.orderBy : '', }; setFinalQuery(newQuery); -}, [router.query, prefixUrl, slug, brand, category, priceFrom, priceTo, currentPage]); + }, [ + router.query, + prefixUrl, + slug, + brand, + category, + priceFrom, + priceTo, + currentPage, + ]); useEffect(() => { - setQueryFinal({ ...finalQuery, q, limit, orderBy }); - }, [router.query, prefixUrl, slug, brand, category, priceFrom, priceTo, currentPage, finalQuery]); + setQueryFinal({ ...finalQuery, q, limit, orderBy }); + }, [ + router.query, + prefixUrl, + slug, + brand, + category, + priceFrom, + priceTo, + currentPage, + finalQuery, + ]); const { productSearch } = useProductSearch({ query: queryFinal, operation: 'OR', }); - const pageCount = Math.ceil(productSearch.data?.response.numFound / limit); const productStart = productSearch.data?.responseHeader.params.start; const productRows = limit; @@ -86,7 +105,8 @@ export default function PromoDetail() { const brands = []; for ( let i = 0; - i < productSearch.data?.facet_counts?.facet_fields?.manufacture_name_s.length; + i < + productSearch.data?.facet_counts?.facet_fields?.manufacture_name_s.length; i += 2 ) { const brand = @@ -104,7 +124,8 @@ export default function PromoDetail() { i < productSearch.data?.facet_counts?.facet_fields?.category_name.length; i += 2 ) { - const name = productSearch.data?.facet_counts?.facet_fields?.category_name[i]; + const name = + productSearch.data?.facet_counts?.facet_fields?.category_name[i]; const qty = productSearch.data?.facet_counts?.facet_fields?.category_name[i + 1]; if (qty > 0) { @@ -114,8 +135,8 @@ export default function PromoDetail() { function capitalizeFirstLetter(string) { string = string.replace(/_/g, ' '); - return string.replace(/(^\w|\s\w)/g, function(match) { - return match.toUpperCase(); + return string.replace(/(^\w|\s\w)/g, function (match) { + return match.toUpperCase(); }); } @@ -144,8 +165,8 @@ export default function PromoDetail() { break; case 'price': params.priceFrom = ''; - params.priceTo = ''; - break; + params.priceTo = ''; + break; case 'delete': params = { q: router.query.q, @@ -165,37 +186,41 @@ export default function PromoDetail() { params = toQuery(params); router.push(`${slug}?${params}`); }; - const toQuery = (obj) => { const str = Object.keys(obj) - .map(key => `${encodeURIComponent(key)}=${encodeURIComponent(obj[key])}`) - .join('&') - return str - } - - const whatPromo = capitalizeFirstLetter(slug) - const queryWithoutSlug = _.omit(router.query, ['slug']) - + .map( + (key) => `${encodeURIComponent(key)}=${encodeURIComponent(obj[key])}` + ) + .join('&'); + return str; + }; + + const whatPromo = capitalizeFirstLetter(slug); + const queryWithoutSlug = _.omit(router.query, ['slug']); + return ( <BasicLayout> <Seo - title={`Promo ${Array.isArray(slug) ? slug[0] : slug} Terkini`} + title={`Promo ${Array.isArray(slug) ? slug[0] : slug} Terkini`} description='B2B Marketplace MRO & Industri dengan Layanan Pembayaran Tempo, Faktur Pajak, Online Quotation, Garansi Resmi & Harga Kompetitif' + canonical={`${process.env.NEXT_PUBLIC_SELF_HOST}${ + router.asPath.split('?')[0] + }`} /> <Promocrumb brandName={whatPromo} /> <MobileView> <div className='p-4 pt-0'> <h1 className='mb-2 font-semibold text-h-sm'>Promo {whatPromo}</h1> - - <FilterChoicesComponent - brandValues={brandValues} - categoryValues={categoryValues} - priceFrom={priceFrom} - priceTo={priceTo} - handleDeleteFilter={handleDeleteFilter} - /> - {products?.length >= 1 && ( + + <FilterChoicesComponent + brandValues={brandValues} + categoryValues={categoryValues} + priceFrom={priceFrom} + priceTo={priceTo} + handleDeleteFilter={handleDeleteFilter} + /> + {products?.length >= 1 && ( <div className='flex items-center gap-x-2 mb-5 justify-between'> <div> <button @@ -207,134 +232,141 @@ export default function PromoDetail() { </div> </div> )} - {productSearch.isLoading && <div className='container flex justify-center my-4'> - <LogoSpinner width={48} height={48} /> - </div>} + {productSearch.isLoading && ( + <div className='container flex justify-center my-4'> + <LogoSpinner width={48} height={48} /> + </div> + )} {products && ( - <> - <div className='grid grid-cols-1 gap-x-1 gap-y-1'> - {products?.map((promotion) => ( - <div key={promotion.id} className="min-w-36 max-w-[400px] mb-[20px] sm:w-full md:w-1/2 lg:w-1/3 xl:w-1/4 "> - <ProductPromoCard promotion={promotion}/> - </div> - ))} - </div> - </> - ) } + <> + <div className='grid grid-cols-1 gap-x-1 gap-y-1'> + {products?.map((promotion) => ( + <div + key={promotion.id} + className='min-w-36 max-w-[400px] mb-[20px] sm:w-full md:w-1/2 lg:w-1/3 xl:w-1/4 ' + > + <ProductPromoCard promotion={promotion} /> + </div> + ))} + </div> + </> + )} - <Pagination - pageCount={pageCount} - currentPage={parseInt(page)} - url={`${prefixUrl}?${toQuery(_.omit(queryWithoutSlug, ['page']))}`} - className='mt-6 mb-2' - /> - <ProductFilter - active={popup.active} - close={popup.deactivate} - brands={brands || []} - categories={categories || []} - prefixUrl={router.asPath.includes('?') ? `${router.asPath}` : `${router.asPath}?`} - defaultBrand={null} - /> + <Pagination + pageCount={pageCount} + currentPage={parseInt(page)} + url={`${prefixUrl}?${toQuery(_.omit(queryWithoutSlug, ['page']))}`} + className='mt-6 mb-2' + /> + <ProductFilter + active={popup.active} + close={popup.deactivate} + brands={brands || []} + categories={categories || []} + prefixUrl={ + router.asPath.includes('?') + ? `${router.asPath}` + : `${router.asPath}?` + } + defaultBrand={null} + /> </div> - </MobileView> <DesktopView> <div className='container mx-auto flex mb-3 flex-col'> <div className='w-full pl-6'> <h1 className='text-2xl mb-2 font-semibold'>Promo {whatPromo}</h1> - <div className=' w-full h-full flex flex-row items-center '> - - <div className='detail-filter w-1/2 flex justify-start items-center mt-4'> - - <FilterChoicesComponent - brandValues={brandValues} - categoryValues={categoryValues} - priceFrom={priceFrom} - priceTo={priceTo} - handleDeleteFilter={handleDeleteFilter} - /> - </div> - <div className='Filter w-1/2 flex flex-col'> - - <ProductFilterDesktop - brands={brands || []} - categories={categories || []} - prefixUrl={'/shop/promo'} - // defaultBrand={null} - /> - </div> - </div> - {productSearch.isLoading ? ( - <div className='container flex justify-center my-4'> - <LogoSpinner width={48} height={48} /> - </div> - ) : products && products.length >= 1 ? ( - <> + <div className=' w-full h-full flex flex-row items-center '> + <div className='detail-filter w-1/2 flex justify-start items-center mt-4'> + <FilterChoicesComponent + brandValues={brandValues} + categoryValues={categoryValues} + priceFrom={priceFrom} + priceTo={priceTo} + handleDeleteFilter={handleDeleteFilter} + /> + </div> + <div className='Filter w-1/2 flex flex-col'> + <ProductFilterDesktop + brands={brands || []} + categories={categories || []} + prefixUrl={'/shop/promo'} + // defaultBrand={null} + /> + </div> + </div> + {productSearch.isLoading ? ( + <div className='container flex justify-center my-4'> + <LogoSpinner width={48} height={48} /> + </div> + ) : products && products.length >= 1 ? ( + <> <div className='grid grid-cols-1 gap-x-6 sm:grid-cols-1 md:grid-cols-2 lg:grid-cols-2 xl:grid-cols-3'> {products?.map((promotion) => ( - <div key={promotion.id} className="min-w-[400px] max-w-[400px] mb-[20px] sm:min-w-[350px] md:min-w-[380px] lg:min-w-[400px] xl:min-w-[400px] "> - <ProductPromoCard promotion={promotion}/> + <div + key={promotion.id} + className='min-w-[400px] max-w-[400px] mb-[20px] sm:min-w-[350px] md:min-w-[380px] lg:min-w-[400px] xl:min-w-[400px] ' + > + <ProductPromoCard promotion={promotion} /> </div> ))} </div> </> - ) : ( - <div className="text-center my-8"> - <p>Belum ada promo pada kategori ini</p> - </div> - )} - <div className='flex justify-between items-center mt-6 mb-2'> - <div className='pt-2 pb-6 flex items-center gap-x-3'> - <NextImage - src='/images/logo-question.png' - alt='Logo Question Indoteknik' - width={60} - height={60} - /> - <div className='text-gray_r-12/90'> - <span> - Barang yang anda cari tidak ada?{' '} - <a - href={ - router.query?.q - ? whatsappUrl('productSearch', { - name: router.query.q, - }) - : whatsappUrl() - } - className='text-danger-500' - > - Hubungi Kami - </a> - </span> - </div> - </div> - - - - <Pagination - pageCount={pageCount} - currentPage={parseInt(page)} - url={`${prefixUrl}?${toQuery(_.omit(queryWithoutSlug, ['page']))}`} - className='mt-6 mb-2' + ) : ( + <div className='text-center my-8'> + <p>Belum ada promo pada kategori ini</p> + </div> + )} + <div className='flex justify-between items-center mt-6 mb-2'> + <div className='pt-2 pb-6 flex items-center gap-x-3'> + <NextImage + src='/images/logo-question.png' + alt='Logo Question Indoteknik' + width={60} + height={60} /> + <div className='text-gray_r-12/90'> + <span> + Barang yang anda cari tidak ada?{' '} + <a + href={ + router.query?.q + ? whatsappUrl('productSearch', { + name: router.query.q, + }) + : whatsappUrl() + } + className='text-danger-500' + > + Hubungi Kami + </a> + </span> + </div> </div> + <Pagination + pageCount={pageCount} + currentPage={parseInt(page)} + url={`${prefixUrl}?${toQuery( + _.omit(queryWithoutSlug, ['page']) + )}`} + className='mt-6 mb-2' + /> + </div> </div> </div> </DesktopView> </BasicLayout> - ) - } - + ); +} + const FilterChoicesComponent = ({ brandValues, categoryValues, priceFrom, priceTo, handleDeleteFilter, - }) => ( +}) => ( <div className='flex items-center mb-4'> <HStack spacing={2} className='flex-wrap'> {brandValues?.map((value, index) => ( @@ -344,7 +376,7 @@ const FilterChoicesComponent = ({ borderRadius='lg' variant='outline' colorScheme='gray' - > + > <TagLabel>{value}</TagLabel> <TagCloseButton onClick={() => handleDeleteFilter('brands', value)} /> </Tag> @@ -357,11 +389,11 @@ const FilterChoicesComponent = ({ borderRadius='lg' variant='outline' colorScheme='gray' - > + > <TagLabel>{value}</TagLabel> <TagCloseButton onClick={() => handleDeleteFilter('category', value)} - /> + /> </Tag> ))} {priceFrom && priceTo && ( @@ -371,7 +403,7 @@ const FilterChoicesComponent = ({ </TagLabel> <TagCloseButton onClick={() => handleDeleteFilter('price', priceFrom)} - /> + /> </Tag> )} {brandValues?.length > 0 || @@ -382,13 +414,13 @@ const FilterChoicesComponent = ({ <button className='btn-transparent py-2 px-5 h-[40px] text-red-700' onClick={() => handleDeleteFilter('delete')} - > + > Hapus Semua </button> </span> ) : ( '' - )} + )} </HStack> </div> ); |
