Merge branch 'master' into feature/tracking
This commit is contained in:
@@ -1,7 +1,3 @@
|
||||
import { notFound } from "next/navigation"
|
||||
|
||||
import { env } from "@/env/server"
|
||||
|
||||
import styles from "./layout.module.css"
|
||||
|
||||
import { LangParams, LayoutArgs } from "@/types/params"
|
||||
@@ -12,9 +8,6 @@ export default function HotelReservationLayout({
|
||||
}: React.PropsWithChildren<LayoutArgs<LangParams>> & {
|
||||
sidePeek: React.ReactNode
|
||||
}) {
|
||||
if (!env.ENABLE_BOOKING_FLOW) {
|
||||
return notFound()
|
||||
}
|
||||
return (
|
||||
<div className={styles.layout}>
|
||||
{children}
|
||||
|
||||
@@ -17,6 +17,7 @@ import { setLang } from "@/i18n/serverContext"
|
||||
|
||||
import { fetchAvailableHotels, getFiltersFromHotels } from "../../utils"
|
||||
|
||||
import type { HotelData } from "@/types/components/hotelReservation/selectHotel/hotelCardListingProps"
|
||||
import type { SelectHotelSearchParams } from "@/types/components/hotelReservation/selectHotel/selectHotelSearchParams"
|
||||
import {
|
||||
TrackingChannelEnum,
|
||||
@@ -59,6 +60,10 @@ export default async function SelectHotelMapPage({
|
||||
children,
|
||||
})
|
||||
|
||||
const validHotels = hotels.filter(
|
||||
(hotel): hotel is HotelData => hotel !== null
|
||||
)
|
||||
|
||||
const arrivalDate = new Date(searchParams.fromDate)
|
||||
const departureDate = new Date(searchParams.toDate)
|
||||
|
||||
@@ -85,15 +90,15 @@ export default async function SelectHotelMapPage({
|
||||
leadTime: differenceInCalendarDays(arrivalDate, new Date()),
|
||||
searchType: "destination",
|
||||
bookingTypeofDay: isWeekend(arrivalDate) ? "weekend" : "weekday",
|
||||
country: hotels?.[0].hotelData.address.country,
|
||||
region: hotels?.[0].hotelData.address.city,
|
||||
country: validHotels?.[0].hotelData.address.country,
|
||||
region: validHotels?.[0].hotelData.address.city,
|
||||
}
|
||||
|
||||
const hotelPins = getHotelPins(hotels)
|
||||
const filterList = getFiltersFromHotels(hotels)
|
||||
const hotelPins = getHotelPins(validHotels)
|
||||
const filterList = getFiltersFromHotels(validHotels)
|
||||
const cityCoordinates = await getCityCoordinates({
|
||||
city: city.name,
|
||||
hotel: { address: hotels[0].hotelData.address.streetAddress },
|
||||
hotel: { address: hotels?.[0]?.hotelData?.address.streetAddress },
|
||||
})
|
||||
|
||||
return (
|
||||
@@ -102,7 +107,7 @@ export default async function SelectHotelMapPage({
|
||||
apiKey={googleMapsApiKey}
|
||||
hotelPins={hotelPins}
|
||||
mapId={googleMapId}
|
||||
hotels={hotels}
|
||||
hotels={validHotels}
|
||||
filterList={filterList}
|
||||
cityCoordinates={cityCoordinates}
|
||||
/>
|
||||
|
||||
@@ -36,6 +36,7 @@ import { setLang } from "@/i18n/serverContext"
|
||||
|
||||
import styles from "./page.module.css"
|
||||
|
||||
import type { HotelData } from "@/types/components/hotelReservation/selectHotel/hotelCardListingProps"
|
||||
import type { SelectHotelSearchParams } from "@/types/components/hotelReservation/selectHotel/selectHotelSearchParams"
|
||||
import {
|
||||
TrackingChannelEnum,
|
||||
@@ -69,6 +70,14 @@ export default async function SelectHotelPage({
|
||||
const selectHotelParams = new URLSearchParams(searchParams)
|
||||
const selectHotelParamsObject =
|
||||
getHotelReservationQueryParams(selectHotelParams)
|
||||
|
||||
if (
|
||||
!selectHotelParamsObject.room ||
|
||||
selectHotelParamsObject.room.length === 0
|
||||
) {
|
||||
return notFound()
|
||||
}
|
||||
|
||||
const adults = selectHotelParamsObject.room[0].adults // TODO: Handle multiple rooms
|
||||
const child = selectHotelParamsObject.room[0].child // TODO: Handle multiple rooms
|
||||
const children = child ? generateChildrenString(child) : undefined
|
||||
@@ -84,7 +93,11 @@ export default async function SelectHotelPage({
|
||||
const arrivalDate = new Date(searchParams.fromDate)
|
||||
const departureDate = new Date(searchParams.toDate)
|
||||
|
||||
const filterList = getFiltersFromHotels(hotels)
|
||||
const validHotels = hotels.filter(
|
||||
(hotel): hotel is HotelData => hotel !== null
|
||||
)
|
||||
|
||||
const filterList = getFiltersFromHotels(validHotels)
|
||||
const breadcrumbs = [
|
||||
{
|
||||
title: intl.formatMessage({ id: "Home" }),
|
||||
@@ -132,8 +145,8 @@ export default async function SelectHotelPage({
|
||||
leadTime: differenceInCalendarDays(arrivalDate, new Date()),
|
||||
searchType: "destination",
|
||||
bookingTypeofDay: isWeekend(arrivalDate) ? "weekend" : "weekday",
|
||||
country: hotels?.[0].hotelData.address.country,
|
||||
region: hotels?.[0].hotelData.address.city,
|
||||
country: validHotels?.[0].hotelData.address.country,
|
||||
region: validHotels?.[0].hotelData.address.city,
|
||||
}
|
||||
|
||||
return (
|
||||
@@ -206,7 +219,7 @@ export default async function SelectHotelPage({
|
||||
})}
|
||||
/>
|
||||
)}
|
||||
<HotelCardListing hotelData={hotels} />
|
||||
<HotelCardListing hotelData={validHotels} />
|
||||
</div>
|
||||
<TrackingSDK
|
||||
pageData={pageTrackingData}
|
||||
|
||||
@@ -4,7 +4,10 @@ import { serverClient } from "@/lib/trpc/server"
|
||||
import { getLang } from "@/i18n/serverContext"
|
||||
|
||||
import type { AvailabilityInput } from "@/types/components/hotelReservation/selectHotel/availabilityInput"
|
||||
import type { HotelData } from "@/types/components/hotelReservation/selectHotel/hotelCardListingProps"
|
||||
import type {
|
||||
HotelData,
|
||||
NullableHotelData,
|
||||
} from "@/types/components/hotelReservation/selectHotel/hotelCardListingProps"
|
||||
import type {
|
||||
CategorizedFilters,
|
||||
Filter,
|
||||
@@ -30,10 +33,10 @@ const hotelFacilitiesFilterNames = [
|
||||
|
||||
export async function fetchAvailableHotels(
|
||||
input: AvailabilityInput
|
||||
): Promise<HotelData[]> {
|
||||
): Promise<NullableHotelData[]> {
|
||||
const availableHotels = await serverClient().hotel.availability.hotels(input)
|
||||
|
||||
if (!availableHotels) throw new Error()
|
||||
if (!availableHotels) return []
|
||||
|
||||
const language = getLang()
|
||||
|
||||
@@ -43,7 +46,7 @@ export async function fetchAvailableHotels(
|
||||
language,
|
||||
})
|
||||
|
||||
if (!hotelData) throw new Error()
|
||||
if (!hotelData) return { hotelData: null, price: hotel.productType }
|
||||
|
||||
return {
|
||||
hotelData: hotelData.data.attributes,
|
||||
@@ -55,7 +58,13 @@ export async function fetchAvailableHotels(
|
||||
}
|
||||
|
||||
export function getFiltersFromHotels(hotels: HotelData[]): CategorizedFilters {
|
||||
const filters = hotels.flatMap((hotel) => hotel.hotelData.detailedFacilities)
|
||||
if (hotels.length === 0)
|
||||
return { facilityFilters: [], surroundingsFilters: [] }
|
||||
|
||||
const filters = hotels.flatMap((hotel) => {
|
||||
if (!hotel.hotelData) return []
|
||||
return hotel.hotelData.detailedFacilities
|
||||
})
|
||||
|
||||
const uniqueFilterIds = [...new Set(filters.map((filter) => filter.id))]
|
||||
const filterList: Filter[] = uniqueFilterIds
|
||||
|
||||
@@ -4,7 +4,8 @@
|
||||
}
|
||||
|
||||
.content {
|
||||
margin: var(--Spacing-x3) var(--Spacing-x2) 0;
|
||||
width: var(--max-width-page);
|
||||
margin: var(--Spacing-x3) auto 0;
|
||||
}
|
||||
|
||||
.summary {
|
||||
@@ -16,14 +17,17 @@
|
||||
|
||||
@media screen and (min-width: 1367px) {
|
||||
.container {
|
||||
width: var(--max-width-page);
|
||||
|
||||
grid-template-columns: 1fr 340px;
|
||||
grid-template-rows: auto 1fr;
|
||||
margin: var(--Spacing-x5) auto 0;
|
||||
/* simulates padding on viewport smaller than --max-width-navigation */
|
||||
width: min(
|
||||
calc(100dvw - (var(--Spacing-x2) * 2)),
|
||||
var(--max-width-navigation)
|
||||
);
|
||||
}
|
||||
|
||||
.content {
|
||||
width: 100%;
|
||||
margin: var(--Spacing-x3) 0 0;
|
||||
}
|
||||
|
||||
.summary {
|
||||
|
||||
@@ -19,7 +19,8 @@ import HistoryStateManager from "@/components/HotelReservation/EnterDetails/Hist
|
||||
import Payment from "@/components/HotelReservation/EnterDetails/Payment"
|
||||
import SectionAccordion from "@/components/HotelReservation/EnterDetails/SectionAccordion"
|
||||
import SelectedRoom from "@/components/HotelReservation/EnterDetails/SelectedRoom"
|
||||
import Summary from "@/components/HotelReservation/EnterDetails/Summary"
|
||||
import DesktopSummary from "@/components/HotelReservation/EnterDetails/Summary/Desktop"
|
||||
import MobileSummary from "@/components/HotelReservation/EnterDetails/Summary/Mobile"
|
||||
import {
|
||||
generateChildrenString,
|
||||
getQueryParamsForEnterDetails,
|
||||
@@ -182,6 +183,13 @@ export default async function StepPage({
|
||||
//lowestRoomPrice:
|
||||
}
|
||||
|
||||
const summary = {
|
||||
cancellationText: roomAvailability.cancellationText,
|
||||
isMember: !!user,
|
||||
rateDetails: roomAvailability.rateDetails,
|
||||
roomType: roomAvailability.selectedRoom.roomType,
|
||||
}
|
||||
|
||||
return (
|
||||
<EnterDetailsProvider
|
||||
bedTypes={roomAvailability.bedTypes}
|
||||
@@ -262,16 +270,8 @@ export default async function StepPage({
|
||||
</section>
|
||||
</div>
|
||||
<aside className={styles.summary}>
|
||||
<Summary
|
||||
adults={adults}
|
||||
fromDate={fromDate}
|
||||
hotelId={hotelId}
|
||||
kids={children}
|
||||
packageCodes={packageCodes}
|
||||
rateCode={rateCode}
|
||||
roomTypeCode={roomTypeCode}
|
||||
toDate={toDate}
|
||||
/>
|
||||
<MobileSummary {...summary} />
|
||||
<DesktopSummary {...summary} />
|
||||
</aside>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
Reference in New Issue
Block a user