346 lines
9.7 KiB
TypeScript
346 lines
9.7 KiB
TypeScript
import { Button } from "antd";
|
|
import { ProBottomSheet } from "components/ProBottomSheet/ProBottomSheet.tsx";
|
|
import { useMemo, useState } from "react";
|
|
import { useTranslation } from "react-i18next";
|
|
|
|
import ProText from "components/ProText";
|
|
import ArabicPrice from "components/ArabicPrice";
|
|
import {
|
|
selectCart,
|
|
selectGrandTotal,
|
|
updateSplitBillAmount,
|
|
} from "features/order/orderSlice";
|
|
import { useAppDispatch, useAppSelector } from "redux/hooks";
|
|
import { ProGray1 } from "ThemeConstants";
|
|
import PayForActions from "../../../split-bill/components/PayForActions";
|
|
import TotalPeopleActions from "../../../split-bill/components/TotalPeopleActions";
|
|
import styles from "./SplitBill.module.css";
|
|
|
|
interface SplitBillChoiceBottomSheetProps {
|
|
isOpen: boolean;
|
|
onClose: () => void;
|
|
onSave?: (value: string) => void;
|
|
onRemoveSplitWay?: () => void;
|
|
}
|
|
|
|
interface SplitBillTmp {
|
|
totalPeople?: number;
|
|
payFor?: number;
|
|
}
|
|
|
|
export function EqualltyChoiceBottomSheet({
|
|
isOpen,
|
|
onClose,
|
|
onRemoveSplitWay,
|
|
}: SplitBillChoiceBottomSheetProps) {
|
|
const { t } = useTranslation();
|
|
const dispatch = useAppDispatch();
|
|
const { tmp, splitBillAmount } = useAppSelector(selectCart);
|
|
const grandTotal = useAppSelector(selectGrandTotal);
|
|
const splitBillTmp = tmp as SplitBillTmp;
|
|
const totalPeople = splitBillTmp?.totalPeople || 2;
|
|
const payFor = splitBillTmp?.payFor || 1;
|
|
|
|
// Calculate original total bill (grandTotal already subtracts splitBillAmount)
|
|
const originalTotalBill = grandTotal + splitBillAmount;
|
|
|
|
// Calculate split amount based on original total bill
|
|
const splitAmount = useMemo(() => {
|
|
if (totalPeople > 0) {
|
|
return (originalTotalBill / totalPeople) * payFor;
|
|
}
|
|
return 0;
|
|
}, [originalTotalBill, totalPeople, payFor]);
|
|
|
|
const handleSave = () => {
|
|
dispatch(updateSplitBillAmount(splitAmount));
|
|
onClose();
|
|
};
|
|
|
|
const handleRemoveSplitWay = () => {
|
|
dispatch(updateSplitBillAmount(0));
|
|
onRemoveSplitWay?.();
|
|
onClose();
|
|
};
|
|
|
|
return (
|
|
<ProBottomSheet
|
|
isOpen={isOpen}
|
|
onClose={onClose}
|
|
title={t("splitBill.divideTheBillEqually")}
|
|
showCloseButton={true}
|
|
initialSnap={1}
|
|
height={630}
|
|
snapPoints={[630]}
|
|
contentStyle={{
|
|
padding: 0,
|
|
}}
|
|
>
|
|
<div
|
|
style={{
|
|
display: "flex",
|
|
flexDirection: "column",
|
|
marginTop: 20,
|
|
}}
|
|
>
|
|
{/* Spinner Visualization - Blank Spin Wheel */}
|
|
{totalPeople > 0 && (
|
|
<div
|
|
style={{
|
|
display: "flex",
|
|
flexDirection: "column",
|
|
gap: 12,
|
|
alignItems: "center",
|
|
}}
|
|
>
|
|
<div
|
|
style={{
|
|
position: "relative",
|
|
width: 200,
|
|
height: 200,
|
|
margin: "0 auto",
|
|
}}
|
|
>
|
|
<svg
|
|
width="200"
|
|
height="200"
|
|
viewBox="0 0 200 200"
|
|
style={{
|
|
transform: "rotate(-90deg)",
|
|
}}
|
|
>
|
|
{Array.from({ length: totalPeople }).map((_, index) => {
|
|
const anglePerSlice = 360 / totalPeople;
|
|
const startAngle = index * anglePerSlice;
|
|
const endAngle = (index + 1) * anglePerSlice;
|
|
const isSelected = index < payFor;
|
|
|
|
// Convert angles to radians
|
|
const startAngleRad = (startAngle * Math.PI) / 180;
|
|
const endAngleRad = (endAngle * Math.PI) / 180;
|
|
|
|
// Calculate path for pie slice (fit 200x200 viewBox)
|
|
const radius = 90;
|
|
const centerX = 100;
|
|
const centerY = 100;
|
|
|
|
const x1 = centerX + radius * Math.cos(startAngleRad);
|
|
const y1 = centerY + radius * Math.sin(startAngleRad);
|
|
const x2 = centerX + radius * Math.cos(endAngleRad);
|
|
const y2 = centerY + radius * Math.sin(endAngleRad);
|
|
|
|
const largeArcFlag = anglePerSlice > 180 ? 1 : 0;
|
|
|
|
const pathData = [
|
|
`M ${centerX} ${centerY}`,
|
|
`L ${x1} ${y1}`,
|
|
`A ${radius} ${radius} 0 ${largeArcFlag} 1 ${x2} ${y2}`,
|
|
"Z",
|
|
].join(" ");
|
|
|
|
return (
|
|
<path
|
|
key={index}
|
|
d={pathData}
|
|
fill={
|
|
isSelected ? "var(--primary)" : "rgba(0, 0, 0, 0.1)"
|
|
}
|
|
stroke="#fff"
|
|
strokeWidth="5"
|
|
/>
|
|
);
|
|
})}
|
|
</svg>
|
|
{/* Center circle with total bill amount */}
|
|
<div
|
|
style={{
|
|
position: "absolute",
|
|
top: "50%",
|
|
left: "50%",
|
|
transform: "translate(-50%, -50%)",
|
|
// Keep the SVG at 200x200, but make the center content smaller
|
|
// so the wheel remains visible around it.
|
|
width: 160,
|
|
height: 160,
|
|
borderRadius: "50%",
|
|
backgroundColor: "var(--secondary-background)",
|
|
display: "flex",
|
|
flexDirection: "column",
|
|
alignItems: "center",
|
|
justifyContent: "center",
|
|
zIndex: 10,
|
|
padding: 10,
|
|
}}
|
|
>
|
|
<div
|
|
style={{
|
|
fontSize: 20,
|
|
fontWeight: 600,
|
|
color: "var(--primary)",
|
|
lineHeight: 1.1,
|
|
textAlign: "center",
|
|
}}
|
|
>
|
|
<ArabicPrice
|
|
price={originalTotalBill}
|
|
style={{
|
|
fontSize: 20,
|
|
fontWeight: 600,
|
|
}}
|
|
/>
|
|
</div>
|
|
<ProText
|
|
style={{
|
|
fontSize: 11,
|
|
color: ProGray1,
|
|
marginTop: 6,
|
|
textAlign: "center",
|
|
lineHeight: 1.2,
|
|
fontWeight: 400,
|
|
}}
|
|
>
|
|
{t("splitBill.totalBill")}
|
|
</ProText>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
)}
|
|
|
|
<div
|
|
style={{
|
|
display: "flex",
|
|
flexDirection: "column",
|
|
gap: "1rem",
|
|
padding: 20,
|
|
}}
|
|
>
|
|
<div
|
|
style={{
|
|
display: "flex",
|
|
flexDirection: "row",
|
|
justifyContent: "space-between",
|
|
gap: "1rem",
|
|
padding: 8,
|
|
}}
|
|
>
|
|
<ProText
|
|
style={{
|
|
fontSize: "1rem",
|
|
marginTop: 3,
|
|
color: ProGray1,
|
|
}}
|
|
>
|
|
{t("checkout.totalPeople")}
|
|
</ProText>
|
|
|
|
<TotalPeopleActions />
|
|
|
|
<ProText
|
|
style={{
|
|
fontSize: "1rem",
|
|
marginTop: 3,
|
|
color: ProGray1,
|
|
}}
|
|
>
|
|
{t("checkout.totalPeople")}
|
|
</ProText>
|
|
</div>
|
|
|
|
<div
|
|
style={{
|
|
display: "flex",
|
|
flexDirection: "row",
|
|
justifyContent: "space-between",
|
|
gap: "1rem",
|
|
padding: 8,
|
|
}}
|
|
>
|
|
<ProText
|
|
style={{
|
|
fontSize: "1rem",
|
|
marginTop: 2,
|
|
color: ProGray1,
|
|
}}
|
|
>
|
|
{t("checkout.payFor")}
|
|
</ProText>
|
|
|
|
<PayForActions />
|
|
|
|
<ProText
|
|
style={{
|
|
fontSize: "1rem",
|
|
marginTop: 2,
|
|
color: ProGray1,
|
|
}}
|
|
>
|
|
{t("checkout.payFor")}
|
|
</ProText>
|
|
</div>
|
|
</div>
|
|
|
|
<div
|
|
style={{
|
|
display: "flex",
|
|
flexDirection: "column",
|
|
backgroundColor: "var(--background)",
|
|
padding: 20,
|
|
opacity: 1,
|
|
gap: 8,
|
|
borderTopLeftRadius: 24,
|
|
borderTopRightRadius: 24,
|
|
paddingTop: 12,
|
|
paddingRight: 24,
|
|
paddingBottom: 24,
|
|
paddingLeft: 24,
|
|
}}
|
|
>
|
|
<div className={styles.summaryRow}>
|
|
<ProText
|
|
style={{
|
|
fontWeight: 400,
|
|
fontStyle: "Regular",
|
|
fontSize: 14,
|
|
lineHeight: "140%",
|
|
letterSpacing: "0%",
|
|
}}
|
|
>
|
|
{t("splitBill.yourShare")}
|
|
</ProText>
|
|
<ArabicPrice price={splitAmount} />
|
|
</div>
|
|
</div>
|
|
|
|
<div
|
|
style={{
|
|
display: "flex",
|
|
gap: 12,
|
|
margin: 20,
|
|
}}
|
|
>
|
|
<Button
|
|
style={{
|
|
flex: 1,
|
|
backgroundColor: "#FEEDED",
|
|
color: "#DD4143",
|
|
boxShadow: "none",
|
|
border: "none",
|
|
height: 48,
|
|
}}
|
|
onClick={handleRemoveSplitWay}
|
|
>
|
|
{t("splitBill.cancelSplit")}
|
|
</Button>
|
|
<Button
|
|
type="primary"
|
|
style={{ flex: 1, boxShadow: "none", height: 48 }}
|
|
onClick={handleSave}
|
|
>
|
|
{t("cart.save")}
|
|
</Button>
|
|
</div>
|
|
</div>
|
|
</ProBottomSheet>
|
|
);
|
|
}
|