Compare commits

..

6 Commits

18 changed files with 872 additions and 567 deletions

View File

@@ -108,6 +108,7 @@
"email_label": "البريد الإلكتروني" "email_label": "البريد الإلكتروني"
}, },
"menu": { "menu": {
"orderTypes": "طرق الطلب",
"meal": "الوجبة", "meal": "الوجبة",
"title": "القائمة", "title": "القائمة",
"ourMenu": "قائمتنا", "ourMenu": "قائمتنا",
@@ -386,7 +387,8 @@
"pleaseLoginToAllowRating": "يرجى تسجيل الدخول لتمكين التقييم", "pleaseLoginToAllowRating": "يرجى تسجيل الدخول لتمكين التقييم",
"remainingTime": "الوقت المتبقي", "remainingTime": "الوقت المتبقي",
"sec": "ثانية", "sec": "ثانية",
"min": "دقيقة" "min": "دقيقة",
"inviteToBill": "دع الجميع يدفعوا معك"
}, },
"orderTypes": { "orderTypes": {
"dine-in": "في المطعم", "dine-in": "في المطعم",

View File

@@ -124,6 +124,7 @@
"email_label": "Email" "email_label": "Email"
}, },
"menu": { "menu": {
"orderTypes": "Order Types",
"meal": "Meal", "meal": "Meal",
"title": "Menu", "title": "Menu",
"ourMenu": "Our Menu", "ourMenu": "Our Menu",
@@ -397,7 +398,8 @@
"pleaseLoginToAllowRating": "Please login to allow rating", "pleaseLoginToAllowRating": "Please login to allow rating",
"remainingTime": "Remaining Time", "remainingTime": "Remaining Time",
"sec": "Sec", "sec": "Sec",
"min": "Min" "min": "Min",
"inviteToBill": "Invite to Bill"
}, },
"orderTypes": { "orderTypes": {
"dine-in": "Dine In", "dine-in": "Dine In",

View File

@@ -0,0 +1,150 @@
import { Button } from "antd";
import { useTranslation } from "react-i18next";
import { ProBottomSheet } from "../ProBottomSheet/ProBottomSheet";
import NextIcon from "components/Icons/NextIcon";
import { useAppSelector } from "redux/hooks";
import { OrderType } from "pages/checkout/hooks/types";
import { useSearchParams } from "react-router-dom";
interface OrderTypesBottomSheetBottomSheetProps {
isOpen: boolean;
onClose: () => void;
}
export function OrderTypesBottomSheet({
isOpen,
onClose,
}: OrderTypesBottomSheetBottomSheetProps) {
const { t } = useTranslation();
const { restaurant, orderType, hiddenServices } = useAppSelector(
(state) => state.order,
);
const [searchParams, setSearchParams] = useSearchParams();
const buttonStyle = {
height: 48,
width: "100%",
display: "flex",
justifyContent: "space-between",
alignItems: "center",
};
// Calculate height: base 620px, subtract 48px for each hidden service
const calculatedHeight = 620 - hiddenServices * 64;
const handleOrderTypeSelect = (selectedOrderType: OrderType) => {
searchParams.set("orderType", selectedOrderType);
setSearchParams(searchParams);
onClose();
};
return (
<ProBottomSheet
isOpen={isOpen}
onClose={onClose}
title={t("menu.orderTypes")}
initialSnap={1}
height={calculatedHeight}
snapPoints={[calculatedHeight.toString()]}
>
<div
style={{
display: "flex",
flexDirection: "column",
gap: 16,
margin: "16px 0",
}}
>
{restaurant?.dineIn == true && (
<Button
icon={<NextIcon />}
iconPlacement="end"
style={buttonStyle}
type={orderType === OrderType.DineIn ? "primary" : "default"}
onClick={() => handleOrderTypeSelect(OrderType.DineIn)}
>
{t("orderTypes.dine-in")}
</Button>
)}
{restaurant?.delivery == true && (
<Button
icon={<NextIcon />}
iconPlacement="end"
style={buttonStyle}
type={orderType === OrderType.Delivery ? "primary" : "default"}
onClick={() => handleOrderTypeSelect(OrderType.Delivery)}
>
{t("orderTypes.delivery")}
</Button>
)}
{restaurant?.pickup == true && (
<Button
icon={<NextIcon />}
iconPlacement="end"
style={buttonStyle}
type={orderType === OrderType.Pickup ? "primary" : "default"}
onClick={() => handleOrderTypeSelect(OrderType.Pickup)}
>
{t("orderTypes.pickup")}
</Button>
)}
{restaurant?.gift == true && (
<Button
icon={<NextIcon />}
iconPlacement="end"
style={buttonStyle}
type={orderType === OrderType.Gift ? "primary" : "default"}
onClick={() => handleOrderTypeSelect(OrderType.Gift)}
>
{t("orderTypes.gift")}
</Button>
)}
{restaurant?.toRoom == true && (
<Button
icon={<NextIcon />}
iconPlacement="end"
style={buttonStyle}
type={orderType === OrderType.ToRoom ? "primary" : "default"}
onClick={() => handleOrderTypeSelect(OrderType.ToRoom)}
>
{t("orderTypes.room")}
</Button>
)}
{restaurant?.toOffice == true && (
<Button
icon={<NextIcon />}
iconPlacement="end"
style={buttonStyle}
type={orderType === OrderType.ToOffice ? "primary" : "default"}
onClick={() => handleOrderTypeSelect(OrderType.ToOffice)}
>
{t("orderTypes.office")}
</Button>
)}
{restaurant?.is_schedule_order_enabled == 1 && (
<Button
icon={<NextIcon />}
iconPlacement="end"
style={buttonStyle}
type={
orderType === OrderType.ScheduledOrder ? "primary" : "default"
}
onClick={() => handleOrderTypeSelect(OrderType.ScheduledOrder)}
>
{t("orderTypes.scheduled_order")}
</Button>
)}
{restaurant?.is_booking_enabled == 1 && (
<Button
icon={<NextIcon />}
iconPlacement="end"
style={buttonStyle}
type={orderType === OrderType.Booking ? "primary" : "default"}
onClick={() => handleOrderTypeSelect(OrderType.Booking)}
>
{t("orderTypes.booking")}
</Button>
)}
</div>
</ProBottomSheet>
);
}

View File

@@ -1,7 +1,5 @@
// import { useGlobals } from "../../hooks/useGlobals"; // import { useGlobals } from "../../hooks/useGlobals";
import { Button, Card, message } from "antd"; 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 RateIcon from "components/Icons/order/RateIcon";
import { useState } from "react"; import { useState } from "react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";

View File

@@ -71,6 +71,9 @@ interface CartState {
order: any; order: any;
splitBillAmount: number; splitBillAmount: number;
customerName: string; customerName: string;
totalServices: number;
hiddenServices: number;
visibleServices: number;
} }
// localStorage keys // localStorage keys
@@ -101,6 +104,9 @@ export const CART_STORAGE_KEYS = {
PICKUP_TIME: "fascano_pickup_time", PICKUP_TIME: "fascano_pickup_time",
PICKUP_TYPE: "fascano_pickup_type", PICKUP_TYPE: "fascano_pickup_type",
ORDER: "fascano_order", ORDER: "fascano_order",
TOTAL_SERVICES: "fascano_total_services",
HIDDEN_SERVICES: "fascano_hidden_services",
VISIBLE_SERVICES: "fascano_visible_services",
} as const; } as const;
// Utility functions for localStorage // Utility functions for localStorage
@@ -189,6 +195,9 @@ const initialState: CartState = {
order: getFromLocalStorage(CART_STORAGE_KEYS.ORDER, null), order: getFromLocalStorage(CART_STORAGE_KEYS.ORDER, null),
splitBillAmount: 0, splitBillAmount: 0,
customerName: "", customerName: "",
totalServices: 8,
hiddenServices: 0,
visibleServices: 0,
}; };
const orderSlice = createSlice({ const orderSlice = createSlice({
@@ -200,11 +209,35 @@ const orderSlice = createSlice({
}, },
updateRestaurant(state, action: PayloadAction<Partial<RestaurantDetails>>) { updateRestaurant(state, action: PayloadAction<Partial<RestaurantDetails>>) {
state.restaurant = action.payload; state.restaurant = action.payload;
state.visibleServices = [
action.payload.dineIn,
action.payload.delivery,
action.payload.pickup,
action.payload.gift,
action.payload.toRoom,
action.payload.toOffice,
action.payload.is_schedule_order_enabled,
action.payload.is_booking_enabled,
].filter(Boolean).length;
state.hiddenServices = state.totalServices - state.visibleServices;
if (typeof window !== "undefined") { if (typeof window !== "undefined") {
localStorage.setItem( localStorage.setItem(
CART_STORAGE_KEYS.RESTAURANT, CART_STORAGE_KEYS.RESTAURANT,
JSON.stringify(state.restaurant), JSON.stringify(state.restaurant),
); );
localStorage.setItem(
CART_STORAGE_KEYS.TOTAL_SERVICES,
JSON.stringify(state.totalServices),
);
localStorage.setItem(
CART_STORAGE_KEYS.HIDDEN_SERVICES,
JSON.stringify(state.hiddenServices),
);
localStorage.setItem(
CART_STORAGE_KEYS.VISIBLE_SERVICES,
JSON.stringify(state.visibleServices),
);
} }
}, },
addItem( addItem(
@@ -633,7 +666,10 @@ const orderSlice = createSlice({
updateOrder(state, action: PayloadAction<any>) { updateOrder(state, action: PayloadAction<any>) {
state.order = action.payload; state.order = action.payload;
if (typeof window !== "undefined") { if (typeof window !== "undefined") {
localStorage.setItem(CART_STORAGE_KEYS.ORDER, JSON.stringify(state.order)); localStorage.setItem(
CART_STORAGE_KEYS.ORDER,
JSON.stringify(state.order),
);
} }
}, },
updateSplitBillAmount(state, action: PayloadAction<number>) { updateSplitBillAmount(state, action: PayloadAction<number>) {
@@ -787,7 +823,13 @@ export const selectGrandTotal = (state: RootState) => {
? Number(state.order.restaurant?.delivery_fees) || 0 ? Number(state.order.restaurant?.delivery_fees) || 0
: 0; : 0;
return subtotal + taxAmount - totalDiscount + deliveryFee - state.order.splitBillAmount; return (
subtotal +
taxAmount -
totalDiscount +
deliveryFee -
state.order.splitBillAmount
);
}; };
export default orderSlice.reducer; export default orderSlice.reducer;

View File

@@ -6,13 +6,24 @@ import { useTranslation } from "react-i18next";
import { useAppSelector } from "redux/hooks"; import { useAppSelector } from "redux/hooks";
import { selectCart } from "features/order/orderSlice"; import { selectCart } from "features/order/orderSlice";
import { useNavigate, useParams } from "react-router-dom"; import { useNavigate, useParams } from "react-router-dom";
import { useGetOrderDetailsQuery } from "redux/api/others";
export default function BriefMenuCard() { export default function BriefMenuCard() {
const { t } = useTranslation(); const { t } = useTranslation();
const { items } = useAppSelector(selectCart); const { items } = useAppSelector(selectCart);
const totalItems = items.length; const { subdomain, orderId } = useParams();
const { subdomain } = useParams();
const navigate = useNavigate(); 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 ( return (
<> <>

View File

@@ -1,23 +1,59 @@
import { Button, FormInstance, Layout } from "antd"; 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 { OrderType } from "pages/checkout/hooks/types.ts";
import { useCallback, useMemo } from "react"; import { useCallback, useMemo, useState } from "react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { useNavigate, useParams } from "react-router-dom"; import { useAppDispatch, useAppSelector } from "redux/hooks";
import { useAppSelector } from "redux/hooks";
import styles from "../../address/address.module.css"; import styles from "../../address/address.module.css";
import useOrder from "../hooks/useOrder"; 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 }) { export default function CheckoutButton({ form }: { form: FormInstance }) {
const dispatch = useAppDispatch();
const { t } = useTranslation(); const { t } = useTranslation();
const { orderType } = useAppSelector(selectCart); const { orderType } = useAppSelector(selectCart);
const navigate = useNavigate();
const { handleCreateOrder } = useOrder(); 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(() => { const handleSplitBillClick = useCallback(() => {
navigate(`/${subdomain}/split-bill`); if (selectedSplitWay === "customAmount") {
}, [navigate, subdomain]); 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 () => { const handlePlaceOrderClick = useCallback(async () => {
try { try {
@@ -34,24 +70,56 @@ export default function CheckoutButton({ form }: { form: FormInstance }) {
); );
return ( return (
<Layout.Footer className={styles.checkoutButtonContainer}> <>
{shouldShowSplitBill && ( <Layout.Footer className={styles.checkoutButtonContainer}>
<Button {shouldShowSplitBill && (
className={styles.splitBillButton} <Button
onClick={handleSplitBillClick} className={styles.splitBillButton}
> onClick={handleSplitBillClick}
{t("checkout.splitBill")} >
</Button> {getSplitButtonTitle}
)} </Button>
)}
<Button <Button
type="primary" type="primary"
shape="round" shape="round"
className={styles.placeOrderButton} className={styles.placeOrderButton}
onClick={handlePlaceOrderClick} onClick={handlePlaceOrderClick}
> >
{t("checkout.placeOrder")} {t("checkout.placeOrder")}
</Button> </Button>
</Layout.Footer> </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}
/>
</>
); );
} }

View File

@@ -34,7 +34,7 @@ export default function CustomerInformationCard() {
/> />
</Form.Item> </Form.Item>
</div> </div>
<div style={{ position: "relative", top: -30 }}> <div style={{ position: "relative", top: -35 }}>
<ProPhoneInput label={t("login.phone")} propName="phone" /> <ProPhoneInput label={t("login.phone")} propName="phone" />
</div> </div>
</ProInputCard> </ProInputCard>

View File

@@ -189,7 +189,10 @@ export function CategoriesList({ categories }: CategoriesListProps) {
data-category-id={category.id} data-category-id={category.id}
style={{ style={{
borderRadius: 8, borderRadius: 8,
border: "none", borderTop: "none",
borderRight: "none",
borderBottom: "none",
borderLeft: "none",
backgroundColor: isCategoriesSticky ? "transparent" : "var(--background)", backgroundColor: isCategoriesSticky ? "transparent" : "var(--background)",
}} }}
styles={{ styles={{
@@ -232,7 +235,7 @@ export function CategoriesList({ categories }: CategoriesListProps) {
)} )}
<Space <Space
direction="vertical" orientation="vertical"
size="small" size="small"
style={{ style={{
flex: 1, flex: 1,
@@ -274,7 +277,6 @@ export function CategoriesList({ categories }: CategoriesListProps) {
width: 104, width: 104,
height: 30, height: 30,
marginBottom: 1, marginBottom: 1,
border: "none",
}} }}
> >
<ProText <ProText

View File

@@ -24,8 +24,6 @@ export function MenuFooter() {
const grandTotal = useAppSelector(selectGrandTotal); const grandTotal = useAppSelector(selectGrandTotal);
const { isRTL } = useAppSelector((state) => state.locale); const { isRTL } = useAppSelector((state) => state.locale);
console.log(orderType);
return ( return (
<> <>
{(isMobile || isTablet) && ( {(isMobile || isTablet) && (

View File

@@ -11,7 +11,7 @@ import useBreakPoint from "hooks/useBreakPoint";
import { useRestaurant } from "hooks/useRestaurant"; import { useRestaurant } from "hooks/useRestaurant";
import { OrderType } from "pages/checkout/hooks/types.ts"; import { OrderType } from "pages/checkout/hooks/types.ts";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { useParams, useSearchParams } from "react-router-dom"; import { useParams } from "react-router-dom";
import { import {
useGetMenuQuery, useGetMenuQuery,
useGetRestaurantDetailsQuery, useGetRestaurantDetailsQuery,
@@ -33,11 +33,10 @@ import NextIcon from "components/Icons/NextIcon";
import { OpeningTimesBottomSheet } from "components/CustomBottomSheet/OpeningTimesBottomSheet"; import { OpeningTimesBottomSheet } from "components/CustomBottomSheet/OpeningTimesBottomSheet";
import { useState } from "react"; import { useState } from "react";
import BackIcon from "components/Icons/BackIcon"; import BackIcon from "components/Icons/BackIcon";
import { OrderTypesBottomSheet } from "components/CustomBottomSheet/OrderTypesBottomSheet";
function MenuPage() { function MenuPage() {
const { subdomain } = useParams(); const { subdomain } = useParams();
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const [_, setSearchParams] = useSearchParams();
const { isRTL } = useAppSelector((state) => state.locale); const { isRTL } = useAppSelector((state) => state.locale);
const { orderType } = useAppSelector((state) => state.order); const { orderType } = useAppSelector((state) => state.order);
const { t } = useTranslation(); const { t } = useTranslation();
@@ -55,6 +54,7 @@ function MenuPage() {
const { isMobile, isTablet, isDesktop } = useBreakPoint(); const { isMobile, isTablet, isDesktop } = useBreakPoint();
const isLoading = isLoadingRestaurant || isLoadingMenu; const isLoading = isLoadingRestaurant || isLoadingMenu;
const [isOpeningTimesOpen, setIsOpeningTimesOpen] = useState(false); const [isOpeningTimesOpen, setIsOpeningTimesOpen] = useState(false);
const [isOrderTypesOpen, setIsOrderTypesOpen] = useState(false);
const orderTypeOptions = enumToSelectOptions(OrderType, t, "orderTypes"); const orderTypeOptions = enumToSelectOptions(OrderType, t, "orderTypes");
// Automatically load restaurant taxes when restaurant data is available // Automatically load restaurant taxes when restaurant data is available
@@ -99,16 +99,18 @@ function MenuPage() {
> >
<Select <Select
value={orderType} value={orderType}
onChange={(value) => {
setSearchParams({ orderType: value });
}}
options={orderTypeOptions} options={orderTypeOptions}
open={false}
onOpenChange={() => false}
onClick={(e) => {
e.stopPropagation();
setIsOrderTypesOpen(true);
}}
variant="borderless" variant="borderless"
size="small" size="small"
className={styles.orderTypeSelect} className={styles.orderTypeSelect}
classNames={{ popup: { root: "order-type-select-dropdown" } }} classNames={{ popup: { root: "order-type-select-dropdown" } }}
listHeight={150} listHeight={150}
disabled
/> />
</div> </div>
<SearchButton /> <SearchButton />
@@ -139,7 +141,7 @@ function MenuPage() {
/> />
) )
} }
iconPosition="end" iconPlacement="end"
onClick={() => setIsOpeningTimesOpen(true)} onClick={() => setIsOpeningTimesOpen(true)}
> >
{restaurant?.isOpened ? t("menu.open") : t("menu.close")} {restaurant?.isOpened ? t("menu.open") : t("menu.close")}
@@ -185,6 +187,10 @@ function MenuPage() {
isOpen={isOpeningTimesOpen} isOpen={isOpeningTimesOpen}
onClose={() => setIsOpeningTimesOpen(false)} onClose={() => setIsOpeningTimesOpen(false)}
/> />
<OrderTypesBottomSheet
isOpen={isOrderTypesOpen}
onClose={() => setIsOrderTypesOpen(false)}
/>
</div> </div>
)} )}
</> </>

View File

@@ -244,4 +244,19 @@
height: 24px; 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%;
}

View File

@@ -7,7 +7,6 @@ import TimeIcon from "components/Icons/order/TimeIcon";
import OrderDishIcon from "components/Icons/OrderDishIcon"; import OrderDishIcon from "components/Icons/OrderDishIcon";
import PaymentDetails from "components/PaymentDetails/PaymentDetails"; import PaymentDetails from "components/PaymentDetails/PaymentDetails";
import ProHeader from "components/ProHeader/ProHeader"; import ProHeader from "components/ProHeader/ProHeader";
import ProInputCard from "components/ProInputCard/ProInputCard";
import ProText from "components/ProText"; import ProText from "components/ProText";
import ProTitle from "components/ProTitle"; import ProTitle from "components/ProTitle";
import dayjs from "dayjs"; import dayjs from "dayjs";
@@ -24,6 +23,8 @@ import styles from "./order.module.css";
import BackIcon from "components/Icons/BackIcon"; import BackIcon from "components/Icons/BackIcon";
import NextIcon from "components/Icons/NextIcon"; import NextIcon from "components/Icons/NextIcon";
import { RateBottomSheet } from "components/CustomBottomSheet/RateBottomSheet"; 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() { export default function OrderPage() {
const { t } = useTranslation(); const { t } = useTranslation();
@@ -32,6 +33,7 @@ export default function OrderPage() {
const { restaurant } = useAppSelector((state) => state.order); const { restaurant } = useAppSelector((state) => state.order);
const navigate = useNavigate(); const navigate = useNavigate();
const hasRefetchedRef = useRef(false); const hasRefetchedRef = useRef(false);
const [isOpen, setIsOpen] = useState(false);
const { data: orderDetails } = useGetOrderDetailsQuery( const { data: orderDetails } = useGetOrderDetailsQuery(
{ {
@@ -346,7 +348,7 @@ export default function OrderPage() {
<Ads2 /> <Ads2 />
<ProInputCard {/* <ProInputCard
title={ title={
<div style={{ marginBottom: 7 }}> <div style={{ marginBottom: 7 }}>
<ProText style={{ fontSize: "1rem" }}> <ProText style={{ fontSize: "1rem" }}>
@@ -393,7 +395,9 @@ export default function OrderPage() {
</div> </div>
))} ))}
</div> </div>
</ProInputCard> </ProInputCard> */}
<BriefMenuCard />
<PaymentDetails order={orderDetails?.order} /> <PaymentDetails order={orderDetails?.order} />
@@ -439,6 +443,34 @@ export default function OrderPage() {
</div> </div>
</Card> </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 /> <RateBottomSheet />
<CancelOrderBottomSheet /> <CancelOrderBottomSheet />

View File

@@ -12,7 +12,6 @@ import { useAppDispatch, useAppSelector } from "redux/hooks";
import ProText from "components/ProText"; import ProText from "components/ProText";
import ArabicPrice from "components/ArabicPrice"; import ArabicPrice from "components/ArabicPrice";
import styles from "./SplitBill.module.css"; import styles from "./SplitBill.module.css";
import { QRBottomSheet } from "./QRBottomSheet";
interface SplitBillChoiceBottomSheetProps { interface SplitBillChoiceBottomSheetProps {
isOpen: boolean; isOpen: boolean;
@@ -32,7 +31,6 @@ export function CustomAmountChoiceBottomSheet({
const [amount, setAmount] = useState<string>( const [amount, setAmount] = useState<string>(
splitBillAmount > 0 ? splitBillAmount.toString() : "", splitBillAmount > 0 ? splitBillAmount.toString() : "",
); );
const [isQROpen, setIsQROpen] = useState(false);
useEffect(() => { useEffect(() => {
if (isOpen && splitBillAmount > 0) { if (isOpen && splitBillAmount > 0) {
setAmount(splitBillAmount.toString()); setAmount(splitBillAmount.toString());
@@ -42,7 +40,6 @@ export function CustomAmountChoiceBottomSheet({
const handleSave = () => { const handleSave = () => {
const numAmount = parseFloat(amount) || 0; const numAmount = parseFloat(amount) || 0;
dispatch(updateSplitBillAmount(numAmount)); dispatch(updateSplitBillAmount(numAmount));
setIsQROpen(true);
onClose(); onClose();
}; };
@@ -62,7 +59,6 @@ export function CustomAmountChoiceBottomSheet({
const previewRemaining = originalTotalBill - currentAmount; const previewRemaining = originalTotalBill - currentAmount;
return ( return (
<>
<ProBottomSheet <ProBottomSheet
isOpen={isOpen} isOpen={isOpen}
onClose={onClose} onClose={onClose}
@@ -193,7 +189,5 @@ export function CustomAmountChoiceBottomSheet({
</Button> </Button>
</div> </div>
</ProBottomSheet> </ProBottomSheet>
<QRBottomSheet isOpen={isQROpen} onClose={() => setIsQROpen(false)} />
</>
); );
} }

View File

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

View File

@@ -8,7 +8,6 @@ import ProText from "components/ProText";
import { selectCart, updateSplitBillAmount } from "features/order/orderSlice"; import { selectCart, updateSplitBillAmount } from "features/order/orderSlice";
import { useAppDispatch, useAppSelector } from "redux/hooks"; import { useAppDispatch, useAppSelector } from "redux/hooks";
import styles from "./SplitBill.module.css"; import styles from "./SplitBill.module.css";
import { QRBottomSheet } from "./QRBottomSheet";
interface SplitBillChoiceBottomSheetProps { interface SplitBillChoiceBottomSheetProps {
isOpen: boolean; isOpen: boolean;
@@ -26,7 +25,6 @@ export function PayForYourItemsChoiceBottomSheet({
const dispatch = useAppDispatch(); const dispatch = useAppDispatch();
const { items } = useAppSelector(selectCart); const { items } = useAppSelector(selectCart);
const [selectedItems, setSelectedItems] = useState<Set<string>>(new Set()); const [selectedItems, setSelectedItems] = useState<Set<string>>(new Set());
const [isQROpen, setIsQROpen] = useState(false);
// Calculate total for selected items // Calculate total for selected items
const selectedTotal = items const selectedTotal = items
.filter((item) => selectedItems.has(item.uniqueId || item.id.toString())) .filter((item) => selectedItems.has(item.uniqueId || item.id.toString()))
@@ -57,7 +55,6 @@ export function PayForYourItemsChoiceBottomSheet({
const handleSave = () => { const handleSave = () => {
dispatch(updateSplitBillAmount(selectedTotal)); dispatch(updateSplitBillAmount(selectedTotal));
setIsQROpen(true);
onClose(); onClose();
}; };
@@ -69,162 +66,159 @@ export function PayForYourItemsChoiceBottomSheet({
}; };
return ( return (
<> <ProBottomSheet
<ProBottomSheet isOpen={isOpen}
isOpen={isOpen} onClose={onClose}
onClose={onClose} title={t("splitBill.payForYourItems")}
title={t("splitBill.payForYourItems")} showCloseButton={true}
showCloseButton={true} initialSnap={1}
initialSnap={1} height={720}
height={720} snapPoints={[720]}
snapPoints={[720]} contentStyle={{ padding: 0 }}
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,
}}
> >
<div <div
style={{ style={{
padding: 20,
display: "flex", display: "flex",
flexDirection: "column", justifyContent: "space-between",
gap: 12, alignItems: "center",
maxHeight: "455px",
minHeight: "455px",
overflowY: "auto",
}} }}
> >
{items.length === 0 ? ( <ProText style={{ fontSize: 16, fontWeight: 600 }}>
<ProText {t("splitBill.selectedTotal")}:
type="secondary" </ProText>
style={{ textAlign: "center", padding: 20 }} <ArabicPrice price={selectedTotal} />
>
{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 </div>
<div
style={{
display: "flex",
gap: 12,
margin: 20,
}}
>
<Button
style={{ style={{
padding: 16, flex: 1,
backgroundColor: "rgba(255, 183, 0, 0.08)", backgroundColor: "#FEEDED",
borderRadius: 8, color: "#DD4143",
marginTop: 8, boxShadow: "none",
border: "none",
}} }}
onClick={handleRemoveSplitWay}
> >
<div {t("splitBill.removeSplit")}
style={{ </Button>
display: "flex", <Button
justifyContent: "space-between", type="primary"
alignItems: "center", style={{ flex: 1, boxShadow: "none" }}
}} onClick={handleSave}
> disabled={selectedTotal === 0}
<ProText style={{ fontSize: 16, fontWeight: 600 }}>
{t("splitBill.selectedTotal")}:
</ProText>
<ArabicPrice price={selectedTotal} />
</div>
</div>
<div
style={{
display: "flex",
gap: 12,
margin: 20,
}}
> >
<Button {t("cart.save")}
style={{ </Button>
flex: 1, </div>
backgroundColor: "#FEEDED", </ProBottomSheet>
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)} />
</>
); );
} }

View File

@@ -55,126 +55,123 @@ export function SplitBillChoiceBottomSheet({
return ( return (
<> <>
<ProBottomSheet <ProBottomSheet
isOpen={isOpen} isOpen={isOpen}
onClose={handleCancel} onClose={handleCancel}
title={t("splitBill.title")} title={t("splitBill.title")}
showCloseButton={false} showCloseButton={false}
initialSnap={1} initialSnap={1}
height={290} height={290}
snapPoints={[290]} snapPoints={[290]}
>
<div
style={{
marginTop: 20,
display: "flex",
flexDirection: "column",
gap: 10,
}}
> >
<Card <div
className={styles.backToHomePage} style={{
onClick={handleCustomAmountClick} marginTop: 20,
display: "flex",
flexDirection: "column",
gap: 10,
}}
> >
<div <Card
style={{ className={styles.backToHomePage}
display: "flex", onClick={handleCustomAmountClick}
flexDirection: "row",
justifyContent: "space-between",
marginTop: 1,
}}
> >
<ProTitle <div
level={5}
style={{ style={{
fontSize: 14, display: "flex",
flexDirection: "row",
justifyContent: "space-between",
marginTop: 1,
}} }}
> >
{t("splitBill.payAsCustomAmount")} <ProTitle
</ProTitle> level={5}
style={{
fontSize: 14,
}}
>
{t("splitBill.payAsCustomAmount")}
</ProTitle>
{isRTL ? ( {isRTL ? (
<BackIcon className={styles.serviceIcon} /> <BackIcon className={styles.serviceIcon} />
) : ( ) : (
<NextIcon className={styles.serviceIcon} /> <NextIcon className={styles.serviceIcon} />
)} )}
</div> </div>
</Card> </Card>
<Card <Card className={styles.backToHomePage} onClick={handleEqualityClick}>
className={styles.backToHomePage} <div
onClick={handleEqualityClick}
>
<div
style={{
display: "flex",
flexDirection: "row",
justifyContent: "space-between",
marginTop: 1,
}}
>
<ProTitle
level={5}
style={{ style={{
fontSize: 14, display: "flex",
flexDirection: "row",
justifyContent: "space-between",
marginTop: 1,
}} }}
> >
{t("splitBill.divideTheBillEqually")} <ProTitle
</ProTitle> level={5}
style={{
fontSize: 14,
}}
>
{t("splitBill.divideTheBillEqually")}
</ProTitle>
{isRTL ? ( {isRTL ? (
<BackIcon className={styles.serviceIcon} /> <BackIcon className={styles.serviceIcon} />
) : ( ) : (
<NextIcon className={styles.serviceIcon} /> <NextIcon className={styles.serviceIcon} />
)} )}
</div> </div>
</Card> </Card>
<Card <Card
className={styles.backToHomePage} className={styles.backToHomePage}
onClick={handlePayForItemsClick} onClick={handlePayForItemsClick}
>
<div
style={{
display: "flex",
flexDirection: "row",
justifyContent: "space-between",
marginTop: 1,
}}
> >
<ProTitle <div
level={5}
style={{ style={{
fontSize: 14, display: "flex",
flexDirection: "row",
justifyContent: "space-between",
marginTop: 1,
}} }}
> >
{t("splitBill.payForYourItems")} <ProTitle
</ProTitle> level={5}
style={{
fontSize: 14,
}}
>
{t("splitBill.payForYourItems")}
</ProTitle>
{isRTL ? ( {isRTL ? (
<BackIcon className={styles.serviceIcon} /> <BackIcon className={styles.serviceIcon} />
) : ( ) : (
<NextIcon className={styles.serviceIcon} /> <NextIcon className={styles.serviceIcon} />
)} )}
</div> </div>
</Card> </Card>
</div> </div>
</ProBottomSheet> </ProBottomSheet>
<CustomAmountChoiceBottomSheet <CustomAmountChoiceBottomSheet
isOpen={isCustomAmountOpen} isOpen={isCustomAmountOpen}
onClose={() => setIsCustomAmountOpen(false)} onClose={() => setIsCustomAmountOpen(false)}
/> />
<EqualltyChoiceBottomSheet <EqualltyChoiceBottomSheet
isOpen={isEqualityOpen} isOpen={isEqualityOpen}
onClose={() => setIsEqualityOpen(false)} onClose={() => setIsEqualityOpen(false)}
/> />
<PayForYourItemsChoiceBottomSheet <PayForYourItemsChoiceBottomSheet
isOpen={isPayForItemsOpen} isOpen={isPayForItemsOpen}
onClose={() => setIsPayForItemsOpen(false)} onClose={() => setIsPayForItemsOpen(false)}
/> />
</> </>
); );
} }

View File

@@ -158,21 +158,21 @@ export default function RestaurantServices() {
}, },
]) || ]) ||
[]), []),
...((true && [ // ...((true && [
{ // {
id: OrderType.Pay, // id: OrderType.Pay,
title: t("common.pay"), // title: t("common.pay"),
description: t("home.services.pay"), // description: t("home.services.pay"),
icon: ( // icon: (
<ToOfficeIcon // <ToOfficeIcon
className={styles.serviceIcon + " " + styles.officeIcon} // className={styles.serviceIcon + " " + styles.officeIcon}
/> // />
), // ),
color: "bg-orange-50 text-orange-600", // color: "bg-orange-50 text-orange-600",
href: `/${subdomain}/pay`, // href: `/${subdomain}/pay`,
}, // },
]) || // ]) ||
[]), // []),
]; ];
// Determine grid class based on number of services // Determine grid class based on number of services