Merged in feat/sw-1975-get-profile-v2 (pull request #1651)

Use get Profile V2 endpoint

Approved-by: Linus Flood
This commit is contained in:
Anton Gunnarsson
2025-04-08 06:26:00 +00:00
parent d282437a3d
commit c56a0b8ce9
18 changed files with 208 additions and 168 deletions

View File

@@ -2,53 +2,85 @@ import { z } from "zod"
import { countriesMap } from "@/constants/countries"
import { getFriendsMembership, scandicMemberships } from "@/utils/user"
import { getFriendsMembership } from "@/utils/user"
import { imageSchema } from "../hotels/schemas/image"
const scandicFriendsTier = z.enum(["L1", "L2", "L3", "L4", "L5", "L6", "L7"])
const sasEurobonusTier = z.enum(["EBB", "EBS", "EBG", "EBD", "EBP"])
const commonMembershipSchema = z.object({
currentPoints: z.number().optional(),
expirationDate: z.string().optional(),
membershipLevel: z.string().optional(),
nextLevel: z.string().optional(),
nightsToTopTier: z.number().optional(),
pointsExpiryDate: z.string().optional(),
pointsRequiredToNextlevel: z.number().optional(),
pointsToExpire: z.number().optional(),
tierExpirationDate: z.string().optional(),
membershipNumber: z.string(),
tierExpires: z.string(),
memberSince: z.string().nullish(),
})
const toLowerCaseString = z.string().transform((s) => s.toLowerCase())
const membershipType = (membershipType: scandicMemberships) =>
toLowerCaseString
// The memberships enum is in lower case so this makes sure it will match regardless of casing in the API response.
.pipe(z.literal(membershipType))
const friendsMembershipSchema = z
// This prevents validation errors if the API returns an unhandled membership type
const otherMembershipSchema = z
.object({
membershipType: membershipType(scandicMemberships.guestpr),
membershipNumber: z.string(),
memberSince: z.string(),
// This ensures that `type` won't widen into "string", losing the literal types, when used in a union
type: z.string().refine((val): val is string & {} => true),
})
.merge(commonMembershipSchema)
const otherMembershipSchema = z
export const sasMembershipSchema = z
.object({
membershipType: toLowerCaseString,
membershipNumber: z.string().optional(),
memberSince: z.string().optional(),
type: z.literal("SAS_EB"),
tier: sasEurobonusTier,
nextTier: sasEurobonusTier.nullish(),
})
.merge(commonMembershipSchema)
export const friendsMembershipSchema = z
.object({
type: z.literal("SCANDIC_NATIVE"),
tier: scandicFriendsTier,
nextTier: scandicFriendsTier.nullish(),
pointsToNextTier: z.number().nullish(),
nightsToTopTier: z.number().nullish(),
})
.merge(commonMembershipSchema)
export const membershipSchema = z.union([
friendsMembershipSchema,
sasMembershipSchema,
otherMembershipSchema,
])
const pointExpirationSchema = z.object({
points: z.number().int(),
expires: z.string(),
})
export const userLoyaltySchema = z.object({
memberships: z.array(membershipSchema),
points: z.object({
spendable: z.number().int(),
earned: z.number().int(),
spent: z.number().int(),
}),
tier: scandicFriendsTier,
tierExpires: z.string(),
tierBoostedBy: z.string().nullish(),
pointExpirations: z.array(pointExpirationSchema),
})
export const getUserSchema = z
.object({
data: z.object({
attributes: z.object({
dateOfBirth: z.string().optional().default("1900-01-01"),
email: z.string().email(),
firstName: z.string(),
language: z
.string()
// Preserve Profile v1 formatting for now so it matches ApiLang enum
.transform((s) => s.charAt(0).toUpperCase() + s.slice(1))
.optional(),
lastName: z.string(),
phoneNumber: z.string().optional(),
profileId: z.string(),
membershipNumber: z.string(),
address: z
.object({
city: z.string().optional(),
@@ -59,14 +91,7 @@ export const getUserSchema = z
})
.optional()
.nullable(),
dateOfBirth: z.string().optional().default("1900-01-01"),
email: z.string().email(),
firstName: z.string(),
language: z.string().optional(),
lastName: z.string(),
memberships: z.array(membershipSchema),
phoneNumber: z.string().optional(),
profileId: z.string(),
loyalty: userLoyaltySchema,
}),
type: z.string(),
}),
@@ -74,7 +99,7 @@ export const getUserSchema = z
.transform((apiResponse) => {
return {
...apiResponse.data.attributes,
membership: getFriendsMembership(apiResponse.data.attributes.memberships),
membership: getFriendsMembership(apiResponse.data.attributes.loyalty),
name: `${apiResponse.data.attributes.firstName} ${apiResponse.data.attributes.lastName}`,
}
})
@@ -224,16 +249,6 @@ export const creditCardsSchema = z.object({
data: z.array(creditCardSchema),
})
export const getMembershipCardsSchema = z.array(
z.object({
currentPoints: z.number(),
expirationDate: z.string(),
membershipNumber: z.string(),
memberSince: z.string(),
membershipType: z.string(),
})
)
export const initiateSaveCardSchema = z.object({
data: z.object({
attribute: z.object({