Merge remote-tracking branch 'origin' into feature/tracking

This commit is contained in:
Linus Flood
2024-12-05 15:12:09 +01:00
114 changed files with 1388 additions and 653 deletions

View File

@@ -1,6 +1,7 @@
import { z } from "zod"
import { ChildBedTypeEnum } from "@/constants/booking"
import { Lang, langToApiLang } from "@/constants/languages"
const signupSchema = z.discriminatedUnion("becomeMember", [
z.object({
@@ -81,6 +82,7 @@ export const createBookingInput = z.object({
checkOutDate: z.string(),
rooms: roomsSchema,
payment: paymentSchema,
language: z.nativeEnum(Lang).transform((val) => langToApiLang[val]),
})
export const priceChangeInput = z.object({

View File

@@ -47,16 +47,18 @@ export const bookingMutationRouter = router({
.input(createBookingInput)
.mutation(async function ({ ctx, input }) {
const accessToken = ctx.session?.token.access_token ?? ctx.serviceToken
const { checkInDate, checkOutDate, hotelId } = input
const { language, ...inputWithoutLang } = input
const { hotelId, checkInDate, checkOutDate } = inputWithoutLang
const loggingAttributes = {
membershipNumber: await getMembershipNumber(ctx.session),
checkInDate,
checkOutDate,
hotelId,
language,
}
createBookingCounter.add(1, { hotelId, checkInDate, checkOutDate })
createBookingCounter.add(1, loggingAttributes)
console.info(
"api.booking.create start",
@@ -68,10 +70,14 @@ export const bookingMutationRouter = router({
Authorization: `Bearer ${accessToken}`,
}
const apiResponse = await api.post(api.endpoints.v1.Booking.bookings, {
headers,
body: input,
})
const apiResponse = await api.post(
api.endpoints.v1.Booking.bookings,
{
headers,
body: inputWithoutLang,
},
{ language }
)
if (!apiResponse.ok) {
const text = await apiResponse.text()

View File

@@ -8,6 +8,7 @@ import { router, serviceProcedure } from "@/server/trpc"
import { getHotelData } from "../hotels/query"
import { bookingConfirmationInput, getBookingStatusInput } from "./input"
import { bookingConfirmationSchema, createBookingSchema } from "./output"
import { getBookedHotelRoom } from "./utils"
const meter = metrics.getMeter("trpc.booking")
const getBookingConfirmationCounter = meter.createCounter(
@@ -144,6 +145,7 @@ export const bookingQueryRouter = router({
...hotelData.data.attributes,
included: hotelData.included,
},
room: getBookedHotelRoom(hotelData.included, booking.data.roomTypeCode),
}
}),
status: serviceProcedure.input(getBookingStatusInput).query(async function ({

View File

@@ -0,0 +1,27 @@
import { RoomData } from "@/types/hotel"
import { BookingConfirmation } from "@/types/trpc/routers/booking/confirmation"
export function getBookedHotelRoom(
rooms: RoomData[] | undefined,
roomTypeCode: BookingConfirmation["booking"]["roomTypeCode"]
) {
if (!rooms?.length || !roomTypeCode) {
return null
}
const room = rooms?.find((r) => {
return r.roomTypes.find((roomType) => roomType.code === roomTypeCode)
})
if (!room) {
return null
}
const bedType = room.roomTypes.find(
(roomType) => roomType.code === roomTypeCode
)
if (!bedType) {
return null
}
return {
...room,
bedType,
}
}

View File

@@ -238,15 +238,18 @@ export const rewardQueryRouter = router({
const nextCursor =
limit + cursor < rewardIds.length ? limit + cursor : undefined
const surprisesIds = validatedApiRewards.data
const wrappedSurprisesIds = validatedApiRewards.data
.filter(
({ type, rewardType }) =>
type === "coupon" && rewardType === "Surprise"
(reward) =>
reward.type === "coupon" &&
reward.rewardType === "Surprise" &&
"coupon" in reward &&
reward.coupon?.some(({ unwrapped }) => !unwrapped)
)
.map(({ rewardId }) => rewardId)
const rewards = cmsRewards.filter(
(reward) => !surprisesIds.includes(reward.reward_id)
(reward) => !wrappedSurprisesIds.includes(reward.reward_id)
)
getCurrentRewardSuccessCounter.add(1)

View File

@@ -19,31 +19,33 @@ export const activitiesCardSchema = z.object({
body_text: z.string(),
cta_text: z.string(),
heading: z.string(),
open_in_new_tab: z.boolean(),
scripted_title: z.string().optional(),
hotel_page_activities_content_pageConnection: z.object({
edges: z.array(
z.object({
node: z.discriminatedUnion("__typename", [
pageLinks.contentPageSchema,
pageLinks.contentPageSchema.extend({
header: z.object({
preamble: z.string(),
}),
}),
]),
})
),
}),
})
.transform((data) => {
let contentPage = { href: "" }
let contentPage = { href: "", preamble: "" }
if (data.hotel_page_activities_content_pageConnection.edges.length) {
const page =
data.hotel_page_activities_content_pageConnection.edges[0].node
contentPage.preamble = page.header.preamble
if (page.web.original_url) {
contentPage = {
href: page.web.original_url,
}
contentPage.href = page.web.original_url
} else {
contentPage = {
href: removeMultipleSlashes(`/${page.system.locale}/${page.url}`),
}
contentPage.href = removeMultipleSlashes(
`/${page.system.locale}/${page.url}`
)
}
}
return {
@@ -52,7 +54,6 @@ export const activitiesCardSchema = z.object({
contentPage,
ctaText: data.cta_text,
heading: data.heading,
openInNewTab: !!data.open_in_new_tab,
scriptedTopTitle: data.scripted_title,
}
}),

View File

@@ -298,6 +298,7 @@ export const parkingSchema = z.object({
numberOfChargingSpaces: z.number().optional(),
distanceToHotel: z.number().optional(),
canMakeReservation: z.boolean(),
externalParkingUrl: z.string().optional(),
pricing: parkingPricingSchema,
})