This creates the alternative hotels page. It is mostly a copy of the select hotel page, and most of the contents of the pages lives under the same component in /components.

Merged in feat/sw-397-alternative-hotels (pull request #1211)

Feat/sw 397 alternative hotels

* fix(SW-397): create alternative hotels page

* update types

* Adapt to new changes for fetching data

* Make bookingcode optional

* Code review fixes


Approved-by: Simon.Emanuelsson
This commit is contained in:
Niclas Edenvin
2025-01-28 12:08:40 +00:00
parent 4247e37667
commit ef22fc4627
28 changed files with 693 additions and 105 deletions

View File

@@ -3,49 +3,81 @@ import { notFound } from "next/navigation"
import { getLocations } from "@/lib/trpc/memoizedRequests"
import { generateChildrenString } from "@/components/HotelReservation/utils"
import { convertSearchParamsToObj } from "@/utils/url"
import { convertSearchParamsToObj, type SelectHotelParams } from "@/utils/url"
import type { SelectHotelSearchParams } from "@/types/components/hotelReservation/selectHotel/selectHotelSearchParams"
import type {
AlternativeHotelsSearchParams,
SelectHotelSearchParams,
} from "@/types/components/hotelReservation/selectHotel/selectHotelSearchParams"
import type {
Child,
SelectRateSearchParams,
} from "@/types/components/hotelReservation/selectRate/selectRate"
import type { Location } from "@/types/trpc/routers/hotel/locations"
import {
type HotelLocation,
isHotelLocation,
type Location,
} from "@/types/trpc/routers/hotel/locations"
interface HotelSearchDetails<T> {
city: Location | null
hotel: Location | null
selectHotelParams: T
hotel: HotelLocation | null
selectHotelParams: SelectHotelParams<T> & { city: string | undefined }
adultsInRoom: number
childrenInRoomString?: string
childrenInRoom?: Child[]
}
export async function getHotelSearchDetails<
T extends SelectHotelSearchParams | SelectRateSearchParams,
>({
searchParams,
}: {
searchParams: T & {
[key: string]: string
}
}): Promise<HotelSearchDetails<T> | null> {
T extends
| SelectHotelSearchParams
| SelectRateSearchParams
| AlternativeHotelsSearchParams,
>(
{
searchParams,
}: {
searchParams: T & {
[key: string]: string
}
},
isAlternativeHotels?: boolean
): Promise<HotelSearchDetails<T> | null> {
const selectHotelParams = convertSearchParamsToObj<T>(searchParams)
const locations = await getLocations()
if (!locations || "error" in locations) return null
const city = locations.data.find(
(location) =>
location.name.toLowerCase() === selectHotelParams.city?.toLowerCase()
)
const hotel = locations.data.find(
(location) =>
"operaId" in location && location.operaId == selectHotelParams.hotelId
)
const hotel =
("hotelId" in selectHotelParams &&
(locations.data.find(
(location) =>
isHotelLocation(location) &&
"operaId" in location &&
location.operaId === selectHotelParams.hotelId
) as HotelLocation | undefined)) ||
null
if (isAlternativeHotels && !hotel) {
return notFound()
}
const cityName = isAlternativeHotels
? hotel?.relationships.city.name
: "city" in selectHotelParams
? (selectHotelParams.city as string | undefined)
: undefined
const city =
(typeof cityName === "string" &&
locations.data.find(
(location) => location.name.toLowerCase() === cityName.toLowerCase()
)) ||
null
if (!city && !hotel) return notFound()
if (isAlternativeHotels && (!city || !hotel)) return notFound()
let adultsInRoom = 1
let childrenInRoomString: HotelSearchDetails<T>["childrenInRoomString"] =
@@ -63,9 +95,9 @@ export async function getHotelSearchDetails<
}
return {
city: city ?? null,
hotel: hotel ?? null,
selectHotelParams,
city,
hotel,
selectHotelParams: { city: cityName, ...selectHotelParams },
adultsInRoom,
childrenInRoomString,
childrenInRoom,