diff --git a/src/components/CustomBottomSheet/GiftBottomSheet.tsx b/src/components/CustomBottomSheet/GiftBottomSheet.tsx index 9cab852..e7e0d2f 100644 --- a/src/components/CustomBottomSheet/GiftBottomSheet.tsx +++ b/src/components/CustomBottomSheet/GiftBottomSheet.tsx @@ -45,8 +45,8 @@ export function GiftBottomSheet({ title={t("address.giftDetails")} showCloseButton={false} initialSnap={1} - height={"90vh"} - snapPoints={["90vh"]} + height={755} + snapPoints={[755]} >
+ + + + + { ); diff --git a/src/components/PaymentMethods/PaymentMethods.tsx b/src/components/PaymentMethods/PaymentMethods.tsx index e321c9c..8956b92 100644 --- a/src/components/PaymentMethods/PaymentMethods.tsx +++ b/src/components/PaymentMethods/PaymentMethods.tsx @@ -10,10 +10,9 @@ import { colors, ProGray1 } from "../../ThemeConstants"; import ProInputCard from "../ProInputCard/ProInputCard"; import styles from "./PaymentMethods.module.css"; - const PaymentMethods = () => { const { t } = useTranslation(); - const { paymentMethod } = useAppSelector(selectCart); + const { paymentMethod, orderType } = useAppSelector(selectCart); const dispatch = useAppDispatch(); const options: { @@ -23,11 +22,15 @@ const PaymentMethods = () => { icon?: React.ReactNode; style?: React.CSSProperties; }[] = [ - { - label: t("checkout.creditDebitCard"), - value: "creditDebitCard", - price: t("checkout.expiresIn") + ":12/26", - }, + ...(orderType !== "gift" + ? [ + { + label: t("checkout.creditDebitCard"), + value: "creditDebitCard", + price: t("checkout.expiresIn") + ":12/26", + }, + ] + : []), { label: t("checkout.differentCard"), diff --git a/src/components/ProBottomSheet/ProBottomSheet.tsx b/src/components/ProBottomSheet/ProBottomSheet.tsx index b3622b5..85a2c5c 100644 --- a/src/components/ProBottomSheet/ProBottomSheet.tsx +++ b/src/components/ProBottomSheet/ProBottomSheet.tsx @@ -218,7 +218,7 @@ export function ProBottomSheet({ const contentStyle: React.CSSProperties = { flex: 1, overflow: "auto", - padding: "20px", + padding: "0 20px", backgroundColor: themeName === "dark" ? "#0a0a0a" : "#ffffff", color: themeName === "dark" ? "#ffffff" : "#000000", }; diff --git a/src/features/order/orderSlice.ts b/src/features/order/orderSlice.ts index 3db9a16..55d47bd 100644 --- a/src/features/order/orderSlice.ts +++ b/src/features/order/orderSlice.ts @@ -30,6 +30,7 @@ export interface GiftDetailsType { message: string; senderName: string; senderPhone: string; + senderEmail: string; isSecret: boolean; } @@ -50,6 +51,7 @@ interface CartState { collectionMethod: string; phone: string; paymentMethod: string; + orderType: string; } // localStorage keys @@ -69,6 +71,7 @@ export const CART_STORAGE_KEYS = { COLLECTION_METHOD: 'fascano_collection_method', PHONE: 'fascano_phone', PAYMENT_METHOD: 'fascano_payment_method', + ORDER_TYPE: 'fascano_order_type', } as const; // Utility functions for localStorage @@ -101,6 +104,7 @@ const initialState: CartState = { collectionMethod: getFromLocalStorage(CART_STORAGE_KEYS.COLLECTION_METHOD, ""), phone: getFromLocalStorage(CART_STORAGE_KEYS.PHONE, ""), paymentMethod: getFromLocalStorage(CART_STORAGE_KEYS.PAYMENT_METHOD, ""), + orderType: getFromLocalStorage(CART_STORAGE_KEYS.ORDER_TYPE, ""), }; const orderSlice = createSlice({ @@ -164,7 +168,7 @@ const orderSlice = createSlice({ state.paymentMethod = ""; // Clear all cart data from localStorage if (typeof window !== 'undefined') { - Object.values(CART_STORAGE_KEYS).forEach(key => { + Object.values(CART_STORAGE_KEYS).filter(key => key !== CART_STORAGE_KEYS.ORDER_TYPE).forEach(key => { localStorage.removeItem(key); }); } @@ -296,6 +300,14 @@ const orderSlice = createSlice({ localStorage.setItem(CART_STORAGE_KEYS.PAYMENT_METHOD, JSON.stringify(state.paymentMethod)); } }, + updateOrderType(state, action: PayloadAction) { + state.orderType = action.payload; + + // Sync to localStorage + if (typeof window !== 'undefined') { + localStorage.setItem(CART_STORAGE_KEYS.ORDER_TYPE, JSON.stringify(state.orderType)); + } + }, }, }); @@ -320,6 +332,7 @@ export const { updateCollectionMethod, updatePhone, updatePaymentMethod, + updateOrderType, reset, } = orderSlice.actions; diff --git a/src/pages/cart/components/specialRequest/SpecialRequestCard.tsx b/src/pages/cart/components/specialRequest/SpecialRequestCard.tsx index b5cf388..9d37f79 100644 --- a/src/pages/cart/components/specialRequest/SpecialRequestCard.tsx +++ b/src/pages/cart/components/specialRequest/SpecialRequestCard.tsx @@ -1,13 +1,13 @@ -import { updateSpecialRequest, selectCart } from "features/order/orderSlice.ts"; -import { message, Input } from "antd"; +import { RightOutlined } from "@ant-design/icons"; +import { Input } from "antd"; +import ProInputCard from "components/ProInputCard/ProInputCard.tsx"; +import { selectCart, updateSpecialRequest } from "features/order/orderSlice.ts"; +import useBreakPoint from "hooks/useBreakPoint.ts"; +import { BottomSheet } from "pages/cart/components/specialRequest/BottomSheet.tsx"; +import { Dialog } from "pages/cart/components/specialRequest/Dialog.tsx"; +import { useState } from "react"; import { useTranslation } from "react-i18next"; import { useAppDispatch, useAppSelector } from "redux/hooks.ts"; -import ProInputCard from "components/ProInputCard/ProInputCard.tsx"; -import { RightOutlined } from "@ant-design/icons"; -import { BottomSheet } from "pages/cart/components/specialRequest/BottomSheet.tsx"; -import { useState } from "react"; -import useBreakPoint from "hooks/useBreakPoint.ts"; -import { Dialog } from "pages/cart/components/specialRequest/Dialog.tsx"; import styles from "./SpecialRequestCard.module.css"; export default function SpecialRequestCard() { @@ -20,7 +20,6 @@ export default function SpecialRequestCard() { const handleSpecialRequestSave = (value: string) => { dispatch(updateSpecialRequest(value)); - message.success(t("cart.specialRequest") + " " + t("updatedSuccessfully")); }; const handleSpecialRequestClose = () => { diff --git a/src/pages/checkout/components/AddressSummary.tsx b/src/pages/checkout/components/AddressSummary.tsx index c9ac65a..17519f7 100644 --- a/src/pages/checkout/components/AddressSummary.tsx +++ b/src/pages/checkout/components/AddressSummary.tsx @@ -19,7 +19,7 @@ export const AddressSummary = () => { const dispatch = useAppDispatch(); const { location } = useAppSelector(selectCart); const [isMapBottomSheetOpen, setIsMapBottomSheetOpen] = useState(false); - const orderType = useMemo(() => localStorage.getItem("orderType"), []); // Default to delivery for now + const { orderType } = useAppSelector(selectCart) // Default to delivery for now const handleLocationSave = useCallback( (locationString: string) => { diff --git a/src/pages/checkout/components/BriefMenu.tsx b/src/pages/checkout/components/BriefMenu.tsx index e325fe4..38d3c8e 100644 --- a/src/pages/checkout/components/BriefMenu.tsx +++ b/src/pages/checkout/components/BriefMenu.tsx @@ -11,7 +11,7 @@ import styles from "../../address/address.module.css"; export default function BriefMenu() { const { tables, items } = useAppSelector(selectCart); const { t } = useTranslation(); - const orderType = useMemo(() => localStorage.getItem("orderType"), []); + const { orderType } = useAppSelector(selectCart) const menuItems = useMemo( () => diff --git a/src/pages/checkout/components/CheckoutButton.tsx b/src/pages/checkout/components/CheckoutButton.tsx index 9a6887a..8e6d614 100644 --- a/src/pages/checkout/components/CheckoutButton.tsx +++ b/src/pages/checkout/components/CheckoutButton.tsx @@ -1,13 +1,15 @@ import { Button, FormInstance } from "antd"; +import { selectCart } from "features/order/orderSlice"; import { useCallback, useMemo } from "react"; import { useTranslation } from "react-i18next"; import { useNavigate, useParams } from "react-router-dom"; +import { useAppSelector } from "redux/hooks"; import styles from "../../address/address.module.css"; import useOrder from "../hooks/useOrder"; export default function CheckoutButton({ form }: { form: FormInstance }) { const { t } = useTranslation(); - const orderType = useMemo(() => localStorage.getItem("orderType"), []); + const { orderType } = useAppSelector(selectCart) const navigate = useNavigate(); const { handleCreateOrder } = useOrder(); const { id } = useParams(); diff --git a/src/pages/checkout/components/GiftDetails.tsx b/src/pages/checkout/components/GiftDetails.tsx index 579f12c..20eb6f0 100644 --- a/src/pages/checkout/components/GiftDetails.tsx +++ b/src/pages/checkout/components/GiftDetails.tsx @@ -23,8 +23,7 @@ export const GiftDetails = () => { const { giftDetails } = useAppSelector(selectCart); const [isOfficeBottomSheetOpen, setIsOfficeBottomSheetOpen] = useState(false); const [isInfoButtonSheetOpen, setIsInfoButtonSheetOpen] = useState(false); - - const orderType = useMemo(() => localStorage.getItem("orderType"), []); + const { orderType } = useAppSelector(selectCart); const handleGiftDetailsSave = useCallback( (giftDetailsData: GiftDetailsType) => { diff --git a/src/pages/checkout/components/OfficeDetails.tsx b/src/pages/checkout/components/OfficeDetails.tsx index ebb701b..aaeb9fe 100644 --- a/src/pages/checkout/components/OfficeDetails.tsx +++ b/src/pages/checkout/components/OfficeDetails.tsx @@ -20,7 +20,7 @@ export const OfficeDetails = () => { const { officeDetails } = useAppSelector(selectCart); const [isOfficeBottomSheetOpen, setIsOfficeBottomSheetOpen] = useState(false); - const orderType = useMemo(() => localStorage.getItem("orderType"), []); + const { orderType } = useAppSelector(selectCart) const handleOfficeDetailsSave = useCallback( (officeDetailsData: OfficeDetailsType) => { diff --git a/src/pages/checkout/components/RoomDetails.tsx b/src/pages/checkout/components/RoomDetails.tsx index bb0d8cf..fcf0afa 100644 --- a/src/pages/checkout/components/RoomDetails.tsx +++ b/src/pages/checkout/components/RoomDetails.tsx @@ -5,9 +5,9 @@ import GoldenHouseIcon from "components/Icons/address/GoldenHouseIcon"; import RoomServiceIcon from "components/Icons/address/RoomServiceIcon"; import ProText from "components/ProText"; import { - RoomDetailsType, - selectCart, - updateRoomDetails, + RoomDetailsType, + selectCart, + updateRoomDetails, } from "features/order/orderSlice"; import { useCallback, useMemo, useState } from "react"; import { useTranslation } from "react-i18next"; @@ -20,7 +20,7 @@ export const RoomDetails = () => { const { roomDetails } = useAppSelector(selectCart); const [isRoomBottomSheetOpen, setIsRoomBottomSheetOpen] = useState(false); - const orderType = useMemo(() => localStorage.getItem("orderType"), []); + const { orderType } = useAppSelector(selectCart) const handleRoomDetailsSave = useCallback( (roomDetailsData: RoomDetailsType) => { diff --git a/src/pages/checkout/components/phoneCard.tsx b/src/pages/checkout/components/phoneCard.tsx index 71ffa78..346be23 100644 --- a/src/pages/checkout/components/phoneCard.tsx +++ b/src/pages/checkout/components/phoneCard.tsx @@ -7,21 +7,30 @@ import { useAppDispatch, useAppSelector } from "redux/hooks"; export default function PhoneCard() { const { t } = useTranslation(); const dispatch = useAppDispatch(); - const { phone } = useAppSelector(selectCart); + const { phone, orderType } = useAppSelector(selectCart); + return ( - <> - - - dispatch(updatePhone(e.target.value))} - /> - - - + orderType !== "gift" && ( + <> + + + dispatch(updatePhone(e.target.value))} + /> + + + + ) ); } diff --git a/src/pages/checkout/hooks/useOrder.ts b/src/pages/checkout/hooks/useOrder.ts index 80fc054..effacca 100644 --- a/src/pages/checkout/hooks/useOrder.ts +++ b/src/pages/checkout/hooks/useOrder.ts @@ -5,11 +5,12 @@ import { useTranslation } from "react-i18next"; import { useNavigate, useParams } from "react-router-dom"; import { useCreateOrderMutation } from "redux/api/others"; import { useAppDispatch, useAppSelector } from "redux/hooks"; +import { PAYMENT_CONFIRMATION_URL } from "utils/constants"; import { Customer } from "../../otp/types"; export default function useOrder() { const dispatch = useAppDispatch(); - const router = useNavigate(); + const navigate = useNavigate(); const { t } = useTranslation(); const { id } = useParams(); const restaurantID = localStorage.getItem("restaurantID"); @@ -25,19 +26,22 @@ export default function useOrder() { phone, estimateTime, officeDetails, + orderType, + giftDetails, } = useAppSelector(selectCart); const [createOrder] = useCreateOrderMutation(); const handleCreateOrder = useCallback(() => { createOrder({ - phone: mobilenumber || phone, + phone: mobilenumber || phone || giftDetails?.senderPhone, couponID: coupon, discountAmount: 0, comment: specialRequest, timeslot: "", table_id: tables, - deliveryType: "table", + deliveryType: orderType, + dineType: orderType, type: "table-pickup", user_id: id, restorant_id: restaurantID, @@ -61,13 +65,33 @@ export default function useOrder() { ), useWallet: 0, tip, + ...(orderType === "gift" + ? { + receiverName: giftDetails?.receiverName, + receiverPhone: giftDetails?.receiverPhone, + specialMessage: giftDetails?.message, + keepNameSecret: giftDetails?.isSecret, + senderEmail: giftDetails?.senderEmail, + senderPhone: giftDetails?.senderPhone, + senderName: giftDetails?.senderName, + } + : {}), }) .then((res: any) => { if (res.error) message.error(res.error.data.message || t("order.createOrderFailed")); else { + if (orderType === "gift") + // navigate(`/${PAYMENT_CONFIRMATION_URL}/${res.data.result.orderID}`, { + // replace: false, + // }); + window.location.href = `${PAYMENT_CONFIRMATION_URL}/${res.data.result.orderID}`; + // window.open( + // `${PAYMENT_CONFIRMATION_URL}/${res.data.result.orderID}`, + // ); + else navigate(`/${id}/order/${res.data.result.orderID}`); dispatch(clearCart()); - router(`/${id}/order/${res.data.result.orderID}`); + localStorage.setItem("orderID", res.data.result.orderID); } }) .catch((error: any) => { @@ -77,9 +101,17 @@ export default function useOrder() { createOrder, mobilenumber, phone, + giftDetails?.senderPhone, + giftDetails?.receiverName, + giftDetails?.receiverPhone, + giftDetails?.message, + giftDetails?.isSecret, + giftDetails?.senderEmail, + giftDetails?.senderName, coupon, specialRequest, tables, + orderType, id, restaurantID, items, @@ -88,8 +120,8 @@ export default function useOrder() { estimateTime, tip, t, + navigate, dispatch, - router, ]); return { handleCreateOrder }; } diff --git a/src/pages/menu/components/ResponsiveServices.tsx b/src/pages/menu/components/ResponsiveServices.tsx index 7867d8b..530911e 100644 --- a/src/pages/menu/components/ResponsiveServices.tsx +++ b/src/pages/menu/components/ResponsiveServices.tsx @@ -1,9 +1,10 @@ "use client"; -import { Button, Grid } from "antd"; +import { Button } from "antd"; import DineInIcon from "components/Icons/DineInIcon"; import DownIcon from "components/Icons/DownIcon"; import PickupIcon from "components/Icons/PickupIcon"; +import useBreakPoint from "hooks/useBreakPoint"; import styles from "../menu.module.css"; interface ResponsiveServicesProps { @@ -17,13 +18,12 @@ interface ResponsiveServicesProps { }; } -const { useBreakpoint } = Grid; export default function ResponsiveServices({ orderType, translations }: ResponsiveServicesProps) { - const { xs } = useBreakpoint(); + const { isMobile } = useBreakPoint(); // Hide pickup service if screen width is less than 400px (insufficient for 3 services) - const shouldHidePickup = xs; + const shouldHidePickup = isMobile; return (
diff --git a/src/pages/order/page.tsx b/src/pages/order/page.tsx index 81c7a56..2abae8a 100644 --- a/src/pages/order/page.tsx +++ b/src/pages/order/page.tsx @@ -33,8 +33,6 @@ export default function OrderPage() { }, ); - console.log(orderDetails); - return ( <> {t("order.title")} diff --git a/src/pages/restaurant/RestaurantServices.tsx b/src/pages/restaurant/RestaurantServices.tsx index d776319..4d2906d 100644 --- a/src/pages/restaurant/RestaurantServices.tsx +++ b/src/pages/restaurant/RestaurantServices.tsx @@ -9,9 +9,10 @@ import SendGiftIcon from "components/Icons/SendGiftIcon"; import ToOfficeIcon from "components/Icons/ToOfficeIcon"; import ToRoomIcon from "components/Icons/ToRoomIcon"; import ProTitle from "components/ProTitle"; +import { updateOrderType } from "features/order/orderSlice"; import { useTranslation } from "react-i18next"; import { Link } from "react-router-dom"; -import { useAppSelector } from "redux/hooks"; +import { useAppDispatch, useAppSelector } from "redux/hooks"; import styles from "./restaurant.module.css"; interface RestaurantServicesProps { @@ -37,7 +38,8 @@ export default function RestaurantServices({ const { t } = useTranslation(); const { isRTL } = useAppSelector((state) => state.locale); const id = localStorage.getItem("restaurantName"); - + const dispatch = useAppDispatch(); + const services = [ ...((dineIn && [ { @@ -161,7 +163,7 @@ export default function RestaurantServices({ to={s?.href} key={s?.id} onClick={() => { - localStorage.setItem("orderType", s?.id); + dispatch(updateOrderType(s?.id)); }} style={{ width: "100%", diff --git a/src/redux/api/others.ts b/src/redux/api/others.ts index 51001f1..ff0823e 100644 --- a/src/redux/api/others.ts +++ b/src/redux/api/others.ts @@ -5,7 +5,7 @@ import { ORDERS_URL, PRODUCTS_AND_CATEGORIES_URL, RESTAURANT_DETAILS_URL, - TABLES_URL, + TABLES_URL } from "utils/constants"; import { OrderDetails } from "pages/checkout/hooks/types"; diff --git a/src/utils/constants.ts b/src/utils/constants.ts index 892a14d..cefa1d6 100644 --- a/src/utils/constants.ts +++ b/src/utils/constants.ts @@ -102,3 +102,4 @@ export const TABLES_URL = `${BASE_URL}restaurant/getTables`; export const LOGIN_URL = `${API_BASE_URL}login`; export const SEND_OTP_URL = `${API_BASE_URL}sendOtp`; export const CONFIRM_OTP_URL = `${API_BASE_URL}confirmOtp`; +export const PAYMENT_CONFIRMATION_URL = `https://menu.fascano.com/payment/confirmation`;