-
+ {currentRewards.map((reward, idx) => {
+ const earliestExpirationDate =
+ "coupons" in reward
+ ? getEarliestExpirationDate(reward.coupons)
+ : null
+
+ return (
+
+
+
+ {showRedeem && (
+
+ )}
+
+ {reward.label}
+
+
+ {earliestExpirationDate ? (
+
+ ) : null}
- )}
-
- ))}
+
+ {showRedeem && "redeem_description" in reward && (
+
+
+
+ )}
+
+ )
+ })}
{totalPages > 1 && (
expiresAt)
- .filter((expiresAt): expiresAt is string => !!expiresAt)
- .reduce((earliestDate: Dayjs | null, expiresAt) => {
- const expiresAtDate = dt(expiresAt)
- if (!earliestDate) {
- return expiresAtDate
- }
-
- return earliestDate.isBefore(expiresAtDate) ? earliestDate : expiresAtDate
- }, null)
+ const earliestExpirationDate = getEarliestExpirationDate(surprise.coupons)
return (
{surprise.description}
{earliestExpirationDate ? (
-
-
- {intl.formatMessage(
- { id: "Valid through {expirationDate}" },
- {
- expirationDate: dt(earliestExpirationDate)
- .locale(lang)
- .format("D MMM YYYY"),
- }
- )}
-
-
+
) : null}
)
diff --git a/apps/scandic-web/components/MyPages/Surprises/surprises.module.css b/apps/scandic-web/components/MyPages/Surprises/surprises.module.css
index 99f290ceb..8b5d24e50 100644
--- a/apps/scandic-web/components/MyPages/Surprises/surprises.module.css
+++ b/apps/scandic-web/components/MyPages/Surprises/surprises.module.css
@@ -125,16 +125,6 @@
transform: rotate(180deg);
}
-.badge {
- padding: var(--Spacing-x1) var(--Spacing-x-one-and-half);
- display: flex;
- flex-direction: column;
- align-items: center;
- gap: var(--Spacing-x-half);
- background-color: var(--Base-Surface-Secondary-light-Normal);
- border-radius: var(--Corner-radius-Small);
-}
-
.close {
background: none;
border: none;
diff --git a/apps/scandic-web/components/Rewards/ExpirationDate/expirationDate.module.css b/apps/scandic-web/components/Rewards/ExpirationDate/expirationDate.module.css
new file mode 100644
index 000000000..6587d7645
--- /dev/null
+++ b/apps/scandic-web/components/Rewards/ExpirationDate/expirationDate.module.css
@@ -0,0 +1,9 @@
+.badge {
+ padding: var(--Spacing-x1) var(--Spacing-x-one-and-half);
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: var(--Spacing-x-half);
+ background-color: var(--Base-Surface-Secondary-light-Normal);
+ border-radius: var(--Corner-radius-Small);
+}
diff --git a/apps/scandic-web/components/Rewards/ExpirationDate/index.tsx b/apps/scandic-web/components/Rewards/ExpirationDate/index.tsx
new file mode 100644
index 000000000..48f81a3be
--- /dev/null
+++ b/apps/scandic-web/components/Rewards/ExpirationDate/index.tsx
@@ -0,0 +1,36 @@
+"use client"
+
+import { useIntl } from "react-intl"
+
+import { dt } from "@/lib/dt"
+
+import Body from "@/components/TempDesignSystem/Text/Body"
+import useLang from "@/hooks/useLang"
+
+import styles from "./expirationDate.module.css"
+
+import type { Dayjs } from "dayjs"
+
+export default function ExpirationDate({
+ expirationDate,
+}: {
+ expirationDate: Dayjs | string
+}) {
+ const intl = useIntl()
+ const lang = useLang()
+
+ return (
+
+
+ {intl.formatMessage(
+ { id: "Valid through {expirationDate}" },
+ {
+ expirationDate: dt(expirationDate)
+ .locale(lang)
+ .format("D MMM YYYY"),
+ }
+ )}
+
+
+ )
+}
diff --git a/apps/scandic-web/server/routers/contentstack/reward/output.ts b/apps/scandic-web/server/routers/contentstack/reward/output.ts
index 3d6a0b20e..6bc19fbe2 100644
--- a/apps/scandic-web/server/routers/contentstack/reward/output.ts
+++ b/apps/scandic-web/server/routers/contentstack/reward/output.ts
@@ -212,6 +212,7 @@ export type Reward = CMSReward & {
rewardTierLevel: string | undefined
operaRewardId: string
couponCode: string | undefined
+ coupons: Coupon[]
}
export type RewardWithRedeem = CMSRewardWithRedeem & {
@@ -221,10 +222,18 @@ export type RewardWithRedeem = CMSRewardWithRedeem & {
rewardTierLevel: string | undefined
operaRewardId: string
couponCode: string | undefined
+ coupons: Coupon[]
+}
+
+export interface Coupon {
+ couponCode?: string
+ expiresAt?: string
+ unwrapped: boolean
+ state: "claimed" | "redeemed" | "viewed"
}
export interface Surprise extends Omit {
- coupons: { couponCode?: string | undefined; expiresAt?: string }[]
+ coupons: Coupon[]
}
// New endpoint related types and schemas.
diff --git a/apps/scandic-web/server/routers/contentstack/reward/query.ts b/apps/scandic-web/server/routers/contentstack/reward/query.ts
index b8f8b9a5f..21d7be257 100644
--- a/apps/scandic-web/server/routers/contentstack/reward/query.ts
+++ b/apps/scandic-web/server/routers/contentstack/reward/query.ts
@@ -287,6 +287,8 @@ export const rewardQueryRouter = router({
? apiReward.operaRewardId
: "",
couponCode: firstRedeemableCouponToExpire,
+ coupons:
+ apiReward && "coupon" in apiReward ? apiReward.coupon || [] : [],
}
})
diff --git a/apps/scandic-web/utils/rewards.ts b/apps/scandic-web/utils/rewards.ts
index 8bde3f671..557cc17b4 100644
--- a/apps/scandic-web/utils/rewards.ts
+++ b/apps/scandic-web/utils/rewards.ts
@@ -3,49 +3,74 @@ import {
REWARD_IDS,
REWARD_TYPES,
} from "@/constants/rewards"
+import { dt } from "@/lib/dt"
+
+import type { Dayjs } from "dayjs"
import type {
RestaurantRewardId,
RewardId,
RewardType,
} from "@/types/components/myPages/rewards"
-import type { RewardWithRedeem } from "@/server/routers/contentstack/reward/output"
+import type {
+ Coupon,
+ RewardWithRedeem,
+} from "@/server/routers/contentstack/reward/output"
-export function isValidRewardId(id: string): id is RewardId {
+export {
+ getEarliestExpirationDate,
+ getRewardType,
+ isOnSiteTierReward,
+ isRestaurantOnSiteTierReward,
+ isRestaurantReward,
+ isTierType,
+ isValidRewardId,
+ redeemLocationIsOnSite,
+}
+
+function isValidRewardId(id: string): id is RewardId {
return Object.values(REWARD_IDS).includes(id)
}
-export function isRestaurantReward(
- rewardId: string
-): rewardId is RestaurantRewardId {
+function isRestaurantReward(rewardId: string): rewardId is RestaurantRewardId {
return RESTAURANT_REWARD_IDS.some((id) => id === rewardId)
}
-export function redeemLocationIsOnSite(
+function redeemLocationIsOnSite(
location: RewardWithRedeem["redeemLocation"]
): location is "On-site" {
return location === "On-site"
}
-export function isTierType(
- type: RewardWithRedeem["rewardType"]
-): type is "Tier" {
+function isTierType(type: RewardWithRedeem["rewardType"]): type is "Tier" {
return type === "Tier"
}
-export function isOnSiteTierReward(reward: RewardWithRedeem): boolean {
+function isOnSiteTierReward(reward: RewardWithRedeem): boolean {
return (
redeemLocationIsOnSite(reward.redeemLocation) &&
isTierType(reward.rewardType)
)
}
-export function isRestaurantOnSiteTierReward(
- reward: RewardWithRedeem
-): boolean {
+function isRestaurantOnSiteTierReward(reward: RewardWithRedeem): boolean {
return isOnSiteTierReward(reward) && isRestaurantReward(reward.reward_id)
}
-export function getRewardType(type?: string): RewardType | null {
+function getRewardType(type?: string): RewardType | null {
return REWARD_TYPES.find((t) => t === type) ?? null
}
+
+function getEarliestExpirationDate(coupons: Coupon[]) {
+ return coupons
+ .map(({ expiresAt }) => expiresAt)
+ .filter((expiresAt): expiresAt is string => !!expiresAt)
+ .reduce((earliestDate: Dayjs | null, expiresAt) => {
+ const expiresAtDate = dt(expiresAt)
+ if (!earliestDate) {
+ return expiresAtDate
+ }
+
+ return earliestDate.isBefore(expiresAtDate) ? earliestDate : expiresAtDate
+ }, null)
+}