diff options
| author | IT Fixcomart <it@fixcomart.co.id> | 2024-06-28 03:26:38 +0000 |
|---|---|---|
| committer | trisusilo <tri.susilo@altama.co.id> | 2024-06-28 03:26:38 +0000 |
| commit | def7fc2f1201286c44545e1305ca9f11eb16f3d0 (patch) | |
| tree | 4c65db77b9aa28f3dd53ce514de9d918440c2887 /src/pages/shop/promo/index.tsx | |
| parent | 98d4f9564bfba66687848b335026bddb6f4dc5b6 (diff) | |
| parent | 936f7f9fb1c6951e02dd8a5f7e85fb8d39cc7e6a (diff) | |
Merged in promotion-program (pull request #140)
Promotion program
Approved-by: trisusilo
Diffstat (limited to 'src/pages/shop/promo/index.tsx')
| -rw-r--r-- | src/pages/shop/promo/index.tsx | 186 |
1 files changed, 186 insertions, 0 deletions
diff --git a/src/pages/shop/promo/index.tsx b/src/pages/shop/promo/index.tsx new file mode 100644 index 00000000..7ec4f6b0 --- /dev/null +++ b/src/pages/shop/promo/index.tsx @@ -0,0 +1,186 @@ +import dynamic from 'next/dynamic' +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 { fetchPromoItemsSolr } from '../../../api/promoApi.js' +import LogoSpinner from '../../../core/components/elements/Spinner/LogoSpinner.jsx' +import ProductPromoCard from '../../../../src-migrate/modules/product-promo/components/Card.tsx' +import { IPromotion } from '../../../../src-migrate/types/promotion.ts' +import React from 'react' +import { SolrResponse } from "../../../../src-migrate/types/solr.ts"; + +const BasicLayout = dynamic(() => import('../../../core/components/layouts/BasicLayout.jsx')) + +export default function Promo() { + const router = useRouter() + const { slug = '' } = router.query + const [promoItems, setPromoItems] = useState<any[]>([]) + const [promoData, setPromoData] = useState<IPromotion[] | null>(null) + const [loading, setLoading] = useState(true) + const [currentPage, setCurrentPage] = useState(1) + const [fetchingData, setFetchingData] = useState(false) + + useEffect(() => { + const loadPromo = async () => { + try { + const items = await fetchPromoItemsSolr(`*:*`) + + + setPromoItems(items) + + + if (items.length === 0) { + setPromoData([]) + setLoading(false); + return; + } + + const promoDataPromises = items.map(async (item) => { + const queryParams = new URLSearchParams({ q: `id:${item.id}` }) + + + try { + const response = await fetch(`/solr/promotion_program_lines/select?${queryParams.toString()}`) + + if (!response.ok) { + throw new Error(`HTTP error! status: ${response.status}`) + } + + const data: SolrResponse<any[]> = await response.json() + + + const promotions = await map(data.response.docs) + return promotions; + } catch (fetchError) { + console.error("Error fetching promotion data:", fetchError) + return []; + } + }); + + const promoDataArray = await Promise.all(promoDataPromises); + const mergedPromoData = promoDataArray.reduce((accumulator, currentValue) => accumulator.concat(currentValue), []); + setPromoData(mergedPromoData); + setTimeout(() => setLoading(false), 120); // Menambahkan delay 200ms sebelum mengubah status loading + } catch (loadError) { + console.error("Error loading promo items:", loadError) + setLoading(false); + } + } + + if (slug) { + loadPromo() + } + }, [slug]) + + const map = async (promotions: any[]): Promise<IPromotion[]> => { + const result: IPromotion[] = [] + + for (const promotion of promotions) { + const data: IPromotion = { + id: promotion.id, + program_id: promotion.program_id_i, + name: promotion.name_s, + type: { + value: promotion.type_value_s, + label: promotion.type_label_s, + }, + limit: promotion.package_limit_i, + limit_user: promotion.package_limit_user_i, + limit_trx: promotion.package_limit_trx_i, + price: promotion.price_f, + total_qty: promotion.total_qty_i, + products: JSON.parse(promotion.products_s), + free_products: JSON.parse(promotion.free_products_s), + } + + result.push(data) + } + + return result + } + + + + + useEffect(() => { + const handleScroll = () => { + if ( + !fetchingData && + window.innerHeight + document.documentElement.scrollTop >= 0.95 * document.documentElement.offsetHeight + ) { + // User has scrolled to 95% of page height + + setTimeout(() => setFetchingData(true), 120); + setCurrentPage((prevPage) => prevPage + 1) + } + } + + window.addEventListener('scroll', handleScroll) + return () => window.removeEventListener('scroll', handleScroll) + }, [fetchingData]) + + useEffect(() => { + if (fetchingData) { + // Fetch more data + // You may need to adjust this logic according to your API + fetchMoreData() + } + }, [fetchingData]) + + const fetchMoreData = async () => { + try { + // Add a delay of approximately 150ms + setTimeout(async () => { + // Fetch more data + // Update promoData state with the new data + }, 150) + } catch (error) { + console.error('Error fetching more data:', error) + } finally { + setTimeout(() => setFetchingData(false), 120); + + } + } + + const visiblePromotions = promoData?.slice(0, currentPage * 12) + + return ( + <BasicLayout> + <Seo + 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' + /> + {/* <Promocrumb brandName={capitalizeFirstLetter(Array.isArray(slug) ? slug[0] : slug)} /> */} + <div className='container mx-auto mt-1 flex mb-1'> + <div className=''> + <h1 className='font-semibold'>Semua Promo di Indoteknik</h1> + </div> + </div> + {loading ? ( + <div className='container flex justify-center my-4'> + <LogoSpinner width={48} height={48} /> + </div> + ) : promoData && promoItems.length >= 1 ? ( + <> + <div className='flex flex-wrap justify-center'> + {visiblePromotions?.map((promotion) => ( + <div key={promotion.id} className="min-w-[40px] max-w-[400px] mr-[20px] mb-[20px] sm:w-full md:w-1/2 lg:w-1/3 xl:w-1/4"> + <ProductPromoCard promotion={promotion} /> + </div> + ))} + </div> + {fetchingData && ( + <div className='container flex justify-center my-4'> + <LogoSpinner width={48} height={48} /> + </div> + )} + </> + ) : ( + <div className="text-center my-8"> + <p>Belum ada promo pada kategori ini</p> + </div> + )} + </BasicLayout> + ) +} |
