summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiqdad <ahmadmiqdad27@gmail.com>2025-05-07 09:46:41 +0700
committerMiqdad <ahmadmiqdad27@gmail.com>2025-05-07 09:46:41 +0700
commitd48f8943b87178ccc653ae1d334b3780c5a23a31 (patch)
tree40fbd0184ae2b278f21a07039b0d152479cf9ff8
parent166191e8f7335810cd0073b9aa2436a908a21d34 (diff)
parent5c8a5df24a9758f3b3a6366d326f61c2c6a13c42 (diff)
Merge branch 'new-release' of https://bitbucket.org/altafixco/next-indoteknik into feat_voucher-category
-rw-r--r--package.json2
-rw-r--r--src-migrate/modules/product-detail/components/ProductDetail.tsx47
-rw-r--r--src-migrate/types/product.ts1
-rw-r--r--src/lib/checkout/components/Checkout.jsx4
-rw-r--r--src/lib/flashSale/api/flashSaleApi.js5
-rw-r--r--src/lib/flashSale/components/FlashSaleNonDisplay.jsx12
-rw-r--r--src/lib/product/components/ProductSearch.jsx7
-rw-r--r--src/pages/api/flashsale-header.js2
-rw-r--r--src/pages/api/shop/search.js1
-rw-r--r--src/utils/solrMapping.js1
10 files changed, 64 insertions, 18 deletions
diff --git a/package.json b/package.json
index 9e7fcc1b..b0f1e3d4 100644
--- a/package.json
+++ b/package.json
@@ -49,8 +49,10 @@
"react-multi-select-component": "^4.3.4",
"react-query": "^3.39.3",
"react-select": "^5.8.0",
+ "react-slick": "^0.30.3",
"react-web-share": "^2.0.2",
"redis": "^4.7.0",
+ "slick-carousel": "^1.8.1",
"snakecase-keys": "^5.5.0",
"swiper": "^8.4.4",
"tw-merge": "^0.0.1-alpha.3",
diff --git a/src-migrate/modules/product-detail/components/ProductDetail.tsx b/src-migrate/modules/product-detail/components/ProductDetail.tsx
index 539ff6d7..bd2c895f 100644
--- a/src-migrate/modules/product-detail/components/ProductDetail.tsx
+++ b/src-migrate/modules/product-detail/components/ProductDetail.tsx
@@ -2,7 +2,7 @@ import style from '../styles/product-detail.module.css';
import Link from 'next/link';
import { useRouter } from 'next/router';
-import { useEffect } from 'react';
+import { useEffect, useState } from 'react';
import { Button } from '@chakra-ui/react';
import { MessageCircleIcon, Share2Icon } from 'lucide-react';
@@ -75,6 +75,19 @@ const ProductDetail = ({ product }: Props) => {
// setSelectedVariant(product?.variants[0])
}, []);
+
+
+ // Gabungkan semua gambar produk (utama + tambahan)
+ const allImages = product.image_carousel ? [...product.image_carousel] : [];
+
+
+ if (product.image) {
+ allImages.unshift(product.image); // Tambahkan gambar utama di awal array
+ }
+ console.log(product);
+
+ const [mainImage, setMainImage] = useState(allImages[0] || '');
+
return (
<>
<div className='md:flex md:flex-wrap'>
@@ -85,7 +98,37 @@ const ProductDetail = ({ product }: Props) => {
<PagePopupInformation />
<div className='md:flex md:flex-wrap'>
<div className='md:w-4/12'>
- <ProductImage product={product} />
+ <ProductImage product={{ ...product, image: mainImage }} />
+
+ {/* Carousel horizontal */}
+ {allImages.length > 0 && (
+ <div className="mt-4 overflow-x-auto">
+ <div className="flex space-x-3 pb-3">
+ {allImages.map((img, index) => (
+ <div
+ key={index}
+ className={`flex-shrink-0 w-16 h-16 cursor-pointer border-2 rounded-md transition-colors ${
+ mainImage === img
+ ? 'border-red-500 ring-2 ring-red-200'
+ : 'border-gray-200 hover:border-gray-300'
+ }`}
+ onClick={() => setMainImage(img)}
+ >
+ <img
+ src={img}
+ alt={`Thumbnail ${index + 1}`}
+ className="w-full h-full object-cover rounded-sm"
+ loading="lazy"
+ onError={(e) => {
+ (e.target as HTMLImageElement).src = '/path/to/fallback-image.jpg';
+ }}
+ />
+ </div>
+ ))}
+ </div>
+ </div>
+ )}
+
</div>
<div className='md:w-8/12 px-4 md:pl-6'>
diff --git a/src-migrate/types/product.ts b/src-migrate/types/product.ts
index 85ea702a..14ba718f 100644
--- a/src-migrate/types/product.ts
+++ b/src-migrate/types/product.ts
@@ -4,6 +4,7 @@ export interface IProduct {
id: number;
image: string;
image_mobile: string;
+ image_carousel: string[];
code: string;
display_name: string;
name: string;
diff --git a/src/lib/checkout/components/Checkout.jsx b/src/lib/checkout/components/Checkout.jsx
index 9ccebe72..be490d32 100644
--- a/src/lib/checkout/components/Checkout.jsx
+++ b/src/lib/checkout/components/Checkout.jsx
@@ -1167,7 +1167,7 @@ const Checkout = () => {
</Skeleton>
)}
<Divider />
- <SectionValidation address={selectedAddress.invoicing} />
+ <SectionValidation address={selectedAddress.shipping} />
<SectionExpedisi
address={selectedAddress.shipping}
listExpedisi={listExpedisi}
@@ -1467,7 +1467,7 @@ const Checkout = () => {
</Skeleton>
)}
<Divider />
- <SectionValidation address={selectedAddress.invoicing} />
+ <SectionValidation address={selectedAddress.shipping} />
<SectionExpedisi
address={selectedAddress.shipping}
listExpedisi={listExpedisi}
diff --git a/src/lib/flashSale/api/flashSaleApi.js b/src/lib/flashSale/api/flashSaleApi.js
index 115b07dc..410b720c 100644
--- a/src/lib/flashSale/api/flashSaleApi.js
+++ b/src/lib/flashSale/api/flashSaleApi.js
@@ -1,8 +1,9 @@
import odooApi from '@/core/api/odooApi'
-const flashSaleApi = async () => {
- const flashSale = await odooApi('GET', '/api/v1/flashsale/header')
+const flashSaleApi = async ({isShow = true}) => {
+ const flashSale = await odooApi('GET', '/api/v1/flashsale/header?is_show_program='+isShow)
return flashSale
}
export default flashSaleApi
+ \ No newline at end of file
diff --git a/src/lib/flashSale/components/FlashSaleNonDisplay.jsx b/src/lib/flashSale/components/FlashSaleNonDisplay.jsx
index 4b420fac..adcc7ba0 100644
--- a/src/lib/flashSale/components/FlashSaleNonDisplay.jsx
+++ b/src/lib/flashSale/components/FlashSaleNonDisplay.jsx
@@ -13,14 +13,14 @@ const FlashSaleNonDisplay = () => {
const router = useRouter();
useEffect(() => {
const loadFlashSales = async () => {
- const dataFlashSales = await flashSaleApi();
+ const dataFlashSales = await flashSaleApi({isShow: false});
setFlashSales(dataFlashSales);
setIsLoading(false);
};
loadFlashSales();
}, []);
- const handleSubmit = () => {
- router.push(`/shop/search?penawaran=${flashSales[0]?.pricelistId}`);
+ const handleSubmit = (flashSale) => {
+ router.push(`/shop/search?penawaran=${flashSale?.pricelistId}`);
};
if (isLoading) {
return <FlashSaleSkeleton />;
@@ -33,10 +33,10 @@ const FlashSaleNonDisplay = () => {
<div key={index}>
<div className='flex items-center mb-4 justify-between '>
<div className='font-medium sm:text-h-lg mt-1.5'>
- Penawaran Terbatas
+ {flashSale.name}
</div>
<div
- onClick={handleSubmit}
+ onClick={() => handleSubmit(flashSale)}
className='!text-red-500 font-semibold cursor-pointer'
>
Lihat Semua
@@ -56,7 +56,7 @@ const FlashSaleProduct = ({ flashSaleId }) => {
useEffect(() => {
const loadProducts = async () => {
const dataProducts = await productSearchApi({
- query: `fq=-flashsale_id_i:${flashSaleId}&fq=flashsale_price_f:[1 TO *]&limit=25&orderBy=flashsale-discount-desc&source=similar`,
+ query: `fq=flashsale_id_i:${flashSaleId}&fq=flashsale_price_f:[1 TO *]&limit=25&orderBy=flashsale-discount-desc&source=similar`,
operation: 'AND',
});
setProducts(dataProducts.response);
diff --git a/src/lib/product/components/ProductSearch.jsx b/src/lib/product/components/ProductSearch.jsx
index e2e1f859..eb86485d 100644
--- a/src/lib/product/components/ProductSearch.jsx
+++ b/src/lib/product/components/ProductSearch.jsx
@@ -84,10 +84,7 @@ const ProductSearch = ({
if (router.asPath.includes('penawaran')) {
query = {
...query,
- fq: [
- `-flashsale_id_i:${router.query.penawaran}`,
- `flashsale_price_f:[1 TO *]`,
- ],
+ fq:`flashsale_id_i:${router.query.penawaran} AND flashsale_price_f:[1 TO *]`,
orderBy: 'flashsale-discount-desc',
};
setFinalQuery(query);
@@ -152,7 +149,7 @@ const ProductSearch = ({
}, [dataCategoriesProduct, dataLob]);
useEffect(() => {
- if (prefixUrl.includes('category') || prefixUrl.includes('lob')) {
+ if (prefixUrl.includes('category') || prefixUrl.includes('lob') || router.asPath.includes('penawaran')) {
setQueryFinal({ ...finalQuery, q, limit, orderBy });
} else {
setQueryFinal({ ...query, q, limit, orderBy });
diff --git a/src/pages/api/flashsale-header.js b/src/pages/api/flashsale-header.js
index 578801ae..916a9cd2 100644
--- a/src/pages/api/flashsale-header.js
+++ b/src/pages/api/flashsale-header.js
@@ -35,7 +35,7 @@ export default async function handler(req, res) {
}
return res.status(200).json({ data });
} else {
- const flashSale = await odooApi('GET', `/api/v1/flashsale/header`);
+ const flashSale = await odooApi('GET', `/api/v1/flashsale/header?is_show_program=true`);
if (flashSale.length === 0) {
return res.status(200).json({ data: [] });
} else {
diff --git a/src/pages/api/shop/search.js b/src/pages/api/shop/search.js
index 63ec7ca0..a1eecc52 100644
--- a/src/pages/api/shop/search.js
+++ b/src/pages/api/shop/search.js
@@ -19,6 +19,7 @@ export default async function handler(req, res) {
source = '',
} = req.query;
+
let { stock = '' } = req.query;
let paramOrderBy = '';
switch (orderBy) {
diff --git a/src/utils/solrMapping.js b/src/utils/solrMapping.js
index ecd62be2..33f0cbaf 100644
--- a/src/utils/solrMapping.js
+++ b/src/utils/solrMapping.js
@@ -43,6 +43,7 @@ export const productMappingSolr = (products, pricelist) => {
let productMapped = {
id: product.product_id_i || '',
image: product.image_s || '',
+ imageCarousel: product.image_carousel_ss || '',
imageMobile: product.image_mobile_s || '',
code: product.default_code_s || '',
description: product.description_t || '',