feat(SW-251): set up filter route

This commit is contained in:
Fredrik Thorsson
2024-09-04 13:44:16 +02:00
parent 21d8a5835a
commit 3f6e2ca06e
5 changed files with 129 additions and 29 deletions

View File

@@ -20,18 +20,28 @@ export default async function SelectHotelPage({
setLang(params.lang)
const tempSearchTerm = "Stockholm"
const hotelFilters = await serverClient().hotel.filters.get({
hotelId: "879",
const getHotelFitlers = await serverClient().hotel.filters.get({
language: params.lang,
country: "Sweden",
city: "Halmstad",
})
const availableHotels = await serverClient().hotel.availability.get({
if (!getHotelFitlers) return null
console.log(getHotelFitlers.data)
const getAvailableHotels = await serverClient().hotel.availability.get({
cityId: "8ec4bba3-1c38-4606-82d1-bbe3f6738e54",
roomStayStartDate: "2024-11-02",
roomStayEndDate: "2024-11-03",
adults: 1,
})
if (!availableHotels) return null
if (!getAvailableHotels) return null
const { availability } = getAvailableHotels
console.log(availability)
return (
<main className={styles.main}>
@@ -48,11 +58,11 @@ export default async function SelectHotelPage({
{intl.formatMessage({ id: "Show map" })}
<ChevronRightIcon color="burgundy" />
</Link>
<HotelFilter filters={hotelFilters} />
{/* <HotelFilter filters={hotelFilters} /> */}
</section>
<section className={styles.hotelCards}>
{availableHotels.availability.length ? (
availableHotels.availability.map((hotel) => (
{availability.length ? (
availability.map((hotel) => (
<HotelCard
key={hotel.hotelId}
checkInDate={hotel.checkInDate}

View File

@@ -11,30 +11,30 @@ export default async function HotelFilter({ filters }: HotelFilterProps) {
<aside className={styles.container}>
<div className={styles.facilities}>
{formatMessage({ id: "Room facilities" })}
{filters.roomFacilities.map((roomFilter) => (
{/* {filters.roomFacilities.map((roomFilter) => (
<div key={roomFilter} className={styles.filter}>
<input id={roomFilter} name={roomFilter} type="checkbox" />
<label htmlFor={roomFilter}>{roomFilter}</label>
</div>
))}
))} */}
</div>
<div className={styles.facilities}>
{formatMessage({ id: "Hotel facilities" })}
{filters.hotelFacilities.map((hotelFilter) => (
{/* {filters.hotelFacilities.map((hotelFilter) => (
<div key={hotelFilter} className={styles.filter}>
<input id={hotelFilter} name={hotelFilter} type="checkbox" />
<label htmlFor={hotelFilter}>{hotelFilter}</label>
</div>
))}
))} */}
</div>
<div className={styles.facilities}>
{formatMessage({ id: "Hotel surroundings" })}
{filters.hotelSurroundings.map((surroundings) => (
{/* {filters.hotelSurroundings.map((surroundings) => (
<div key={surroundings} className={styles.filter}>
<input id={surroundings} name={surroundings} type="checkbox" />
<label htmlFor={surroundings}>{surroundings}</label>
</div>
))}
))} */}
</div>
</aside>
)

View File

@@ -22,5 +22,7 @@ export const getRatesInputSchema = z.object({
})
export const getFiltersInputSchema = z.object({
hotelId: z.string(),
language: z.string(),
country: z.string(),
city: z.string(),
})

View File

@@ -554,11 +554,29 @@ export const getRatesSchema = z.array(rate)
export type Rate = z.infer<typeof rate>
const hotelFilter = z.object({
roomFacilities: z.array(z.string()),
hotelFacilities: z.array(z.string()),
hotelSurroundings: z.array(z.string()),
const hotelFilterSchema = z.object({
data: z.array(
z.object({
attributes: z.object({
name: z.string(),
operaId: z.string(),
isPublished: z.boolean(),
cityId: z.string(),
cityName: z.string(),
ratings: ratingsSchema,
address: addressSchema,
location: locationSchema,
hotelContent: hotelContentSchema,
detailedFacilities: z.array(detailedFacilitySchema),
isActive: z.boolean(),
}),
id: z.string(),
language: z.unknown(),
hotelInformationSystemId: z.number(),
type: z.string(),
})
),
})
export const getFiltersSchema = hotelFilter
export type HotelFilter = z.infer<typeof hotelFilter>
export const getHotelFilterSchema = hotelFilterSchema
export type HotelFilter = z.infer<typeof hotelFilterSchema>

View File

@@ -33,8 +33,8 @@ import {
} from "./input"
import {
getAvailabilitySchema,
getFiltersSchema,
getHotelDataSchema,
getHotelFilterSchema,
getRatesSchema,
roomSchema,
} from "./output"
@@ -57,6 +57,10 @@ const availabilityFailCounter = meter.createCounter(
"trpc.hotel.availability-fail"
)
const filterCounter = meter.createCounter("trcp.hotel.filter")
const filterSuccessCounter = meter.createCounter("trcp.hotel.filter-success")
const filterFailCounter = meter.createCounter("trcp.hotel.filter-fail")
async function getContentstackData(
locale: string,
uid: string | null | undefined
@@ -420,31 +424,97 @@ export const hotelQueryRouter = router({
}),
}),
filters: router({
get: publicProcedure
get: serviceProcedure
.input(getFiltersInputSchema)
.query(async ({ input, ctx }) => {
console.info("api.hotels.filters start", JSON.stringify({}))
const { language, country, city } = input
const params: Record<string, string> = {
language,
country,
city,
}
if (!tempFilterData) {
filterCounter.add(1, {
language,
country,
city,
})
console.info(
"api.hotels.filters start",
JSON.stringify({
query: { params },
})
)
const apiResponse = await api.get(
api.endpoints.v1.hotels,
{
headers: {
Authorization: `Bearer ${ctx.serviceToken}`,
},
},
params
)
if (!apiResponse.ok) {
const text = await apiResponse.text()
filterFailCounter.add(1, {
language,
country,
city,
error_type: "http_error",
error: JSON.stringify({
status: apiResponse.status,
statusText: apiResponse.statusText,
text,
}),
})
console.error(
"api.hotels.filters error",
JSON.stringify({ error: null })
JSON.stringify({
query: {
params,
},
error: {
status: apiResponse.status,
statusText: apiResponse.statusText,
text,
},
})
)
//Can't return null here since consuming component does not handle null yet
// return null
return null
}
const validateFilterData = getFiltersSchema.safeParse(tempFilterData)
const apiJson = await apiResponse.json()
const validateFilterData = getHotelFilterSchema.safeParse(apiJson)
if (!validateFilterData.success) {
filterFailCounter.add(1, {
language,
country,
city,
error_type: "validation_error",
error: JSON.stringify(validateFilterData.error),
})
console.error(
"api.hotels.filters validation error",
JSON.stringify({
query: { params },
error: validateFilterData.error,
})
)
throw badRequestError()
}
console.info("api.hotels.rates success", JSON.stringify({}))
filterSuccessCounter.add(1, {
language,
country,
city,
})
console.info(
"api.hotels.fuilters success",
JSON.stringify({ query: { params: params } })
)
return validateFilterData.data
}),
}),