split bill: reorder flow
This commit is contained in:
@@ -387,7 +387,8 @@
|
||||
"pleaseLoginToAllowRating": "يرجى تسجيل الدخول لتمكين التقييم",
|
||||
"remainingTime": "الوقت المتبقي",
|
||||
"sec": "ثانية",
|
||||
"min": "دقيقة"
|
||||
"min": "دقيقة",
|
||||
"inviteToBill": "دع الجميع يدفعوا معك"
|
||||
},
|
||||
"orderTypes": {
|
||||
"dine-in": "في المطعم",
|
||||
|
||||
@@ -398,7 +398,8 @@
|
||||
"pleaseLoginToAllowRating": "Please login to allow rating",
|
||||
"remainingTime": "Remaining Time",
|
||||
"sec": "Sec",
|
||||
"min": "Min"
|
||||
"min": "Min",
|
||||
"inviteToBill": "Invite to Bill"
|
||||
},
|
||||
"orderTypes": {
|
||||
"dine-in": "Dine In",
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
// import { useGlobals } from "../../hooks/useGlobals";
|
||||
import { Button, Card, message } from "antd";
|
||||
import BackIcon from "components/Icons/BackIcon";
|
||||
import NextIcon from "components/Icons/NextIcon";
|
||||
import RateIcon from "components/Icons/order/RateIcon";
|
||||
import { useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
@@ -6,13 +6,24 @@ import { useTranslation } from "react-i18next";
|
||||
import { useAppSelector } from "redux/hooks";
|
||||
import { selectCart } from "features/order/orderSlice";
|
||||
import { useNavigate, useParams } from "react-router-dom";
|
||||
import { useGetOrderDetailsQuery } from "redux/api/others";
|
||||
|
||||
export default function BriefMenuCard() {
|
||||
const { t } = useTranslation();
|
||||
const { items } = useAppSelector(selectCart);
|
||||
const totalItems = items.length;
|
||||
const { subdomain } = useParams();
|
||||
const { subdomain, orderId } = useParams();
|
||||
const navigate = useNavigate();
|
||||
const { data: orderDetails } = useGetOrderDetailsQuery(
|
||||
{
|
||||
orderID: orderId || "",
|
||||
restaurantID: localStorage.getItem("restaurantID") || "",
|
||||
},
|
||||
{
|
||||
skip: !orderId,
|
||||
// return it t0 60000 after finish testing
|
||||
},
|
||||
);
|
||||
const totalItems = items.length || orderDetails?.orderItems.length;
|
||||
|
||||
return (
|
||||
<>
|
||||
|
||||
@@ -1,23 +1,59 @@
|
||||
import { Button, FormInstance, Layout } from "antd";
|
||||
import { selectCart } from "features/order/orderSlice";
|
||||
import { selectCart, updateSplitBillAmount } from "features/order/orderSlice";
|
||||
import { OrderType } from "pages/checkout/hooks/types.ts";
|
||||
import { useCallback, useMemo } from "react";
|
||||
import { useCallback, useMemo, useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useNavigate, useParams } from "react-router-dom";
|
||||
import { useAppSelector } from "redux/hooks";
|
||||
import { useAppDispatch, useAppSelector } from "redux/hooks";
|
||||
import styles from "../../address/address.module.css";
|
||||
import useOrder from "../hooks/useOrder";
|
||||
import { EqualltyChoiceBottomSheet } from "pages/pay/components/splitBill/EqualltyChoiceBottomSheet";
|
||||
import { SplitBillChoiceBottomSheet } from "pages/pay/components/splitBill/SplitBillChoiceBottomSheet";
|
||||
import { CustomAmountChoiceBottomSheet } from "pages/pay/components/splitBill/CustomAmountChoiceBottomSheet";
|
||||
import { PayForYourItemsChoiceBottomSheet } from "pages/pay/components/splitBill/PayForYourItemsChoiceBottomSheet";
|
||||
|
||||
type SplitWay = "customAmount" | "equality" | "payForItems" | null;
|
||||
|
||||
export default function CheckoutButton({ form }: { form: FormInstance }) {
|
||||
const dispatch = useAppDispatch();
|
||||
const { t } = useTranslation();
|
||||
const { orderType } = useAppSelector(selectCart);
|
||||
const navigate = useNavigate();
|
||||
const { handleCreateOrder } = useOrder();
|
||||
const { subdomain } = useParams();
|
||||
const [selectedSplitWay, setSelectedSplitWay] = useState<SplitWay>(null);
|
||||
const [
|
||||
isSplitBillChoiceBottomSheetOpen,
|
||||
setIsSplitBillChoiceBottomSheetOpen,
|
||||
] = useState(false);
|
||||
const [isCustomAmountOpen, setIsCustomAmountOpen] = useState(false);
|
||||
const [isEqualityOpen, setIsEqualityOpen] = useState(false);
|
||||
const [isPayForItemsOpen, setIsPayForItemsOpen] = useState(false);
|
||||
|
||||
const handleSplitBillClick = useCallback(() => {
|
||||
navigate(`/${subdomain}/split-bill`);
|
||||
}, [navigate, subdomain]);
|
||||
if (selectedSplitWay === "customAmount") {
|
||||
setIsCustomAmountOpen(true);
|
||||
} else if (selectedSplitWay === "equality") {
|
||||
setIsEqualityOpen(true);
|
||||
} else if (selectedSplitWay === "payForItems") {
|
||||
setIsPayForItemsOpen(true);
|
||||
} else {
|
||||
setIsSplitBillChoiceBottomSheetOpen(true);
|
||||
}
|
||||
}, [selectedSplitWay]);
|
||||
|
||||
const handleRemoveSplitWay = useCallback(() => {
|
||||
setSelectedSplitWay(null);
|
||||
dispatch(updateSplitBillAmount(0));
|
||||
}, [dispatch]);
|
||||
|
||||
const getSplitButtonTitle = useMemo(() => {
|
||||
if (selectedSplitWay === "customAmount") {
|
||||
return t("splitBill.payAsCustomAmount");
|
||||
} else if (selectedSplitWay === "equality") {
|
||||
return t("splitBill.divideTheBillEqually");
|
||||
} else if (selectedSplitWay === "payForItems") {
|
||||
return t("splitBill.payForYourItems");
|
||||
}
|
||||
return t("checkout.splitBill");
|
||||
}, [selectedSplitWay, t]);
|
||||
|
||||
const handlePlaceOrderClick = useCallback(async () => {
|
||||
try {
|
||||
@@ -34,13 +70,14 @@ export default function CheckoutButton({ form }: { form: FormInstance }) {
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Layout.Footer className={styles.checkoutButtonContainer}>
|
||||
{shouldShowSplitBill && (
|
||||
<Button
|
||||
className={styles.splitBillButton}
|
||||
onClick={handleSplitBillClick}
|
||||
>
|
||||
{t("checkout.splitBill")}
|
||||
{getSplitButtonTitle}
|
||||
</Button>
|
||||
)}
|
||||
|
||||
@@ -53,5 +90,36 @@ export default function CheckoutButton({ form }: { form: FormInstance }) {
|
||||
{t("checkout.placeOrder")}
|
||||
</Button>
|
||||
</Layout.Footer>
|
||||
|
||||
<SplitBillChoiceBottomSheet
|
||||
isOpen={isSplitBillChoiceBottomSheetOpen}
|
||||
onClose={() => setIsSplitBillChoiceBottomSheetOpen(false)}
|
||||
onSelectSplitWay={setSelectedSplitWay}
|
||||
/>
|
||||
|
||||
<CustomAmountChoiceBottomSheet
|
||||
isOpen={isCustomAmountOpen}
|
||||
onClose={() => {
|
||||
setIsCustomAmountOpen(false);
|
||||
}}
|
||||
onRemoveSplitWay={handleRemoveSplitWay}
|
||||
/>
|
||||
|
||||
<EqualltyChoiceBottomSheet
|
||||
isOpen={isEqualityOpen}
|
||||
onClose={() => {
|
||||
setIsEqualityOpen(false);
|
||||
}}
|
||||
onRemoveSplitWay={handleRemoveSplitWay}
|
||||
/>
|
||||
|
||||
<PayForYourItemsChoiceBottomSheet
|
||||
isOpen={isPayForItemsOpen}
|
||||
onClose={() => {
|
||||
setIsPayForItemsOpen(false);
|
||||
}}
|
||||
onRemoveSplitWay={handleRemoveSplitWay}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -244,4 +244,19 @@
|
||||
height: 24px;
|
||||
}
|
||||
|
||||
.inviteToBillCard {
|
||||
width: 100%;
|
||||
height: 48px;
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
padding: 12px 18px !important;
|
||||
row-gap: 10px;
|
||||
transition: all 0.3s ease;
|
||||
border-radius: 50px;
|
||||
}
|
||||
|
||||
.inviteToBillCard :global(.ant-card-body) {
|
||||
padding: 0px !important;
|
||||
text-align: start;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@ import TimeIcon from "components/Icons/order/TimeIcon";
|
||||
import OrderDishIcon from "components/Icons/OrderDishIcon";
|
||||
import PaymentDetails from "components/PaymentDetails/PaymentDetails";
|
||||
import ProHeader from "components/ProHeader/ProHeader";
|
||||
import ProInputCard from "components/ProInputCard/ProInputCard";
|
||||
import ProText from "components/ProText";
|
||||
import ProTitle from "components/ProTitle";
|
||||
import dayjs from "dayjs";
|
||||
@@ -24,6 +23,8 @@ import styles from "./order.module.css";
|
||||
import BackIcon from "components/Icons/BackIcon";
|
||||
import NextIcon from "components/Icons/NextIcon";
|
||||
import { RateBottomSheet } from "components/CustomBottomSheet/RateBottomSheet";
|
||||
import BriefMenuCard from "pages/checkout/components/BriefMenuCard";
|
||||
import { QRBottomSheet } from "pages/pay/components/splitBill/QRBottomSheet";
|
||||
|
||||
export default function OrderPage() {
|
||||
const { t } = useTranslation();
|
||||
@@ -32,6 +33,7 @@ export default function OrderPage() {
|
||||
const { restaurant } = useAppSelector((state) => state.order);
|
||||
const navigate = useNavigate();
|
||||
const hasRefetchedRef = useRef(false);
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
|
||||
const { data: orderDetails } = useGetOrderDetailsQuery(
|
||||
{
|
||||
@@ -346,7 +348,7 @@ export default function OrderPage() {
|
||||
|
||||
<Ads2 />
|
||||
|
||||
<ProInputCard
|
||||
{/* <ProInputCard
|
||||
title={
|
||||
<div style={{ marginBottom: 7 }}>
|
||||
<ProText style={{ fontSize: "1rem" }}>
|
||||
@@ -393,7 +395,9 @@ export default function OrderPage() {
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</ProInputCard>
|
||||
</ProInputCard> */}
|
||||
|
||||
<BriefMenuCard />
|
||||
|
||||
<PaymentDetails order={orderDetails?.order} />
|
||||
|
||||
@@ -439,6 +443,34 @@ export default function OrderPage() {
|
||||
</div>
|
||||
</Card>
|
||||
|
||||
<Card
|
||||
className={styles.inviteToBillCard}
|
||||
onClick={() => setIsOpen(true)}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
justifyContent: "center",
|
||||
marginTop: 1,
|
||||
}}
|
||||
>
|
||||
<div style={{ display: "flex", flexDirection: "row", gap: 10 }}>
|
||||
<ProTitle
|
||||
level={5}
|
||||
style={{
|
||||
marginTop: 1,
|
||||
fontSize: 14,
|
||||
}}
|
||||
>
|
||||
{t("order.inviteToBill")}
|
||||
</ProTitle>
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
|
||||
<QRBottomSheet isOpen={isOpen} onClose={() => setIsOpen(false)} />
|
||||
|
||||
<RateBottomSheet />
|
||||
|
||||
<CancelOrderBottomSheet />
|
||||
|
||||
@@ -12,7 +12,6 @@ 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;
|
||||
@@ -32,7 +31,6 @@ 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,7 +40,6 @@ export function CustomAmountChoiceBottomSheet({
|
||||
const handleSave = () => {
|
||||
const numAmount = parseFloat(amount) || 0;
|
||||
dispatch(updateSplitBillAmount(numAmount));
|
||||
setIsQROpen(true);
|
||||
onClose();
|
||||
};
|
||||
|
||||
@@ -62,7 +59,6 @@ export function CustomAmountChoiceBottomSheet({
|
||||
const previewRemaining = originalTotalBill - currentAmount;
|
||||
|
||||
return (
|
||||
<>
|
||||
<ProBottomSheet
|
||||
isOpen={isOpen}
|
||||
onClose={onClose}
|
||||
@@ -193,7 +189,5 @@ export function CustomAmountChoiceBottomSheet({
|
||||
</Button>
|
||||
</div>
|
||||
</ProBottomSheet>
|
||||
<QRBottomSheet isOpen={isQROpen} onClose={() => setIsQROpen(false)} />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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,7 +64,6 @@ export function EqualltyChoiceBottomSheet({
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<ProBottomSheet
|
||||
isOpen={isOpen}
|
||||
onClose={onClose}
|
||||
@@ -344,7 +340,5 @@ export function EqualltyChoiceBottomSheet({
|
||||
</div>
|
||||
</div>
|
||||
</ProBottomSheet>
|
||||
<QRBottomSheet isOpen={isQROpen} onClose={() => setIsQROpen(false)} />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -8,7 +8,6 @@ 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;
|
||||
@@ -26,7 +25,6 @@ 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()))
|
||||
@@ -57,7 +55,6 @@ export function PayForYourItemsChoiceBottomSheet({
|
||||
|
||||
const handleSave = () => {
|
||||
dispatch(updateSplitBillAmount(selectedTotal));
|
||||
setIsQROpen(true);
|
||||
onClose();
|
||||
};
|
||||
|
||||
@@ -69,7 +66,6 @@ export function PayForYourItemsChoiceBottomSheet({
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<ProBottomSheet
|
||||
isOpen={isOpen}
|
||||
onClose={onClose}
|
||||
@@ -224,7 +220,5 @@ export function PayForYourItemsChoiceBottomSheet({
|
||||
</Button>
|
||||
</div>
|
||||
</ProBottomSheet>
|
||||
<QRBottomSheet isOpen={isQROpen} onClose={() => setIsQROpen(false)} />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -101,10 +101,7 @@ export function SplitBillChoiceBottomSheet({
|
||||
</div>
|
||||
</Card>
|
||||
|
||||
<Card
|
||||
className={styles.backToHomePage}
|
||||
onClick={handleEqualityClick}
|
||||
>
|
||||
<Card className={styles.backToHomePage} onClick={handleEqualityClick}>
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
|
||||
@@ -158,21 +158,21 @@ export default function RestaurantServices() {
|
||||
},
|
||||
]) ||
|
||||
[]),
|
||||
...((true && [
|
||||
{
|
||||
id: OrderType.Pay,
|
||||
title: t("common.pay"),
|
||||
description: t("home.services.pay"),
|
||||
icon: (
|
||||
<ToOfficeIcon
|
||||
className={styles.serviceIcon + " " + styles.officeIcon}
|
||||
/>
|
||||
),
|
||||
color: "bg-orange-50 text-orange-600",
|
||||
href: `/${subdomain}/pay`,
|
||||
},
|
||||
]) ||
|
||||
[]),
|
||||
// ...((true && [
|
||||
// {
|
||||
// id: OrderType.Pay,
|
||||
// title: t("common.pay"),
|
||||
// description: t("home.services.pay"),
|
||||
// icon: (
|
||||
// <ToOfficeIcon
|
||||
// className={styles.serviceIcon + " " + styles.officeIcon}
|
||||
// />
|
||||
// ),
|
||||
// color: "bg-orange-50 text-orange-600",
|
||||
// href: `/${subdomain}/pay`,
|
||||
// },
|
||||
// ]) ||
|
||||
// []),
|
||||
];
|
||||
|
||||
// Determine grid class based on number of services
|
||||
|
||||
Reference in New Issue
Block a user