Compare commits
4 Commits
c84168cec5
...
ce9092d634
| Author | SHA1 | Date | |
|---|---|---|---|
| ce9092d634 | |||
| 90e729cdce | |||
| f35cf0bd3a | |||
| a98d1b7790 |
@@ -166,6 +166,7 @@
|
||||
"customizable": "قابل للتخصيص"
|
||||
},
|
||||
"cart": {
|
||||
"leaveANoteHere": "أي تعليمات خاصة لطلبك..",
|
||||
"title": "السلة",
|
||||
"emptyCart": "سلة المشتريات فارغة",
|
||||
"emptyCartMessage": "يبدو أنك لم تضيف أي عناصر إلى سلة المشتريات بعد. ابدأ في استكشاف قائمتنا للعثور على وجبات لذيذة!",
|
||||
@@ -263,6 +264,8 @@
|
||||
"checkRequiredFields": "يرجى التحقق من الحقول المطلوبة"
|
||||
},
|
||||
"checkout": {
|
||||
"customerName": "اسم العميل",
|
||||
"customerInformation": "تفاصيل العميل",
|
||||
"title": "الدفع",
|
||||
"cash": "كاش",
|
||||
"creditDebitCard": "بطاقة ائتمان/ائتمان",
|
||||
@@ -436,6 +439,12 @@
|
||||
"howMuchWouldYouLikeToPay": "كم مبلغ تريد دفعه؟",
|
||||
"confirm": "تأكيد",
|
||||
"totalBill": "الفاتورة الكلية",
|
||||
"remainingToPay": "المبلغ المتبقي"
|
||||
"remainingToPay": "المبلغ المتبقي",
|
||||
"scanQRCodeToPay": "مسح الكود الباري الى الدفع",
|
||||
"copyQRCode": "نسخ الكود الباري",
|
||||
"payWithQR": "دفع باستخدام الكود الباري",
|
||||
"cancel": "إلغاء",
|
||||
"done": "تم",
|
||||
"inviteEveryonePayingWithYou": "دع الجميع يدفعوا معك"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -178,6 +178,7 @@
|
||||
"customizable": "Customizable"
|
||||
},
|
||||
"cart": {
|
||||
"leaveANoteHere": "Leave a note here..",
|
||||
"title": "Cart",
|
||||
"emptyCart": "Cart is empty",
|
||||
"emptyCartMessage": "Looks like you haven't added any items to your cart yet. Start exploring our menu to find delicious meals!",
|
||||
@@ -273,6 +274,8 @@
|
||||
"checkRequiredFields": "Please check required fields"
|
||||
},
|
||||
"checkout": {
|
||||
"customerName": "Customer Name",
|
||||
"customerInformation": "Customer Information",
|
||||
"title": "Checkout",
|
||||
"cash": "Cash",
|
||||
"creditDebitCard": "Credit/Debit Card",
|
||||
@@ -448,6 +451,12 @@
|
||||
"howMuchWouldYouLikeToPay": "How much would you like to pay?",
|
||||
"confirm": "Confirm",
|
||||
"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"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,7 +104,7 @@ export default function CartActionsButtons({ item }: { item: CartItem }) {
|
||||
)}
|
||||
<InputNumber
|
||||
min={1}
|
||||
max={100}
|
||||
max={99}
|
||||
value={item.quantity || 1}
|
||||
onChange={(value: number | null) =>
|
||||
dispatch(
|
||||
|
||||
@@ -42,7 +42,7 @@ export function TipBottomSheet({
|
||||
showCloseButton={false}
|
||||
initialSnap={1}
|
||||
height={370}
|
||||
snapPoints={["30vh"]}
|
||||
snapPoints={[370]}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
@@ -52,7 +52,9 @@ export function TipBottomSheet({
|
||||
justifyContent: "center",
|
||||
}}
|
||||
>
|
||||
<WaiterRewardingIcon />
|
||||
<div style={{ marginTop: 20 }}>
|
||||
<WaiterRewardingIcon />
|
||||
</div>
|
||||
|
||||
<br />
|
||||
|
||||
|
||||
@@ -1,22 +1,26 @@
|
||||
interface DeleteIconType {
|
||||
className?: string;
|
||||
onClick?: () => void;
|
||||
color?: string;
|
||||
dimension?: number;
|
||||
}
|
||||
|
||||
const DeleteIcon = ({ className, onClick }: DeleteIconType) => {
|
||||
const DeleteIcon = ({ className, onClick, color, dimension }: DeleteIconType) => {
|
||||
return (
|
||||
<svg
|
||||
width="12"
|
||||
height="12"
|
||||
viewBox="0 0 12 12"
|
||||
width={dimension || "14"}
|
||||
height={dimension || "14"}
|
||||
viewBox="0 0 14 14"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
className={className}
|
||||
onClick={onClick}
|
||||
>
|
||||
<path
|
||||
d="M3 2.4V0.6C3 0.44087 3.06321 0.288258 3.17574 0.175736C3.28826 0.0632141 3.44087 0 3.6 0H8.4C8.55913 0 8.71174 0.0632141 8.82426 0.175736C8.93679 0.288258 9 0.44087 9 0.6V2.4H12V3.6H10.8V11.4C10.8 11.5591 10.7368 11.7117 10.6243 11.8243C10.5117 11.9368 10.3591 12 10.2 12H1.8C1.64087 12 1.48826 11.9368 1.37574 11.8243C1.26321 11.7117 1.2 11.5591 1.2 11.4V3.6H0V2.4H3ZM6.8484 7.2L7.9092 6.1392L7.0608 5.2908L6 6.3516L4.9392 5.2908L4.0908 6.1392L5.1516 7.2L4.0908 8.2608L4.9392 9.1092L6 8.0484L7.0608 9.1092L7.9092 8.2608L6.8484 7.2ZM4.2 1.2V2.4H7.8V1.2H4.2Z"
|
||||
fill="#DC2626"
|
||||
d="M11.375 3.20866L11.0133 9.05658C10.9212 10.5505 10.8751 11.2977 10.5 11.835C10.3148 12.1005 10.0764 12.3246 9.8 12.493C9.24175 12.8337 8.49333 12.8337 6.9965 12.8337C5.49733 12.8337 4.74775 12.8337 4.18833 12.4924C3.91177 12.3237 3.67337 12.0992 3.48833 11.8332C3.11383 11.2954 3.06833 10.547 2.9785 9.05074L2.625 3.20866M1.75 3.20866H12.25M9.366 3.20866L8.96758 2.38733C8.70333 1.84133 8.57092 1.56891 8.34283 1.39858C8.29217 1.36084 8.23852 1.32729 8.18242 1.29824C7.92983 1.16699 7.6265 1.16699 7.02042 1.16699C6.39858 1.16699 6.08767 1.16699 5.83042 1.30349C5.77355 1.33395 5.71931 1.36907 5.66825 1.40849C5.43783 1.58524 5.30892 1.86816 5.05108 2.43341L4.69758 3.20866M5.54167 9.62533V6.12533M8.45833 9.62533V6.12533"
|
||||
stroke={color || "#DD4143"}
|
||||
strokeWidth="1.5"
|
||||
strokeLinecap="round"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
interface PlusIconType {
|
||||
className?: string;
|
||||
onClick?: () => void;
|
||||
dimesion?: string
|
||||
}
|
||||
|
||||
const PlusIcon = ({ className, onClick }: PlusIconType) => {
|
||||
const PlusIcon = ({ className, onClick, dimesion }: PlusIconType) => {
|
||||
return (
|
||||
<svg
|
||||
width="16"
|
||||
height="16"
|
||||
width={dimesion || "16"}
|
||||
height={dimesion || "16"}
|
||||
viewBox="0 0 16 16"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
|
||||
55
src/components/Icons/QRIcon.tsx
Normal file
55
src/components/Icons/QRIcon.tsx
Normal 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;
|
||||
@@ -32,7 +32,7 @@ export default function InputCard({
|
||||
placeholder={placeholder}
|
||||
size="large"
|
||||
autoFocus={false}
|
||||
style={{ padding: "7px 11px", height: 50, borderRadius: 888 }}
|
||||
style={{ padding: "7px 11px", height: 48, borderRadius: 888 }}
|
||||
value={value}
|
||||
onChange={handleChange}
|
||||
/>
|
||||
|
||||
@@ -88,7 +88,7 @@ const PaymentMethods = () => {
|
||||
}}
|
||||
size="large"
|
||||
>
|
||||
<Space orientation="vertical" style={{ width: "100%" }}>
|
||||
<Space orientation="vertical" style={{ width: "100%", gap: 16 }}>
|
||||
{options.map((option) => (
|
||||
<div key={option.value}>
|
||||
<Radio
|
||||
@@ -96,7 +96,7 @@ const PaymentMethods = () => {
|
||||
value={option.value}
|
||||
onClick={() => onPaymentSelect(option.value)}
|
||||
style={{
|
||||
height: 50,
|
||||
height: 48,
|
||||
borderRadius: 888,
|
||||
border: "1px solid #DDD",
|
||||
padding: 16,
|
||||
|
||||
@@ -86,7 +86,7 @@ export const PhoneInputWrapper = ({
|
||||
const inputStyle = useMemo(
|
||||
() => ({
|
||||
borderRadius: 1000,
|
||||
height: 50,
|
||||
height: 48,
|
||||
width: "100%",
|
||||
color: themeName === "light" ? "#000" : "#FFF",
|
||||
backgroundColor: themeName === "light" ? "#FFF" : ProBlack1,
|
||||
|
||||
@@ -37,9 +37,15 @@ const ProRatioGroups = ({
|
||||
onChange={handleChange}
|
||||
{...props}
|
||||
>
|
||||
<Space direction="vertical" style={{ width: "100%" }}>
|
||||
<Space orientation="vertical" style={{ width: "100%" }}>
|
||||
{options.map((option) => (
|
||||
<Radio key={option.value} value={option.value}>
|
||||
<Radio
|
||||
key={option.value}
|
||||
value={option.value}
|
||||
// style={{
|
||||
// height: 48,
|
||||
// }}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
|
||||
@@ -70,6 +70,7 @@ interface CartState {
|
||||
pickupType: string;
|
||||
order: any;
|
||||
splitBillAmount: number;
|
||||
customerName: string;
|
||||
}
|
||||
|
||||
// localStorage keys
|
||||
@@ -187,6 +188,7 @@ const initialState: CartState = {
|
||||
pickupType: getFromLocalStorage(CART_STORAGE_KEYS.PICKUP_TYPE, ""),
|
||||
order: getFromLocalStorage(CART_STORAGE_KEYS.ORDER, null),
|
||||
splitBillAmount: 0,
|
||||
customerName: "",
|
||||
};
|
||||
|
||||
const orderSlice = createSlice({
|
||||
@@ -637,6 +639,9 @@ const orderSlice = createSlice({
|
||||
updateSplitBillAmount(state, action: PayloadAction<number>) {
|
||||
state.splitBillAmount = action.payload;
|
||||
},
|
||||
updateCustomerName(state, action: PayloadAction<string>) {
|
||||
state.customerName = action.payload;
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
@@ -675,6 +680,7 @@ export const {
|
||||
updatePickUpType,
|
||||
updateOrder,
|
||||
updateSplitBillAmount,
|
||||
updateCustomerName,
|
||||
} = orderSlice.actions;
|
||||
|
||||
// Tax calculation helper functions
|
||||
|
||||
@@ -605,3 +605,8 @@
|
||||
outline: 2px solid #ffffff;
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
.deleteIcon {
|
||||
position: relative;
|
||||
top: 1px;
|
||||
}
|
||||
@@ -24,7 +24,7 @@ export default function CarPlateCard() {
|
||||
placeholder={t("cart.plateNumber")}
|
||||
size="large"
|
||||
autoFocus={false}
|
||||
style={{ padding: "7px 11px", height: 50, borderRadius: 888 }}
|
||||
style={{ padding: "7px 11px", height: 48, borderRadius: 888 }}
|
||||
value={plateCar}
|
||||
onChange={(e) => {
|
||||
dispatch(updatePlateCar(e.target.value));
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { PlusOutlined } from "@ant-design/icons";
|
||||
import { Card, Divider, Space, Layout } from "antd";
|
||||
import { Card, Divider, Space, Layout, Button } from "antd";
|
||||
import ArabicPrice from "components/ArabicPrice";
|
||||
import CartActionsButtons from "components/CartActionsButtons/CartActionsButtons.tsx";
|
||||
import ImageWithFallback from "components/ImageWithFallback";
|
||||
@@ -9,8 +8,7 @@ import ProTitle from "components/ProTitle.tsx";
|
||||
import { selectCart } from "features/order/orderSlice.ts";
|
||||
import styles from "pages/cart/cart.module.css";
|
||||
import YouMightAlsoLike from "pages/cart/components/youMayLike/YouMightAlsoLike.tsx";
|
||||
import { Link, useParams } from "react-router-dom";
|
||||
import { colors } from "ThemeConstants.ts";
|
||||
import { Link, useNavigate, useParams } from "react-router-dom";
|
||||
|
||||
import { useAppSelector } from "redux/hooks.ts";
|
||||
|
||||
@@ -18,13 +16,14 @@ import { FormInstance } from "antd";
|
||||
import useBreakPoint from "hooks/useBreakPoint.ts";
|
||||
import CarPlateCard from "pages/cart/components/CarPlateCard.tsx";
|
||||
import CartFooter from "pages/cart/components/cartFooter/CartFooter.tsx";
|
||||
import CouponCard from "pages/cart/components/CouponCard.tsx";
|
||||
import SpecialRequestCard from "pages/cart/components/specialRequest/SpecialRequestCard.tsx";
|
||||
import TableNumberCard from "pages/cart/components/TableNumberCard.tsx";
|
||||
import TimeEstimateCard from "pages/cart/components/timeEstimate/TimeEstimateCard.tsx";
|
||||
import { OrderType } from "pages/checkout/hooks/types";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Variant } from "utils/types/appTypes";
|
||||
import DeleteIcon from "components/Icons/DeleteIcon";
|
||||
import PlusIcon from "components/Icons/PlusIcon";
|
||||
|
||||
interface CartMobileTabletLayoutProps {
|
||||
form: FormInstance;
|
||||
@@ -39,8 +38,8 @@ export default function CartMobileTabletLayout({
|
||||
const { subdomain } = useParams();
|
||||
const { pickup_type } = useAppSelector((state) => state.order.restaurant);
|
||||
const { isMobile, isTablet } = useBreakPoint();
|
||||
|
||||
const getResponsiveClass = () => (isTablet ? "tablet" : "mobile");
|
||||
const navigate = useNavigate();
|
||||
|
||||
const getMenuItemImageStyle = () => {
|
||||
if (isMobile) {
|
||||
@@ -82,11 +81,21 @@ export default function CartMobileTabletLayout({
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
marginTop: 10,
|
||||
marginTop: 3,
|
||||
boxSizing: "border-box", // Explicit box model definition
|
||||
}}
|
||||
>
|
||||
<ProTitle level={5} style={{ whiteSpace: "nowrap" }}>
|
||||
<ProTitle
|
||||
level={5}
|
||||
style={{
|
||||
whiteSpace: "nowrap",
|
||||
fontWeight: 500,
|
||||
fontStyle: "Medium",
|
||||
fontSize: 18,
|
||||
lineHeight: "140%",
|
||||
letterSpacing: 0,
|
||||
}}
|
||||
>
|
||||
{t("cart.yourOrder")}
|
||||
</ProTitle>
|
||||
</div>
|
||||
@@ -100,25 +109,29 @@ export default function CartMobileTabletLayout({
|
||||
textAlign: "end",
|
||||
}}
|
||||
>
|
||||
<div
|
||||
<Button
|
||||
shape="circle"
|
||||
iconPlacement="start"
|
||||
icon={
|
||||
<DeleteIcon
|
||||
className={styles.deleteIcon}
|
||||
color={"#C0BFC4"}
|
||||
dimension={16}
|
||||
/>
|
||||
}
|
||||
size="small"
|
||||
className={styles.addButton}
|
||||
style={{
|
||||
color: colors.primary,
|
||||
width: 32,
|
||||
height: 32,
|
||||
border: "1px solid #DEDEE0",
|
||||
}}
|
||||
>
|
||||
<PlusOutlined
|
||||
style={{
|
||||
color: colors.primary,
|
||||
marginLeft: 5,
|
||||
marginTop: 15,
|
||||
}}
|
||||
/>
|
||||
{t("cart.addMore")}
|
||||
</div>
|
||||
/>
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
{items.length >= 1 && (
|
||||
<Divider style={{ margin: "0px 0px 10px 0px" }} />
|
||||
<Divider style={{ margin: "8px 0px 12px 0px" }} />
|
||||
)}
|
||||
{items.map((item, index) => (
|
||||
<div key={index} style={{ position: "relative" }}>
|
||||
@@ -178,10 +191,10 @@ export default function CartMobileTabletLayout({
|
||||
overflowWrap: "break-word",
|
||||
lineHeight: "1.4",
|
||||
maxHeight: isMobile
|
||||
? "2.8em"
|
||||
? "3em"
|
||||
: isTablet
|
||||
? "4.8em"
|
||||
: "6.8em",
|
||||
? "5em"
|
||||
: "7em",
|
||||
fontWeight: 500,
|
||||
letterSpacing: "0.01em",
|
||||
width: "55%",
|
||||
@@ -230,6 +243,16 @@ export default function CartMobileTabletLayout({
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
<Button
|
||||
style={{ width: "100%", marginTop: 24, color: "#4C4A58" }}
|
||||
onClick={() => {
|
||||
navigate(`/${subdomain}/menu?${
|
||||
orderType ? `orderType=${orderType}` : ""
|
||||
}`);
|
||||
}}
|
||||
>
|
||||
<PlusIcon dimesion="18" /> {t("cart.addMore")}
|
||||
</Button>
|
||||
</Card>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -83,7 +83,7 @@ export default function CouponCard() {
|
||||
placeholder={t("cart.couponCode")}
|
||||
size="large"
|
||||
autoFocus={false}
|
||||
style={{ padding: "7px 11px", height: 50 }}
|
||||
style={{ padding: "7px 11px", height: 48 }}
|
||||
onChange={(e) => {
|
||||
dispatch(updateCoupon(e.target.value));
|
||||
}}
|
||||
|
||||
@@ -1,5 +1,12 @@
|
||||
.inputField {
|
||||
height: 50px;
|
||||
border-radius: 8px !important;
|
||||
justify-content: space-between;
|
||||
padding-top: 12px;
|
||||
padding-right: 16px;
|
||||
padding-bottom: 12px;
|
||||
padding-left: 16px;
|
||||
opacity: 1;
|
||||
border-width: 1px;
|
||||
}
|
||||
|
||||
.editButton {
|
||||
|
||||
@@ -9,13 +9,13 @@ import { useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useAppDispatch, useAppSelector } from "redux/hooks.ts";
|
||||
import styles from "./SpecialRequestCard.module.css";
|
||||
import TextArea from "antd/es/input/TextArea";
|
||||
|
||||
export default function SpecialRequestCard() {
|
||||
const { t } = useTranslation();
|
||||
const { isDesktop } = useBreakPoint();
|
||||
const dispatch = useAppDispatch();
|
||||
const { specialRequest } = useAppSelector(selectCart);
|
||||
const { isRTL } = useAppSelector((state) => state.locale);
|
||||
const [isSpecialRequestOpen, setIsSpecialRequestOpen] = useState(false);
|
||||
|
||||
const handleSpecialRequestSave = (value: string) => {
|
||||
@@ -32,12 +32,8 @@ export default function SpecialRequestCard() {
|
||||
title={t("cart.specialRequest")}
|
||||
dividerStyle={{ margin: "5px 0 0 0" }}
|
||||
>
|
||||
<Form.Item
|
||||
label={t("cart.specialRequest")}
|
||||
name="specialRequest"
|
||||
style={{ position: "relative", top: -5 }}
|
||||
>
|
||||
<Input
|
||||
<Form.Item name="specialRequest" style={{ marginTop: 12 }}>
|
||||
{/* <Input
|
||||
placeholder={t("cart.specialRequest")}
|
||||
size="large"
|
||||
autoFocus={false}
|
||||
@@ -51,6 +47,13 @@ export default function SpecialRequestCard() {
|
||||
<u>{t("cart.editNote")}</u> {isRTL ? <LeftOutlined /> : <RightOutlined />}
|
||||
</div>
|
||||
}
|
||||
/> */}
|
||||
<TextArea
|
||||
placeholder={t("cart.leaveANoteHere")}
|
||||
rows={2}
|
||||
autoFocus={false}
|
||||
className={styles.inputField}
|
||||
onChange={(e) => handleSpecialRequestSave(e.target.value)}
|
||||
/>
|
||||
</Form.Item>
|
||||
</ProInputCard>
|
||||
|
||||
@@ -22,8 +22,8 @@ export function BottomSheet({
|
||||
title={t("cart.selectTimeEstimate")}
|
||||
showCloseButton={true}
|
||||
initialSnap={1}
|
||||
height={555}
|
||||
snapPoints={["65vh"]}
|
||||
height={495}
|
||||
snapPoints={[495]}
|
||||
>
|
||||
<Content onSave={onSave} onClose={onClose} />
|
||||
</ProBottomSheet>
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
.customerInformationCard {
|
||||
height: 215px !important;
|
||||
}
|
||||
44
src/pages/checkout/components/CustomerInformationCard.tsx
Normal file
44
src/pages/checkout/components/CustomerInformationCard.tsx
Normal file
@@ -0,0 +1,44 @@
|
||||
import ProInputCard from "components/ProInputCard/ProInputCard.tsx";
|
||||
import ProPhoneInput from "components/ProPhoneInput";
|
||||
import { selectCart, updateCustomerName } from "features/order/orderSlice";
|
||||
import { OrderType } from "pages/checkout/hooks/types.ts";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useAppDispatch, useAppSelector } from "redux/hooks";
|
||||
import { Form, Input } from "antd";
|
||||
import styles from "./CustomerInformationCard.module.css";
|
||||
|
||||
export default function CustomerInformationCard() {
|
||||
const { t } = useTranslation();
|
||||
const { orderType } = useAppSelector(selectCart);
|
||||
const dispatch = useAppDispatch();
|
||||
const customerName = useAppSelector((state) => state.order.customerName);
|
||||
|
||||
return (
|
||||
orderType !== OrderType.Gift && (
|
||||
<>
|
||||
<ProInputCard
|
||||
title={t("checkout.customerInformation")}
|
||||
className={styles.customerInformationCard}
|
||||
>
|
||||
<div style={{ position: "relative", top: -25 }}>
|
||||
<Form.Item label={t("checkout.customerName")} name="customerName">
|
||||
<Input
|
||||
placeholder={t("checkout.customerName")}
|
||||
size="large"
|
||||
autoFocus={false}
|
||||
style={{ padding: "7px 11px", height: 48, borderRadius: 888 }}
|
||||
value={customerName}
|
||||
onChange={(e) => {
|
||||
dispatch(updateCustomerName(e.target.value));
|
||||
}}
|
||||
/>
|
||||
</Form.Item>
|
||||
</div>
|
||||
<div style={{ position: "relative", top: -30 }}>
|
||||
<ProPhoneInput label={t("login.phone")} propName="phone" />
|
||||
</div>
|
||||
</ProInputCard>
|
||||
</>
|
||||
)
|
||||
);
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
.phoneCard {
|
||||
height: 150px !important;
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
import ProInputCard from "components/ProInputCard/ProInputCard.tsx";
|
||||
import ProPhoneInput from "components/ProPhoneInput";
|
||||
import { selectCart } from "features/order/orderSlice";
|
||||
import { OrderType } from "pages/checkout/hooks/types.ts";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useAppSelector } from "redux/hooks";
|
||||
import styles from "./PhoneCard.module.css";
|
||||
|
||||
export default function PhoneCard() {
|
||||
const { t } = useTranslation();
|
||||
const { orderType } = useAppSelector(selectCart);
|
||||
|
||||
return (
|
||||
orderType !== OrderType.Gift && (
|
||||
<>
|
||||
<ProInputCard
|
||||
title={t("checkout.phoneNumber")}
|
||||
className={styles.phoneCard}
|
||||
>
|
||||
<div style={{ position: "relative", top: -20 }}>
|
||||
<ProPhoneInput label={t("login.phone")} propName="phone" />
|
||||
</div>
|
||||
</ProInputCard>
|
||||
</>
|
||||
)
|
||||
);
|
||||
}
|
||||
@@ -15,8 +15,8 @@ import RewardWaiterCard from "pages/cart/components/RewardWaiterCard";
|
||||
import ProInputCard from "components/ProInputCard/ProInputCard";
|
||||
import ProRatioGroups from "components/ProRatioGroups/ProRatioGroups";
|
||||
import CouponCard from "pages/cart/components/CouponCard";
|
||||
import PhoneCard from "./components/PhoneCard";
|
||||
import BriefMenuCard from "./components/BriefMenuCard";
|
||||
import CustomerInformationCard from "./components/CustomerInformationCard";
|
||||
|
||||
export default function CheckoutPage() {
|
||||
const { t } = useTranslation();
|
||||
@@ -37,7 +37,7 @@ export default function CheckoutPage() {
|
||||
<ProHeader>{t("checkout.title")}</ProHeader>
|
||||
<Layout.Content className={styles.checkoutContainer}>
|
||||
<PaymentMethods />
|
||||
{!token && <PhoneCard />}
|
||||
{!token && <CustomerInformationCard />}
|
||||
<AddressSummary />
|
||||
{orderType === OrderType.ToRoom && (
|
||||
<InputCard
|
||||
|
||||
@@ -99,19 +99,25 @@ export default function PayButton({ form }: { form: FormInstance }) {
|
||||
|
||||
<CustomAmountChoiceBottomSheet
|
||||
isOpen={isCustomAmountOpen}
|
||||
onClose={() => setIsCustomAmountOpen(false)}
|
||||
onClose={() => {
|
||||
setIsCustomAmountOpen(false);
|
||||
}}
|
||||
onRemoveSplitWay={handleRemoveSplitWay}
|
||||
/>
|
||||
|
||||
<EqualltyChoiceBottomSheet
|
||||
isOpen={isEqualityOpen}
|
||||
onClose={() => setIsEqualityOpen(false)}
|
||||
onClose={() => {
|
||||
setIsEqualityOpen(false);
|
||||
}}
|
||||
onRemoveSplitWay={handleRemoveSplitWay}
|
||||
/>
|
||||
|
||||
<PayForYourItemsChoiceBottomSheet
|
||||
isOpen={isPayForItemsOpen}
|
||||
onClose={() => setIsPayForItemsOpen(false)}
|
||||
onClose={() => {
|
||||
setIsPayForItemsOpen(false);
|
||||
}}
|
||||
onRemoveSplitWay={handleRemoveSplitWay}
|
||||
/>
|
||||
</>
|
||||
|
||||
@@ -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<string>(
|
||||
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 (
|
||||
<ProBottomSheet
|
||||
isOpen={isOpen}
|
||||
onClose={onClose}
|
||||
title={t("splitBill.payAsCustomAmount")}
|
||||
showCloseButton={true}
|
||||
initialSnap={1}
|
||||
height={430}
|
||||
snapPoints={[430]}
|
||||
contentStyle={{
|
||||
padding: 0,
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
padding: "20px",
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
gap: 20,
|
||||
<>
|
||||
<ProBottomSheet
|
||||
isOpen={isOpen}
|
||||
onClose={onClose}
|
||||
title={t("splitBill.payAsCustomAmount")}
|
||||
showCloseButton={true}
|
||||
initialSnap={1}
|
||||
height={430}
|
||||
snapPoints={[430]}
|
||||
contentStyle={{
|
||||
padding: 0,
|
||||
}}
|
||||
>
|
||||
<div>
|
||||
<ProText
|
||||
style={{
|
||||
fontWeight: 400,
|
||||
fontStyle: "Regular",
|
||||
fontSize: 16,
|
||||
lineHeight: "140%",
|
||||
letterSpacing: "0%",
|
||||
}}
|
||||
>
|
||||
{t("splitBill.howMuchWouldYouLikeToPay")}
|
||||
</ProText>
|
||||
<Form.Item
|
||||
label={t("splitBill.amount")}
|
||||
name="amount"
|
||||
style={{ position: "relative", top: -5 }}
|
||||
>
|
||||
<InputNumber
|
||||
value={amount}
|
||||
onChange={(value) => {
|
||||
setAmount(value?.toString() || "");
|
||||
dispatch(updateSplitBillAmount(Number(value) || 0));
|
||||
<div
|
||||
style={{
|
||||
padding: "20px",
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
gap: 20,
|
||||
}}
|
||||
>
|
||||
<div>
|
||||
<ProText
|
||||
style={{
|
||||
fontWeight: 400,
|
||||
fontStyle: "Regular",
|
||||
fontSize: 16,
|
||||
lineHeight: "140%",
|
||||
letterSpacing: "0%",
|
||||
}}
|
||||
placeholder={t("splitBill.amount")}
|
||||
max={(grandTotal + splitBillAmount).toString()}
|
||||
min={"0"}
|
||||
style={{ width: "100%", fontSize: "1rem" }}
|
||||
/>
|
||||
</Form.Item>
|
||||
>
|
||||
{t("splitBill.howMuchWouldYouLikeToPay")}
|
||||
</ProText>
|
||||
<Form.Item
|
||||
label={t("splitBill.amount")}
|
||||
name="amount"
|
||||
style={{ position: "relative", top: -5 }}
|
||||
>
|
||||
<InputNumber
|
||||
value={amount}
|
||||
onChange={(value) => {
|
||||
setAmount(value?.toString() || "");
|
||||
dispatch(updateSplitBillAmount(Number(value) || 0));
|
||||
}}
|
||||
placeholder={t("splitBill.amount")}
|
||||
max={(grandTotal + splitBillAmount).toString()}
|
||||
min={"0"}
|
||||
style={{ width: "100%", fontSize: "1rem" }}
|
||||
/>
|
||||
</Form.Item>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
backgroundColor: "var(--background)",
|
||||
padding: "20px",
|
||||
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.totalBill")}
|
||||
</ProText>
|
||||
<ArabicPrice price={previewTotalBill} />
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
backgroundColor: "var(--background)",
|
||||
padding: "20px",
|
||||
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.totalBill")}
|
||||
</ProText>
|
||||
<ArabicPrice price={previewTotalBill} />
|
||||
</div>
|
||||
<div className={styles.summaryRow}>
|
||||
<ProText
|
||||
style={{
|
||||
fontWeight: 400,
|
||||
fontStyle: "Regular",
|
||||
fontSize: 14,
|
||||
lineHeight: "140%",
|
||||
letterSpacing: "0%",
|
||||
}}
|
||||
>
|
||||
{t("splitBill.remainingToPay")}
|
||||
</ProText>
|
||||
<ArabicPrice price={Math.max(0, previewRemaining)} />
|
||||
</div>
|
||||
</div>
|
||||
<div className={styles.summaryRow}>
|
||||
<ProText
|
||||
style={{
|
||||
fontWeight: 400,
|
||||
fontStyle: "Regular",
|
||||
fontSize: 14,
|
||||
lineHeight: "140%",
|
||||
letterSpacing: "0%",
|
||||
}}
|
||||
>
|
||||
{t("splitBill.remainingToPay")}
|
||||
</ProText>
|
||||
<ArabicPrice price={Math.max(0, previewRemaining)} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
gap: 12,
|
||||
margin: 20,
|
||||
}}
|
||||
>
|
||||
<Button
|
||||
<div
|
||||
style={{
|
||||
flex: 1,
|
||||
backgroundColor: "#FEEDED",
|
||||
color: "#DD4143",
|
||||
boxShadow: "none",
|
||||
border: "none",
|
||||
display: "flex",
|
||||
gap: 12,
|
||||
margin: 20,
|
||||
}}
|
||||
onClick={handleRemoveSplitWay}
|
||||
>
|
||||
{t("splitBill.removeSplit")}
|
||||
</Button>
|
||||
<Button
|
||||
type="primary"
|
||||
style={{
|
||||
flex: 1,
|
||||
boxShadow: "none",
|
||||
}}
|
||||
onClick={handleSave}
|
||||
disabled={!amount || parseFloat(amount) <= 0}
|
||||
>
|
||||
{t("splitBill.confirm")}
|
||||
</Button>
|
||||
</div>
|
||||
</ProBottomSheet>
|
||||
<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={!amount || parseFloat(amount) <= 0}
|
||||
>
|
||||
{t("splitBill.confirm")}
|
||||
</Button>
|
||||
</div>
|
||||
</ProBottomSheet>
|
||||
<QRBottomSheet isOpen={isQROpen} onClose={() => setIsQROpen(false)} />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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 (
|
||||
<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,
|
||||
<>
|
||||
<ProBottomSheet
|
||||
isOpen={isOpen}
|
||||
onClose={onClose}
|
||||
title={t("splitBill.divideTheBillEqually")}
|
||||
showCloseButton={true}
|
||||
initialSnap={1}
|
||||
height={630}
|
||||
snapPoints={[630]}
|
||||
contentStyle={{
|
||||
padding: 0,
|
||||
}}
|
||||
>
|
||||
{/* Spinner Visualization - Blank Spin Wheel */}
|
||||
{totalPeople > 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: 12,
|
||||
alignItems: "center",
|
||||
gap: "1rem",
|
||||
padding: 20,
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
position: "relative",
|
||||
width: 200,
|
||||
height: 200,
|
||||
margin: "0 auto",
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
justifyContent: "space-between",
|
||||
gap: "1rem",
|
||||
padding: 8,
|
||||
}}
|
||||
>
|
||||
<svg
|
||||
width="200"
|
||||
height="200"
|
||||
viewBox="0 0 200 200"
|
||||
<ProText
|
||||
style={{
|
||||
transform: "rotate(-90deg)",
|
||||
fontSize: "1rem",
|
||||
marginTop: 3,
|
||||
color: ProGray1,
|
||||
}}
|
||||
>
|
||||
{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")}
|
||||
</ProText>
|
||||
|
||||
// Convert angles to radians
|
||||
const startAngleRad = (startAngle * Math.PI) / 180;
|
||||
const endAngleRad = (endAngle * Math.PI) / 180;
|
||||
<TotalPeopleActions />
|
||||
|
||||
// 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
|
||||
<ProText
|
||||
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,
|
||||
fontSize: "1rem",
|
||||
marginTop: 3,
|
||||
color: ProGray1,
|
||||
}}
|
||||
>
|
||||
<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>
|
||||
{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",
|
||||
gap: "1rem",
|
||||
padding: 20,
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
justifyContent: "space-between",
|
||||
gap: "1rem",
|
||||
padding: 8,
|
||||
flexDirection: "column",
|
||||
backgroundColor: "var(--background)",
|
||||
padding: 20,
|
||||
opacity: 1,
|
||||
gap: 8,
|
||||
borderTopLeftRadius: 24,
|
||||
borderTopRightRadius: 24,
|
||||
paddingTop: 12,
|
||||
paddingRight: 24,
|
||||
paddingBottom: 24,
|
||||
paddingLeft: 24,
|
||||
}}
|
||||
>
|
||||
<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 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",
|
||||
flexDirection: "row",
|
||||
justifyContent: "space-between",
|
||||
gap: "1rem",
|
||||
padding: 8,
|
||||
gap: 12,
|
||||
margin: 20,
|
||||
}}
|
||||
>
|
||||
<ProText
|
||||
<Button
|
||||
style={{
|
||||
fontSize: "1rem",
|
||||
marginTop: 2,
|
||||
color: ProGray1,
|
||||
flex: 1,
|
||||
backgroundColor: "#FEEDED",
|
||||
color: "#DD4143",
|
||||
boxShadow: "none",
|
||||
border: "none",
|
||||
}}
|
||||
onClick={handleRemoveSplitWay}
|
||||
>
|
||||
{t("checkout.payFor")}
|
||||
</ProText>
|
||||
|
||||
<PayForActions />
|
||||
|
||||
<ProText
|
||||
style={{
|
||||
fontSize: "1rem",
|
||||
marginTop: 2,
|
||||
color: ProGray1,
|
||||
}}
|
||||
{t("splitBill.removeSplit")}
|
||||
</Button>
|
||||
<Button
|
||||
type="primary"
|
||||
style={{ flex: 1, boxShadow: "none" }}
|
||||
onClick={handleSave}
|
||||
>
|
||||
{t("checkout.payFor")}
|
||||
</ProText>
|
||||
{t("cart.save")}
|
||||
</Button>
|
||||
</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",
|
||||
}}
|
||||
onClick={handleRemoveSplitWay}
|
||||
>
|
||||
{t("splitBill.removeSplit")}
|
||||
</Button>
|
||||
<Button
|
||||
type="primary"
|
||||
style={{ flex: 1, boxShadow: "none" }}
|
||||
onClick={handleSave}
|
||||
>
|
||||
{t("cart.save")}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</ProBottomSheet>
|
||||
</ProBottomSheet>
|
||||
<QRBottomSheet isOpen={isQROpen} onClose={() => setIsQROpen(false)} />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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<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()))
|
||||
@@ -56,6 +57,7 @@ export function PayForYourItemsChoiceBottomSheet({
|
||||
|
||||
const handleSave = () => {
|
||||
dispatch(updateSplitBillAmount(selectedTotal));
|
||||
setIsQROpen(true);
|
||||
onClose();
|
||||
};
|
||||
|
||||
@@ -67,159 +69,162 @@ export function PayForYourItemsChoiceBottomSheet({
|
||||
};
|
||||
|
||||
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,
|
||||
}}
|
||||
<>
|
||||
<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",
|
||||
justifyContent: "space-between",
|
||||
alignItems: "center",
|
||||
flexDirection: "column",
|
||||
gap: 12,
|
||||
maxHeight: "455px",
|
||||
minHeight: "455px",
|
||||
overflowY: "auto",
|
||||
}}
|
||||
>
|
||||
<ProText style={{ fontSize: 16, fontWeight: 600 }}>
|
||||
{t("splitBill.selectedTotal")}:
|
||||
</ProText>
|
||||
<ArabicPrice price={selectedTotal} />
|
||||
{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>
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
gap: 12,
|
||||
margin: 20,
|
||||
}}
|
||||
>
|
||||
<Button
|
||||
<div
|
||||
style={{
|
||||
flex: 1,
|
||||
backgroundColor: "#FEEDED",
|
||||
color: "#DD4143",
|
||||
boxShadow: "none",
|
||||
border: "none",
|
||||
padding: 16,
|
||||
backgroundColor: "rgba(255, 183, 0, 0.08)",
|
||||
borderRadius: 8,
|
||||
marginTop: 8,
|
||||
}}
|
||||
onClick={handleRemoveSplitWay}
|
||||
>
|
||||
{t("splitBill.removeSplit")}
|
||||
</Button>
|
||||
<Button
|
||||
type="primary"
|
||||
style={{ flex: 1, boxShadow: "none" }}
|
||||
onClick={handleSave}
|
||||
disabled={selectedTotal === 0}
|
||||
<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,
|
||||
}}
|
||||
>
|
||||
{t("cart.save")}
|
||||
</Button>
|
||||
</div>
|
||||
</ProBottomSheet>
|
||||
<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)} />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
123
src/pages/pay/components/splitBill/QRBottomSheet.tsx
Normal file
123
src/pages/pay/components/splitBill/QRBottomSheet.tsx
Normal 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>
|
||||
);
|
||||
}
|
||||
@@ -7,18 +7,19 @@ import { selectCart } from "features/order/orderSlice";
|
||||
import { AddressSummary } from "pages/checkout/components/AddressSummary";
|
||||
import BriefMenu from "pages/checkout/components/BriefMenu";
|
||||
import { GiftCard } from "pages/checkout/components/GiftCard";
|
||||
import PhoneCard from "pages/checkout/components/PhoneCard";
|
||||
import { OrderType } from "pages/checkout/hooks/types";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useAppSelector } from "redux/hooks";
|
||||
import styles from "../address/address.module.css";
|
||||
import PayButton from "./components/PayButton";
|
||||
|
||||
import CustomerInformationCard from "pages/checkout/components/CustomerInformationCard";
|
||||
|
||||
export default function PayPage() {
|
||||
const { t } = useTranslation();
|
||||
const [form] = Form.useForm();
|
||||
const { phone, order, orderType } = useAppSelector(selectCart);
|
||||
const { token } = useAppSelector((state) => state.auth);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Form
|
||||
@@ -54,7 +55,7 @@ export default function PayPage() {
|
||||
{/* <GiftDetails /> */}
|
||||
<BriefMenu />
|
||||
<OrderSummary />
|
||||
<PhoneCard />
|
||||
{!token && <CustomerInformationCard />}
|
||||
<PaymentMethods />
|
||||
</Layout.Content>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user