feat(LOY-62): Add ScriptedRewardText component
This commit is contained in:
@@ -0,0 +1,98 @@
|
||||
"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 <LoadingSpinner />
|
||||
}
|
||||
|
||||
if (!rewards.length) {
|
||||
return null
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Grids.Stackable>
|
||||
{rewards.map((reward, idx) => (
|
||||
<article className={styles.card} key={`${reward.reward_id}-${idx}`}>
|
||||
<div className={styles.content}>
|
||||
<Image
|
||||
src="/_static/img/loyalty-award.png"
|
||||
width={113}
|
||||
height={125}
|
||||
alt={reward.label || ""}
|
||||
/>
|
||||
<ScriptedRewardText
|
||||
rewardType={reward.rewardType}
|
||||
rewardTierLevel={reward.rewardTierLevel}
|
||||
/>
|
||||
<Title
|
||||
as="h4"
|
||||
level="h3"
|
||||
textAlign="center"
|
||||
textTransform="regular"
|
||||
>
|
||||
{reward.label}
|
||||
</Title>
|
||||
</div>
|
||||
{showRedeem && (
|
||||
<div className={styles.btnContainer}>
|
||||
<Redeem reward={reward} />
|
||||
</div>
|
||||
)}
|
||||
</article>
|
||||
))}
|
||||
</Grids.Stackable>
|
||||
{hasNextPage &&
|
||||
(isFetching ? (
|
||||
<LoadingSpinner />
|
||||
) : (
|
||||
<ShowMoreButton loadMoreData={loadMoreData} />
|
||||
))}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
import { useIntl } from "react-intl"
|
||||
|
||||
import {
|
||||
isMembershipLevel,
|
||||
MembershipLevelEnum,
|
||||
} from "@/constants/membershipLevels"
|
||||
|
||||
import BiroScript from "@/components/TempDesignSystem/Text/BiroScript"
|
||||
|
||||
import type { ScriptedRewardTextProps } from "@/types/components/myPages/myPage/accountPage"
|
||||
|
||||
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 default function ScriptedRewardText({
|
||||
rewardType,
|
||||
rewardTierLevel,
|
||||
}: 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
|
||||
|
||||
// TODO: Add Voucher type
|
||||
|
||||
default:
|
||||
label = null
|
||||
}
|
||||
|
||||
return (
|
||||
<BiroScript type="two" color="red" tilted="small">
|
||||
{label}
|
||||
</BiroScript>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user