feat: add included param to hotel call, fetch room data, setup schema, use in hotelpage
This commit is contained in:
@@ -5,6 +5,9 @@ import { Lang } from "@/constants/languages"
|
||||
export const getHotelInputSchema = z.object({
|
||||
hotelId: z.string(),
|
||||
language: z.nativeEnum(Lang),
|
||||
include: z
|
||||
.array(z.enum(["RoomCategories", "NearbyHotels", "Restaurants", "City"]))
|
||||
.optional(),
|
||||
})
|
||||
|
||||
export const getRatesInputSchema = z.object({
|
||||
|
||||
@@ -335,6 +335,83 @@ const RelationshipsSchema = z.object({
|
||||
}),
|
||||
})
|
||||
|
||||
const RoomContentSchema = z.object({
|
||||
images: z.array(
|
||||
z.object({
|
||||
metaData: ImageMetaDataSchema,
|
||||
imageSizes: ImageSizesSchema,
|
||||
})
|
||||
),
|
||||
texts: z.object({
|
||||
descriptions: z.object({
|
||||
short: z.string(),
|
||||
medium: z.string(),
|
||||
}),
|
||||
}),
|
||||
})
|
||||
|
||||
const RoomTypesSchema = z.object({
|
||||
name: z.string(),
|
||||
description: z.string(),
|
||||
code: z.string(),
|
||||
roomCount: z.number(),
|
||||
mainBed: z.object({
|
||||
type: z.string(),
|
||||
description: z.string(),
|
||||
widthRange: z.object({
|
||||
min: z.number(),
|
||||
max: z.number(),
|
||||
}),
|
||||
}),
|
||||
fixedExtraBed: z.object({
|
||||
type: z.string(),
|
||||
description: z.string().optional(),
|
||||
widthRange: z.object({
|
||||
min: z.number(),
|
||||
max: z.number(),
|
||||
}),
|
||||
}),
|
||||
roomSize: z.object({
|
||||
min: z.number(),
|
||||
max: z.number(),
|
||||
}),
|
||||
occupancy: z.object({
|
||||
total: z.number(),
|
||||
adults: z.number(),
|
||||
children: z.number(),
|
||||
}),
|
||||
isLackingCribs: z.boolean(),
|
||||
isLackingExtraBeds: z.boolean(),
|
||||
})
|
||||
|
||||
const RoomFacilitiesSchema = z.object({
|
||||
availableInAllRooms: z.boolean(),
|
||||
name: z.string(),
|
||||
isUniqueSellingPoint: z.boolean(),
|
||||
sortOrder: z.number(),
|
||||
})
|
||||
|
||||
export const RoomSchema = z.object({
|
||||
attributes: z.object({
|
||||
name: z.string(),
|
||||
sortOrder: z.number(),
|
||||
content: RoomContentSchema,
|
||||
roomTypes: z.array(RoomTypesSchema),
|
||||
roomFacilities: z.array(RoomFacilitiesSchema),
|
||||
occupancy: z.object({
|
||||
total: z.number(),
|
||||
adults: z.number(),
|
||||
children: z.number(),
|
||||
}),
|
||||
roomSize: z.object({
|
||||
min: z.number(),
|
||||
max: z.number(),
|
||||
}),
|
||||
}),
|
||||
id: z.string(),
|
||||
type: z.enum(["roomcategories"]),
|
||||
})
|
||||
|
||||
// NOTE: Find schema at: https://aks-test.scandichotels.com/hotel/swagger/v1/index.html
|
||||
export const getHotelDataSchema = z.object({
|
||||
data: z.object({
|
||||
@@ -385,11 +462,10 @@ export const getHotelDataSchema = z.object({
|
||||
}),
|
||||
relationships: RelationshipsSchema,
|
||||
}),
|
||||
//TODO: We can pass an "included" param to the hotel API to retrieve additional data for an individual hotel.
|
||||
// - This is out of scope for current work (and I'm unsure if we need it for hotel pages specifically),
|
||||
// - but if/when we do we can extend this schema to add necessary requirements.
|
||||
// - Example "included" data available in our tempHotelData file.
|
||||
// included: z.any(),
|
||||
// NOTE: We can pass an "include" param to the hotel API to retrieve
|
||||
// additional data for an individual hotel.
|
||||
// Example "included" data can be found in our tempHotelData file.
|
||||
included: z.array(RoomSchema).optional(),
|
||||
})
|
||||
|
||||
const Rate = z.object({
|
||||
|
||||
@@ -3,7 +3,7 @@ import { badRequestError } from "@/server/errors/trpc"
|
||||
import { publicProcedure, router } from "@/server/trpc"
|
||||
|
||||
import { getHotelInputSchema, getRatesInputSchema } from "./input"
|
||||
import { getHotelDataSchema, getRatesSchema } from "./output"
|
||||
import { getHotelDataSchema, getRatesSchema, RoomSchema } from "./output"
|
||||
import tempHotelData from "./tempHotelData.json"
|
||||
import tempRatesData from "./tempRatesData.json"
|
||||
import { toApiLang } from "./utils"
|
||||
@@ -12,12 +12,15 @@ export const hotelQueryRouter = router({
|
||||
getHotel: publicProcedure
|
||||
.input(getHotelInputSchema)
|
||||
.query(async ({ input, ctx }) => {
|
||||
const { hotelId, language } = input
|
||||
const { hotelId, language, include } = input
|
||||
|
||||
const params = new URLSearchParams()
|
||||
const apiLang = toApiLang(language)
|
||||
params.set("hotelId", hotelId.toString())
|
||||
params.set("language", apiLang)
|
||||
if (include) {
|
||||
params.set("include", include.join(","))
|
||||
}
|
||||
|
||||
// TODO: Enable once we have authorized API access.
|
||||
// const apiResponse = await api.get(
|
||||
@@ -33,10 +36,9 @@ export const hotelQueryRouter = router({
|
||||
// }
|
||||
// const apiJson = await apiResponse.json()
|
||||
|
||||
//TODO: We can pass an "included" param to the hotel API to retrieve additional data for an individual hotel.
|
||||
// - This is out of scope for current work (and I'm unsure if we need it for hotel pages specifically),
|
||||
// - but if/when we do we can extend the endpoint (and schema) to add necessary requirements.
|
||||
// - Example "included" data available in our tempHotelData file.
|
||||
// NOTE: We can pass an "include" param to the hotel API to retrieve
|
||||
// additional data for an individual hotel.
|
||||
// Example "included" data can be found in our tempHotelData file.
|
||||
const { included, ...apiJsonWithoutIncluded } = tempHotelData
|
||||
const validatedHotelData = getHotelDataSchema.safeParse(
|
||||
apiJsonWithoutIncluded
|
||||
@@ -48,7 +50,24 @@ export const hotelQueryRouter = router({
|
||||
throw badRequestError()
|
||||
}
|
||||
|
||||
return validatedHotelData.data.data.attributes
|
||||
const roomCategories = included
|
||||
? included
|
||||
.filter((item) => item.type === "roomcategories")
|
||||
.map((roomCategory) => {
|
||||
const validatedRoom = RoomSchema.safeParse(roomCategory)
|
||||
if (!validatedRoom.success) {
|
||||
console.info(`Get Room Category Data - Verified Data Error`)
|
||||
console.error(validatedRoom.error)
|
||||
throw badRequestError()
|
||||
}
|
||||
return validatedRoom.data
|
||||
})
|
||||
: []
|
||||
|
||||
return {
|
||||
attributes: validatedHotelData.data.data.attributes,
|
||||
roomCategories: roomCategories,
|
||||
}
|
||||
}),
|
||||
getRates: publicProcedure
|
||||
.input(getRatesInputSchema)
|
||||
|
||||
Reference in New Issue
Block a user