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:
Erik Tiekstra
2025-02-05 13:10:28 +00:00
parent f3e6318d49
commit e3b1bfc414
27 changed files with 522 additions and 103 deletions

View File

@@ -1,4 +1,3 @@
import { env } from "@/env/server"
import {
GetDestinationCountryPage,
GetDestinationCountryPageRefs,
@@ -10,7 +9,6 @@ import { toApiLang } from "@/server/utils"
import { generateTag } from "@/utils/generateTag"
import { getCitiesByCountry } from "../../hotels/utils"
import {
destinationCountryPageRefsSchema,
destinationCountryPageSchema,
@@ -23,10 +21,9 @@ import {
getDestinationCountryPageRefsSuccessCounter,
getDestinationCountryPageSuccessCounter,
} from "./telemetry"
import { generatePageTags, getCityListDataByCityIdentifier } from "./utils"
import { generatePageTags, getCityPages } from "./utils"
import { ApiCountry } from "@/types/enums/country"
import type { RequestOptionsWithOutBody } from "@/types/fetch"
import type {
GetDestinationCountryPageData,
GetDestinationCountryPageRefsSchema,
@@ -155,44 +152,10 @@ export const destinationCountryPageQueryRouter = router({
return null
}
const params = new URLSearchParams({
language: apiLang,
})
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 selectedCountry =
validatedResponse.data.destinationCountryPage.destination_settings.country
const apiCountry = ApiCountry[lang][selectedCountry]
const cities = await getCitiesByCountry(
[apiCountry],
options,
params,
const cities = await getCityPages(
lang,
true,
"destinationCountryPage"
)
const cityPages = await Promise.all(
cities[apiCountry].map(async (city) => {
if (!city.cityIdentifier) {
return null
}
const data = await getCityListDataByCityIdentifier(
lang,
city.cityIdentifier
)
return data ? { ...data, cityName: city.name } : null
})
serviceToken,
validatedResponse.data.destinationCountryPage.destination_settings.country
)
getDestinationCountryPageSuccessCounter.add(1, { lang, uid: `${uid}` })
@@ -205,10 +168,12 @@ export const destinationCountryPageQueryRouter = router({
return {
...validatedResponse.data,
translatedCountry: apiCountry,
cities: cityPages
.flat()
.filter((city): city is NonNullable<typeof city> => !!city),
translatedCountry:
ApiCountry[lang][
validatedResponse.data.destinationCountryPage.destination_settings
.country
],
cities,
}
}),
})

View File

@@ -1,8 +1,11 @@
import { env } from "@/env/server"
import { GetDestinationCityListData } from "@/lib/graphql/Query/DestinationCityPage/DestinationCityListData.graphql"
import { request } from "@/lib/graphql/request"
import { toApiLang } from "@/server/utils"
import { generateTag, generateTagsFromSystem } from "@/utils/generateTag"
import { getCitiesByCountry } from "../../hotels/utils"
import { destinationCityListDataSchema } from "../destinationCityPage/output"
import {
getCityListDataCounter,
@@ -10,6 +13,8 @@ import {
getCityListDataSuccessCounter,
} from "./telemetry"
import { ApiCountry, type Country } from "@/types/enums/country"
import type { RequestOptionsWithOutBody } from "@/types/fetch"
import type { System } from "@/types/requests/system"
import type { GetDestinationCityListDataResponse } from "@/types/trpc/routers/contentstack/destinationCityPage"
import type { GetDestinationCountryPageRefsSchema } from "@/types/trpc/routers/contentstack/destinationCountryPage"
@@ -108,3 +113,47 @@ export async function getCityListDataByCityIdentifier(
return validatedResponse.data
}
export async function getCityPages(
lang: Lang,
serviceToken: string,
country: Country
) {
const apiLang = toApiLang(lang)
const params = new URLSearchParams({
language: apiLang,
})
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 apiCountry = ApiCountry[lang][country]
const cities = await getCitiesByCountry([apiCountry], options, params, lang)
const publishedCities = cities[apiCountry].filter((city) => city.isPublished)
const cityPages = await Promise.all(
publishedCities.map(async (city) => {
if (!city.cityIdentifier) {
return null
}
const data = await getCityListDataByCityIdentifier(
lang,
city.cityIdentifier
)
return data ? { ...data, cityName: city.name } : null
})
)
return cityPages
.flat()
.filter((city): city is NonNullable<typeof city> => !!city)
}