chore: refactor points

This commit is contained in:
Michael Zetterberg
2025-01-05 16:23:17 +01:00
parent d2ce9c0d7c
commit 0477d2375b
6 changed files with 33 additions and 127 deletions

View File

@@ -4,53 +4,18 @@ import { getIntl } from "@/i18n"
import styles from "./pointsColumn.module.css" import styles from "./pointsColumn.module.css"
import type { import type { PointsColumnProps } from "@/types/components/myPages/points"
NightsColumn,
PointsColumn,
PointsColumnProps,
} from "@/types/components/myPages/points"
export const YourPointsColumn = ({ points }: PointsColumn) => export async function PointsColumn({
PointsColumn({
points,
title: "Your points to spend",
subtitle: "as of today",
})
export const NextLevelPointsColumn = ({ points, subtitle }: PointsColumn) =>
PointsColumn({
points,
title: "Points needed to level up",
subtitle,
})
export const StayOnLevelColumn = ({ points, subtitle }: PointsColumn) =>
PointsColumn({
points,
title: "Points needed to stay on level",
subtitle,
})
export const NextLevelNightsColumn = ({ nights, subtitle }: NightsColumn) =>
PointsColumn({
nights,
title: "Nights needed to level up",
subtitle,
})
async function PointsColumn({
points,
nights,
title, title,
subtitle, subtitle,
value,
}: PointsColumnProps) { }: PointsColumnProps) {
const intl = await getIntl() const intl = await getIntl()
let number = "N/A" let number = "N/A"
if (typeof points === "number") { if (typeof value === "number") {
number = intl.formatNumber(points) number = intl.formatNumber(value)
} else if (typeof nights === "number") {
number = intl.formatNumber(nights)
} }
return ( return (
@@ -61,16 +26,14 @@ async function PointsColumn({
textAlign="center" textAlign="center"
className={styles.firstRow} className={styles.firstRow}
> >
{intl.formatMessage({ {title}
id: title,
})}
</Body> </Body>
<Title color="white" level="h2" textAlign="center"> <Title color="white" level="h2" textAlign="center">
{number} {number}
</Title> </Title>
{subtitle ? ( {subtitle ? (
<Body color="white" textAlign="center"> <Body color="white" textAlign="center">
{intl.formatMessage({ id: subtitle })} {subtitle}
</Body> </Body>
) : null} ) : null}
</article> </article>

View File

@@ -5,7 +5,7 @@ import { getIntl } from "@/i18n"
import { getMembership } from "@/utils/user" import { getMembership } from "@/utils/user"
import PointsContainer from "./Container" import PointsContainer from "./Container"
import { NextLevelPointsColumn, YourPointsColumn } from "./PointsColumn" import { PointsColumn } from "./PointsColumn"
import type { UserProps } from "@/types/components/myPages/user" import type { UserProps } from "@/types/components/myPages/user"
@@ -23,11 +23,19 @@ export default async function Points({ user }: UserProps) {
return ( return (
<PointsContainer> <PointsContainer>
<YourPointsColumn points={membership?.currentPoints} /> <PointsColumn
value={membership?.currentPoints}
title={intl.formatMessage({ id: "Your points to spend" })}
subtitle={intl.formatMessage({ id: "as of today" })}
/>
{nextLevel && ( {nextLevel && (
<NextLevelPointsColumn <PointsColumn
points={membership?.pointsRequiredToNextlevel} value={membership?.pointsRequiredToNextlevel}
subtitle={`${intl.formatMessage({ id: "next level:" })} ${nextLevel.name}`} title={intl.formatMessage({ id: "Points needed to level up" })}
subtitle={intl.formatMessage(
{ id: "next level: {nextLevel}" },
{ nextLevel: nextLevel.name }
)}
/> />
)} )}
{/* TODO: Show NextLevelNightsColumn when nightsToTopTier data is correct from Antavo */} {/* TODO: Show NextLevelNightsColumn when nightsToTopTier data is correct from Antavo */}

View File

@@ -1,60 +0,0 @@
import { MembershipLevelEnum } from "@/constants/membershipLevels"
import { serverClient } from "@/lib/trpc/server"
import { getIntl } from "@/i18n"
import { getMembership } from "@/utils/user"
import PointsContainer from "../../../Overview/Stats/Points/Container"
import {
NextLevelNightsColumn,
NextLevelPointsColumn,
StayOnLevelColumn,
YourPointsColumn,
} from "../../../Overview/Stats/Points/PointsColumn"
import type { UserProps } from "@/types/components/myPages/user"
import type { LangParams } from "@/types/params"
/* TODO */
export default async function Points({ user, lang }: UserProps & LangParams) {
const intl = await getIntl()
const membership = getMembership(user.memberships)
if (!membership?.nextLevel || !MembershipLevelEnum[membership.nextLevel]) {
return null
}
const nextLevel = await serverClient().contentstack.loyaltyLevels.byLevel({
level: MembershipLevelEnum[membership.nextLevel],
})
return (
<PointsContainer>
<YourPointsColumn points={membership?.currentPoints} />
{nextLevel && (
<>
{membership?.currentPoints ? (
<StayOnLevelColumn
points={membership?.currentPoints} //TODO
subtitle={`${intl.formatMessage({ id: "by" })} ${membership?.expirationDate}`}
/>
) : (
<>
<NextLevelPointsColumn
points={membership?.pointsRequiredToNextlevel}
subtitle={`${intl.formatMessage({ id: "next level:" })} ${nextLevel.name}`}
/>
{membership?.nightsToTopTier && (
<NextLevelNightsColumn
nights={membership.nightsToTopTier}
subtitle={
membership.tierExpirationDate &&
`by ${membership.tierExpirationDate}`
}
/>
)}
</>
)}
</>
)}
</PointsContainer>
)
}

View File

@@ -21,4 +21,4 @@ export const validateLoyaltyLevelsSchema = z
export type LoyaltyLevelsResponse = z.input<typeof validateLoyaltyLevelsSchema> export type LoyaltyLevelsResponse = z.input<typeof validateLoyaltyLevelsSchema>
export type LoyaltyLevel = z.output<typeof validateLoyaltyLevelsSchema>[0] export type LoyaltyLevel = z.output<typeof validateLoyaltyLevelsSchema>[number]

View File

@@ -2,7 +2,7 @@ import { metrics } from "@opentelemetry/api"
import { cache } from "react" import { cache } from "react"
import { import {
MembershipLevel, type MembershipLevel,
MembershipLevelEnum, MembershipLevelEnum,
} from "@/constants/membershipLevels" } from "@/constants/membershipLevels"
import { import {
@@ -10,14 +10,19 @@ import {
GetLoyaltyLevel, GetLoyaltyLevel,
} from "@/lib/graphql/Query/LoyaltyLevels.graphql" } from "@/lib/graphql/Query/LoyaltyLevels.graphql"
import { request } from "@/lib/graphql/request" import { request } from "@/lib/graphql/request"
import { Context } from "@/server/context"
import { notFound } from "@/server/errors/trpc" import { notFound } from "@/server/errors/trpc"
import { contentstackBaseProcedure, router } from "@/server/trpc" import { contentstackBaseProcedure, router } from "@/server/trpc"
import { generateLoyaltyConfigTag } from "@/utils/generateTag" import { generateLoyaltyConfigTag } from "@/utils/generateTag"
import { loyaltyLevelInput } from "./input" import { loyaltyLevelInput } from "./input"
import { LoyaltyLevelsResponse, validateLoyaltyLevelsSchema } from "./output" import {
type LoyaltyLevel,
type LoyaltyLevelsResponse,
validateLoyaltyLevelsSchema,
} from "./output"
import type { Context } from "@/server/context"
const meter = metrics.getMeter("trpc.loyaltyLevel") const meter = metrics.getMeter("trpc.loyaltyLevel")
// OpenTelemetry metrics: Loyalty Level // OpenTelemetry metrics: Loyalty Level
@@ -147,7 +152,7 @@ export const getLoyaltyLevel = cache(
} }
getByLevelLoyaltyLevelSuccessCounter.add(1) getByLevelLoyaltyLevelSuccessCounter.add(1)
return validatedLoyaltyLevels.data[0] return validatedLoyaltyLevels.data[0] as LoyaltyLevel
} }
) )

View File

@@ -1,15 +1,5 @@
interface PointsOrNightColumn { export type PointsColumnProps = {
title?: string title: string
subtitle?: string subtitle?: string
value?: number
} }
export interface PointsColumn extends PointsOrNightColumn {
points: number | undefined
nights?: never
}
export interface NightsColumn extends PointsOrNightColumn {
points?: never
nights: number | undefined
}
export type PointsColumnProps = PointsColumn | NightsColumn