add qr bottom sheet

This commit is contained in:
2025-12-25 00:35:32 +03:00
parent a98d1b7790
commit f35cf0bd3a
5 changed files with 212 additions and 5 deletions

View File

@@ -436,6 +436,12 @@
"howMuchWouldYouLikeToPay": "كم مبلغ تريد دفعه؟", "howMuchWouldYouLikeToPay": "كم مبلغ تريد دفعه؟",
"confirm": "تأكيد", "confirm": "تأكيد",
"totalBill": "الفاتورة الكلية", "totalBill": "الفاتورة الكلية",
"remainingToPay": "المبلغ المتبقي" "remainingToPay": "المبلغ المتبقي",
"scanQRCodeToPay": "مسح الكود الباري الى الدفع",
"copyQRCode": "نسخ الكود الباري",
"payWithQR": "دفع باستخدام الكود الباري",
"cancel": "إلغاء",
"done": "تم",
"inviteEveryonePayingWithYou": "دع الجميع يدفعوا معك"
} }
} }

View File

@@ -448,6 +448,12 @@
"howMuchWouldYouLikeToPay": "How much would you like to pay?", "howMuchWouldYouLikeToPay": "How much would you like to pay?",
"confirm": "Confirm", "confirm": "Confirm",
"totalBill": "Total Bill", "totalBill": "Total Bill",
"remainingToPay": "Remaining to Pay" "remainingToPay": "Remaining to Pay",
"scanQRCodeToPay": "Scan QR Code to Pay",
"copyQRCode": "Copy QR Code",
"payWithQR": "Pay with QR",
"cancel": "Cancel",
"done": "Done",
"inviteEveryonePayingWithYou": "Invite everyone paying with you"
} }
} }

View File

@@ -0,0 +1,55 @@
interface QRIconType {
className?: string;
onClick?: () => void;
}
const QRIcon = ({ className, onClick }: QRIconType) => {
return (
<svg
width="116"
height="116"
viewBox="0 0 116 116"
fill="none"
xmlns="http://www.w3.org/2000/svg"
className={className}
onClick={onClick}
>
<path
d="M4.8335 4.8335H53.1668V53.1668H4.8335V4.8335ZM14.5002 14.5002V43.5002H43.5002V14.5002H14.5002Z"
fill="black"
/>
<path
fillRule="evenodd"
clipRule="evenodd"
d="M24.1665 24.1665H33.8332V33.8332H24.1665V24.1665Z"
fill="black"
/>
<path
d="M62.8335 4.8335H111.167V53.1668H62.8335V4.8335ZM72.5002 14.5002V43.5002H101.5V14.5002H72.5002Z"
fill="black"
/>
<path
fillRule="evenodd"
clipRule="evenodd"
d="M82.1665 24.1665H91.8332V33.8332H82.1665V24.1665Z"
fill="black"
/>
<path
d="M4.8335 62.8335H53.1668V111.167H4.8335V62.8335ZM14.5002 72.5002V101.5H43.5002V72.5002H14.5002Z"
fill="black"
/>
<path
fillRule="evenodd"
clipRule="evenodd"
d="M24.1665 82.1665H33.8332V91.8332H24.1665V82.1665Z"
fill="black"
/>
<path
d="M111.167 91.8335H91.8335V111.167H62.8335V62.8335V91.8335H72.5002V101.5H82.1668V72.5002H72.5002V62.8335H67.6668H82.1668V72.5002H91.8335V82.1668H101.5V62.8335H111.167V91.8335ZM111.167 101.5V111.167H101.5V101.5H111.167Z"
fill="black"
/>
</svg>
);
};
export default QRIcon;

View File

@@ -10,6 +10,7 @@ import { CustomAmountChoiceBottomSheet } from "./splitBill/CustomAmountChoiceBot
import { EqualltyChoiceBottomSheet } from "./splitBill/EqualltyChoiceBottomSheet"; import { EqualltyChoiceBottomSheet } from "./splitBill/EqualltyChoiceBottomSheet";
import { PayForYourItemsChoiceBottomSheet } from "./splitBill/PayForYourItemsChoiceBottomSheet"; import { PayForYourItemsChoiceBottomSheet } from "./splitBill/PayForYourItemsChoiceBottomSheet";
import { SplitBillChoiceBottomSheet } from "./splitBill/SplitBillChoiceBottomSheet"; import { SplitBillChoiceBottomSheet } from "./splitBill/SplitBillChoiceBottomSheet";
import { QRBottomSheet } from "./splitBill/QRBottomSheet";
type SplitWay = "customAmount" | "equality" | "payForItems" | null; type SplitWay = "customAmount" | "equality" | "payForItems" | null;
@@ -26,6 +27,7 @@ export default function PayButton({ form }: { form: FormInstance }) {
const [isCustomAmountOpen, setIsCustomAmountOpen] = useState(false); const [isCustomAmountOpen, setIsCustomAmountOpen] = useState(false);
const [isEqualityOpen, setIsEqualityOpen] = useState(false); const [isEqualityOpen, setIsEqualityOpen] = useState(false);
const [isPayForItemsOpen, setIsPayForItemsOpen] = useState(false); const [isPayForItemsOpen, setIsPayForItemsOpen] = useState(false);
const [isQROpen, setIsQROpen] = useState(false);
const handleSplitBillClick = useCallback(() => { const handleSplitBillClick = useCallback(() => {
if (selectedSplitWay === "customAmount") { if (selectedSplitWay === "customAmount") {
@@ -99,21 +101,36 @@ export default function PayButton({ form }: { form: FormInstance }) {
<CustomAmountChoiceBottomSheet <CustomAmountChoiceBottomSheet
isOpen={isCustomAmountOpen} isOpen={isCustomAmountOpen}
onClose={() => setIsCustomAmountOpen(false)} onClose={() => {
setIsCustomAmountOpen(false);
}}
onRemoveSplitWay={handleRemoveSplitWay} onRemoveSplitWay={handleRemoveSplitWay}
onSave={() => {
setIsQROpen(true);
}}
/> />
<EqualltyChoiceBottomSheet <EqualltyChoiceBottomSheet
isOpen={isEqualityOpen} isOpen={isEqualityOpen}
onClose={() => setIsEqualityOpen(false)} onClose={() => {
setIsEqualityOpen(false);
}}
onRemoveSplitWay={handleRemoveSplitWay} onRemoveSplitWay={handleRemoveSplitWay}
onSave={() => {
setIsQROpen(true);
}}
/> />
<PayForYourItemsChoiceBottomSheet <PayForYourItemsChoiceBottomSheet
isOpen={isPayForItemsOpen} isOpen={isPayForItemsOpen}
onClose={() => setIsPayForItemsOpen(false)} onClose={() => {
setIsPayForItemsOpen(false);
setIsQROpen(true);
}}
onRemoveSplitWay={handleRemoveSplitWay} onRemoveSplitWay={handleRemoveSplitWay}
/> />
<QRBottomSheet isOpen={isQROpen} onClose={() => setIsQROpen(false)} />
</> </>
); );
} }

View File

@@ -0,0 +1,123 @@
import { Button } from "antd";
import { ProBottomSheet } from "components/ProBottomSheet/ProBottomSheet.tsx";
import { useState } from "react";
import { useTranslation } from "react-i18next";
import ProText from "components/ProText";
import QRIcon from "components/Icons/QRIcon";
interface QRBottomSheetProps {
isOpen: boolean;
onClose: () => void;
onSave?: (value: string) => void;
}
export function QRBottomSheet({
isOpen,
onClose,
}: QRBottomSheetProps) {
const { t } = useTranslation();
const [qrCode, setQRCode] = useState("");
const handleSave = () => {
onClose();
};
const handleCopyQRCode = () => {
navigator.clipboard.writeText(qrCode);
};
return (
<ProBottomSheet
isOpen={isOpen}
onClose={onClose}
title={t("splitBill.payWithQR")}
showCloseButton={true}
initialSnap={1}
height={430}
snapPoints={[430]}
contentStyle={{
padding: 0,
}}
>
<div
style={{
padding: "20px",
display: "flex",
flexDirection: "column",
gap: 20,
}}
>
<ProText
style={{
fontWeight: 400,
fontStyle: "Regular",
fontSize: 16,
lineHeight: "140%",
letterSpacing: "0%",
}}
>
{t("splitBill.inviteEveryonePayingWithYou")}
</ProText>
<div
style={{
display: "flex",
flexDirection: "column",
gap: 12,
alignItems: "center",
}}
>
<QRIcon />
<Button
style={{
width: 169,
height: 40,
borderRadius: 888,
gap: 16,
opacity: 1,
borderWidth: 1,
paddingTop: 8,
paddingRight: 32,
paddingBottom: 8,
paddingLeft: 32,
}}
onClick={handleCopyQRCode}
>
{t("splitBill.copyQRCode")}
</Button>
</div>
</div>
<div
style={{
display: "flex",
gap: 12,
margin: 20,
}}
>
<Button
style={{
flex: 1,
backgroundColor: "#FEEDED",
color: "#DD4143",
boxShadow: "none",
border: "none",
}}
onClick={onClose}
>
{t("splitBill.cancel")}
</Button>
<Button
type="primary"
style={{
flex: 1,
boxShadow: "none",
}}
onClick={handleSave}
>
{t("splitBill.done")}
</Button>
</div>
</ProBottomSheet>
);
}