115 lines
3.9 KiB
TypeScript
115 lines
3.9 KiB
TypeScript
|
|
import React, { useState } from 'react';
|
||
|
|
import { Swiper, SwiperSlide } from 'swiper/react';
|
||
|
|
import { Autoplay, Navigation, Pagination } from 'swiper/modules';
|
||
|
|
import 'swiper/css';
|
||
|
|
import { ComboSet, ComboProduct, ComboGroup } from '@/types';
|
||
|
|
import { ItemComboSet } from './ItemComboset';
|
||
|
|
import { ChangeProductPopup } from './ChangeProductPopup';
|
||
|
|
|
||
|
|
interface ComboProps {
|
||
|
|
combo_set: ComboSet[];
|
||
|
|
}
|
||
|
|
|
||
|
|
interface PopupGroup {
|
||
|
|
title: string;
|
||
|
|
products: ComboProduct[];
|
||
|
|
}
|
||
|
|
|
||
|
|
export const ComboSetBox: React.FC<ComboProps> = ({ combo_set }) => {
|
||
|
|
const [openPopup, setOpenPopup] = useState(false);
|
||
|
|
const [popupGroup, setPopupGroup] = useState<PopupGroup>({
|
||
|
|
title: '',
|
||
|
|
products: [],
|
||
|
|
});
|
||
|
|
const [selectedProduct, setSelectedProduct] = useState<ComboProduct | null>(null);
|
||
|
|
|
||
|
|
const handleOpenPopup = (
|
||
|
|
titleGroup: string,
|
||
|
|
products: ComboProduct[],
|
||
|
|
currentItem: ComboProduct,
|
||
|
|
) => {
|
||
|
|
setPopupGroup({ title: titleGroup, products });
|
||
|
|
setSelectedProduct(currentItem); // lưu sản phẩm đang hiển thị
|
||
|
|
setOpenPopup(true);
|
||
|
|
};
|
||
|
|
|
||
|
|
const handleReplaceProduct = (newProduct: ComboProduct) => {
|
||
|
|
// cập nhật selectedProduct bằng sản phẩm mới
|
||
|
|
setSelectedProduct(newProduct);
|
||
|
|
setOpenPopup(false);
|
||
|
|
};
|
||
|
|
|
||
|
|
const getDisplayedProduct = (group: ComboGroup) => {
|
||
|
|
// Nếu selectedProduct thuộc group này thì hiển thị nó
|
||
|
|
if (selectedProduct && group.product_list.some((p) => p.id === selectedProduct.id)) {
|
||
|
|
return selectedProduct;
|
||
|
|
}
|
||
|
|
// Ngược lại lấy sản phẩm mặc định
|
||
|
|
return group.product_list.find((p) => p.is_first === 'yes') || group.product_list[0];
|
||
|
|
};
|
||
|
|
|
||
|
|
if (!combo_set || combo_set.length === 0) return null;
|
||
|
|
const setInfo = combo_set[0];
|
||
|
|
|
||
|
|
return (
|
||
|
|
<div className="box-comboset mb-8">
|
||
|
|
<p className="title-comboset font-weight-600">Mua theo combo</p>
|
||
|
|
<div id="comboset">
|
||
|
|
<Swiper
|
||
|
|
className="list-product-comboset swiper-comboset"
|
||
|
|
modules={[Autoplay, Navigation, Pagination]}
|
||
|
|
spaceBetween={16}
|
||
|
|
slidesPerView={3}
|
||
|
|
navigation
|
||
|
|
>
|
||
|
|
{setInfo.group_list.map((group, index) => {
|
||
|
|
// lấy sản phẩm đầu tiên theo logic "is_first" hoặc mặc định
|
||
|
|
const firstProduct =
|
||
|
|
group.product_list.find((p) => p.is_first === 'yes') || group.product_list[0];
|
||
|
|
|
||
|
|
return (
|
||
|
|
<SwiperSlide key={index}>
|
||
|
|
<ItemComboSet
|
||
|
|
item={getDisplayedProduct(group)}
|
||
|
|
keyGroup={group.key}
|
||
|
|
titleGroup={group.title}
|
||
|
|
setId={setInfo.id}
|
||
|
|
products={group.product_list}
|
||
|
|
onOpenPopup={handleOpenPopup}
|
||
|
|
/>
|
||
|
|
</SwiperSlide>
|
||
|
|
);
|
||
|
|
})}
|
||
|
|
</Swiper>
|
||
|
|
|
||
|
|
<div className="comboset-info mt-4 flex justify-between">
|
||
|
|
<div className="box-left">
|
||
|
|
<div className="total-comboset flex items-center gap-2">
|
||
|
|
<p>Tạm tính:</p>
|
||
|
|
<p className="js-pass-price price text-red font-weight-600">
|
||
|
|
{/* giả sử lấy giá từ product_info */}
|
||
|
|
3.050.000 đ
|
||
|
|
</p>
|
||
|
|
</div>
|
||
|
|
<p className="save-price-combo">
|
||
|
|
Tiết kiệm thêm <span className="save-price">215.000đ</span>
|
||
|
|
</p>
|
||
|
|
</div>
|
||
|
|
<div className="box-right flex items-center justify-end gap-2">
|
||
|
|
<p className="js-combo-set js-combo-set-checkout buy_combo" data-set-id={setInfo.id}>
|
||
|
|
Mua thêm <span id="count-pro-selected">0</span> sản phẩm
|
||
|
|
</p>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
<ChangeProductPopup
|
||
|
|
titleGroup={popupGroup.title}
|
||
|
|
products={popupGroup.products}
|
||
|
|
open={openPopup}
|
||
|
|
onClose={() => setOpenPopup(false)}
|
||
|
|
onSelect={handleReplaceProduct}
|
||
|
|
/>
|
||
|
|
</div>
|
||
|
|
);
|
||
|
|
};
|