Merged in fix/hide-cs-rewards-flag (pull request #1065)
fix: hide new cs rewards model behind feature flag Approved-by: Michael Zetterberg Approved-by: Chuma Mcphoy (We Ahead)
This commit is contained in:
@@ -61,3 +61,5 @@ ENABLE_BOOKING_WIDGET_HOTELRESERVATION_PATH="false"
|
||||
SHOW_SITE_WIDE_ALERT="false"
|
||||
SHOW_SIGNUP_FLOW="true"
|
||||
USE_NEW_REWARDS_ENDPOINT="true"
|
||||
|
||||
USE_NEW_REWARD_MODEL="true"
|
||||
|
||||
@@ -45,6 +45,7 @@ GOOGLE_DYNAMIC_MAP_ID="test"
|
||||
HIDE_FOR_NEXT_RELEASE="true"
|
||||
SALESFORCE_PREFERENCE_BASE_URL="test"
|
||||
USE_NEW_REWARDS_ENDPOINT="true"
|
||||
USE_NEW_REWARD_MODEL="true"
|
||||
|
||||
TZ=UTC
|
||||
ENABLE_BOOKING_FLOW="false"
|
||||
|
||||
@@ -53,7 +53,7 @@ export default function ClientCurrentRewards({
|
||||
{reward.label}
|
||||
</Title>
|
||||
</div>
|
||||
{showRedeem && (
|
||||
{showRedeem && "redeem_description" in reward && (
|
||||
<div className={styles.btnContainer}>
|
||||
<Redeem reward={reward} />
|
||||
</div>
|
||||
|
||||
@@ -24,15 +24,15 @@ import { RewardIcon } from "../RewardIcon"
|
||||
import styles from "./current.module.css"
|
||||
|
||||
import type {
|
||||
Redeem,
|
||||
RedeemModalState,
|
||||
RedeemProps,
|
||||
RedeemStep,
|
||||
} from "@/types/components/myPages/myPage/accountPage"
|
||||
|
||||
const MotionOverlay = motion(ModalOverlay)
|
||||
const MotionModal = motion(Modal)
|
||||
|
||||
export default function Redeem({ reward }: Redeem) {
|
||||
export default function Redeem({ reward }: RedeemProps) {
|
||||
const [animation, setAnimation] = useState<RedeemModalState>("unmounted")
|
||||
const intl = useIntl()
|
||||
const update = trpc.contentstack.rewards.redeem.useMutation()
|
||||
@@ -121,9 +121,12 @@ export default function Redeem({ reward }: Redeem) {
|
||||
<Body textAlign="center">{reward.description}</Body>
|
||||
)}
|
||||
|
||||
{redeemStep === "confirmation" && (
|
||||
<Body textAlign="center">{reward.redeem_description}</Body>
|
||||
)}
|
||||
{redeemStep === "confirmation" &&
|
||||
"redeem_description" in reward && (
|
||||
<Body textAlign="center">
|
||||
{reward.redeem_description}
|
||||
</Body>
|
||||
)}
|
||||
</div>
|
||||
{redeemStep === "initial" && (
|
||||
<footer className={styles.modalFooter}>
|
||||
|
||||
@@ -26,7 +26,7 @@ export default async function CurrentRewardsBlock({
|
||||
<ClientCurrentRewards
|
||||
rewards={rewardsResponse.rewards}
|
||||
pageSize={6}
|
||||
showRedeem={env.USE_NEW_REWARDS_ENDPOINT}
|
||||
showRedeem={env.USE_NEW_REWARDS_ENDPOINT && env.USE_NEW_REWARD_MODEL}
|
||||
/>
|
||||
<SectionLink link={link} variant="mobile" />
|
||||
</SectionContainer>
|
||||
|
||||
8
env/server.ts
vendored
8
env/server.ts
vendored
@@ -115,6 +115,13 @@ export const env = createEnv({
|
||||
// transform to boolean
|
||||
.transform((s) => s === "true")
|
||||
.default("false"),
|
||||
USE_NEW_REWARD_MODEL: z
|
||||
.string()
|
||||
// only allow "true" or "false"
|
||||
.refine((s) => s === "true" || s === "false")
|
||||
// transform to boolean
|
||||
.transform((s) => s === "true")
|
||||
.default("false"),
|
||||
},
|
||||
emptyStringAsUndefined: true,
|
||||
runtimeEnv: {
|
||||
@@ -172,6 +179,7 @@ export const env = createEnv({
|
||||
GOOGLE_DYNAMIC_MAP_ID: process.env.GOOGLE_DYNAMIC_MAP_ID,
|
||||
HIDE_FOR_NEXT_RELEASE: process.env.HIDE_FOR_NEXT_RELEASE,
|
||||
USE_NEW_REWARDS_ENDPOINT: process.env.USE_NEW_REWARDS_ENDPOINT,
|
||||
USE_NEW_REWARD_MODEL: process.env.USE_NEW_REWARD_MODEL,
|
||||
ENABLE_BOOKING_FLOW: process.env.ENABLE_BOOKING_FLOW,
|
||||
ENABLE_BOOKING_WIDGET: process.env.ENABLE_BOOKING_WIDGET,
|
||||
ENABLE_BOOKING_WIDGET_HOTELRESERVATION_PATH:
|
||||
|
||||
@@ -7,7 +7,6 @@ query GetRewards($locale: String!, $rewardIds: [String!]) {
|
||||
label
|
||||
grouped_label
|
||||
description
|
||||
redeem_description
|
||||
grouped_description
|
||||
value
|
||||
reward_id
|
||||
|
||||
16
lib/graphql/Query/RewardsWithRedeem.graphql
Normal file
16
lib/graphql/Query/RewardsWithRedeem.graphql
Normal file
@@ -0,0 +1,16 @@
|
||||
query GetRewards($locale: String!, $rewardIds: [String!]) {
|
||||
all_reward(locale: $locale, where: { reward_id_in: $rewardIds }) {
|
||||
items {
|
||||
taxonomies {
|
||||
term_uid
|
||||
}
|
||||
label
|
||||
grouped_label
|
||||
description
|
||||
redeem_description
|
||||
grouped_description
|
||||
value
|
||||
reward_id
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -92,6 +92,30 @@ export const validateApiTierRewardsSchema = z.record(
|
||||
)
|
||||
|
||||
export const validateCmsRewardsSchema = z
|
||||
.object({
|
||||
data: z.object({
|
||||
all_reward: z.object({
|
||||
items: z.array(
|
||||
z.object({
|
||||
taxonomies: z.array(
|
||||
z.object({
|
||||
term_uid: z.string().optional(),
|
||||
})
|
||||
),
|
||||
label: z.string().optional(),
|
||||
reward_id: z.string(),
|
||||
grouped_label: z.string().optional(),
|
||||
description: z.string().optional(),
|
||||
grouped_description: z.string().optional(),
|
||||
value: z.string().optional(),
|
||||
})
|
||||
),
|
||||
}),
|
||||
}),
|
||||
})
|
||||
.transform((data) => data.data.all_reward.items)
|
||||
|
||||
export const validateCmsRewardsWithRedeemSchema = z
|
||||
.object({
|
||||
data: z.object({
|
||||
all_reward: z.object({
|
||||
@@ -125,12 +149,24 @@ export type SurpriseReward = z.output<typeof SurpriseReward>
|
||||
|
||||
export type CmsRewardsResponse = z.input<typeof validateCmsRewardsSchema>
|
||||
|
||||
export type CmsRewardsWithRedeemResponse = z.input<
|
||||
typeof validateCmsRewardsWithRedeemSchema
|
||||
>
|
||||
|
||||
export type CMSReward = z.output<typeof validateCmsRewardsSchema>[0]
|
||||
|
||||
export type CMSRewardWithRedeem = z.output<
|
||||
typeof validateCmsRewardsWithRedeemSchema
|
||||
>[0]
|
||||
|
||||
export type Reward = CMSReward & {
|
||||
id: string | undefined
|
||||
}
|
||||
|
||||
export type RewardWithRedeem = CMSRewardWithRedeem & {
|
||||
id: string | undefined
|
||||
}
|
||||
|
||||
// New endpoint related types and schemas.
|
||||
|
||||
const BenefitReward = z.object({
|
||||
|
||||
@@ -2,8 +2,10 @@ import { metrics } from "@opentelemetry/api"
|
||||
import { unstable_cache } from "next/cache"
|
||||
|
||||
import { Lang } from "@/constants/languages"
|
||||
import { env } from "@/env/server"
|
||||
import * as api from "@/lib/api"
|
||||
import { GetRewards } from "@/lib/graphql/Query/Rewards.graphql"
|
||||
import { GetRewards as GetRewardsWithReedem } from "@/lib/graphql/Query/RewardsWithRedeem.graphql"
|
||||
import { request } from "@/lib/graphql/request"
|
||||
import { notFound } from "@/server/errors/trpc"
|
||||
|
||||
@@ -11,9 +13,11 @@ import { generateLoyaltyConfigTag } from "@/utils/generateTag"
|
||||
|
||||
import {
|
||||
CmsRewardsResponse,
|
||||
CmsRewardsWithRedeemResponse,
|
||||
validateApiAllTiersSchema,
|
||||
validateApiTierRewardsSchema,
|
||||
validateCmsRewardsSchema,
|
||||
validateCmsRewardsWithRedeemSchema,
|
||||
} from "./output"
|
||||
|
||||
const meter = metrics.getMeter("trpc.reward")
|
||||
@@ -196,14 +200,24 @@ export async function getCmsRewards(locale: Lang, rewardIds: string[]) {
|
||||
const tags = rewardIds.map((id) =>
|
||||
generateLoyaltyConfigTag(locale, "reward", id)
|
||||
)
|
||||
const cmsRewardsResponse = await request<CmsRewardsResponse>(
|
||||
GetRewards,
|
||||
{
|
||||
locale: locale,
|
||||
rewardIds,
|
||||
},
|
||||
{ next: { tags }, cache: "force-cache" }
|
||||
)
|
||||
|
||||
const cmsRewardsResponse = env.USE_NEW_REWARD_MODEL
|
||||
? await request<CmsRewardsWithRedeemResponse>(
|
||||
GetRewardsWithReedem,
|
||||
{
|
||||
locale: locale,
|
||||
rewardIds,
|
||||
},
|
||||
{ next: { tags }, cache: "force-cache" }
|
||||
)
|
||||
: await request<CmsRewardsResponse>(
|
||||
GetRewards,
|
||||
{
|
||||
locale: locale,
|
||||
rewardIds,
|
||||
},
|
||||
{ next: { tags }, cache: "force-cache" }
|
||||
)
|
||||
|
||||
if (!cmsRewardsResponse.data) {
|
||||
getAllRewardFailCounter.add(1, {
|
||||
@@ -225,8 +239,9 @@ export async function getCmsRewards(locale: Lang, rewardIds: string[]) {
|
||||
throw notFoundError
|
||||
}
|
||||
|
||||
const validatedCmsRewards =
|
||||
validateCmsRewardsSchema.safeParse(cmsRewardsResponse)
|
||||
const validatedCmsRewards = env.USE_NEW_REWARD_MODEL
|
||||
? validateCmsRewardsWithRedeemSchema.safeParse(cmsRewardsResponse)
|
||||
: validateCmsRewardsSchema.safeParse(cmsRewardsResponse)
|
||||
|
||||
if (!validatedCmsRewards.success) {
|
||||
getAllRewardFailCounter.add(1, {
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
import { z } from "zod"
|
||||
|
||||
import { blocksSchema } from "@/server/routers/contentstack/accountPage/output"
|
||||
import { Reward } from "@/server/routers/contentstack/reward/output"
|
||||
import {
|
||||
Reward,
|
||||
RewardWithRedeem,
|
||||
} from "@/server/routers/contentstack/reward/output"
|
||||
|
||||
import { DynamicContent } from "@/types/trpc/routers/contentstack/blocks"
|
||||
|
||||
@@ -21,13 +24,13 @@ export type ContentProps = {
|
||||
}
|
||||
|
||||
export interface CurrentRewardsClientProps {
|
||||
rewards: Reward[]
|
||||
rewards: (Reward | RewardWithRedeem)[]
|
||||
pageSize: number
|
||||
showRedeem: boolean
|
||||
}
|
||||
|
||||
export interface Redeem {
|
||||
reward: Reward
|
||||
export interface RedeemProps {
|
||||
reward: RewardWithRedeem
|
||||
}
|
||||
|
||||
export type RedeemModalState = "unmounted" | "hidden" | "visible"
|
||||
|
||||
Reference in New Issue
Block a user