feat(LOY-23): redeem benefit modal

This commit is contained in:
Christian Andolf
2024-12-05 14:15:44 +01:00
parent af3c68e464
commit 7be90facd0
16 changed files with 484 additions and 24 deletions

View File

@@ -24,3 +24,8 @@ export const rewardsUpdateInput = z.array(
couponCode: z.string(),
})
)
export const rewardsRedeemInput = z.object({
rewardId: z.string(),
couponCode: z.string().optional(),
})

View File

@@ -106,6 +106,10 @@ export const validateCmsRewardsSchema = z
reward_id: z.string(),
grouped_label: z.string().optional(),
description: z.string().optional(),
redeem_description: z
.string()
.nullable()
.transform((val) => val || ""),
grouped_description: z.string().optional(),
value: z.string().optional(),
})
@@ -121,7 +125,11 @@ export type SurpriseReward = z.output<typeof SurpriseReward>
export type CmsRewardsResponse = z.input<typeof validateCmsRewardsSchema>
export type Reward = z.output<typeof validateCmsRewardsSchema>[0]
export type CMSReward = z.output<typeof validateCmsRewardsSchema>[0]
export type Reward = CMSReward & {
id: string | undefined
}
// New endpoint related types and schemas.

View File

@@ -13,6 +13,7 @@ import {
rewardsAllInput,
rewardsByLevelInput,
rewardsCurrentInput,
rewardsRedeemInput,
rewardsUpdateInput,
} from "./input"
import {
@@ -33,6 +34,9 @@ import {
getCurrentRewardCounter,
getCurrentRewardFailCounter,
getCurrentRewardSuccessCounter,
getRedeemCounter,
getRedeemFailCounter,
getRedeemSuccessCounter,
getUniqueRewardIds,
getUnwrapSurpriseCounter,
getUnwrapSurpriseFailCounter,
@@ -248,9 +252,16 @@ export const rewardQueryRouter = router({
)
.map(({ rewardId }) => rewardId)
const rewards = cmsRewards.filter(
(reward) => !wrappedSurprisesIds.includes(reward.reward_id)
)
const rewards = cmsRewards
.filter((reward) => !wrappedSurprisesIds.includes(reward.reward_id))
.map((reward) => {
return {
...reward,
id: validatedApiRewards.data.find(
({ rewardId }) => rewardId === reward.reward_id
)?.id,
}
})
getCurrentRewardSuccessCounter.add(1)
@@ -427,6 +438,53 @@ export const rewardQueryRouter = router({
getUnwrapSurpriseSuccessCounter.add(1)
return true
}),
redeem: protectedProcedure
.input(rewardsRedeemInput)
.mutation(async ({ input, ctx }) => {
getRedeemCounter.add(1)
const { rewardId, couponCode } = input
const apiResponse = await api.post(
api.endpoints.v1.Profile.Reward.redeem,
{
body: {
rewardId,
couponCode,
},
headers: {
Authorization: `Bearer ${ctx.session.token.access_token}`,
},
}
)
if (!apiResponse.ok) {
const text = await apiResponse.text()
getRedeemFailCounter.add(1, {
error_type: "http_error",
error: JSON.stringify({
status: apiResponse.status,
statusText: apiResponse.statusText,
text,
}),
})
console.error(
"api.redeem error ",
JSON.stringify({
error: {
status: apiResponse.status,
statusText: apiResponse.statusText,
text,
},
})
)
return null
}
getRedeemSuccessCounter.add(1)
return true
}),
})

View File

@@ -53,6 +53,15 @@ export const getUnwrapSurpriseFailCounter = meter.createCounter(
export const getUnwrapSurpriseSuccessCounter = meter.createCounter(
"trpc.contentstack.reward.unwrap-success"
)
export const getRedeemCounter = meter.createCounter(
"trpc.contentstack.reward.redeem"
)
export const getRedeemFailCounter = meter.createCounter(
"trpc.contentstack.reward.redeem-fail"
)
export const getRedeemSuccessCounter = meter.createCounter(
"trpc.contentstack.reward.redeem-success"
)
const ONE_HOUR = 60 * 60