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 type {
NightsColumn,
PointsColumn,
PointsColumnProps,
} from "@/types/components/myPages/points"
import type { PointsColumnProps } from "@/types/components/myPages/points"
export const YourPointsColumn = ({ points }: 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,
export async function PointsColumn({
title,
subtitle,
value,
}: PointsColumnProps) {
const intl = await getIntl()
let number = "N/A"
if (typeof points === "number") {
number = intl.formatNumber(points)
} else if (typeof nights === "number") {
number = intl.formatNumber(nights)
if (typeof value === "number") {
number = intl.formatNumber(value)
}
return (
@@ -61,16 +26,14 @@ async function PointsColumn({
textAlign="center"
className={styles.firstRow}
>
{intl.formatMessage({
id: title,
})}
{title}
</Body>
<Title color="white" level="h2" textAlign="center">
{number}
</Title>
{subtitle ? (
<Body color="white" textAlign="center">
{intl.formatMessage({ id: subtitle })}
{subtitle}
</Body>
) : null}
</article>

View File

@@ -5,7 +5,7 @@ import { getIntl } from "@/i18n"
import { getMembership } from "@/utils/user"
import PointsContainer from "./Container"
import { NextLevelPointsColumn, YourPointsColumn } from "./PointsColumn"
import { PointsColumn } from "./PointsColumn"
import type { UserProps } from "@/types/components/myPages/user"
@@ -23,11 +23,19 @@ export default async function Points({ user }: UserProps) {
return (
<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 && (
<NextLevelPointsColumn
points={membership?.pointsRequiredToNextlevel}
subtitle={`${intl.formatMessage({ id: "next level:" })} ${nextLevel.name}`}
<PointsColumn
value={membership?.pointsRequiredToNextlevel}
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 */}

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 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 {
MembershipLevel,
type MembershipLevel,
MembershipLevelEnum,
} from "@/constants/membershipLevels"
import {
@@ -10,14 +10,19 @@ import {
GetLoyaltyLevel,
} from "@/lib/graphql/Query/LoyaltyLevels.graphql"
import { request } from "@/lib/graphql/request"
import { Context } from "@/server/context"
import { notFound } from "@/server/errors/trpc"
import { contentstackBaseProcedure, router } from "@/server/trpc"
import { generateLoyaltyConfigTag } from "@/utils/generateTag"
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")
// OpenTelemetry metrics: Loyalty Level
@@ -147,7 +152,7 @@ export const getLoyaltyLevel = cache(
}
getByLevelLoyaltyLevelSuccessCounter.add(1)
return validatedLoyaltyLevels.data[0]
return validatedLoyaltyLevels.data[0] as LoyaltyLevel
}
)

View File

@@ -1,15 +1,5 @@
interface PointsOrNightColumn {
title?: string
export type PointsColumnProps = {
title: 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