From da31539610df91625655551d0a1d4cd3f6f630c5 Mon Sep 17 00:00:00 2001 From: Chuma McPhoy Date: Mon, 13 Jan 2025 13:45:13 +0100 Subject: [PATCH] refactor(LOY-62): implement code review feedback --- .../Rewards/CurrentLevel/Client.tsx | 98 ------------------- .../Rewards/CurrentRewards/Client.tsx | 5 + .../Rewards/ScriptedRewardText/index.tsx | 54 ++++------ constants/membershipLevels.ts | 12 ++- constants/rewards.ts | 6 ++ server/routers/contentstack/reward/output.ts | 2 - server/routers/contentstack/reward/query.ts | 1 + types/components/myPages/rewards.ts | 8 +- utils/membershipLevels.ts | 5 + utils/rewards.ts | 13 ++- 10 files changed, 61 insertions(+), 143 deletions(-) delete mode 100644 components/Blocks/DynamicContent/Rewards/CurrentLevel/Client.tsx create mode 100644 utils/membershipLevels.ts diff --git a/components/Blocks/DynamicContent/Rewards/CurrentLevel/Client.tsx b/components/Blocks/DynamicContent/Rewards/CurrentLevel/Client.tsx deleted file mode 100644 index a9f6d4bd3..000000000 --- a/components/Blocks/DynamicContent/Rewards/CurrentLevel/Client.tsx +++ /dev/null @@ -1,98 +0,0 @@ -"use client" - -import { trpc } from "@/lib/trpc/client" -import { Reward } from "@/server/routers/contentstack/reward/output" - -import Image from "@/components/Image" -import LoadingSpinner from "@/components/LoadingSpinner" -import Grids from "@/components/TempDesignSystem/Grids" -import ShowMoreButton from "@/components/TempDesignSystem/ShowMoreButton" -import Title from "@/components/TempDesignSystem/Text/Title" -import useLang from "@/hooks/useLang" - -import ScriptedRewardText from "../ScriptedRewardText" -import Redeem from "./Redeem" - -import styles from "./current.module.css" - -import type { CurrentRewardsClientProps } from "@/types/components/myPages/myPage/accountPage" - -export default function ClientCurrentRewards({ - initialCurrentRewards, - showRedeem, -}: CurrentRewardsClientProps) { - const lang = useLang() - const { data, isFetching, fetchNextPage, hasNextPage, isLoading } = - trpc.contentstack.rewards.current.useInfiniteQuery( - { - limit: 3, - lang, - }, - { - getNextPageParam: (lastPage) => lastPage?.nextCursor, - initialData: { - pageParams: [undefined, 1], - pages: [initialCurrentRewards], - }, - } - ) - function loadMoreData() { - if (hasNextPage) { - fetchNextPage() - } - } - const filteredRewards = data?.pages.filter((page) => page?.rewards) ?? [] - const rewards = filteredRewards - .flatMap((page) => page?.rewards) - .filter((reward): reward is Reward => !!reward) - - if (isLoading) { - return - } - - if (!rewards.length) { - return null - } - - return ( -
- - {rewards.map((reward, idx) => ( -
-
- {reward.label - - - {reward.label} - -
- {showRedeem && ( -
- -
- )} -
- ))} -
- {hasNextPage && - (isFetching ? ( - - ) : ( - - ))} -
- ) -} diff --git a/components/Blocks/DynamicContent/Rewards/CurrentRewards/Client.tsx b/components/Blocks/DynamicContent/Rewards/CurrentRewards/Client.tsx index 6dab0e030..742ea1bbf 100644 --- a/components/Blocks/DynamicContent/Rewards/CurrentRewards/Client.tsx +++ b/components/Blocks/DynamicContent/Rewards/CurrentRewards/Client.tsx @@ -3,6 +3,7 @@ import { useRef, useState } from "react" import { RewardIcon } from "@/components/Blocks/DynamicContent/Rewards/RewardIcon" +import ScriptedRewardText from "@/components/Blocks/DynamicContent/Rewards/ScriptedRewardText" import Pagination from "@/components/MyPages/Pagination" import Grids from "@/components/TempDesignSystem/Grids" import Title from "@/components/TempDesignSystem/Text/Title" @@ -45,6 +46,10 @@ export default function ClientCurrentRewards({
+ = { - [MembershipLevelEnum.L1]: "New Friend", - [MembershipLevelEnum.L2]: "Good Friend", - [MembershipLevelEnum.L3]: "Close Friend", - [MembershipLevelEnum.L4]: "Dear Friend", - [MembershipLevelEnum.L5]: "Loyal Friend", - [MembershipLevelEnum.L6]: "True Friend", - [MembershipLevelEnum.L7]: "Best Friend", -} +import type { CouponRewardType } from "@/types/components/myPages/rewards" export default function ScriptedRewardText({ rewardType, @@ -25,31 +15,21 @@ export default function ScriptedRewardText({ }: ScriptedRewardTextProps) { const intl = useIntl() - let label: string | null = null - - switch (rewardType) { - case "Tier": - if (rewardTierLevel && isMembershipLevel(rewardTierLevel)) { - label = TIER_TO_FRIEND_MAP[rewardTierLevel] - } - break - - case "Campaign": - label = intl.formatMessage({ id: "Campaign" }) - break - - case "Surprise": - label = intl.formatMessage({ id: "Surprise!" }) - break - - case "Member-voucher": - label = intl.formatMessage({ id: "Voucher" }) - break - - default: - label = null + const couponLabelMap: Record<CouponRewardType, string> = { + Campaign: intl.formatMessage({ id: "Campaign" }), + Surprise: intl.formatMessage({ id: "Surprise!" }), + "Member-voucher": intl.formatMessage({ id: "Voucher" }), } + const label = + rewardTierLevel && isMembershipLevel(rewardTierLevel) + ? TIER_TO_FRIEND_MAP[rewardTierLevel] + : isCouponRewardType(rewardType) + ? couponLabelMap[rewardType] + : null + + if (!label) return null + return ( <BiroScript type="two" color="red" tilted="small"> {label} diff --git a/constants/membershipLevels.ts b/constants/membershipLevels.ts index 19e8711db..692d4e14b 100644 --- a/constants/membershipLevels.ts +++ b/constants/membershipLevels.ts @@ -18,10 +18,14 @@ export enum MembershipLevelEnum { L7 = "L7", } -export function isMembershipLevel(value: string): value is MembershipLevelEnum { - return Object.values(MembershipLevelEnum).includes( - value as MembershipLevelEnum - ) +export const TIER_TO_FRIEND_MAP: Record<MembershipLevelEnum, string> = { + [MembershipLevelEnum.L1]: "New Friend", + [MembershipLevelEnum.L2]: "Good Friend", + [MembershipLevelEnum.L3]: "Close Friend", + [MembershipLevelEnum.L4]: "Dear Friend", + [MembershipLevelEnum.L5]: "Loyal Friend", + [MembershipLevelEnum.L6]: "True Friend", + [MembershipLevelEnum.L7]: "Best Friend", } export type MembershipLevel = keyof typeof MembershipLevelEnum diff --git a/constants/rewards.ts b/constants/rewards.ts index 56a743ca4..98c39a2e2 100644 --- a/constants/rewards.ts +++ b/constants/rewards.ts @@ -37,3 +37,9 @@ export const RESTAURANT_REWARD_IDS = [ REWARD_IDS.FreeKidsDrink, REWARD_IDS.FreeBreakfast, ] as const + +export const COUPON_REWARD_TYPES = [ + "Surprise", + "Campaign", + "Member-voucher", +] as const diff --git a/server/routers/contentstack/reward/output.ts b/server/routers/contentstack/reward/output.ts index 46cc27a47..59e21d60a 100644 --- a/server/routers/contentstack/reward/output.ts +++ b/server/routers/contentstack/reward/output.ts @@ -239,5 +239,3 @@ export const validateApiAllTiersSchema = z.record( ) export type RedeemLocation = "Non-redeemable" | "On-site" | "Online" - -export type RewardType = "Tier" | "Member-voucher" | "Surprise" | "Campaign" diff --git a/server/routers/contentstack/reward/query.ts b/server/routers/contentstack/reward/query.ts index 202b148f1..856e4dbe7 100644 --- a/server/routers/contentstack/reward/query.ts +++ b/server/routers/contentstack/reward/query.ts @@ -378,6 +378,7 @@ export const rewardQueryRouter = router({ ...reward, id: surprise.id, rewardType: surprise.rewardType, + rewardTierLevel: undefined, redeemLocation: surprise.redeemLocation, coupons: "coupon" in surprise ? surprise.coupon || [] : [], } diff --git a/types/components/myPages/rewards.ts b/types/components/myPages/rewards.ts index 4f67602be..a25b3805f 100644 --- a/types/components/myPages/rewards.ts +++ b/types/components/myPages/rewards.ts @@ -1,5 +1,9 @@ import type { IconProps } from "@/types/components/icon" -import type { RESTAURANT_REWARD_IDS, REWARD_IDS } from "@/constants/rewards" +import type { + COUPON_REWARD_TYPES, + RESTAURANT_REWARD_IDS, + REWARD_IDS, +} from "@/constants/rewards" export interface RewardIconProps extends IconProps { rewardId: string @@ -9,3 +13,5 @@ export interface RewardIconProps extends IconProps { export type RewardId = (typeof REWARD_IDS)[keyof typeof REWARD_IDS] export type RestaurantRewardId = (typeof RESTAURANT_REWARD_IDS)[number] + +export type CouponRewardType = (typeof COUPON_REWARD_TYPES)[number] diff --git a/utils/membershipLevels.ts b/utils/membershipLevels.ts new file mode 100644 index 000000000..3d08bdf00 --- /dev/null +++ b/utils/membershipLevels.ts @@ -0,0 +1,5 @@ +import { MembershipLevelEnum } from "@/constants/membershipLevels" + +export function isMembershipLevel(value: string): value is MembershipLevelEnum { + return Object.values(MembershipLevelEnum).some((level) => level === value) +} diff --git a/utils/rewards.ts b/utils/rewards.ts index 77e57d8e9..c468e54fc 100644 --- a/utils/rewards.ts +++ b/utils/rewards.ts @@ -1,6 +1,11 @@ -import { RESTAURANT_REWARD_IDS, REWARD_IDS } from "@/constants/rewards" +import { + COUPON_REWARD_TYPES, + RESTAURANT_REWARD_IDS, + REWARD_IDS, +} from "@/constants/rewards" import type { + CouponRewardType, RestaurantRewardId, RewardId, } from "@/types/components/myPages/rewards" @@ -40,3 +45,9 @@ export function isRestaurantOnSiteTierReward( ): boolean { return isOnSiteTierReward(reward) && isRestaurantReward(reward.reward_id) } + +export function isCouponRewardType( + type: RewardWithRedeem["rewardType"] +): type is CouponRewardType { + return COUPON_REWARD_TYPES.some((t) => t === type) +}