From 90e729cdcef8a287f46337f4efbf460fe7fb6d59 Mon Sep 17 00:00:00 2001 From: Mohammed Al-yaseen Date: Thu, 25 Dec 2025 00:35:44 +0300 Subject: [PATCH] implemt QRBottomSheet --- src/pages/pay/components/PayButton.tsx | 11 - .../CustomAmountChoiceBottomSheet.tsx | 248 ++++----- .../splitBill/EqualltyChoiceBottomSheet.tsx | 479 +++++++++--------- .../PayForYourItemsChoiceBottomSheet.tsx | 293 +++++------ 4 files changed, 517 insertions(+), 514 deletions(-) diff --git a/src/pages/pay/components/PayButton.tsx b/src/pages/pay/components/PayButton.tsx index 0370613..37a775e 100644 --- a/src/pages/pay/components/PayButton.tsx +++ b/src/pages/pay/components/PayButton.tsx @@ -10,7 +10,6 @@ import { CustomAmountChoiceBottomSheet } from "./splitBill/CustomAmountChoiceBot import { EqualltyChoiceBottomSheet } from "./splitBill/EqualltyChoiceBottomSheet"; import { PayForYourItemsChoiceBottomSheet } from "./splitBill/PayForYourItemsChoiceBottomSheet"; import { SplitBillChoiceBottomSheet } from "./splitBill/SplitBillChoiceBottomSheet"; -import { QRBottomSheet } from "./splitBill/QRBottomSheet"; type SplitWay = "customAmount" | "equality" | "payForItems" | null; @@ -27,7 +26,6 @@ export default function PayButton({ form }: { form: FormInstance }) { const [isCustomAmountOpen, setIsCustomAmountOpen] = useState(false); const [isEqualityOpen, setIsEqualityOpen] = useState(false); const [isPayForItemsOpen, setIsPayForItemsOpen] = useState(false); - const [isQROpen, setIsQROpen] = useState(false); const handleSplitBillClick = useCallback(() => { if (selectedSplitWay === "customAmount") { @@ -105,9 +103,6 @@ export default function PayButton({ form }: { form: FormInstance }) { setIsCustomAmountOpen(false); }} onRemoveSplitWay={handleRemoveSplitWay} - onSave={() => { - setIsQROpen(true); - }} /> { - setIsQROpen(true); - }} /> { setIsPayForItemsOpen(false); - setIsQROpen(true); }} onRemoveSplitWay={handleRemoveSplitWay} /> - - setIsQROpen(false)} /> ); } diff --git a/src/pages/pay/components/splitBill/CustomAmountChoiceBottomSheet.tsx b/src/pages/pay/components/splitBill/CustomAmountChoiceBottomSheet.tsx index 75f40d6..14fed93 100644 --- a/src/pages/pay/components/splitBill/CustomAmountChoiceBottomSheet.tsx +++ b/src/pages/pay/components/splitBill/CustomAmountChoiceBottomSheet.tsx @@ -12,11 +12,11 @@ import { useAppDispatch, useAppSelector } from "redux/hooks"; import ProText from "components/ProText"; import ArabicPrice from "components/ArabicPrice"; import styles from "./SplitBill.module.css"; +import { QRBottomSheet } from "./QRBottomSheet"; interface SplitBillChoiceBottomSheetProps { isOpen: boolean; onClose: () => void; - onSave?: (value: string) => void; onRemoveSplitWay?: () => void; } @@ -32,7 +32,7 @@ export function CustomAmountChoiceBottomSheet({ const [amount, setAmount] = useState( splitBillAmount > 0 ? splitBillAmount.toString() : "", ); - + const [isQROpen, setIsQROpen] = useState(false); useEffect(() => { if (isOpen && splitBillAmount > 0) { setAmount(splitBillAmount.toString()); @@ -42,6 +42,7 @@ export function CustomAmountChoiceBottomSheet({ const handleSave = () => { const numAmount = parseFloat(amount) || 0; dispatch(updateSplitBillAmount(numAmount)); + setIsQROpen(true); onClose(); }; @@ -61,135 +62,138 @@ export function CustomAmountChoiceBottomSheet({ const previewRemaining = originalTotalBill - currentAmount; return ( - -
+ -
- - {t("splitBill.howMuchWouldYouLikeToPay")} - - - { - setAmount(value?.toString() || ""); - dispatch(updateSplitBillAmount(Number(value) || 0)); +
+
+ - + > + {t("splitBill.howMuchWouldYouLikeToPay")} + + + { + setAmount(value?.toString() || ""); + dispatch(updateSplitBillAmount(Number(value) || 0)); + }} + placeholder={t("splitBill.amount")} + max={(grandTotal + splitBillAmount).toString()} + min={"0"} + style={{ width: "100%", fontSize: "1rem" }} + /> + +
-
-
-
- - {t("splitBill.totalBill")} - - +
+
+ + {t("splitBill.totalBill")} + + +
+
+ + {t("splitBill.remainingToPay")} + + +
-
- - {t("splitBill.remainingToPay")} - - -
-
-
- - -
- + + +
+
+ setIsQROpen(false)} /> + ); } diff --git a/src/pages/pay/components/splitBill/EqualltyChoiceBottomSheet.tsx b/src/pages/pay/components/splitBill/EqualltyChoiceBottomSheet.tsx index 3b59d4e..45ce118 100644 --- a/src/pages/pay/components/splitBill/EqualltyChoiceBottomSheet.tsx +++ b/src/pages/pay/components/splitBill/EqualltyChoiceBottomSheet.tsx @@ -1,6 +1,6 @@ import { Button } from "antd"; import { ProBottomSheet } from "components/ProBottomSheet/ProBottomSheet.tsx"; -import { useMemo } from "react"; +import { useMemo, useState } from "react"; import { useTranslation } from "react-i18next"; import ProText from "components/ProText"; @@ -15,6 +15,7 @@ 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; @@ -37,7 +38,7 @@ 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; @@ -55,6 +56,7 @@ export function EqualltyChoiceBottomSheet({ const handleSave = () => { dispatch(updateSplitBillAmount(splitAmount)); + setIsQROpen(true); onClose(); }; @@ -65,281 +67,284 @@ export function EqualltyChoiceBottomSheet({ }; return ( - -
+ - {/* Spinner Visualization - Blank Spin Wheel */} - {totalPeople > 0 && ( +
+ {/* Spinner Visualization - Blank Spin Wheel */} + {totalPeople > 0 && ( +
+
+ + {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 ( + + ); + })} + + {/* Center circle with total bill amount */} +
+
+ +
+ + {t("splitBill.totalBill")} + +
+
+
+ )} +
- - {Array.from({ length: totalPeople }).map((_, index) => { - const anglePerSlice = 360 / totalPeople; - const startAngle = index * anglePerSlice; - const endAngle = (index + 1) * anglePerSlice; - const isSelected = index < payFor; + {t("checkout.totalPeople")} + - // 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 ( - - ); - })} - - {/* Center circle with total bill amount */} -
-
- -
- - {t("splitBill.totalBill")} - -
+ {t("checkout.totalPeople")} + +
+ +
+ + {t("checkout.payFor")} + + + + + + {t("checkout.payFor")} +
- )} -
- - {t("checkout.totalPeople")} - - - - - - {t("checkout.totalPeople")} - +
+ + {t("splitBill.yourShare")} + + +
- - {t("checkout.payFor")} - - - - - +
- -
-
- - {t("splitBill.yourShare")} - - -
-
- -
- - -
-
-
+ + setIsQROpen(false)} /> + ); } diff --git a/src/pages/pay/components/splitBill/PayForYourItemsChoiceBottomSheet.tsx b/src/pages/pay/components/splitBill/PayForYourItemsChoiceBottomSheet.tsx index 3bc2f24..57fb0ca 100644 --- a/src/pages/pay/components/splitBill/PayForYourItemsChoiceBottomSheet.tsx +++ b/src/pages/pay/components/splitBill/PayForYourItemsChoiceBottomSheet.tsx @@ -8,6 +8,7 @@ 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; @@ -25,7 +26,7 @@ export function PayForYourItemsChoiceBottomSheet({ const dispatch = useAppDispatch(); const { items } = useAppSelector(selectCart); const [selectedItems, setSelectedItems] = useState>(new Set()); - + const [isQROpen, setIsQROpen] = useState(false); // Calculate total for selected items const selectedTotal = items .filter((item) => selectedItems.has(item.uniqueId || item.id.toString())) @@ -56,6 +57,7 @@ export function PayForYourItemsChoiceBottomSheet({ const handleSave = () => { dispatch(updateSplitBillAmount(selectedTotal)); + setIsQROpen(true); onClose(); }; @@ -67,159 +69,162 @@ export function PayForYourItemsChoiceBottomSheet({ }; return ( - -
- {items.length === 0 ? ( - - {t("cart.emptyCart")} - - ) : ( - items.map((item) => { - const itemId = item.uniqueId || item.id.toString(); - const isSelected = selectedItems.has(itemId); - const itemTotal = item.price * item.quantity; - - return ( - <> - handleItemToggle(itemId)} - > -
- {item.name} -
- - {item.name} - - -
-
e.stopPropagation()} - > - handleItemToggle(itemId)} - /> -
-
-
- {item !== items[items.length - 1] && ( - - )} - - ); - }) - )} -
-
+
- - {t("splitBill.selectedTotal")}: - - + {items.length === 0 ? ( + + {t("cart.emptyCart")} + + ) : ( + items.map((item) => { + const itemId = item.uniqueId || item.id.toString(); + const isSelected = selectedItems.has(itemId); + const itemTotal = item.price * item.quantity; + + return ( + <> + handleItemToggle(itemId)} + > +
+ {item.name} +
+ + {item.name} + + +
+
e.stopPropagation()} + > + handleItemToggle(itemId)} + /> +
+
+
+ {item !== items[items.length - 1] && ( + + )} + + ); + }) + )}
-
-
- -
+
+
- {t("cart.save")} - -
-
+ + +
+
+ setIsQROpen(false)} /> + ); }