From 4459d5762c03bd713ef18f2f95993e3e6e47ce8e Mon Sep 17 00:00:00 2001 From: Christian Andolf Date: Mon, 10 Feb 2025 13:37:03 +0100 Subject: [PATCH] fix(LOY-119): hiding redeemed rewards some smaller cleanup on coupon property to avoid optional checks --- components/MyPages/Surprises/Client.tsx | 4 ++-- server/routers/contentstack/reward/output.ts | 11 +++++++++-- server/routers/contentstack/reward/query.ts | 12 +++++------- server/routers/contentstack/reward/utils.ts | 19 +++++++++++++++++++ 4 files changed, 35 insertions(+), 11 deletions(-) diff --git a/components/MyPages/Surprises/Client.tsx b/components/MyPages/Surprises/Client.tsx index a39e02841..f37db0eb4 100644 --- a/components/MyPages/Surprises/Client.tsx +++ b/components/MyPages/Surprises/Client.tsx @@ -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, diff --git a/server/routers/contentstack/reward/output.ts b/server/routers/contentstack/reward/output.ts index b31fbe1a6..e9d134703 100644 --- a/server/routers/contentstack/reward/output.ts +++ b/server/routers/contentstack/reward/output.ts @@ -146,7 +146,7 @@ export const validateCmsRewardsWithRedeemSchema = z }) .transform((data) => data.data.all_reward.items) -export type ApiReward = z.output[0] +export type ApiReward = z.output[number] export type SurpriseReward = z.output @@ -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] diff --git a/server/routers/contentstack/reward/query.ts b/server/routers/contentstack/reward/query.ts index d423da2b1..51e111918 100644 --- a/server/routers/contentstack/reward/query.ts +++ b/server/routers/contentstack/reward/query.ts @@ -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 } diff --git a/server/routers/contentstack/reward/utils.ts b/server/routers/contentstack/reward/utils.ts index f8cd7ffc3..e3309417a 100644 --- a/server/routers/contentstack/reward/utils.ts +++ b/server/routers/contentstack/reward/utils.ts @@ -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 +) { + 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() +}