gift: update UI and voucher & items BS

This commit is contained in:
2025-12-30 11:09:52 +03:00
parent f3b8bdba63
commit 3ed5c4d5d6
17 changed files with 434 additions and 10 deletions

View File

@@ -0,0 +1,24 @@
import { Layout, Spin } from "antd";
import PaymentMethods from "components/PaymentMethods/PaymentMethods";
import ProHeader from "components/ProHeader/ProHeader";
import { useTranslation } from "react-i18next";
import styles from "../address/address.module.css";
import ECardButton from "./components/ECardButton";
import { useGetEGiftCardsQuery } from "redux/api/others";
import ECardList from "./components/ECardList";
export default function EGiftCardsPage() {
const { t } = useTranslation();
const { data: eGiftCards, isLoading } = useGetEGiftCardsQuery();
return (
<Layout>
<ProHeader>{t("checkout.title")}</ProHeader>
<Layout.Content className={styles.checkoutContainer}>
<PaymentMethods />
{isLoading ? <Spin /> : <ECardList eGiftCards={eGiftCards || []} />}
</Layout.Content>
<ECardButton />
</Layout>
);
}

View File

@@ -0,0 +1,37 @@
import { Button, Layout, message } from "antd";
import { useTranslation } from "react-i18next";
import styles from "../../address/address.module.css";
import { useCallback } from "react";
import { useNavigate, useParams } from "react-router-dom";
import { selectCart } from "features/order/orderSlice";
import { useAppSelector } from "redux/hooks";
export default function ECardButton() {
const { t } = useTranslation();
const { subdomain } = useParams();
const navigate = useNavigate();
const { giftDetails } = useAppSelector(selectCart);
const handleSelectCard = useCallback(() => {
if (giftDetails?.cardId) {
navigate(`/${subdomain}/cardDetails/${giftDetails?.cardId}`);
} else {
message.error(t("gift.pleaseSelectCard"));
}
}, [navigate, subdomain, giftDetails?.cardId]);
return (
<>
<Layout.Footer className={styles.checkoutButtonContainer}>
<Button
type="primary"
shape="round"
className={styles.placeOrderButton}
onClick={handleSelectCard}
>
{t("checkout.placeOrder")}
</Button>
</Layout.Footer>
</>
);
}

View File

@@ -0,0 +1,14 @@
import { Card, Image } from "antd";
import { EGiftCard } from "../type";
export default function ECardList({ eGiftCards }: { eGiftCards: EGiftCard[] }) {
return (
<>
{eGiftCards.map((card: EGiftCard) => (
<Card key={card.id}>
<Image src={card.imageURL} alt={card.image} />
</Card>
))}
</>
);
}

View File

@@ -0,0 +1,9 @@
export interface EGiftCard {
id: number;
image: string;
restorant_id: number | null;
is_available: number;
created_at: string;
updated_at: string;
imageURL: string;
}

View File

@@ -5,6 +5,7 @@ import { useTranslation } from "react-i18next";
import { Link, useNavigate, useParams } from "react-router-dom";
import { useAppSelector } from "redux/hooks.ts";
import styles from "./footer.module.css";
import { OrderType } from "pages/checkout/hooks/types";
interface CartFooterProps {
form: FormInstance;
@@ -63,7 +64,9 @@ export default function CartFooter({ form }: CartFooterProps) {
}}
onClick={handleCheckoutClick}
>
{t("cart.checkout")}
{orderType === OrderType.Gift
? t("cart.continueToGiftDetails")
: t("cart.checkout")}
</Button>
</Layout.Footer>
);

View File

@@ -1,4 +1,3 @@
import { ScheduleFilled } from "@ant-design/icons";
import { Card } from "antd";
import BackIcon from "components/Icons/BackIcon";
import DeliveryIcon from "components/Icons/DeliveryIcon";
@@ -11,21 +10,26 @@ import ToRoomIcon from "components/Icons/ToRoomIcon";
import { updateOrderType } from "features/order/orderSlice";
import { OrderType } from "pages/checkout/hooks/types.ts";
import { useTranslation } from "react-i18next";
import { Link, useParams } from "react-router-dom";
import { Link, useNavigate, useParams } from "react-router-dom";
import { useGetRestaurantDetailsQuery } from "redux/api/others";
import { useAppDispatch, useAppSelector } from "redux/hooks";
import styles from "./restaurant.module.css";
import ScheduleOrderIcon from "components/Icons/ScheduleOrderIcon";
import ProText from "components/ProText";
import { GiftTypeBottomSheet } from "components/CustomBottomSheet/GiftTypeBottomSheet";
import { useState } from "react";
export default function RestaurantServices() {
const { t } = useTranslation();
const { isRTL } = useAppSelector((state) => state.locale);
const { subdomain } = useParams();
const navigate = useNavigate();
const dispatch = useAppDispatch();
const { data: restaurant } = useGetRestaurantDetailsQuery(subdomain, {
skip: !subdomain,
});
const [isGiftTypeBottomSheetOpen, setIsGiftTypeBottomSheetOpen] =
useState(false);
const {
dineIn,
@@ -188,12 +192,19 @@ export default function RestaurantServices() {
return (
<div className={getGridClass()}>
{services?.map((s) => {
const isGift = s?.id === OrderType.Gift;
return (
<Link
to={s?.href}
to={isGift ? "#" : s?.href}
key={s?.id}
onClick={() => {
dispatch(updateOrderType(s?.id));
onClick={(e) => {
if (isGift) {
e.preventDefault();
dispatch(updateOrderType(s?.id));
setIsGiftTypeBottomSheetOpen(true);
} else {
dispatch(updateOrderType(s?.id));
}
}}
style={{
width: "100%",
@@ -225,7 +236,7 @@ export default function RestaurantServices() {
lineHeight: "140%",
letterSpacing: "0%",
verticalAlign: "middle",
color: "#434E5C"
color: "#434E5C",
}}
>
{s?.title}
@@ -242,6 +253,14 @@ export default function RestaurantServices() {
</Link>
);
})}
<GiftTypeBottomSheet
isOpen={isGiftTypeBottomSheetOpen}
onClose={() => setIsGiftTypeBottomSheetOpen(false)}
onSave={() => {
setIsGiftTypeBottomSheetOpen(false);
navigate(`/${subdomain}/menu?orderType=${OrderType.Gift}`);
}}
/>
</div>
);
}

View File

@@ -145,7 +145,7 @@
display: grid;
gap: 16px;
padding: 0 1rem;
margin: 10px 0;
margin: 24px 0 10px 0;
}
}