From 1d9ae7190e6b341dc6477f634b80ea2f3ac27adc Mon Sep 17 00:00:00 2001 From: Mohammed Al-yaseen Date: Tue, 13 Jan 2026 23:09:37 +0300 Subject: [PATCH] enhance loyalty section UI --- src/assets/locals/ar.json | 2 +- src/assets/locals/en.json | 6 +- .../OrderSummary/OrderSummary.module.css | 1 + src/components/OrderSummary/OrderSummary.tsx | 95 +++++++++---------- .../EarnLoyaltyPointsCard.module.css | 10 ++ .../EarnLoyaltyPointsCard.tsx | 67 +++++++++++++ src/pages/checkout/page.tsx | 12 ++- src/pages/rewardsAndLoyalty/page.tsx | 35 ++++--- .../rewardsAndLoyalty.module.css | 10 +- 9 files changed, 162 insertions(+), 76 deletions(-) create mode 100644 src/pages/cart/components/earnLoyaltyPointsCard/EarnLoyaltyPointsCard.module.css create mode 100644 src/pages/cart/components/earnLoyaltyPointsCard/EarnLoyaltyPointsCard.tsx diff --git a/src/assets/locals/ar.json b/src/assets/locals/ar.json index 7619ca0..4c9e88f 100644 --- a/src/assets/locals/ar.json +++ b/src/assets/locals/ar.json @@ -92,7 +92,7 @@ "scheduledOrder": "طلب مجدول" }, "promotion": { - "title": "الترويجات", + "title": "عرض التفاصيل", "description": "احصل على خصم 10% على طلبك الأول" } }, diff --git a/src/assets/locals/en.json b/src/assets/locals/en.json index d0da9c6..307b1ad 100644 --- a/src/assets/locals/en.json +++ b/src/assets/locals/en.json @@ -108,7 +108,7 @@ "scheduledOrder": "Scheduled Order" }, "promotion": { - "title": "Promotions", + "title": "Show details", "description": "Get 10% off your first order" } }, @@ -282,7 +282,9 @@ "am": "AM", "pm": "PM", "cannotSelectPastDate": "You cannot select a past date. Please select today or a future date.", - "checkRequiredFields": "Please check required fields" + "checkRequiredFields": "Please check required fields", + "applyYourAvailableRewardsToGetDiscountsOnItemsInYourCart": "Apply your available rewards to get discounts on items in your cart", + "loyalty": "Loyalty" }, "checkout": { "addCarDetails": "Add Car Details", diff --git a/src/components/OrderSummary/OrderSummary.module.css b/src/components/OrderSummary/OrderSummary.module.css index 374e5c0..52f9ec9 100644 --- a/src/components/OrderSummary/OrderSummary.module.css +++ b/src/components/OrderSummary/OrderSummary.module.css @@ -11,6 +11,7 @@ justify-content: space-between; align-items: center; font-size: 16px; + min-height: 24px; } .summaryDivider { diff --git a/src/components/OrderSummary/OrderSummary.tsx b/src/components/OrderSummary/OrderSummary.tsx index dd0f362..91be0f8 100644 --- a/src/components/OrderSummary/OrderSummary.tsx +++ b/src/components/OrderSummary/OrderSummary.tsx @@ -1,4 +1,4 @@ -import { Card, Checkbox, Divider, Space } from "antd"; +import { Card, Checkbox, Divider, Space, Tag } from "antd"; import ArabicPrice from "components/ArabicPrice"; import { selectCart, @@ -69,7 +69,7 @@ export default function OrderSummary() { {t("cart.basketTotal")} - + {orderType === OrderType.Delivery && (
@@ -78,7 +78,7 @@ export default function OrderSummary() {
)} @@ -87,10 +87,42 @@ export default function OrderSummary() { {t("cart.discount")} - +
+ {isHasLoyaltyGift && + useLoyaltyPoints && + highestLoyaltyItem && + restaurant?.is_loyalty_enabled === 1 ? ( + + {t("cart.loyalty")} + + ) : null} + +
)} {orderType !== OrderType.Redeem && ( @@ -100,7 +132,7 @@ export default function OrderSummary() { )} @@ -111,7 +143,7 @@ export default function OrderSummary() { )} @@ -122,7 +154,7 @@ export default function OrderSummary() { )} @@ -133,7 +165,7 @@ export default function OrderSummary() { )} @@ -144,7 +176,7 @@ export default function OrderSummary() { )} @@ -167,7 +199,7 @@ export default function OrderSummary() { - - {isHasLoyaltyGift && - restaurant?.is_loyalty_enabled === 1 && - orderType !== OrderType.Redeem && ( - <> - { - dispatch(updateUseLoyaltyPoints(value.target.checked)); - }} - style={{ marginTop: 8 }} - > - {t("cart.useLoyaltyPoints")} - - - )} - - {isHasLoyaltyGift && - loyaltyValidation.errorMessage && - orderType !== OrderType.Redeem && ( -
- {t(loyaltyValidation.errorMessage)} -
- )} - - {isHasLoyaltyGift && - orderType !== OrderType.Redeem && - useLoyaltyPoints && - highestLoyaltyItem && - restaurant?.is_loyalty_enabled === 1 && ( -
- {t("cart.loyaltyDiscountApplied", { - itemName: highestLoyaltyItem.name, - amount: Math.round(highestLoyaltyItem.price || 0).toFixed(2), - })} -
- )} ); diff --git a/src/pages/cart/components/earnLoyaltyPointsCard/EarnLoyaltyPointsCard.module.css b/src/pages/cart/components/earnLoyaltyPointsCard/EarnLoyaltyPointsCard.module.css new file mode 100644 index 0000000..ca11b40 --- /dev/null +++ b/src/pages/cart/components/earnLoyaltyPointsCard/EarnLoyaltyPointsCard.module.css @@ -0,0 +1,10 @@ +.useLoyaltyPointsContainer { + gap: 20px; + border-radius: 16px; + display: flex; + flex-direction: row; + justify-content: space-between; + align-items: center; + background-color: var(--secondary-background); + width: 100%; +} \ No newline at end of file diff --git a/src/pages/cart/components/earnLoyaltyPointsCard/EarnLoyaltyPointsCard.tsx b/src/pages/cart/components/earnLoyaltyPointsCard/EarnLoyaltyPointsCard.tsx new file mode 100644 index 0000000..7f83e73 --- /dev/null +++ b/src/pages/cart/components/earnLoyaltyPointsCard/EarnLoyaltyPointsCard.tsx @@ -0,0 +1,67 @@ +import { Button, Form, Switch } from "antd"; +import ProInputCard from "components/ProInputCard/ProInputCard.tsx"; +import { useTranslation } from "react-i18next"; +import { useAppDispatch, useAppSelector } from "redux/hooks.ts"; +import { selectCart, updateUseLoyaltyPoints } from "features/order/orderSlice"; +import ProText from "components/ProText"; +import styles from "./EarnLoyaltyPointsCard.module.css"; + +export default function EarnLoyaltyPointsCard() { + const { t } = useTranslation(); + const dispatch = useAppDispatch(); + const { useLoyaltyPoints } = useAppSelector(selectCart); + + return ( + <> + + +
+
+ + {t("cart.useLoyaltyPoints")} + + + + {t( + "cart.applyYourAvailableRewardsToGetDiscountsOnItemsInYourCart", + )} + +
+ { + dispatch(updateUseLoyaltyPoints(!useLoyaltyPoints)); + }} + /> +
+
+
+ + ); +} diff --git a/src/pages/checkout/page.tsx b/src/pages/checkout/page.tsx index e56b359..e532e8a 100644 --- a/src/pages/checkout/page.tsx +++ b/src/pages/checkout/page.tsx @@ -23,6 +23,7 @@ import { CarCard } from "./components/CarCard"; import { CollectWay } from "./components/CollectWay/CollectWay"; import PickupTimeCard from "./components/pickupEstimate/TimeEstimateCard"; import VoucherSummary from "pages/redeem/components/VoucherSummary/VoucherSummary"; +import EarnLoyaltyPointsCard from "pages/cart/components/earnLoyaltyPointsCard/EarnLoyaltyPointsCard"; export default function CheckoutPage() { const { t } = useTranslation(); @@ -85,7 +86,9 @@ export default function CheckoutPage() { */} {/* */} {/* */} - {orderType !== OrderType.Redeem && orderType !== OrderType.Gift && } + {orderType !== OrderType.Redeem && orderType !== OrderType.Gift && ( + + )} {/* Collection Method */} {orderType === OrderType.Pickup && ( @@ -123,7 +126,12 @@ export default function CheckoutPage() { )} {/* Reward Your Waiter */} - {orderType !== OrderType.Redeem && orderType !== OrderType.Gift && } + {orderType !== OrderType.Redeem && orderType !== OrderType.Gift && ( + + )} + {orderType !== OrderType.Redeem && orderType !== OrderType.Gift && ( + + )} diff --git a/src/pages/rewardsAndLoyalty/page.tsx b/src/pages/rewardsAndLoyalty/page.tsx index bc99a4c..6215224 100644 --- a/src/pages/rewardsAndLoyalty/page.tsx +++ b/src/pages/rewardsAndLoyalty/page.tsx @@ -7,8 +7,8 @@ import { useNavigate, useParams } from "react-router-dom"; import styles from "./rewardsAndLoyalty.module.css"; import { OrderType } from "pages/checkout/hooks/types.ts"; -import { useAppSelector } from "redux/hooks"; -import { selectCart } from "features/order/orderSlice"; +import { useAppDispatch, useAppSelector } from "redux/hooks"; +import { selectCart, updateUseLoyaltyPoints } from "features/order/orderSlice"; import CoinsIcon from "components/Icons/CoinsIcon"; import ArabicPrice from "components/ArabicPrice"; import RaiseIcon from "components/Icons/RaiseIcon"; @@ -19,6 +19,7 @@ import dayjs from "dayjs"; import PopularIcon from "components/Icons/PopularIcon"; export default function RewardsAndLoyalityPage() { + const dispatch = useAppDispatch(); const { t } = useTranslation(); const navigate = useNavigate(); const { subdomain } = useParams(); @@ -27,19 +28,17 @@ export default function RewardsAndLoyalityPage() { const loyaltyStamps = restaurant?.loyalty_stamps ?? 0; const customerLoyaltyPoints = restaurant?.customer_loyalty_points ?? 0; const { data: loyaltyHistory } = useGetLoyaltyHistoryQuery(); + const loyaltyHistories = loyaltyHistory?.filter( + (LH) => Number(LH.restaurant_id) === Number(restaurant.restautantId), + ); - console.log(loyaltyHistory); - - // Calculate percentage: (customer_loyalty_points / loyalty_stamps) * 100 - const progressPercent = - loyaltyStamps > 0 - ? Math.min((customerLoyaltyPoints / loyaltyStamps) * 100, 100) - : 0; - - const handleCheckout = () => { - navigate(`/${subdomain}/menu?orderType=${OrderType.Redeem}`); + const handleRedeem = () => { + navigate(`/${subdomain}/menu?orderType=${OrderType.DineIn}`); + dispatch(updateUseLoyaltyPoints(true)); }; + const currentStampRound = customerLoyaltyPoints % loyaltyStamps; + return ( <> @@ -49,7 +48,7 @@ export default function RewardsAndLoyalityPage() {
(
- {Number(customerLoyaltyPoints / loyaltyStamps).toFixed( - 0, - )} + {currentStampRound} / {loyaltyStamps} 0 - ? loyaltyHistory.map((item: any, index: number) => ({ + loyaltyHistories && loyaltyHistories.length > 0 + ? loyaltyHistories.map((item: any, index: number) => ({ content: (
{/*