fix(LOY-119): hiding redeemed rewards

some smaller cleanup on coupon property to avoid optional checks
This commit is contained in:
Christian Andolf
2025-02-10 13:37:03 +01:00
parent 967c776ab8
commit 4459d5762c
4 changed files with 35 additions and 11 deletions

View File

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

View File

@@ -146,7 +146,7 @@ export const validateCmsRewardsWithRedeemSchema = z
})
.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>
@@ -207,7 +207,10 @@ const CouponReward = z.object({
redeemLocation: z.string().optional(),
operaRewardId: z.string().default(""),
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(
z.nativeEnum(TierKey).transform((data) => {
return TierKey[data as unknown as Key]

View File

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

View File

@@ -11,6 +11,8 @@ import { notFound } from "@/server/errors/trpc"
import { generateLoyaltyConfigTag } from "@/utils/generateTag"
import {
type ApiReward,
type CategorizedApiReward,
type CmsRewardsResponse,
type CmsRewardsWithRedeemResponse,
validateApiAllTiersSchema,
@@ -264,3 +266,20 @@ export async function getCmsRewards(locale: Lang, rewardIds: string[]) {
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()
}