split bill: reorder flow

This commit is contained in:
2025-12-26 00:25:26 +03:00
parent 86c12e2c53
commit b261f3508f
12 changed files with 656 additions and 551 deletions

View File

@@ -15,7 +15,6 @@ import { ProGray1 } from "ThemeConstants";
import PayForActions from "../../../split-bill/components/PayForActions";
import TotalPeopleActions from "../../../split-bill/components/TotalPeopleActions";
import styles from "./SplitBill.module.css";
import { QRBottomSheet } from "./QRBottomSheet";
interface SplitBillChoiceBottomSheetProps {
isOpen: boolean;
@@ -38,7 +37,6 @@ export function EqualltyChoiceBottomSheet({
const dispatch = useAppDispatch();
const { tmp, splitBillAmount } = useAppSelector(selectCart);
const grandTotal = useAppSelector(selectGrandTotal);
const [isQROpen, setIsQROpen] = useState(false);
const splitBillTmp = tmp as SplitBillTmp;
const totalPeople = splitBillTmp?.totalPeople || 2;
const payFor = splitBillTmp?.payFor || 1;
@@ -56,7 +54,6 @@ export function EqualltyChoiceBottomSheet({
const handleSave = () => {
dispatch(updateSplitBillAmount(splitAmount));
setIsQROpen(true);
onClose();
};
@@ -67,284 +64,281 @@ export function EqualltyChoiceBottomSheet({
};
return (
<>
<ProBottomSheet
isOpen={isOpen}
onClose={onClose}
title={t("splitBill.divideTheBillEqually")}
showCloseButton={true}
initialSnap={1}
height={630}
snapPoints={[630]}
contentStyle={{
padding: 0,
<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",
marginTop: 20,
gap: "1rem",
padding: 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",
flexDirection: "row",
justifyContent: "space-between",
gap: "1rem",
padding: 20,
padding: 8,
}}
>
<div
<ProText
style={{
display: "flex",
flexDirection: "row",
justifyContent: "space-between",
gap: "1rem",
padding: 8,
fontSize: "1rem",
marginTop: 3,
color: ProGray1,
}}
>
<ProText
style={{
fontSize: "1rem",
marginTop: 3,
color: ProGray1,
}}
>
{t("checkout.totalPeople")}
</ProText>
{t("checkout.totalPeople")}
</ProText>
<TotalPeopleActions />
<TotalPeopleActions />
<ProText
style={{
fontSize: "1rem",
marginTop: 3,
color: ProGray1,
}}
>
{t("checkout.totalPeople")}
</ProText>
</div>
<div
<ProText
style={{
display: "flex",
flexDirection: "row",
justifyContent: "space-between",
gap: "1rem",
padding: 8,
fontSize: "1rem",
marginTop: 3,
color: ProGray1,
}}
>
<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>
{t("checkout.totalPeople")}
</ProText>
</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,
flexDirection: "row",
justifyContent: "space-between",
gap: "1rem",
padding: 8,
}}
>
<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
<ProText
style={{
flex: 1,
backgroundColor: "#FEEDED",
color: "#DD4143",
boxShadow: "none",
border: "none",
fontSize: "1rem",
marginTop: 2,
color: ProGray1,
}}
onClick={handleRemoveSplitWay}
>
{t("splitBill.removeSplit")}
</Button>
<Button
type="primary"
style={{ flex: 1, boxShadow: "none" }}
onClick={handleSave}
{t("checkout.payFor")}
</ProText>
<PayForActions />
<ProText
style={{
fontSize: "1rem",
marginTop: 2,
color: ProGray1,
}}
>
{t("cart.save")}
</Button>
{t("checkout.payFor")}
</ProText>
</div>
</div>
</ProBottomSheet>
<QRBottomSheet isOpen={isQROpen} onClose={() => setIsQROpen(false)} />
</>
<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",
}}
onClick={handleRemoveSplitWay}
>
{t("splitBill.removeSplit")}
</Button>
<Button
type="primary"
style={{ flex: 1, boxShadow: "none" }}
onClick={handleSave}
>
{t("cart.save")}
</Button>
</div>
</div>
</ProBottomSheet>
);
}