summaryrefslogtreecommitdiff
path: root/src-migrate/modules/promo
diff options
context:
space:
mode:
Diffstat (limited to 'src-migrate/modules/promo')
-rw-r--r--src-migrate/modules/promo/components/Hero.tsx14
-rw-r--r--src-migrate/modules/promo/components/PromoList.jsx194
-rw-r--r--src-migrate/modules/promo/components/PromotinProgram.jsx95
3 files changed, 298 insertions, 5 deletions
diff --git a/src-migrate/modules/promo/components/Hero.tsx b/src-migrate/modules/promo/components/Hero.tsx
index 5470b93b..d8bb0be4 100644
--- a/src-migrate/modules/promo/components/Hero.tsx
+++ b/src-migrate/modules/promo/components/Hero.tsx
@@ -3,26 +3,30 @@ import 'swiper/css';
import Image from 'next/image';
import { useEffect, useMemo } from 'react';
import { useQuery } from 'react-query';
-import { Swiper, SwiperProps, SwiperSlide } from 'swiper/react';
+import { Swiper, SwiperProps, SwiperSlide } from 'swiper/react';
import { getBanner } from '~/services/banner';
import style from '../styles/hero.module.css';
+import 'swiper/css/navigation';
+import { Navigation, Pagination } from 'swiper';
const swiperBanner: SwiperProps = {
+ modules:[Navigation, Pagination],
autoplay: {
delay: 6000,
disableOnInteraction: false
},
- loop: false,
+ loop: true,
className: 'h-[400px] w-full',
slidesPerView: 1,
- spaceBetween: 10
+ spaceBetween: 10,
+ navigation:true,
}
const Hero = () => {
const bannerQuery = useQuery({
queryKey: ['banner.all-promo'],
- queryFn: () => getBanner({ type: 'all-promo' })
+ queryFn: () => getBanner({ type: 'banner-promotion' })
})
const banners = useMemo(() => bannerQuery.data || [], [bannerQuery.data]);
@@ -47,7 +51,7 @@ const Hero = () => {
{banners.map((banner, index) => (
<SwiperSlide key={index}>
<Image
- src='https://erp.indoteknik.com/api/image/x_banner.banner/x_banner_image/363'
+ src={banner.image}
alt={banner.name}
width={666}
height={450}
diff --git a/src-migrate/modules/promo/components/PromoList.jsx b/src-migrate/modules/promo/components/PromoList.jsx
new file mode 100644
index 00000000..af2958aa
--- /dev/null
+++ b/src-migrate/modules/promo/components/PromoList.jsx
@@ -0,0 +1,194 @@
+import Image from 'next/image';
+import Link from '@/core/components/elements/Link/Link';
+import ProductPromoCard from '../../../../src-migrate/modules/product-promo/components/Card'
+// import { fetchPromoItemsSolr, fetchVariantSolr } from '../../../api/promoApi'
+
+
+export const fetchPromoItemsSolr = async (type) => {
+ // let query = type ? `type_value_s:${type}` : '*:*';
+ let start = 0
+ let rows = 100
+ try {
+ const queryParams = new URLSearchParams({ q: type });
+ const response = await fetch(`/solr/promotion_program_lines/select?${queryParams.toString()}&rows=${rows}&start=${start}`);
+ 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 PromoList = ({ selectedPromo }) => {
+
+ useEffect(() => {
+ const loadPromo = async () => {
+ setLoading(true);
+
+
+ try {
+ const items = await fetchPromoItemsSolr(`type_value_s:${Array.isArray(slug) ? slug[0] : slug}`);
+ setPromoItems(items);
+
+ if (items.length === 0) {
+ setPromoData([])
+ setLoading(false);
+ return;
+ }
+
+ const brandArray = Array.isArray(brand) ? brand : brand.split(',');
+ const categoryArray = Array.isArray(category) ? category : category.split(',');
+
+ const promoDataPromises = items.map(async (item) => {
+
+ try {
+ let brandQuery = '';
+ if (brand) {
+ brandQuery = brandArray.map(b => `manufacture_name_s:${b}`).join(' OR ');
+ brandQuery = `(${brandQuery})`;
+ }
+
+ let categoryQuery = '';
+ if (category) {
+ categoryQuery = categoryArray.map(c => `category_name:${c}`).join(' OR ');
+ categoryQuery = `(${categoryQuery})`;
+ }
+
+ let priceQuery = '';
+ if (priceFrom && priceTo) {
+ priceQuery = `price_f:[${priceFrom} TO ${priceTo}]`;
+ } else if (priceFrom) {
+ priceQuery = `price_f:[${priceFrom} TO *]`;
+ } else if (priceTo) {
+ priceQuery = `price_f:[* TO ${priceTo}]`;
+ }
+
+ let combinedQuery = '';
+ let combinedQueryPrice = `${priceQuery}`;
+ if (brand && category && priceFrom || priceTo) {
+ combinedQuery = `${brandQuery} AND ${categoryQuery} `;
+ } else if (brand && category) {
+ combinedQuery = `${brandQuery} AND ${categoryQuery}`;
+ } else if (brand && priceFrom || priceTo) {
+ combinedQuery = `${brandQuery}`;
+ } else if (category && priceFrom || priceTo) {
+ combinedQuery = `${categoryQuery}`;
+ } else if (brand) {
+ combinedQuery = brandQuery;
+ } else if (category) {
+ combinedQuery = categoryQuery;
+ }
+
+ if (combinedQuery && priceFrom || priceTo) {
+ const response = await fetchVariantSolr(`id:${item.product_id} AND ${combinedQuery}`);
+ const product = response.response.docs[0];
+ const product_id = product.id;
+ const response2 = await fetchPromoItemsSolr(`type_value_s:${Array.isArray(slug) ? slug[0] : slug} AND product_ids:${product_id} AND ${combinedQueryPrice}`);
+ return response2;
+ }else if(combinedQuery){
+ const response = await fetchVariantSolr(`id:${item.product_id} AND ${combinedQuery}`);
+ const product = response.response.docs[0];
+ const product_id = product.id;
+ const response2 = await fetchPromoItemsSolr(`type_value_s:${Array.isArray(slug) ? slug[0] : slug} AND product_ids:${product_id} `);
+ return response2;
+ } else {
+ const response = await fetchPromoItemsSolr(`id:${item.id}`);
+ return response;
+ }
+ } catch (fetchError) {
+ return [];
+ }
+ });
+
+ const promoDataArray = await Promise.all(promoDataPromises);
+ const mergedPromoData = promoDataArray.reduce((accumulator, currentValue) => accumulator.concat(currentValue), []);
+ setPromoData(mergedPromoData);
+
+ const dataBrandCategoryPromises = promoDataArray.map(async (promoData) => {
+ if (promoData) {
+ const dataBrandCategory = promoData.map(async (item) => {
+ let response;
+ if(category){
+ const categoryQuery = categoryArray.map(c => `category_name:${c}`).join(' OR ');
+ response = await fetchVariantSolr(`id:${item.products[0].product_id} AND (${categoryQuery})`);
+ }else{
+ response = await fetchVariantSolr(`id:${item.products[0].product_id}`)
+ }
+
+
+ if (response.response?.docs?.length > 0) {
+ const product = response.response.docs[0];
+ const manufactureNameS = product.manufacture_name;
+ if (Array.isArray(manufactureNameS)) {
+ for (let i = 0; i < manufactureNameS.length; i += 2) {
+ const brand = manufactureNameS[i];
+ const qty = 1;
+ const existingBrandIndex = brandsData.findIndex(b => b.brand === brand);
+ if (existingBrandIndex !== -1) {
+ brandsData[existingBrandIndex].qty += qty;
+ } else {
+ brandsData.push({ brand, qty });
+ }
+ }
+ }
+
+ const categoryNameS = product.category_name;
+ if (Array.isArray(categoryNameS)) {
+ for (let i = 0; i < categoryNameS.length; i += 2) {
+ const name = categoryNameS[i];
+ const qty = 1;
+ const existingCategoryIndex = categoriesData.findIndex(c => c.name === name);
+ if (existingCategoryIndex !== -1) {
+ categoriesData[existingCategoryIndex].qty += qty;
+ } else {
+ categoriesData.push({ name, qty });
+ }
+ }
+ }
+ }
+ });
+
+ return Promise.all(dataBrandCategory);
+ }
+ });
+
+ await Promise.all(dataBrandCategoryPromises);
+ setBrands(brandsData);
+ setCategories(categoriesData);
+ setLoading(false);
+
+ } catch (loadError) {
+ // console.error("Error loading promo items:", loadError)
+ setLoading(false);
+ }
+ }
+
+ if (slug) {
+ loadPromo()
+ }
+ },[slug, brand, category, priceFrom, priceTo, currentPage]);
+
+ let title = '';
+
+ if (selectedPromo === 'Bundling') {
+ title = 'Kombinasi Kilat Pilihan Kami!';
+ } else if (selectedPromo === 'Loading') {
+ title = 'Belanja Borong Pilihan Kami!';
+ } else if (selectedPromo === 'Merchandise') {
+ title = 'Gratis Merchandise Spesial Indoteknik';
+ }
+
+ return (
+ <div>
+ <h1 className='text-h-sm md:text-h-lg font-semibold mb-4'>{title}</h1>
+ <div>DISINI CARD {selectedPromo}</div>
+ </div>
+ );
+}
+
+export default PromoList;
diff --git a/src-migrate/modules/promo/components/PromotinProgram.jsx b/src-migrate/modules/promo/components/PromotinProgram.jsx
new file mode 100644
index 00000000..a7e5dfef
--- /dev/null
+++ b/src-migrate/modules/promo/components/PromotinProgram.jsx
@@ -0,0 +1,95 @@
+import React from 'react';
+import Image from 'next/image';
+import { InfoIcon } from "lucide-react"
+
+const PromotionProgram = ({ selectedPromo, onSelectPromo }) => {
+ return (
+ <>
+ <div className="text-h-sm md:text-h-lg font-semibold mb-4">Serba Serbi Promo</div>
+ <div className='px-4 sm:px-0'>
+ <div className='grid md:grid-cols-3 grid-cols-2 justify-between gap-2 items-center'>
+ <div className='w-full'>
+ <div
+ onClick={() => onSelectPromo('Bundling')}
+ className={`border p-2 flex items-center gap-x-2 rounded-lg cursor-pointer ${selectedPromo === 'Bundling' ? 'bg-red-50 border-red-500 text-red-500' : 'border-gray-200 text-gray-900'}`}
+ >
+ <div>
+ <Image
+ width={24}
+ height={24}
+ quality={100}
+ src='/images/icon_promo/silat.svg'
+ alt=''
+ className='h-20 w-20 rounded'
+ />
+ </div>
+ <div>
+ <div className='flex w-full flex-row items-center justify-start'>
+ <h1 className={`mr-1 font-semibold text-base ${selectedPromo === 'Bundling' ? 'text-red-500' : 'text-gray-900'}`}>Paket Silat</h1>
+ <InfoIcon className='mt-[1px] text-red-500' size={14} />
+ </div>
+ <p className={`text-xs md:text-sm ${selectedPromo === 'Bundling' ? 'text-red-500' : 'text-gray-500'}`}>
+ Pilihan bundling barang kombinasi Silat.
+ </p>
+ </div>
+ </div>
+ </div>
+ <div className='w-full'>
+ <div
+ onClick={() => onSelectPromo('Loading')}
+ className={`border p-2 flex items-center gap-x-2 rounded-lg cursor-pointer ${selectedPromo === 'Loading' ? 'bg-red-50 border-red-500 text-red-500' : 'border-gray-200 text-gray-900'}`}
+ >
+ <div>
+ <Image
+ width={24}
+ height={24}
+ quality={100}
+ src='/images/icon_promo/barong.svg'
+ alt=''
+ className='h-20 w-20 rounded'
+ />
+ </div>
+ <div>
+ <div className='flex w-full flex-row items-center justify-start'>
+ <h1 className={`mr-1 font-semibold text-base ${selectedPromo === 'Loading' ? 'text-red-500' : 'text-gray-900'}`}>Paket Barong</h1>
+ <InfoIcon className='mt-[1px] text-red-500' size={14} />
+ </div>
+ <p className={`text-xs md:text-sm ${selectedPromo === 'Loading' ? 'text-red-500' : 'text-gray-500'}`}>
+ Beli banyak barang/partai barang borong.
+ </p>
+ </div>
+ </div>
+ </div>
+ <div className='w-full'>
+ <div
+ onClick={() => onSelectPromo('Merchandise')}
+ className={`border p-2 flex items-center gap-x-2 rounded-lg cursor-pointer ${selectedPromo === 'Merchandise' ? 'bg-red-50 border-red-500 text-red-500' : 'border-gray-200 text-gray-900'}`}
+ >
+ <div>
+ <Image
+ width={24}
+ height={24}
+ quality={100}
+ src='/images/icon_promo/angklung.svg'
+ alt=''
+ className='h-20 w-20 rounded'
+ />
+ </div>
+ <div >
+ <div className='flex w-full flex-row items-center justify-start '>
+ <h1 className={`mr-1 font-semibold text-base ${selectedPromo === 'Merchandise' ? 'text-red-500' : 'text-gray-900'}`}>Paket Angklung</h1>
+ <InfoIcon className='mt-[1px] text-red-500' size={14} />
+ </div>
+ <p className={` m1 text-xs md:text-sm ${selectedPromo === 'Merchandise' ? 'text-red-500' : 'text-gray-500'}`}>
+ Gratis barang promosi/merchandise menang langsung.
+ </p>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </>
+ );
+};
+
+export default PromotionProgram;