redeem: integration
This commit is contained in:
@@ -1,73 +1,51 @@
|
||||
import { Button, Card, Image, Layout, Skeleton } from "antd";
|
||||
import { Button, Card, Image, Layout, QRCode, Skeleton, message } from "antd";
|
||||
|
||||
import ProHeader from "components/ProHeader/ProHeader";
|
||||
import ProText from "components/ProText";
|
||||
import { useEffect, useRef } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useNavigate, useParams } from "react-router-dom";
|
||||
import {
|
||||
useGetOrderDetailsQuery,
|
||||
useGetRestaurantDetailsQuery,
|
||||
} from "redux/api/others";
|
||||
import { useGetRedeemDetailsQuery } from "redux/api/others";
|
||||
import styles from "./redeem.module.css";
|
||||
import QRIcon from "components/Icons/QRIcon";
|
||||
import CopyIcon from "components/Icons/CopyIcon";
|
||||
import { useAppSelector } from "redux/hooks";
|
||||
import { LocationCard } from "./components/LocationCard.tsx";
|
||||
import { GiftItemsCard } from "./components/GiftItemsCard.tsx";
|
||||
import { VoucherBalanceCard } from "./components/VoucherBalanceCard.tsx";
|
||||
import { OrderType } from "pages/checkout/hooks/types.ts";
|
||||
import { Loader } from "components/Loader/Loader.tsx";
|
||||
|
||||
export default function RedeemPage() {
|
||||
const { t } = useTranslation();
|
||||
const { voucherId } = useParams();
|
||||
const { restaurant } = useAppSelector((state) => state.order);
|
||||
const hasRefetchedRef = useRef(false);
|
||||
const navigate = useNavigate();
|
||||
const { subdomain } = useParams();
|
||||
|
||||
const { data: orderDetails, isLoading } = useGetOrderDetailsQuery(
|
||||
{
|
||||
orderID: voucherId || "",
|
||||
restaurantID: localStorage.getItem("restaurantID") || "",
|
||||
},
|
||||
const { data: redeemDetails, isLoading } = useGetRedeemDetailsQuery(
|
||||
voucherId || "",
|
||||
{
|
||||
skip: !voucherId,
|
||||
},
|
||||
);
|
||||
|
||||
// Get restaurant subdomain for refetching
|
||||
const restaurantSubdomain = restaurant?.subdomain;
|
||||
const { refetch: refetchRestaurantDetails } = useGetRestaurantDetailsQuery(
|
||||
restaurantSubdomain || "",
|
||||
{
|
||||
skip: !restaurantSubdomain,
|
||||
},
|
||||
);
|
||||
|
||||
// Reset refetch flag when orderId changes
|
||||
useEffect(() => {
|
||||
hasRefetchedRef.current = false;
|
||||
}, [voucherId]);
|
||||
|
||||
// Refetch restaurant details when order status has alias "closed"
|
||||
useEffect(() => {
|
||||
if (orderDetails?.status && !hasRefetchedRef.current) {
|
||||
const hasClosedStatus = orderDetails.status.some(
|
||||
(status) => status?.alias === "closed",
|
||||
);
|
||||
|
||||
if (hasClosedStatus && restaurantSubdomain) {
|
||||
refetchRestaurantDetails();
|
||||
hasRefetchedRef.current = true;
|
||||
}
|
||||
}
|
||||
}, [orderDetails?.status, restaurantSubdomain, refetchRestaurantDetails]);
|
||||
|
||||
const handleCheckout = () => {
|
||||
navigate(`/${subdomain}/menu?orderType=${OrderType.Redeem}`);
|
||||
};
|
||||
|
||||
const handleCopyVoucherCode = async () => {
|
||||
const voucherCode = redeemDetails?.gift?.voucher_code;
|
||||
if (voucherCode) {
|
||||
try {
|
||||
await navigator.clipboard.writeText(voucherCode);
|
||||
message.success(
|
||||
t("redeem.voucherCodeCopied") || "Voucher code copied!",
|
||||
);
|
||||
} catch (error) {
|
||||
message.error(t("redeem.copyFailed") || "Failed to copy voucher code");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if (isLoading) return <Loader />;
|
||||
|
||||
return (
|
||||
<>
|
||||
<Layout>
|
||||
@@ -96,7 +74,7 @@ export default function RedeemPage() {
|
||||
</ProText>
|
||||
</div>
|
||||
|
||||
{isLoading || !orderDetails?.restaurant_iimage ? (
|
||||
{isLoading || !redeemDetails?.gift?.restaurant_iimage ? (
|
||||
<div className={styles.carouselContainer}>
|
||||
<div className={styles.cardWrapper}>
|
||||
<Skeleton.Image
|
||||
@@ -113,7 +91,7 @@ export default function RedeemPage() {
|
||||
<div className={styles.carouselContainer}>
|
||||
<div className={styles.cardWrapper}>
|
||||
<Image
|
||||
src={orderDetails?.restaurant_iimage}
|
||||
src={redeemDetails?.gift?.card_url}
|
||||
width={205}
|
||||
height={134}
|
||||
className={styles.cardImage}
|
||||
@@ -161,56 +139,28 @@ export default function RedeemPage() {
|
||||
</ProText>
|
||||
</div>
|
||||
|
||||
<Card
|
||||
style={{
|
||||
borderRadius: 0,
|
||||
borderTopRightRadius: 16,
|
||||
borderTopLeftRadius: 16,
|
||||
border: "1px solid transparent",
|
||||
borderImageSource:
|
||||
"radial-gradient(38.92% 103.83% at 49.85% -3.83%, #FFB700 0%, rgba(255, 233, 179, 0) 100%)",
|
||||
borderImageSlice: 1,
|
||||
}}
|
||||
styles={{
|
||||
body: {
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
gap: 24,
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
padding: 32,
|
||||
},
|
||||
}}
|
||||
>
|
||||
<ProText
|
||||
<div>
|
||||
<Card
|
||||
style={{
|
||||
fontWeight: 400,
|
||||
fontStyle: "Regular",
|
||||
fontSize: 14,
|
||||
lineHeight: "140%",
|
||||
letterSpacing: "0%",
|
||||
color: "#95949C",
|
||||
alignItems: "center",
|
||||
borderRadius: 0,
|
||||
borderTopRightRadius: 16,
|
||||
borderTopLeftRadius: 16,
|
||||
border: "1px solid transparent",
|
||||
borderImageSource:
|
||||
"radial-gradient(38.92% 103.83% at 49.85% -3.83%, #FFB700 0%, rgba(255, 233, 179, 0) 100%)",
|
||||
borderImageSlice: 1,
|
||||
}}
|
||||
styles={{
|
||||
body: {
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
gap: 24,
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
padding: 32,
|
||||
},
|
||||
}}
|
||||
>
|
||||
{t("redeem.showThisCodeAtTheRestaurant")}
|
||||
</ProText>
|
||||
<QRIcon />
|
||||
<div style={{ display: "flex", flexDirection: "column", gap: 12 }}>
|
||||
<Button
|
||||
style={{
|
||||
height: 40,
|
||||
borderRadius: 888,
|
||||
gap: 16,
|
||||
opacity: 1,
|
||||
borderWidth: 1,
|
||||
backgroundColor: "var(--background)",
|
||||
}}
|
||||
icon={<CopyIcon className={styles.copyIcon} />}
|
||||
iconPlacement="end"
|
||||
>
|
||||
GFT - 92KD - 7X84
|
||||
</Button>
|
||||
<ProText
|
||||
style={{
|
||||
fontWeight: 400,
|
||||
@@ -222,40 +172,73 @@ export default function RedeemPage() {
|
||||
alignItems: "center",
|
||||
}}
|
||||
>
|
||||
{t("redeem.useThisCodeIfScanningNotPossible")}
|
||||
{t("redeem.showThisCodeAtTheRestaurant")}
|
||||
</ProText>
|
||||
</div>
|
||||
</Card>
|
||||
<QRCode value={redeemDetails?.gift?.gr_url || "-"} />
|
||||
<div
|
||||
style={{ display: "flex", flexDirection: "column", gap: 12 }}
|
||||
>
|
||||
<Button
|
||||
style={{
|
||||
height: 40,
|
||||
borderRadius: 888,
|
||||
gap: 16,
|
||||
opacity: 1,
|
||||
borderWidth: 1,
|
||||
backgroundColor: "var(--background)",
|
||||
}}
|
||||
icon={<CopyIcon className={styles.copyIcon} />}
|
||||
iconPlacement="end"
|
||||
onClick={handleCopyVoucherCode}
|
||||
>
|
||||
{redeemDetails?.gift?.voucher_code}
|
||||
</Button>
|
||||
<ProText
|
||||
style={{
|
||||
fontWeight: 400,
|
||||
fontStyle: "Regular",
|
||||
fontSize: 14,
|
||||
lineHeight: "140%",
|
||||
letterSpacing: "0%",
|
||||
color: "#95949C",
|
||||
alignItems: "center",
|
||||
}}
|
||||
>
|
||||
{t("redeem.useThisCodeIfScanningNotPossible")}
|
||||
</ProText>
|
||||
</div>
|
||||
</Card>
|
||||
|
||||
<div
|
||||
style={{
|
||||
width: "100%",
|
||||
height: 44,
|
||||
opacity: 1,
|
||||
borderBottomRightRadius: 16,
|
||||
borderBottomLeftRadius: 16,
|
||||
paddingTop: 12,
|
||||
paddingBottom: 12,
|
||||
gap: 10,
|
||||
borderTopWidth: 1,
|
||||
background: "#FFF9E6",
|
||||
borderTop: "1px solid #FFEDB0",
|
||||
textAlign: "center",
|
||||
}}
|
||||
>
|
||||
<ProText
|
||||
<div
|
||||
style={{
|
||||
fontSize: 14,
|
||||
fontWeight: 500,
|
||||
fontStyle: "Medium",
|
||||
lineHeight: "140%",
|
||||
letterSpacing: "0%",
|
||||
width: "100%",
|
||||
height: 44,
|
||||
opacity: 1,
|
||||
borderBottomRightRadius: 16,
|
||||
borderBottomLeftRadius: 16,
|
||||
paddingTop: 12,
|
||||
paddingBottom: 12,
|
||||
gap: 10,
|
||||
borderTopWidth: 1,
|
||||
background: "#FFF9E6",
|
||||
borderTop: "1px solid #FFEDB0",
|
||||
textAlign: "center",
|
||||
color: "#E8B400",
|
||||
}}
|
||||
>
|
||||
Active - Expires in 12 days
|
||||
</ProText>
|
||||
<ProText
|
||||
style={{
|
||||
fontSize: 14,
|
||||
fontWeight: 500,
|
||||
fontStyle: "Medium",
|
||||
lineHeight: "140%",
|
||||
letterSpacing: "0%",
|
||||
textAlign: "center",
|
||||
color: "#E8B400",
|
||||
}}
|
||||
>
|
||||
Active - Expires in 12 days
|
||||
</ProText>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
|
||||
Reference in New Issue
Block a user