summaryrefslogtreecommitdiff
path: root/src/pages
diff options
context:
space:
mode:
authorit-fixcomart <it@fixcomart.co.id>2024-06-11 13:40:23 +0700
committerit-fixcomart <it@fixcomart.co.id>2024-06-11 13:40:23 +0700
commit9565ddf794165e297acf511a108f9a9643ee615d (patch)
tree07bf6168f6f221c73bc8db5aa17e6bd097c6e4b2 /src/pages
parent5e5b67e5b98d3183044dc5149fe67a29feeb3c41 (diff)
<iman> update promotion program
Diffstat (limited to 'src/pages')
-rw-r--r--src/pages/shop/promo/[slug].tsx77
-rw-r--r--src/pages/shop/promo/index.tsx188
2 files changed, 248 insertions, 17 deletions
diff --git a/src/pages/shop/promo/[slug].tsx b/src/pages/shop/promo/[slug].tsx
index cd3e93c4..be5a715d 100644
--- a/src/pages/shop/promo/[slug].tsx
+++ b/src/pages/shop/promo/[slug].tsx
@@ -10,7 +10,6 @@ import { IPromotion } from '../../../../src-migrate/types/promotion'
import React from 'react'
import { SolrResponse } from "../../../../src-migrate/types/solr.ts";
-
const BasicLayout = dynamic(() => import('../../../core/components/layouts/BasicLayout'))
export default function PromoDetail() {
@@ -22,14 +21,15 @@ export default function PromoDetail() {
const itemsPerPage = 12; // Jumlah item yang ingin ditampilkan per halaman
const startIndex = (currentPage - 1) * itemsPerPage;
const endIndex = Math.min(startIndex + itemsPerPage, promoData?.length || 0);
- const visiblePromotions = promoData?.slice(startIndex, endIndex);
+ // const visiblePromotions = promoData?.slice(startIndex, endIndex);
const [loading, setLoading] = useState(true); // Menambahkan status loading
+ const [fetchingData, setFetchingData] = useState(false)
useEffect(() => {
const loadPromo = async () => {
try {
- const items = await fetchPromoItemsSolr(Array.isArray(slug) ? slug[0] : slug)
+ const items = await fetchPromoItemsSolr(`type_value_s:${Array.isArray(slug) ? slug[0] : slug}`)
console.log("slug sekarang ", slug)
setPromoItems(items)
@@ -112,18 +112,60 @@ export default function PromoDetail() {
console.log("data yg dikirim ke ProductPromoCard", promoData)
function capitalizeFirstLetter(string) {
- return string.charAt(0).toUpperCase() + string.slice(1);
+ // Ganti semua tanda _ dengan spasi
+ string = string.replace(/_/g, ' ');
+
+ // Kapitalisasi huruf pertama setelah spasi atau awal string
+ return string.replace(/(^\w|\s\w)/g, function(match) {
+ return match.toUpperCase();
+ });
+
+
+ }
+
+ 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 goToNextPage = () => {
- setCurrentPage((prevPage) => prevPage + 1);
- window.scrollTo({ top: 0, behavior: 'smooth' });
- };
+ const visiblePromotions = promoData?.slice(0, currentPage * 12)
+
- const goToPreviousPage = () => {
- setCurrentPage((prevPage) => Math.max(prevPage - 1, 1));
- window.scrollTo({ top: 0, behavior: 'smooth' });
- };
return (
<BasicLayout>
@@ -142,14 +184,15 @@ export default function PromoDetail() {
<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} slug={Array.isArray(slug) ? slug[0] : slug} />
+ <ProductPromoCard promotion={promotion}/>
</div>
))}
</div>
- <div className="flex justify-center mt-4">
- <button onClick={goToPreviousPage} disabled={currentPage === 1} className="mr-2 px-4 py-2 bg-gray-200 rounded">Back</button>
- <button onClick={goToNextPage} disabled={endIndex >= promoData.length} className="px-4 py-2 bg-gray-200 rounded">Next</button>
- </div>
+ {fetchingData && (
+ <div className='container flex justify-center my-4'>
+ <LogoSpinner width={48} height={48} />
+ </div>
+ )}
</>
) : (
<div className="text-center my-8">
diff --git a/src/pages/shop/promo/index.tsx b/src/pages/shop/promo/index.tsx
new file mode 100644
index 00000000..6f5134a3
--- /dev/null
+++ b/src/pages/shop/promo/index.tsx
@@ -0,0 +1,188 @@
+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(`*:*`)
+ console.log("slug sekarang ", slug)
+
+ setPromoItems(items)
+ console.log("data dari promotion pakai SOLR", items)
+
+ if (items.length === 0) {
+ setPromoData([])
+ setLoading(false);
+ return;
+ }
+
+ const promoDataPromises = items.map(async (item) => {
+ const queryParams = new URLSearchParams({ q: `id:${item.id}` })
+ console.log("Constructed URL:", `/solr/promotion_program_lines/select?${queryParams.toString()}`)
+
+ try {
+ const response = await fetch(`/solr/promotion_program_lines/select?${queryParams.toString()}`)
+ console.log("respon data ", response)
+ if (!response.ok) {
+ throw new Error(`HTTP error! status: ${response.status}`)
+ }
+
+ const data: SolrResponse<any[]> = await response.json()
+ console.log("data promo IPromotion[]", data)
+
+ 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
+ }
+
+ console.log("data yg dikirim ke ProductPromoCard", promoData)
+ function capitalizeFirstLetter(string) {
+ return string.charAt(0).toUpperCase() + string.slice(1);
+ }
+
+ 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>
+ )
+}