Merged in feat/SW-1454-hotel-listing-city-page (pull request #1250)
feat(SW-1454): added hotel listing * feat(SW-1454): added hotel listing Approved-by: Fredrik Thorsson
This commit is contained in:
@@ -251,16 +251,23 @@ export const packagesSchema = z
|
||||
})
|
||||
.transform(({ data }) => data?.attributes.packages)
|
||||
|
||||
export const getHotelIdsByCityIdSchema = z
|
||||
export const getHotelIdsSchema = z
|
||||
.object({
|
||||
data: z.array(
|
||||
z.object({
|
||||
// We only care about the hotel id
|
||||
attributes: z.object({
|
||||
isPublished: z.boolean(),
|
||||
}),
|
||||
id: z.string(),
|
||||
})
|
||||
),
|
||||
})
|
||||
.transform((data) => data.data.map((hotel) => hotel.id))
|
||||
.transform(({ data }) => {
|
||||
const filteredHotels = data.filter(
|
||||
(hotel) => !!hotel.attributes.isPublished
|
||||
)
|
||||
return filteredHotels.map((hotel) => hotel.id)
|
||||
})
|
||||
|
||||
export const getNearbyHotelIdsSchema = z
|
||||
.object({
|
||||
|
||||
@@ -91,7 +91,7 @@ export const getHotel = cache(
|
||||
})
|
||||
console.info(
|
||||
"api.hotels.hotelData start",
|
||||
JSON.stringify({ query: { hotelId, params } })
|
||||
JSON.stringify({ query: { hotelId, params: params.toString() } })
|
||||
)
|
||||
|
||||
const apiResponse = await api.get(
|
||||
@@ -126,7 +126,7 @@ export const getHotel = cache(
|
||||
console.error(
|
||||
"api.hotels.hotelData error",
|
||||
JSON.stringify({
|
||||
query: { hotelId, params },
|
||||
query: { hotelId, params: params.toString() },
|
||||
error: {
|
||||
status: apiResponse.status,
|
||||
statusText: apiResponse.statusText,
|
||||
@@ -151,7 +151,7 @@ export const getHotel = cache(
|
||||
console.error(
|
||||
"api.hotels.hotelData validation error",
|
||||
JSON.stringify({
|
||||
query: { hotelId, params },
|
||||
query: { hotelId, params: params.toString() },
|
||||
error: validateHotelData.error,
|
||||
})
|
||||
)
|
||||
@@ -165,7 +165,7 @@ export const getHotel = cache(
|
||||
console.info(
|
||||
"api.hotels.hotelData success",
|
||||
JSON.stringify({
|
||||
query: { hotelId, params: params },
|
||||
query: { hotelId, params: params.toString() },
|
||||
})
|
||||
)
|
||||
const hotelData = validateHotelData.data
|
||||
|
||||
@@ -30,7 +30,7 @@ export const restaurantsOverviewPageSchema = z.object({
|
||||
})
|
||||
|
||||
export const extraPageSchema = z.object({
|
||||
elevatorPitch: z.string().optional(),
|
||||
elevatorPitch: z.string().default(""),
|
||||
mainBody: z.string().optional(),
|
||||
})
|
||||
|
||||
|
||||
@@ -1,14 +1,17 @@
|
||||
import deepmerge from "deepmerge"
|
||||
import { unstable_cache } from "next/cache"
|
||||
|
||||
import { Lang } from "@/constants/languages"
|
||||
import { env } from "@/env/server"
|
||||
import * as api from "@/lib/api"
|
||||
import { toApiLang } from "@/server/utils"
|
||||
|
||||
import { metrics } from "./metrics"
|
||||
import {
|
||||
citiesByCountrySchema,
|
||||
citiesSchema,
|
||||
countriesSchema,
|
||||
getHotelIdsByCityIdSchema,
|
||||
getHotelIdsSchema,
|
||||
locationsSchema,
|
||||
} from "./output"
|
||||
|
||||
@@ -17,10 +20,9 @@ import { PointOfInterestGroupEnum } from "@/types/enums/pointOfInterest"
|
||||
import type { RequestOptionsWithOutBody } from "@/types/fetch"
|
||||
import type {
|
||||
CitiesGroupedByCountry,
|
||||
Countries,
|
||||
CityLocation,
|
||||
HotelLocation,
|
||||
} from "@/types/trpc/routers/hotel/locations"
|
||||
import type { Lang } from "@/constants/languages"
|
||||
import type { Endpoint } from "@/lib/api/endpoints"
|
||||
|
||||
export function getPoiGroupByCategoryName(category: string | undefined) {
|
||||
@@ -305,11 +307,11 @@ export async function getHotelIdsByCityId(
|
||||
})
|
||||
)
|
||||
|
||||
return null
|
||||
return []
|
||||
}
|
||||
|
||||
const apiJson = await apiResponse.json()
|
||||
const validatedHotelIds = getHotelIdsByCityIdSchema.safeParse(apiJson)
|
||||
const validatedHotelIds = getHotelIdsSchema.safeParse(apiJson)
|
||||
if (!validatedHotelIds.success) {
|
||||
metrics.hotelIds.fail.add(1, {
|
||||
params: params.toString(),
|
||||
@@ -323,19 +325,22 @@ export async function getHotelIdsByCityId(
|
||||
error: validatedHotelIds.error,
|
||||
})
|
||||
)
|
||||
return null
|
||||
return []
|
||||
}
|
||||
|
||||
metrics.hotelIds.success.add(1, { cityId })
|
||||
console.info(
|
||||
"api.hotel.hotel-ids success",
|
||||
JSON.stringify({ params: params.toString() })
|
||||
JSON.stringify({
|
||||
params: params.toString(),
|
||||
response: validatedHotelIds.data,
|
||||
})
|
||||
)
|
||||
|
||||
return validatedHotelIds.data
|
||||
},
|
||||
[`hotelsByCityId`, params.toString()],
|
||||
{ revalidate: TWENTYFOUR_HOURS }
|
||||
{ revalidate: env.CACHE_TIME_HOTELS }
|
||||
)(params)
|
||||
}
|
||||
|
||||
@@ -376,11 +381,11 @@ export async function getHotelIdsByCountry(
|
||||
})
|
||||
)
|
||||
|
||||
return null
|
||||
return []
|
||||
}
|
||||
|
||||
const apiJson = await apiResponse.json()
|
||||
const validatedHotelIds = getHotelIdsByCityIdSchema.safeParse(apiJson)
|
||||
const validatedHotelIds = getHotelIdsSchema.safeParse(apiJson)
|
||||
if (!validatedHotelIds.success) {
|
||||
metrics.hotelIds.fail.add(1, {
|
||||
country,
|
||||
@@ -394,7 +399,7 @@ export async function getHotelIdsByCountry(
|
||||
error: validatedHotelIds.error,
|
||||
})
|
||||
)
|
||||
return null
|
||||
return []
|
||||
}
|
||||
|
||||
metrics.hotelIds.success.add(1, { country })
|
||||
@@ -406,6 +411,69 @@ export async function getHotelIdsByCountry(
|
||||
return validatedHotelIds.data
|
||||
},
|
||||
[`hotelsByCountry`, params.toString()],
|
||||
{ revalidate: TWENTYFOUR_HOURS }
|
||||
{ revalidate: env.CACHE_TIME_HOTELS }
|
||||
)(params)
|
||||
}
|
||||
|
||||
export async function getHotelIdsByCityIdentifier(
|
||||
cityIdentifier: string,
|
||||
serviceToken: string
|
||||
) {
|
||||
const apiLang = toApiLang(Lang.en)
|
||||
const cityId = await getCityIdByCityIdentifier(cityIdentifier, serviceToken)
|
||||
|
||||
if (!cityId) {
|
||||
return []
|
||||
}
|
||||
|
||||
const hotelIdsParams = new URLSearchParams({
|
||||
language: apiLang,
|
||||
city: cityId,
|
||||
onlyBasicInfo: "true",
|
||||
})
|
||||
const options: RequestOptionsWithOutBody = {
|
||||
// needs to clear default option as only
|
||||
// cache or next.revalidate is permitted
|
||||
cache: undefined,
|
||||
headers: {
|
||||
Authorization: `Bearer ${serviceToken}`,
|
||||
},
|
||||
next: {
|
||||
revalidate: env.CACHE_TIME_HOTELS,
|
||||
},
|
||||
}
|
||||
const hotelIds = await getHotelIdsByCityId(cityId, options, hotelIdsParams)
|
||||
return hotelIds
|
||||
}
|
||||
|
||||
export async function getCityIdByCityIdentifier(
|
||||
cityIdentifier: string,
|
||||
serviceToken: string
|
||||
) {
|
||||
const lang = Lang.en
|
||||
const apiLang = toApiLang(lang)
|
||||
const options: RequestOptionsWithOutBody = {
|
||||
// needs to clear default option as only
|
||||
// cache or next.revalidate is permitted
|
||||
cache: undefined,
|
||||
headers: {
|
||||
Authorization: `Bearer ${serviceToken}`,
|
||||
},
|
||||
next: {
|
||||
revalidate: env.CACHE_TIME_HOTELS,
|
||||
},
|
||||
}
|
||||
const params = new URLSearchParams({
|
||||
language: apiLang,
|
||||
})
|
||||
const locations = await getLocations(lang, options, params, null)
|
||||
if (!locations || "error" in locations) {
|
||||
return null
|
||||
}
|
||||
|
||||
const cityId = locations
|
||||
.filter((loc): loc is CityLocation => loc.type === "cities")
|
||||
.find((loc) => loc.cityIdentifier === cityIdentifier)?.id
|
||||
|
||||
return cityId ?? null
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user