Merged in fix/LOY-119-hide-redeemed-rewards (pull request #1292)

fix(LOY-119): hiding redeemed rewards

Approved-by: Chuma Mcphoy (We Ahead)
This commit is contained in:
Christian Andolf
2025-02-11 12:09:44 +00:00
4 changed files with 35 additions and 11 deletions

View File

@@ -98,8 +98,8 @@ export default function SurprisesNotification({
const updates = surprises const updates = surprises
.map((surprise) => { .map((surprise) => {
const coupons = surprise.coupons const coupons = surprise.coupons
?.map((coupon) => { .map((coupon) => {
if (coupon?.couponCode) { if (coupon.couponCode) {
return { return {
rewardId: surprise.id, rewardId: surprise.id,
couponCode: coupon.couponCode, couponCode: coupon.couponCode,

View File

@@ -146,7 +146,7 @@ export const validateCmsRewardsWithRedeemSchema = z
}) })
.transform((data) => data.data.all_reward.items) .transform((data) => data.data.all_reward.items)
export type ApiReward = z.output<typeof validateApiRewardSchema>[0] export type ApiReward = z.output<typeof validateApiRewardSchema>[number]
export type SurpriseReward = z.output<typeof SurpriseReward> export type SurpriseReward = z.output<typeof SurpriseReward>
@@ -207,7 +207,10 @@ const CouponReward = z.object({
redeemLocation: z.string().optional(), redeemLocation: z.string().optional(),
operaRewardId: z.string().default(""), operaRewardId: z.string().default(""),
status: z.string().optional(), status: z.string().optional(),
coupon: z.array(CouponData).optional(), coupon: z
.array(CouponData)
.optional()
.transform((val) => val || []),
}) })
/** /**
@@ -233,6 +236,10 @@ export const validateCategorizedRewardsSchema = z
})), })),
]) ])
export type CategorizedApiReward = z.output<
typeof validateCategorizedRewardsSchema
>[number]
export const validateApiAllTiersSchema = z.record( export const validateApiAllTiersSchema = z.record(
z.nativeEnum(TierKey).transform((data) => { z.nativeEnum(TierKey).transform((data) => {
return TierKey[data as unknown as Key] return TierKey[data as unknown as Key]

View File

@@ -35,6 +35,7 @@ import {
getCurrentRewardCounter, getCurrentRewardCounter,
getCurrentRewardFailCounter, getCurrentRewardFailCounter,
getCurrentRewardSuccessCounter, getCurrentRewardSuccessCounter,
getNonRedeemedRewardIds,
getRedeemCounter, getRedeemCounter,
getRedeemFailCounter, getRedeemFailCounter,
getRedeemSuccessCounter, getRedeemSuccessCounter,
@@ -226,10 +227,7 @@ export const rewardQueryRouter = router({
return null return null
} }
const rewardIds = validatedApiRewards.data const rewardIds = getNonRedeemedRewardIds(validatedApiRewards.data)
.map((reward) => reward?.rewardId)
.filter((rewardId): rewardId is string => !!rewardId)
.sort()
const cmsRewards = await getCmsRewards(ctx.lang, rewardIds) const cmsRewards = await getCmsRewards(ctx.lang, rewardIds)
@@ -243,7 +241,7 @@ export const rewardQueryRouter = router({
reward.type === "coupon" && reward.type === "coupon" &&
reward.rewardType === "Surprise" && reward.rewardType === "Surprise" &&
"coupon" in reward && "coupon" in reward &&
reward.coupon?.some(({ unwrapped }) => !unwrapped) reward.coupon.some(({ unwrapped }) => !unwrapped)
) )
.map(({ rewardId }) => rewardId) .map(({ rewardId }) => rewardId)
@@ -259,7 +257,7 @@ export const rewardQueryRouter = router({
const redeemableCoupons = const redeemableCoupons =
(apiReward && (apiReward &&
"coupon" in apiReward && "coupon" in apiReward &&
apiReward.coupon?.filter( apiReward.coupon.filter(
(coupon) => coupon.state !== "redeemed" && coupon.unwrapped (coupon) => coupon.state !== "redeemed" && coupon.unwrapped
)) || )) ||
[] []
@@ -381,7 +379,7 @@ export const rewardQueryRouter = router({
} }
const unwrappedCoupons = const unwrappedCoupons =
reward.coupon?.filter((coupon) => !coupon.unwrapped) || [] reward.coupon.filter((coupon) => !coupon.unwrapped) || []
if (unwrappedCoupons.length === 0) { if (unwrappedCoupons.length === 0) {
return false return false
} }

View File

@@ -11,6 +11,8 @@ import { notFound } from "@/server/errors/trpc"
import { generateLoyaltyConfigTag } from "@/utils/generateTag" import { generateLoyaltyConfigTag } from "@/utils/generateTag"
import { import {
type ApiReward,
type CategorizedApiReward,
type CmsRewardsResponse, type CmsRewardsResponse,
type CmsRewardsWithRedeemResponse, type CmsRewardsWithRedeemResponse,
validateApiAllTiersSchema, validateApiAllTiersSchema,
@@ -264,3 +266,20 @@ export async function getCmsRewards(locale: Lang, rewardIds: string[]) {
return validatedCmsRewards.data return validatedCmsRewards.data
} }
export function getNonRedeemedRewardIds(
rewards: Array<ApiReward | CategorizedApiReward>
) {
return rewards
.filter((reward) => {
if ("coupon" in reward && reward.coupon.length > 0) {
if (reward.coupon.every((coupon) => coupon.state === "redeemed")) {
return false
}
}
return true
})
.map((reward) => reward?.rewardId)
.filter((rewardId): rewardId is string => !!rewardId)
.sort()
}