231 lines
7.0 KiB
TypeScript
231 lines
7.0 KiB
TypeScript
import { Button, Card, Checkbox, Divider, Image } from "antd";
|
|
import { ProBottomSheet } from "components/ProBottomSheet/ProBottomSheet.tsx";
|
|
import { useEffect, useState } from "react";
|
|
import { useTranslation } from "react-i18next";
|
|
|
|
import ArabicPrice from "components/ArabicPrice";
|
|
import ProText from "components/ProText";
|
|
import { selectCart, updateSplitBillAmount } from "features/order/orderSlice";
|
|
import { useAppDispatch, useAppSelector } from "redux/hooks";
|
|
import styles from "./SplitBill.module.css";
|
|
import { QRBottomSheet } from "./QRBottomSheet";
|
|
|
|
interface SplitBillChoiceBottomSheetProps {
|
|
isOpen: boolean;
|
|
onClose: () => void;
|
|
onSave?: (value: string) => void;
|
|
onRemoveSplitWay?: () => void;
|
|
}
|
|
|
|
export function PayForYourItemsChoiceBottomSheet({
|
|
isOpen,
|
|
onClose,
|
|
onRemoveSplitWay,
|
|
}: SplitBillChoiceBottomSheetProps) {
|
|
const { t } = useTranslation();
|
|
const dispatch = useAppDispatch();
|
|
const { items } = useAppSelector(selectCart);
|
|
const [selectedItems, setSelectedItems] = useState<Set<string>>(new Set());
|
|
const [isQROpen, setIsQROpen] = useState(false);
|
|
// Calculate total for selected items
|
|
const selectedTotal = items
|
|
.filter((item) => selectedItems.has(item.uniqueId || item.id.toString()))
|
|
.reduce((sum, item) => sum + item.price * item.quantity, 0);
|
|
|
|
useEffect(() => {
|
|
if (isOpen) {
|
|
setSelectedItems(new Set());
|
|
dispatch(updateSplitBillAmount(0));
|
|
}
|
|
}, [isOpen, dispatch]);
|
|
|
|
const handleItemToggle = (uniqueId: string) => {
|
|
const newSelected = new Set(selectedItems);
|
|
if (newSelected.has(uniqueId)) {
|
|
newSelected.delete(uniqueId);
|
|
} else {
|
|
newSelected.add(uniqueId);
|
|
}
|
|
setSelectedItems(newSelected);
|
|
|
|
// Calculate and update split bill amount
|
|
const newTotal = items
|
|
.filter((item) => newSelected.has(item.uniqueId || item.id.toString()))
|
|
.reduce((sum, item) => sum + item.price * item.quantity, 0);
|
|
dispatch(updateSplitBillAmount(newTotal));
|
|
};
|
|
|
|
const handleSave = () => {
|
|
dispatch(updateSplitBillAmount(selectedTotal));
|
|
setIsQROpen(true);
|
|
onClose();
|
|
};
|
|
|
|
const handleRemoveSplitWay = () => {
|
|
setSelectedItems(new Set());
|
|
dispatch(updateSplitBillAmount(0));
|
|
onRemoveSplitWay?.();
|
|
onClose();
|
|
};
|
|
|
|
return (
|
|
<>
|
|
<ProBottomSheet
|
|
isOpen={isOpen}
|
|
onClose={onClose}
|
|
title={t("splitBill.payForYourItems")}
|
|
showCloseButton={true}
|
|
initialSnap={1}
|
|
height={720}
|
|
snapPoints={[720]}
|
|
contentStyle={{ padding: 0 }}
|
|
>
|
|
<div
|
|
style={{
|
|
padding: 20,
|
|
display: "flex",
|
|
flexDirection: "column",
|
|
gap: 12,
|
|
maxHeight: "455px",
|
|
minHeight: "455px",
|
|
overflowY: "auto",
|
|
}}
|
|
>
|
|
{items.length === 0 ? (
|
|
<ProText
|
|
type="secondary"
|
|
style={{ textAlign: "center", padding: 20 }}
|
|
>
|
|
{t("cart.emptyCart")}
|
|
</ProText>
|
|
) : (
|
|
items.map((item) => {
|
|
const itemId = item.uniqueId || item.id.toString();
|
|
const isSelected = selectedItems.has(itemId);
|
|
const itemTotal = item.price * item.quantity;
|
|
|
|
return (
|
|
<>
|
|
<Card
|
|
key={itemId}
|
|
style={{
|
|
border: "none",
|
|
cursor: "pointer",
|
|
padding: 0,
|
|
}}
|
|
onClick={() => handleItemToggle(itemId)}
|
|
>
|
|
<div
|
|
style={{
|
|
display: "flex",
|
|
flexDirection: "row",
|
|
gap: 12,
|
|
alignItems: "center",
|
|
}}
|
|
>
|
|
<Image
|
|
src={item.image}
|
|
alt={item.name}
|
|
width={60}
|
|
height={60}
|
|
preview={false}
|
|
style={{
|
|
borderRadius: 8,
|
|
objectFit: "cover",
|
|
}}
|
|
/>
|
|
<div
|
|
style={{
|
|
flex: 1,
|
|
display: "flex",
|
|
flexDirection: "column",
|
|
gap: 4,
|
|
}}
|
|
>
|
|
<ProText style={{ fontSize: 14, fontWeight: 500 }}>
|
|
{item.name}
|
|
</ProText>
|
|
<ArabicPrice price={itemTotal} />
|
|
</div>
|
|
<div
|
|
style={{
|
|
width: 32,
|
|
height: 32,
|
|
minWidth: 32,
|
|
display: "flex",
|
|
alignItems: "center",
|
|
justifyContent: "center",
|
|
}}
|
|
onClick={(e) => e.stopPropagation()}
|
|
>
|
|
<Checkbox
|
|
className={styles.circleCheckbox}
|
|
checked={isSelected}
|
|
onChange={() => handleItemToggle(itemId)}
|
|
/>
|
|
</div>
|
|
</div>
|
|
</Card>
|
|
{item !== items[items.length - 1] && (
|
|
<Divider style={{ margin: "0" }} />
|
|
)}
|
|
</>
|
|
);
|
|
})
|
|
)}
|
|
</div>
|
|
<div
|
|
style={{
|
|
padding: 16,
|
|
backgroundColor: "rgba(255, 183, 0, 0.08)",
|
|
borderRadius: 8,
|
|
marginTop: 8,
|
|
}}
|
|
>
|
|
<div
|
|
style={{
|
|
display: "flex",
|
|
justifyContent: "space-between",
|
|
alignItems: "center",
|
|
}}
|
|
>
|
|
<ProText style={{ fontSize: 16, fontWeight: 600 }}>
|
|
{t("splitBill.selectedTotal")}:
|
|
</ProText>
|
|
<ArabicPrice price={selectedTotal} />
|
|
</div>
|
|
</div>
|
|
<div
|
|
style={{
|
|
display: "flex",
|
|
gap: 12,
|
|
margin: 20,
|
|
}}
|
|
>
|
|
<Button
|
|
style={{
|
|
flex: 1,
|
|
backgroundColor: "#FEEDED",
|
|
color: "#DD4143",
|
|
boxShadow: "none",
|
|
border: "none",
|
|
}}
|
|
onClick={handleRemoveSplitWay}
|
|
>
|
|
{t("splitBill.removeSplit")}
|
|
</Button>
|
|
<Button
|
|
type="primary"
|
|
style={{ flex: 1, boxShadow: "none" }}
|
|
onClick={handleSave}
|
|
disabled={selectedTotal === 0}
|
|
>
|
|
{t("cart.save")}
|
|
</Button>
|
|
</div>
|
|
</ProBottomSheet>
|
|
<QRBottomSheet isOpen={isQROpen} onClose={() => setIsQROpen(false)} />
|
|
</>
|
|
);
|
|
}
|