diff --git a/src/pages/cart/components/CartDesktopLayout.tsx b/src/pages/cart/components/CartDesktopLayout.tsx new file mode 100644 index 0000000..735f933 --- /dev/null +++ b/src/pages/cart/components/CartDesktopLayout.tsx @@ -0,0 +1,420 @@ +import styles from "pages/cart/cart.module.css"; +import { Row, Col, Button, Card, Input, Divider, Space, message } from "antd"; +import ProTitle from "components/ProTitle.tsx"; +import { colors, ProBlack2 } from "ThemeConstants.ts"; +import ProText from "components/ProText.tsx"; +import EmptyOrdersIcon from "components/Icons/EmptyOrdersIcon.tsx"; +import { Link } from "react-router-dom"; +import ImageWithFallback from "components/ImageWithFallback"; +import ArabicPrice from "components/ArabicPrice"; +import CartActionsButtons from "components/CartActionsButtons/CartActionsButtons.tsx"; +import { CartItem } from "utils/types/appTypes.ts"; +import ProInputCard from "components/ProInputCard/ProInputCard.tsx"; +import { EditOutlined } from "@ant-design/icons"; +import DonateIcon from "components/Icons/cart/DonateIcon.tsx"; +import CouponHeartIcon from "components/Icons/cart/CouponHeart.tsx"; +import DonateHandIcon from "components/Icons/cart/DonateHandIcon.tsx"; +import ProInModalMultiSelect from "components/ProSelect/ProInModalMultiSelect.tsx"; +import { + updateTables, + removeTable, + selectCart, + selectCartTotal, + updateCoupon, + updateTip, +} from "features/order/orderSlice.ts"; +import { CouponDialog } from "components/CustomBottomSheet/CouponDialog.tsx"; +import { TipDialog } from "components/CustomBottomSheet/TipDialog.tsx"; +import { useTranslation } from "react-i18next"; +import { useAppSelector, useAppDispatch } from "redux/hooks.ts"; +import { useState } from "react"; +import { getTableOptions } from "pages/cart/page.tsx"; +import SpecialRequestCard from "pages/cart/components/SpecialRequestCard.tsx"; + +export default function CartDesktopLayout() { + const { t } = useTranslation(); + const dispatch = useAppDispatch(); + const { themeName } = useAppSelector((state) => state.theme); + const { items, coupon, tip, tables } = useAppSelector(selectCart); + const subtotal = useAppSelector(selectCartTotal); + const tax = subtotal * 0.1; // 10% tax + const total = subtotal + tax; + + const [isCouponOpen, setIsCouponOpen] = useState(false); + const [isTipOpen, setIsTipOpen] = useState(false); + + const handleCouponSave = (value: string) => { + dispatch(updateCoupon(value)); + message.success(t("cart.coupon") + " " + t("updatedSuccessfully")); + }; + + const handleCouponClose = () => { + setIsCouponOpen(false); + }; + + const handleTipSave = (value: string) => { + dispatch(updateTip(value)); + message.success(t("cart.tip") + " " + t("updatedSuccessfully")); + }; + + const handleTipClose = () => { + setIsTipOpen(false); + }; + + return ( + <> +
+ + {/* Main Content Column */} + +
+ {/*
+ +
*/} + + {/* Cart Items Section */} +
+
+ + {t("cartItems")} ({items.length}) + + + {items.length === 0 + ? t("emptyCart") + : `${items.length} ${ + items.length === 1 ? t("item") : t("items") + } ${t("inYourCart")}`} + +
+ + {items.length === 0 ? ( +
+
+ +
+ + {t("emptyCart")} + + + {t("emptyCartMessage")} + + + + +
+ ) : ( +
+ {items.map((item, index) => ( + + + +
+ +
+ + + +
+ + {item.name} + + + {item.description} + +
+ + + +
+
+ + + +
+ +
+ +
+
+ ))} +
+ )} +
+
+ + + {/* Sidebar Column */} + +
+ {/* Special Request */} +
+ +
+ + {/* Coupon Code */} +
+ setIsCouponOpen(true)} + > + {t("viewOffers")} + + } + > + + {t("apply")} + + + } + /> + +
+ + {/* Reward Your Waiter */} + +
+
+ +
+
+ {t("rewardYourWaiter")} + {t("rewardYourWaiter100")} +
+
+ + + +
+ + + +
+
+ + {/* Table Number */} +
+ + { + updateTables(value); + }} + onClear={() => { + removeTable(); + }} + /> + +
+ + {/* Order Summary */} + + + {t("orderSummary")} + + + + + +
+ {t("basketTotal")} + +
+
+ {t("discount")} + +
+
+ {t("riderTip")} + +
+ + + +
+ + {t("totalAmount")} + + + + +
+
+
+ + {/* Checkout Button */} + +
+ +
+
+ + {/* Desktop Dialogs */} + + + + + + ); +} diff --git a/src/pages/cart/components/CartMobileTabletLayout.tsx b/src/pages/cart/components/CartMobileTabletLayout.tsx new file mode 100644 index 0000000..640e030 --- /dev/null +++ b/src/pages/cart/components/CartMobileTabletLayout.tsx @@ -0,0 +1,566 @@ +import ProHeader from "components/ProHeader/ProHeader.tsx"; +import styles from "pages/cart/cart.module.css"; +import { Space, Card, Divider, Input, Button, message } from "antd"; +import ProTitle from "components/ProTitle.tsx"; +import { Link, useParams } from "react-router-dom"; +import { colors, ProBlack2 } from "ThemeConstants.ts"; +import { PlusOutlined } from "@ant-design/icons"; +import ProText from "components/ProText.tsx"; +import ArabicPrice from "components/ArabicPrice"; +import ImageWithFallback from "components/ImageWithFallback"; +import CartActionsButtons from "components/CartActionsButtons/CartActionsButtons.tsx"; +import YouMightAlsoLike from "pages/cart/components/YouMightAlsoLike.tsx"; +import ProInputCard from "components/ProInputCard/ProInputCard.tsx"; +import DonateIcon from "components/Icons/cart/DonateIcon.tsx"; +import CouponHeartIcon from "components/Icons/cart/CouponHeart.tsx"; +import ProRatioGroups from "components/ProRatioGroups/ProRatioGroups.tsx"; +import { + updateCollectionMethod, + updateTables, + removeTable, + updateCoupon, + updateTip, + updateEstimateTime, + selectCart, +} from "features/order/orderSlice.ts"; +import DonateHandIcon from "components/Icons/cart/DonateHandIcon.tsx"; +import EditIcon from "components/Icons/EditIcon.tsx"; +import ProInModalMultiSelect from "components/ProSelect/ProInModalMultiSelect.tsx"; +import OrderSummary from "components/OrderSummary/OrderSummary.tsx"; +import { CouponBottomSheet } from "components/CustomBottomSheet/CouponBottomSheet.tsx"; +import { TipBottomSheet } from "components/CustomBottomSheet/TipBottomSheet.tsx"; +import { EstimateTimeBottomSheet } from "components/CustomBottomSheet/EstimateTimeBottomSheet.tsx"; +import { getTableOptions } from "pages/cart/page.tsx"; +import { useAppSelector, useAppDispatch } from "redux/hooks.ts"; +import { useState } from "react"; +import { useTranslation } from "react-i18next"; +import SpecialRequestCard from "pages/cart/components/SpecialRequestCard.tsx"; +import useBreakPoint from "hooks/useBreakPoint.ts"; + +export default function CartMobileTabletLayout() { + const { t } = useTranslation(); + const dispatch = useAppDispatch(); + const { items, coupon, tip, tables, estimateTimeDate, collectionMethod } = + useAppSelector(selectCart); + const { id } = useParams(); + + const { isMobile, isTablet } = useBreakPoint(); + + const getResponsiveClass = () => (isTablet ? "tablet" : "mobile"); + + const { themeName } = useAppSelector((state) => state.theme); + const orderType = localStorage.getItem("orderType"); + + const [isCouponOpen, setIsCouponOpen] = useState(false); + const [estimateWay, setEstimateWay] = useState("now"); + const [isEstimateTimeOpen, setIsEstimateTimeOpen] = useState(false); + const [isTipOpen, setIsTipOpen] = useState(false); + + const handleCouponSave = (value: string) => { + dispatch(updateCoupon(value)); + message.success(t("cart.coupon") + " " + t("updatedSuccessfully")); + }; + + const handleCouponClose = () => { + setIsCouponOpen(false); + }; + + const handleTipSave = (value: string) => { + dispatch(updateTip(value)); + message.success(t("cart.tip") + " " + t("updatedSuccessfully")); + }; + + const handleTipClose = () => { + setIsTipOpen(false); + }; + + const handleEstimateTimeSave = (date: Date, time: string) => { + dispatch(updateEstimateTime({ date, time })); + message.success(t("cart.estimateTime") + " " + t("updatedSuccessfully")); + }; + + const handleEstimateTimeClose = () => { + setIsEstimateTimeOpen(false); + }; + + const getMenuItemImageStyle = () => { + if (isMobile) { + return { + width: 90, + height: 80, + }; + } + return { + width: 120, + height: 120, + }; + }; + return ( + <> + {t("cart.title")} +
+ +
+
+ +
+
+ + {t("cart.yourOrder")} + +
+ + +
+ + {t("cart.addMore")} +
+ +
+ + {items.length >= 1 && ( + + )} + {items.map((item, index) => ( +
+ + +
+ + {item.name} + +
+ + {item.description} + +
+
+ + + +
+
+
+ +
+ +
+
+
+ + {index !== items.length - 1 && ( + + )} +
+ ))} +
+
+
+ + + + {/* Mobile/Tablet layout */} + {/* Special Request */} + + {/* Coupon Code */} + setIsCouponOpen(true)} + > + + {t("cart.viewOffers")} + + +
+ } + > + + {t("cart.apply")} + + + } + /> + + + {/* Car Plate*/} + {orderType === "pickup" && ( + + + + )} + + {/* Estimate Time */} + {(orderType === "delivery" || orderType === "pickup") && ( + + { + if (value === "now") { + setEstimateWay(value); + handleEstimateTimeSave(new Date(), "now"); + } else { + setEstimateWay(value); + setIsEstimateTimeOpen(true); + } + }} + /> + + )} + + {/* Collection Method */} + {orderType === "pickup" && ( + + { + if (value === "cod") { + updateCollectionMethod(value); + } else { + updateCollectionMethod(value); + } + }} + /> + + )} + + {/* Reward Your Waiter */} + +
+
+ +
+
+ + {t("cart.rewardYourWaiter")} + + + {t("cart.rewardYourWaiter100")} + +
+
+ +
+ + + +
+
+ + {/* Table Number */} + {orderType === "dine-in" && ( + + { + updateTables(value); + }} + onClear={() => { + removeTable(); + }} + /> + + )} + + {/* Invoice Summary */} + + + + +
+ + + + + + + +
+ + {/* Mobile/Tablet Bottom Sheets */} + + + + + + + + ); +} diff --git a/src/pages/cart/components/SpecialRequestCard.tsx b/src/pages/cart/components/SpecialRequestCard.tsx new file mode 100644 index 0000000..a76e856 --- /dev/null +++ b/src/pages/cart/components/SpecialRequestCard.tsx @@ -0,0 +1,69 @@ +import { updateSpecialRequest, selectCart } from "features/order/orderSlice.ts"; +import { message, Input } from "antd"; +import { useTranslation } from "react-i18next"; +import { useAppDispatch, useAppSelector } from "redux/hooks.ts"; +import ProInputCard from "components/ProInputCard/ProInputCard.tsx"; +import { colors } from "ThemeConstants.ts"; +import { RightOutlined } from "@ant-design/icons"; +import { SpecialRequestBottomSheet } from "components/CustomBottomSheet/SpecialRequestBottomSheet.tsx"; +import { useState } from "react"; +import useBreakPoint from "hooks/useBreakPoint.ts"; +import { SpecialRequestDialog } from "components/CustomBottomSheet/SpecialRequestDialog.tsx"; + +export default function SpecialRequestCard() { + const { t } = useTranslation(); + const { isDesktop } = useBreakPoint(); + const dispatch = useAppDispatch(); + const { specialRequest } = useAppSelector(selectCart); + + const [isSpecialRequestOpen, setIsSpecialRequestOpen] = useState(false); + + const handleSpecialRequestSave = (value: string) => { + dispatch(updateSpecialRequest(value)); + message.success(t("cart.specialRequest") + " " + t("updatedSuccessfully")); + }; + + const handleSpecialRequestClose = () => { + setIsSpecialRequestOpen(false); + }; + return ( + <> + + setIsSpecialRequestOpen(true)} + > + {t("cart.editNote")} + + } + /> + + {isDesktop ? ( + + ) : ( + + )} + + ); +} diff --git a/src/pages/cart/page.tsx b/src/pages/cart/page.tsx index d52338a..6c74e67 100644 --- a/src/pages/cart/page.tsx +++ b/src/pages/cart/page.tsx @@ -1,110 +1,26 @@ -import ArabicPrice from "components/ArabicPrice"; -import CartActionsButtons from "components/CartActionsButtons/CartActionsButtons"; -import { CouponBottomSheet } from "components/CustomBottomSheet/CouponBottomSheet"; -import { CouponDialog } from "components/CustomBottomSheet/CouponDialog"; -import { SpecialRequestBottomSheet } from "components/CustomBottomSheet/SpecialRequestBottomSheet"; -import { SpecialRequestDialog } from "components/CustomBottomSheet/SpecialRequestDialog"; -import { TipBottomSheet } from "components/CustomBottomSheet/TipBottomSheet"; -import { TipDialog } from "components/CustomBottomSheet/TipDialog"; -import CouponHeartIcon from "components/Icons/cart/CouponHeart"; -import DonateHandIcon from "components/Icons/cart/DonateHandIcon"; -import DonateIcon from "components/Icons/cart/DonateIcon"; -import EmptyOrdersIcon from "components/Icons/EmptyOrdersIcon"; -import ImageWithFallback from "components/ImageWithFallback"; -import ProHeader from "components/ProHeader/ProHeader"; -import ProInputCard from "components/ProInputCard/ProInputCard"; -import ProText from "components/ProText"; -import ProTitle from "components/ProTitle"; -import { - removeTable, - selectCart, - selectCartTotal, - updateCollectionMethod, - updateCoupon, - updateEstimateTime, - updateSpecialRequest, - updateTables, - updateTip, -} from "features/order/orderSlice"; -import { useAppDispatch, useAppSelector } from "redux/hooks"; +import { useEffect } from "react"; -import { EditOutlined, PlusOutlined, RightOutlined } from "@ant-design/icons"; -import { - Button, - Card, - Col, - Divider, - Grid, - Input, - message, - Row, - Space, -} from "antd"; -import { EstimateTimeBottomSheet } from "components/CustomBottomSheet/EstimateTimeBottomSheet"; -import EditIcon from "components/Icons/EditIcon"; -import OrderSummary from "components/OrderSummary/OrderSummary"; -import ProRatioGroups from "components/ProRatioGroups/ProRatioGroups"; -import ProInModalMultiSelect from "components/ProSelect/ProInModalMultiSelect"; -import { useEffect, useState } from "react"; -import { useTranslation } from "react-i18next"; -import { Link, useParams } from "react-router-dom"; -import { colors, ProBlack2 } from "ThemeConstants"; -import { CartItem } from "utils/types/appTypes"; -import styles from "./cart.module.css"; // Import CSS module -import YouMightAlsoLike from "./components/YouMightAlsoLike"; +import CartDesktopLayout from "pages/cart/components/CartDesktopLayout.tsx"; +import i18n from "i18n/i18n.ts"; +import CartMobileTabletLayout from "pages/cart/components/CartMobileTabletLayout.tsx"; +import useBreakPoint from "hooks/useBreakPoint.ts"; -const { useBreakpoint } = Grid; +// Function to get translated table names +export const getTableOptions = () => [ + { id: "1", name: i18n.t("table1") }, + { id: "2", name: i18n.t("table2") }, + { id: "3", name: i18n.t("table3") }, + { id: "4", name: i18n.t("table4") }, + { id: "5", name: i18n.t("table5") }, + { id: "6", name: i18n.t("table6") }, + { id: "7", name: i18n.t("table7") }, + { id: "8", name: i18n.t("table8") }, + { id: "9", name: i18n.t("table9") }, + { id: "10", name: i18n.t("table10") }, +]; export default function CartPage() { - const { t } = useTranslation(); - const dispatch = useAppDispatch(); - const cart = useAppSelector(selectCart); - const { - items, - specialRequest, - coupon, - tip, - tables, - estimateTimeDate, - collectionMethod, - } = cart; - const subtotal = useAppSelector(selectCartTotal); - const tax = subtotal * 0.1; // 10% tax - const total = subtotal + tax; - const { id } = useParams(); - - const { sm, md } = useBreakpoint(); - - // Mock responsive values for now - const isMobile = !sm; - const isTablet = sm && !md; - const isDesktop = md; - const isLargeDesktop = md; - const getResponsiveClass = () => - isDesktop ? "desktop" : isTablet ? "tablet" : "mobile"; - const { themeName } = useAppSelector((state) => state.theme); - const orderType = localStorage.getItem("orderType"); - - // Function to get translated table names - const getTableOptions = () => [ - { id: "1", name: t("table1") }, - { id: "2", name: t("table2") }, - { id: "3", name: t("table3") }, - { id: "4", name: t("table4") }, - { id: "5", name: t("table5") }, - { id: "6", name: t("table6") }, - { id: "7", name: t("table7") }, - { id: "8", name: t("table8") }, - { id: "9", name: t("table9") }, - { id: "10", name: t("table10") }, - ]; - - const [isSpecialRequestOpen, setIsSpecialRequestOpen] = useState(false); - const [isCouponOpen, setIsCouponOpen] = useState(false); - const [estimateWay, setEstimateWay] = useState("now"); - const [isEstimateTimeOpen, setIsEstimateTimeOpen] = useState(false); - const [isTipOpen, setIsTipOpen] = useState(false); - + const { isDesktop } = useBreakPoint(); // Prevent keyboard from appearing automatically on mobile useEffect(() => { // Blur any focused element when component mounts @@ -121,943 +37,11 @@ export default function CartPage() { }); }, []); - const handleSpecialRequestSave = (value: string) => { - dispatch(updateSpecialRequest(value)); - message.success(t("cart.specialRequest") + " " + t("updatedSuccessfully")); - }; - - const handleSpecialRequestClose = () => { - setIsSpecialRequestOpen(false); - }; - - const handleCouponSave = (value: string) => { - dispatch(updateCoupon(value)); - message.success(t("cart.coupon") + " " + t("updatedSuccessfully")); - }; - - const handleCouponClose = () => { - setIsCouponOpen(false); - }; - - const handleTipSave = (value: string) => { - dispatch(updateTip(value)); - message.success(t("cart.tip") + " " + t("updatedSuccessfully")); - }; - - const handleTipClose = () => { - setIsTipOpen(false); - }; - - const handleEstimateTimeSave = (date: Date, time: string) => { - dispatch(updateEstimateTime({ date, time })); - message.success(t("cart.estimateTime") + " " + t("updatedSuccessfully")); - }; - - const handleEstimateTimeClose = () => { - setIsEstimateTimeOpen(false); - }; - - const getMenuItemImageStyle = () => { - if (isMobile) { - return { - width: 90, - height: 80, - }; - } else if (isTablet) { - return { - width: 120, - height: 120, - }; - } else { - return { - width: 140, - height: 140, - }; - } - }; - // Enhanced desktop layout - if (isDesktop || isLargeDesktop) { - return ( - <> -
- - {/* Main Content Column */} - -
- {/*
- -
*/} - - {/* Cart Items Section */} -
-
- - {t("cartItems")} ({items.length}) - - - {items.length === 0 - ? t("emptyCart") - : `${items.length} ${ - items.length === 1 ? t("item") : t("items") - } ${t("inYourCart")}`} - -
- - {items.length === 0 ? ( -
-
- -
- - {t("emptyCart")} - - - {t("emptyCartMessage")} - - - - -
- ) : ( -
- {items.map((item, index) => ( - - - -
- -
- - - -
- - {item.name} - - - {item.description} - -
- - - -
-
- - - -
- -
- -
-
- ))} -
- )} -
-
- - - {/* Sidebar Column */} - -
- {/* Special Request */} -
- - setIsSpecialRequestOpen(true)} - > - {t("edit")} - - } - /> - -
- - {/* Coupon Code */} -
- setIsCouponOpen(true)} - > - {t("viewOffers")} - - } - > - - {t("apply")} - - - } - /> - -
- - {/* Reward Your Waiter */} - -
-
- -
-
- {t("rewardYourWaiter")} - {t("rewardYourWaiter100")} -
-
- - - -
- - - -
-
- - {/* Table Number */} -
- - { - updateTables(value); - }} - onClear={() => { - removeTable(); - }} - /> - -
- - {/* Order Summary */} - - - {t("orderSummary")} - - - - - -
- {t("basketTotal")} - -
-
- {t("discount")} - -
-
- {t("riderTip")} - -
- - - -
- - {t("totalAmount")} - - - - -
-
-
- - {/* Checkout Button */} - -
- -
-
- - {/* Desktop Dialogs */} - - - - - - - ); + if (isDesktop) { + return ; } // Mobile/Tablet Layout (existing code) - return ( - <> - {t("cart.title")} -
- -
-
- -
-
- - {t("cart.yourOrder")} - -
- - -
- - {t("cart.addMore")} -
- -
- - {items.length >= 1 && ( - - )} - {items.map((item, index) => ( -
- - -
- - {item.name} - -
- - {item.description} - -
-
- - - -
-
-
- -
- -
-
-
- - {index !== items.length - 1 && ( - - )} -
- ))} -
-
-
- - - - {/* Mobile/Tablet layout */} - {/* Special Request */} - - setIsSpecialRequestOpen(true)} - > - {t("cart.editNote")} -
- } - /> - - - {/* Coupon Code */} - setIsCouponOpen(true)} - > - - {t("cart.viewOffers")} - - - - } - > - - {t("cart.apply")} - - - } - /> - - - {/* Car Plate*/} - {orderType === "pickup" && ( - - - - )} - - {/* Estimate Time */} - {(orderType === "delivery" || orderType === "pickup") && ( - - { - if (value === "now") { - setEstimateWay(value); - handleEstimateTimeSave(new Date(), "now"); - } else { - setEstimateWay(value); - setIsEstimateTimeOpen(true); - } - }} - /> - - )} - - {/* Collection Method */} - {orderType === "pickup" && ( - - { - if (value === "cod") { - updateCollectionMethod(value); - } else { - updateCollectionMethod(value); - } - }} - /> - - )} - - {/* Reward Your Waiter */} - -
-
- -
-
- - {t("cart.rewardYourWaiter")} - - - {t("cart.rewardYourWaiter100")} - -
-
- -
- - - -
-
- - {/* Table Number */} - {orderType === "dine-in" && ( - - { - updateTables(value); - }} - onClear={() => { - removeTable(); - }} - /> - - )} - - {/* Invoice Summary */} - - - - -
- - - - - - - -
- - {/* Mobile/Tablet Bottom Sheets */} - - - - - - - - - ); + return ; }