redeem: initial commit
This commit is contained in:
77
src/pages/redeem/components/GiftItemsCard.module.css
Normal file
77
src/pages/redeem/components/GiftItemsCard.module.css
Normal file
@@ -0,0 +1,77 @@
|
||||
.floatingContainer {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
height: 150px;
|
||||
}
|
||||
|
||||
.floatingPresent {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
animation: float 3s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.floatingShadow {
|
||||
position: absolute;
|
||||
bottom: 10px;
|
||||
left: 50%;
|
||||
width: 80px;
|
||||
height: 20px;
|
||||
background-color: rgba(0, 0, 0, 0.2);
|
||||
border-radius: 50%;
|
||||
filter: blur(6px);
|
||||
z-index: 1;
|
||||
transform-origin: center;
|
||||
transform: translateX(-50%);
|
||||
animation: shadowPulse 3s ease-in-out infinite;
|
||||
}
|
||||
|
||||
@keyframes float {
|
||||
0%,
|
||||
100% {
|
||||
transform: translateY(0px);
|
||||
}
|
||||
50% {
|
||||
transform: translateY(-15px);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes shadowPulse {
|
||||
0%,
|
||||
100% {
|
||||
transform: translateX(-50%) scale(1);
|
||||
opacity: 0.3;
|
||||
}
|
||||
50% {
|
||||
transform: translateX(-50%) scale(0.6);
|
||||
opacity: 0.15;
|
||||
}
|
||||
}
|
||||
|
||||
.orderNotes {
|
||||
gap: 20px;
|
||||
opacity: 1;
|
||||
border-radius: 6px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.menuItemImage {
|
||||
object-fit: cover;
|
||||
border-radius: 8px;
|
||||
transition: transform 0.3s ease;
|
||||
width: 90px;
|
||||
height: 80px;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
.backIcon {
|
||||
position: relative;
|
||||
top: 1px;
|
||||
}
|
||||
|
||||
.nextIcon {
|
||||
position: relative;
|
||||
top: 1px;
|
||||
}
|
||||
328
src/pages/redeem/components/GiftItemsCard.tsx
Normal file
328
src/pages/redeem/components/GiftItemsCard.tsx
Normal file
@@ -0,0 +1,328 @@
|
||||
import { Button, Divider, Space, Switch, Tag, Skeleton } from "antd";
|
||||
import ProInputCard from "components/ProInputCard/ProInputCard";
|
||||
import ProText from "components/ProText";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import styles from "./GiftItemsCard.module.css";
|
||||
import { useParams } from "react-router-dom";
|
||||
import { useGetOrderDetailsQuery } from "redux/api/others";
|
||||
import ImageWithFallback from "components/ImageWithFallback";
|
||||
import { useAppSelector } from "redux/hooks";
|
||||
import useBreakPoint from "hooks/useBreakPoint";
|
||||
import GiftIcon from "components/Icons/GiftIcon";
|
||||
import NextIcon from "components/Icons/NextIcon";
|
||||
import BackIcon from "components/Icons/BackIcon";
|
||||
|
||||
export function GiftItemsCard({ isCart = false }: { isCart?: boolean }) {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const { voucherId } = useParams();
|
||||
const { data: orderDetails, isLoading } = useGetOrderDetailsQuery(
|
||||
{
|
||||
orderID: voucherId || "5711385",
|
||||
restaurantID: localStorage.getItem("restaurantID") || "",
|
||||
},
|
||||
// {
|
||||
// skip: !voucherId,
|
||||
// },
|
||||
);
|
||||
const { isRTL } = useAppSelector((state) => state.locale);
|
||||
const { isMobile, isTablet } = useBreakPoint();
|
||||
const getMenuItemImageStyle = () => {
|
||||
if (isMobile) {
|
||||
return {
|
||||
width: 72,
|
||||
height: 72,
|
||||
};
|
||||
}
|
||||
return {
|
||||
width: 120,
|
||||
height: 120,
|
||||
};
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<ProInputCard
|
||||
title={t("redeem.giftedItems")}
|
||||
titleRight={
|
||||
<>
|
||||
{!isCart && (
|
||||
<Tag
|
||||
style={{
|
||||
height: 23,
|
||||
textAlign: "center",
|
||||
opacity: 1,
|
||||
paddingRight: 10,
|
||||
paddingLeft: 10,
|
||||
borderRadius: 100,
|
||||
fontWeight: 500,
|
||||
fontStyle: "Medium",
|
||||
fontSize: 12,
|
||||
lineHeight: "140%",
|
||||
letterSpacing: "0%",
|
||||
cursor: "pointer",
|
||||
backgroundColor: "#FFF9E6",
|
||||
color: "#B58D00",
|
||||
}}
|
||||
>
|
||||
{t("redeem.pending")}
|
||||
</Tag>
|
||||
)}
|
||||
</>
|
||||
}
|
||||
>
|
||||
{!isCart && (
|
||||
<>
|
||||
<div className={styles.orderNotes}>
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
gap: 7,
|
||||
width: "100%",
|
||||
}}
|
||||
>
|
||||
<ProText
|
||||
style={{
|
||||
fontWeight: 500,
|
||||
fontStyle: "Medium",
|
||||
fontSize: 14,
|
||||
lineHeight: "140%",
|
||||
letterSpacing: "0%",
|
||||
color: "#333333",
|
||||
}}
|
||||
>
|
||||
{t("redeem.redeemGiftedItems")}
|
||||
</ProText>
|
||||
|
||||
<ProText
|
||||
style={{
|
||||
fontWeight: 500,
|
||||
fontStyle: "Medium",
|
||||
fontSize: 12,
|
||||
lineHeight: "140%",
|
||||
letterSpacing: "0%",
|
||||
color: "#777580",
|
||||
}}
|
||||
>
|
||||
{t("redeem.includesFreeItemsInThisOrder")}
|
||||
</ProText>
|
||||
</div>
|
||||
<Switch />
|
||||
</div>
|
||||
|
||||
<Divider style={{ margin: "16px 0" }} />
|
||||
</>
|
||||
)}
|
||||
|
||||
{isLoading ? (
|
||||
// Skeleton loading state
|
||||
<>
|
||||
{[1, 2].map((skeletonIndex) => (
|
||||
<div key={skeletonIndex} style={{ position: "relative" }}>
|
||||
<Space
|
||||
size="middle"
|
||||
style={{
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
justifyContent: "space-between",
|
||||
height: "100%",
|
||||
}}
|
||||
>
|
||||
<Space orientation="vertical" size="small">
|
||||
<div>
|
||||
<Skeleton.Input
|
||||
active
|
||||
style={{
|
||||
width: isMobile ? 150 : 200,
|
||||
height: 20,
|
||||
marginBottom: 8,
|
||||
}}
|
||||
/>
|
||||
<Skeleton.Input
|
||||
active
|
||||
style={{
|
||||
width: isMobile ? 120 : 180,
|
||||
height: 16,
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<Skeleton.Button
|
||||
active
|
||||
style={{
|
||||
width: isMobile ? 80 : 100,
|
||||
height: 21,
|
||||
}}
|
||||
size="small"
|
||||
/>
|
||||
</div>
|
||||
</Space>
|
||||
<div style={{ position: "relative" }}>
|
||||
<Skeleton.Image
|
||||
active
|
||||
style={{
|
||||
width: getMenuItemImageStyle().width,
|
||||
height: getMenuItemImageStyle().height,
|
||||
borderRadius: 8,
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</Space>
|
||||
{skeletonIndex !== 3 && (
|
||||
<Divider style={{ margin: "16px 0" }} />
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
</>
|
||||
) : (
|
||||
orderDetails?.orderItems?.map((item: any, index: number) => (
|
||||
<div key={index} style={{ position: "relative" }}>
|
||||
<Space
|
||||
size="middle"
|
||||
style={{
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
justifyContent: "space-between",
|
||||
height: "100%",
|
||||
}}
|
||||
>
|
||||
<Space orientation="vertical" size="small">
|
||||
<div>
|
||||
<ProText
|
||||
style={{
|
||||
fontWeight: 600,
|
||||
fontStyle: "SemiBold",
|
||||
fontSize: 14,
|
||||
lineHeight: "140%",
|
||||
letterSpacing: "0%",
|
||||
color: "#333333",
|
||||
}}
|
||||
>
|
||||
{item.name}
|
||||
<span
|
||||
style={{
|
||||
fontWeight: 400,
|
||||
}}
|
||||
>
|
||||
{/* {isRTL
|
||||
? (item.variant as Variant)?.optionsAR?.[0]?.value
|
||||
: (item.variant as Variant)?.options?.[0]?.value} */}
|
||||
</span>
|
||||
</ProText>
|
||||
<br />
|
||||
<ProText
|
||||
className={`${styles.itemDescription} responsive-text`}
|
||||
style={{
|
||||
margin: 0,
|
||||
lineClamp: 1,
|
||||
padding: isMobile ? "3px 0" : isTablet ? 8 : 10,
|
||||
fontSize: isMobile ? 12 : isTablet ? 18 : 20,
|
||||
display: "-webkit-box",
|
||||
WebkitBoxOrient: "vertical",
|
||||
WebkitLineClamp: 1,
|
||||
overflow: "hidden",
|
||||
textOverflow: "ellipsis",
|
||||
wordWrap: "break-word",
|
||||
overflowWrap: "break-word",
|
||||
lineHeight: "140%",
|
||||
maxHeight: isMobile ? "3em" : isTablet ? "5em" : "7em",
|
||||
width: "55%",
|
||||
fontWeight: 400,
|
||||
fontStyle: "Regular",
|
||||
letterSpacing: "0%",
|
||||
color: "#777580",
|
||||
}}
|
||||
>
|
||||
{item.name}
|
||||
</ProText>
|
||||
</div>
|
||||
<div>
|
||||
<Button
|
||||
iconPlacement="start"
|
||||
size="small"
|
||||
style={{
|
||||
background: "#F5F5F6",
|
||||
height: 21,
|
||||
border: "none",
|
||||
borderRadius: 888,
|
||||
}}
|
||||
>
|
||||
<GiftIcon />
|
||||
<ProText
|
||||
style={{
|
||||
fontWeight: 500,
|
||||
fontStyle: "Medium",
|
||||
fontSize: 12,
|
||||
lineHeight: "140%",
|
||||
letterSpacing: "0%",
|
||||
textAlign: "right",
|
||||
color: "#7950E6",
|
||||
padding: "2px 8px 2px 0",
|
||||
}}
|
||||
>
|
||||
Gift x {item.qty}
|
||||
</ProText>
|
||||
</Button>
|
||||
</div>
|
||||
</Space>
|
||||
<div style={{ position: "relative" }}>
|
||||
<ImageWithFallback
|
||||
src={item.image}
|
||||
alt={item.name}
|
||||
className={`${styles.menuItemImage} responsive-image`}
|
||||
{...getMenuItemImageStyle()}
|
||||
fallbackSrc={
|
||||
"https://fascano-space.s3.me-central-1.amazonaws.com/uploads/restorants/685a8fc884a8c_large.jpg"
|
||||
}
|
||||
style={{
|
||||
width: 72,
|
||||
height: 72,
|
||||
borderRadius: 8,
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</Space>
|
||||
|
||||
{index !== orderDetails?.orderItems?.length - 1 && (
|
||||
<Divider style={{ margin: "16px 0" }} />
|
||||
)}
|
||||
</div>
|
||||
)) || null
|
||||
)}
|
||||
|
||||
{!isCart && (
|
||||
<>
|
||||
<Divider style={{ margin: "16px 0" }} />
|
||||
|
||||
<Button
|
||||
style={{
|
||||
height: 48,
|
||||
borderRadius: 888,
|
||||
gap: 16,
|
||||
opacity: 1,
|
||||
borderWidth: 1,
|
||||
paddingTop: 8,
|
||||
paddingRight: 32,
|
||||
paddingBottom: 8,
|
||||
paddingLeft: 32,
|
||||
width: "100%",
|
||||
color: "#4C4A58",
|
||||
}}
|
||||
icon={
|
||||
isRTL ? (
|
||||
<BackIcon className={styles.backIcon} iconColor="#FFC600" />
|
||||
) : (
|
||||
<NextIcon className={styles.nextIcon} iconColor="#FFC600" />
|
||||
)
|
||||
}
|
||||
iconPlacement={isRTL ? "start" : "end"}
|
||||
>
|
||||
{t("redeem.viewAll")}
|
||||
</Button>
|
||||
</>
|
||||
)}
|
||||
</ProInputCard>
|
||||
</>
|
||||
);
|
||||
}
|
||||
58
src/pages/redeem/components/LocationCard.module.css
Normal file
58
src/pages/redeem/components/LocationCard.module.css
Normal file
@@ -0,0 +1,58 @@
|
||||
.floatingContainer {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
height: 150px;
|
||||
}
|
||||
|
||||
.floatingPresent {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
animation: float 3s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.floatingShadow {
|
||||
position: absolute;
|
||||
bottom: 10px;
|
||||
left: 50%;
|
||||
width: 80px;
|
||||
height: 20px;
|
||||
background-color: rgba(0, 0, 0, 0.2);
|
||||
border-radius: 50%;
|
||||
filter: blur(6px);
|
||||
z-index: 1;
|
||||
transform-origin: center;
|
||||
transform: translateX(-50%);
|
||||
animation: shadowPulse 3s ease-in-out infinite;
|
||||
}
|
||||
|
||||
@keyframes float {
|
||||
0%,
|
||||
100% {
|
||||
transform: translateY(0px);
|
||||
}
|
||||
50% {
|
||||
transform: translateY(-15px);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes shadowPulse {
|
||||
0%,
|
||||
100% {
|
||||
transform: translateX(-50%) scale(1);
|
||||
opacity: 0.3;
|
||||
}
|
||||
50% {
|
||||
transform: translateX(-50%) scale(0.6);
|
||||
opacity: 0.15;
|
||||
}
|
||||
}
|
||||
|
||||
.orderNotes {
|
||||
gap: 20px;
|
||||
opacity: 1;
|
||||
border-radius: 6px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
94
src/pages/redeem/components/LocationCard.tsx
Normal file
94
src/pages/redeem/components/LocationCard.tsx
Normal file
@@ -0,0 +1,94 @@
|
||||
import { Divider, Tag } from "antd";
|
||||
import ProInputCard from "components/ProInputCard/ProInputCard";
|
||||
import ProText from "components/ProText";
|
||||
import { selectCart } from "features/order/orderSlice";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useAppSelector } from "redux/hooks";
|
||||
import styles from "./LocationCard.module.css";
|
||||
import { GoogleMap } from "components/CustomBottomSheet/GoogleMap";
|
||||
import DirectionsIcon from "components/Icons/DirectionsIcon";
|
||||
|
||||
export function LocationCard() {
|
||||
const { t } = useTranslation();
|
||||
const { restaurant } = useAppSelector(selectCart);
|
||||
|
||||
return (
|
||||
<>
|
||||
<ProInputCard title={t("redeem.restaurantLocation")}>
|
||||
<div className={styles.mapContainer}>
|
||||
<GoogleMap
|
||||
readOnly={true}
|
||||
initialLocation={{
|
||||
lat: parseFloat(restaurant.lat || "0"),
|
||||
lng: parseFloat(restaurant.lng || "0"),
|
||||
address: "",
|
||||
}}
|
||||
height="160px"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<Divider style={{ margin: "16px 0" }} />
|
||||
|
||||
<div className={styles.orderNotes}>
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
gap: 4,
|
||||
width: "100%",
|
||||
}}
|
||||
>
|
||||
<ProText
|
||||
style={{
|
||||
fontWeight: 500,
|
||||
fontStyle: "Medium",
|
||||
fontSize: 14,
|
||||
lineHeight: "140%",
|
||||
letterSpacing: "0%",
|
||||
color: "#333333",
|
||||
}}
|
||||
>
|
||||
{restaurant.restautantName}
|
||||
</ProText>
|
||||
|
||||
<ProText
|
||||
style={{
|
||||
fontWeight: 500,
|
||||
fontStyle: "Medium",
|
||||
fontSize: 14,
|
||||
lineHeight: "140%",
|
||||
letterSpacing: "0%",
|
||||
color: "#777580",
|
||||
}}
|
||||
>
|
||||
{restaurant.address}
|
||||
</ProText>
|
||||
</div>
|
||||
<Tag
|
||||
style={{
|
||||
backgroundColor: "#FFF9E6",
|
||||
color: "#E8B400",
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
gap: 4,
|
||||
}}
|
||||
>
|
||||
<DirectionsIcon />
|
||||
<ProText
|
||||
style={{
|
||||
fontWeight: 500,
|
||||
fontStyle: "Medium",
|
||||
fontSize: 14,
|
||||
lineHeight: "140%",
|
||||
letterSpacing: "0%",
|
||||
color: "#E8B400",
|
||||
}}
|
||||
>
|
||||
{t("redeem.getDirections")}
|
||||
</ProText>
|
||||
</Tag>
|
||||
</div>
|
||||
</ProInputCard>
|
||||
</>
|
||||
);
|
||||
}
|
||||
58
src/pages/redeem/components/VoucherBalanceCard.module.css
Normal file
58
src/pages/redeem/components/VoucherBalanceCard.module.css
Normal file
@@ -0,0 +1,58 @@
|
||||
.floatingContainer {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
height: 150px;
|
||||
}
|
||||
|
||||
.floatingPresent {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
animation: float 3s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.floatingShadow {
|
||||
position: absolute;
|
||||
bottom: 10px;
|
||||
left: 50%;
|
||||
width: 80px;
|
||||
height: 20px;
|
||||
background-color: rgba(0, 0, 0, 0.2);
|
||||
border-radius: 50%;
|
||||
filter: blur(6px);
|
||||
z-index: 1;
|
||||
transform-origin: center;
|
||||
transform: translateX(-50%);
|
||||
animation: shadowPulse 3s ease-in-out infinite;
|
||||
}
|
||||
|
||||
@keyframes float {
|
||||
0%,
|
||||
100% {
|
||||
transform: translateY(0px);
|
||||
}
|
||||
50% {
|
||||
transform: translateY(-15px);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes shadowPulse {
|
||||
0%,
|
||||
100% {
|
||||
transform: translateX(-50%) scale(1);
|
||||
opacity: 0.3;
|
||||
}
|
||||
50% {
|
||||
transform: translateX(-50%) scale(0.6);
|
||||
opacity: 0.15;
|
||||
}
|
||||
}
|
||||
|
||||
.orderNotes {
|
||||
gap: 20px;
|
||||
opacity: 1;
|
||||
border-radius: 6px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
124
src/pages/redeem/components/VoucherBalanceCard.tsx
Normal file
124
src/pages/redeem/components/VoucherBalanceCard.tsx
Normal file
@@ -0,0 +1,124 @@
|
||||
import { Divider, Switch, Tag } from "antd";
|
||||
import ProInputCard from "components/ProInputCard/ProInputCard";
|
||||
import ProText from "components/ProText";
|
||||
import { selectCart } from "features/order/orderSlice";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useAppSelector } from "redux/hooks";
|
||||
import styles from "./VoucherBalanceCard.module.css";
|
||||
import { useNavigate, useParams } from "react-router-dom";
|
||||
import CardAmountIcon from "components/Icons/CardAmountIcon";
|
||||
import ArabicPrice from "components/ArabicPrice";
|
||||
|
||||
export function VoucherBalanceCard() {
|
||||
const { t } = useTranslation();
|
||||
const { giftDetails } = useAppSelector(selectCart);
|
||||
|
||||
const navigate = useNavigate();
|
||||
const { subdomain } = useParams();
|
||||
|
||||
return (
|
||||
<>
|
||||
<ProInputCard
|
||||
title={t("redeem.voucherBalance")}
|
||||
titleRight={
|
||||
<>
|
||||
<Tag
|
||||
style={{
|
||||
height: 23,
|
||||
textAlign: "center",
|
||||
opacity: 1,
|
||||
paddingRight: 10,
|
||||
paddingLeft: 10,
|
||||
borderRadius: 100,
|
||||
fontWeight: 500,
|
||||
fontStyle: "Medium",
|
||||
fontSize: 12,
|
||||
lineHeight: "140%",
|
||||
letterSpacing: "0%",
|
||||
cursor: "pointer",
|
||||
backgroundColor: "#FFF9E6",
|
||||
color: "#B58D00",
|
||||
}}
|
||||
>
|
||||
{t("redeem.pending")}
|
||||
</Tag>
|
||||
</>
|
||||
}
|
||||
>
|
||||
<div className={styles.orderNotes}>
|
||||
<div
|
||||
style={{
|
||||
height: 42,
|
||||
width: 64,
|
||||
backgroundColor: "var(--background)",
|
||||
borderRadius: 8,
|
||||
}}
|
||||
>
|
||||
<CardAmountIcon />
|
||||
</div>
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
gap: 4,
|
||||
width: "100%",
|
||||
}}
|
||||
>
|
||||
<ProText
|
||||
style={{
|
||||
fontWeight: 500,
|
||||
fontStyle: "Medium",
|
||||
fontSize: 14,
|
||||
lineHeight: "140%",
|
||||
letterSpacing: "0%",
|
||||
color: "#777580",
|
||||
}}
|
||||
>
|
||||
{t("redeem.yourGiftCardBalance")}
|
||||
</ProText>
|
||||
|
||||
<ProText
|
||||
style={{
|
||||
fontWeight: 500,
|
||||
fontStyle: "Medium",
|
||||
fontSize: 14,
|
||||
lineHeight: "140%",
|
||||
letterSpacing: "0%",
|
||||
color: "#333333",
|
||||
}}
|
||||
>
|
||||
<ArabicPrice price={giftDetails?.amount || 0} />
|
||||
</ProText>
|
||||
</div>
|
||||
<Switch />
|
||||
</div>
|
||||
|
||||
<Divider style={{ margin: "10px 0" }} />
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
justifyContent: "space-between",
|
||||
}}
|
||||
onClick={() => {
|
||||
navigate(`/${subdomain}/cart`);
|
||||
}}
|
||||
>
|
||||
<ProText
|
||||
style={{
|
||||
fontWeight: 400,
|
||||
fontStyle: "Regular",
|
||||
fontSize: 14,
|
||||
lineHeight: "140%",
|
||||
letterSpacing: "0%",
|
||||
color: "#777580",
|
||||
cursor: "pointer",
|
||||
}}
|
||||
>
|
||||
{t("redeem.voucherWillBeAppliedAtCheckout")}
|
||||
</ProText>
|
||||
</div>
|
||||
</ProInputCard>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
.voucherSummary :global(.ant-card-body) {
|
||||
padding: 16px !important;
|
||||
}
|
||||
|
||||
.voucherSummary {
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.summaryRow {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.summaryDivider {
|
||||
margin: 0 !important;
|
||||
}
|
||||
|
||||
.totalRow {
|
||||
font-weight: bold;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.desktopOrderSummary {
|
||||
background: linear-gradient(135deg, #f8f9fa 0%, #ffffff 100%);
|
||||
border: 1px solid rgba(0, 0, 0, 0.08);
|
||||
}
|
||||
|
||||
.desktopSummaryRow {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 12px 0;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.desktopTotalRow {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 16px 0;
|
||||
margin-top: 16px;
|
||||
}
|
||||
|
||||
/* Enhanced responsive focus states */
|
||||
.voucherSummary:focus {
|
||||
outline: 2px solid var(--primary);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
/* Enhanced responsive animations */
|
||||
@keyframes fadeInUp {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(20px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
/* ===== MEDIA QUERIES ===== */
|
||||
|
||||
/* Tablet styles (769px - 1024px) */
|
||||
@media (min-width: 769px) and (max-width: 1024px) {
|
||||
.summaryRow {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.summaryDivider {
|
||||
margin: 10px 0 !important;
|
||||
}
|
||||
|
||||
.totalRow {
|
||||
font-size: 18px;
|
||||
}
|
||||
}
|
||||
|
||||
/* Desktop styles (1025px+) */
|
||||
@media (min-width: 1025px) {
|
||||
.summaryRow {
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.summaryDivider {
|
||||
margin: 10px 0 !important;
|
||||
}
|
||||
|
||||
.totalRow {
|
||||
font-size: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
/* Focus states for larger screens */
|
||||
@media (min-width: 768px) {
|
||||
.voucherSummary:focus {
|
||||
outline-offset: 4px;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
import { Card, Checkbox, Divider, Space } from "antd";
|
||||
import ArabicPrice from "components/ArabicPrice";
|
||||
import {
|
||||
selectCart,
|
||||
selectCartTotal,
|
||||
selectGrandTotal,
|
||||
} from "features/order/orderSlice";
|
||||
import { OrderType } from "pages/checkout/hooks/types";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useParams } from "react-router-dom";
|
||||
import { useGetRestaurantDetailsQuery } from "redux/api/others";
|
||||
import { useAppSelector } from "redux/hooks";
|
||||
import ProText from "components/ProText";
|
||||
import ProTitle from "components/ProTitle";
|
||||
import styles from "./VoucherSummary.module.css";
|
||||
import { CSSProperties } from "react";
|
||||
|
||||
export default function VoucherSummary() {
|
||||
const { t } = useTranslation();
|
||||
const { subdomain } = useParams();
|
||||
const { data: restaurant } = useGetRestaurantDetailsQuery(subdomain);
|
||||
const subtotal = useAppSelector(selectCartTotal);
|
||||
const grandTotal = useAppSelector(selectGrandTotal);
|
||||
|
||||
const titlesStyle: CSSProperties = {
|
||||
fontWeight: 400,
|
||||
fontStyle: "Regular",
|
||||
fontSize: 12,
|
||||
lineHeight: "140%",
|
||||
letterSpacing: "0%",
|
||||
textAlign: "center",
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<Card className={`${styles.voucherSummary}`}>
|
||||
<ProTitle
|
||||
style={{
|
||||
fontWeight: 500,
|
||||
fontStyle: "Medium",
|
||||
fontSize: 18,
|
||||
lineHeight: "140%",
|
||||
letterSpacing: "0%",
|
||||
color: "#333333",
|
||||
}}
|
||||
>
|
||||
{t("cart.voucherSummary")}
|
||||
</ProTitle>
|
||||
<Divider style={{ margin: "15px 0 15px 0" }} />
|
||||
<Space orientation="vertical" style={{ width: "100%", gap: 16 }}>
|
||||
<div className={styles.summaryRow}>
|
||||
<ProText type="secondary" style={titlesStyle}>
|
||||
{t("cart.voucherBalance")}
|
||||
</ProText>
|
||||
<ArabicPrice price={subtotal} textStyle={titlesStyle} />
|
||||
</div>
|
||||
<div className={styles.summaryRow}>
|
||||
<ProText type="secondary" style={titlesStyle}>
|
||||
{t("cart.voucherApplied")}
|
||||
</ProText>
|
||||
<ArabicPrice
|
||||
price={Number(restaurant?.delivery_fees || 0)}
|
||||
textStyle={{ ...titlesStyle, color: "#434E5C" }}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className={`${styles.summaryRow} ${styles.totalRow}`}>
|
||||
<ProText
|
||||
style={{
|
||||
fontWeight: 600,
|
||||
fontStyle: "SemiBold",
|
||||
fontSize: 14,
|
||||
lineHeight: "140%",
|
||||
letterSpacing: "0%",
|
||||
textAlign: "center",
|
||||
color: "#333333",
|
||||
}}
|
||||
>
|
||||
{t("cart.remainingVoucherAmount")}
|
||||
</ProText>
|
||||
<ArabicPrice
|
||||
price={grandTotal}
|
||||
textStyle={{ ...titlesStyle, color: "#434E5C" }}
|
||||
/>
|
||||
</div>
|
||||
</Space>
|
||||
</Card>
|
||||
</>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user