From 43e58dcf0106047aef84b3e90e06809eae922ccf Mon Sep 17 00:00:00 2001 From: Fredrik Thorsson Date: Wed, 11 Sep 2024 10:22:01 +0200 Subject: [PATCH] feat(SW-251): use parallel fetch for hotels --- .../select-hotel/page.module.css | 3 +- .../hotelreservation/select-hotel/page.tsx | 84 ++++++++++++------- .../HotelReservation/HotelCard/index.tsx | 46 ++++------ .../hotelCardListing.module.css | 5 ++ .../HotelCardListing/index.tsx | 25 ++++++ .../SelectHotel/HotelFilter/index.tsx | 6 +- .../selectHotel/availabilityInput.ts | 10 +++ .../selectHotel/hotelCardListingProps.ts | 12 +++ .../selectHotel/hotelCardProps.ts | 10 +-- 9 files changed, 126 insertions(+), 75 deletions(-) create mode 100644 components/HotelReservation/HotelCardListing/hotelCardListing.module.css create mode 100644 components/HotelReservation/HotelCardListing/index.tsx create mode 100644 types/components/hotelReservation/selectHotel/availabilityInput.ts create mode 100644 types/components/hotelReservation/selectHotel/hotelCardListingProps.ts diff --git a/app/[lang]/(live)/(public)/hotelreservation/select-hotel/page.module.css b/app/[lang]/(live)/(public)/hotelreservation/select-hotel/page.module.css index 9877bc4cf..3a8bcfe07 100644 --- a/app/[lang]/(live)/(public)/hotelreservation/select-hotel/page.module.css +++ b/app/[lang]/(live)/(public)/hotelreservation/select-hotel/page.module.css @@ -6,10 +6,9 @@ min-height: 100dvh; } -.hotelCards { +.section { display: flex; flex-direction: column; - gap: var(--Spacing-x4); } .link { diff --git a/app/[lang]/(live)/(public)/hotelreservation/select-hotel/page.tsx b/app/[lang]/(live)/(public)/hotelreservation/select-hotel/page.tsx index bc5231f08..0c128c835 100644 --- a/app/[lang]/(live)/(public)/hotelreservation/select-hotel/page.tsx +++ b/app/[lang]/(live)/(public)/hotelreservation/select-hotel/page.tsx @@ -1,40 +1,75 @@ import { serverClient } from "@/lib/trpc/server" +import { notFound } from "@/server/errors/next" -import HotelCard from "@/components/HotelReservation/HotelCard" +import HotelCardListing from "@/components/HotelReservation/HotelCardListing" import HotelFilter from "@/components/HotelReservation/SelectHotel/HotelFilter" import { ChevronRightIcon } from "@/components/Icons" import StaticMap from "@/components/Maps/StaticMap" import Link from "@/components/TempDesignSystem/Link" -import Title from "@/components/TempDesignSystem/Text/Title" import { getIntl } from "@/i18n" -import { setLang } from "@/i18n/serverContext" +import { getLang, setLang } from "@/i18n/serverContext" import styles from "./page.module.css" +import { AvailabilityInput } from "@/types/components/hotelReservation/selectHotel/availabilityInput" +import { HotelData } from "@/types/components/hotelReservation/selectHotel/hotelCardListingProps" import { LangParams, PageArgs } from "@/types/params" -export default async function SelectHotelPage({ - params, -}: PageArgs) { - const intl = await getIntl() - setLang(params.lang) - - const tempSearchTerm = "Stockholm" - +async function getAvailableHotels({ + cityId, + roomStayStartDate, + roomStayEndDate, + adults, +}: AvailabilityInput): Promise { const getAvailableHotels = await serverClient().hotel.availability.get({ - cityId: "8ec4bba3-1c38-4606-82d1-bbe3f6738e54", - roomStayStartDate: "2024-11-02", - roomStayEndDate: "2024-11-03", - adults: 1, + cityId: cityId, + roomStayStartDate: roomStayStartDate, + roomStayEndDate: roomStayEndDate, + adults: adults, }) if (!getAvailableHotels) return null const { availability } = getAvailableHotels + const hotels = availability.map(async (hotel) => { + const hotelData = await serverClient().hotel.hotel.get({ + hotelId: hotel.hotelId.toString(), + language: getLang(), + }) + + return { + hotelData: hotelData?.data.attributes, + price: hotel.bestPricePerNight, + } + }) + + return await Promise.all(hotels) +} + +export default async function SelectHotelPage({ + params, +}: PageArgs) { + setLang(params.lang) + + const tempSearchTerm = "Stockholm" + + const intl = await getIntl() + + const hotels = await getAvailableHotels({ + cityId: "8ec4bba3-1c38-4606-82d1-bbe3f6738e54", + roomStayStartDate: "2024-11-02", + roomStayEndDate: "2024-11-03", + adults: 1, + }) + + if (!hotels) return null + + if (hotels.some((item) => item?.hotelData === undefined)) return notFound() + return (
-
+
-
- {availability.length ? ( - availability.map((hotel) => ( - - )) - ) : ( - // TODO: handle no hotels found - No hotels found - )} -
+
) } diff --git a/components/HotelReservation/HotelCard/index.tsx b/components/HotelReservation/HotelCard/index.tsx index 0f37287f1..5cd6989f0 100644 --- a/components/HotelReservation/HotelCard/index.tsx +++ b/components/HotelReservation/HotelCard/index.tsx @@ -1,5 +1,4 @@ -import { serverClient } from "@/lib/trpc/server" -import tempHotelData from "@/server/routers/hotels/tempHotelData.json" +import { useIntl } from "react-intl" import { mapFacilityToIcon } from "@/components/ContentType/HotelPage/data" import { @@ -15,43 +14,30 @@ import Link from "@/components/TempDesignSystem/Link" import Caption from "@/components/TempDesignSystem/Text/Caption" import Footnote from "@/components/TempDesignSystem/Text/Footnote" import Title from "@/components/TempDesignSystem/Text/Title" -import { getIntl } from "@/i18n" -import { getLang } from "@/i18n/serverContext" import styles from "./hotelCard.module.css" import { HotelCardProps } from "@/types/components/hotelReservation/selectHotel/hotelCardProps" -export default async function HotelCard({ - checkInDate, - checkOutDate, - hotelId, - price, -}: HotelCardProps) { - const intl = await getIntl() +export default function HotelCard({ hotel }: HotelCardProps) { + const intl = useIntl() - // TODO: Use real endpoint. - const hotel = tempHotelData.data.attributes + const { hotelData } = hotel + const { price } = hotel - const hotelResponse = await serverClient().hotel.hotel.get({ - hotelId: hotelId.toString(), - language: getLang(), - }) + if (!hotelData) return null + if (!price) return null - if (!hotelResponse) return null - - const { data } = hotelResponse - - const sortedAmenities = data.attributes.detailedFacilities - .sort((a, b) => b.sortOrder - a.sortOrder) + const sortedAmenities = hotelData.detailedFacilities + ?.sort((a, b) => b.sortOrder - a.sortOrder) .slice(0, 5) return (
{data.attributes.hotelContent.images.metaData.altText} - {data.attributes.ratings?.tripAdvisor.rating} + {hotelData.ratings?.tripAdvisor.rating}
- {hotel.name} + {hotelData.name} - {`${data.attributes.address.streetAddress}, ${data.attributes.address.city}`} + {`${hotelData.address?.streetAddress}, ${hotelData.address?.city}`} - {`${data.attributes.location.distanceToCentre} ${intl.formatMessage({ id: "km to city center" })}`} + {`${hotelData.location.distanceToCentre} ${intl.formatMessage({ id: "km to city center" })}`}
- {sortedAmenities.map((facility) => { + {sortedAmenities?.map((facility) => { const IconComponent = mapFacilityToIcon(facility.name) return (
diff --git a/components/HotelReservation/HotelCardListing/hotelCardListing.module.css b/components/HotelReservation/HotelCardListing/hotelCardListing.module.css new file mode 100644 index 000000000..be62321df --- /dev/null +++ b/components/HotelReservation/HotelCardListing/hotelCardListing.module.css @@ -0,0 +1,5 @@ +.hotelCards { + display: flex; + flex-direction: column; + gap: var(--Spacing-x4); +} diff --git a/components/HotelReservation/HotelCardListing/index.tsx b/components/HotelReservation/HotelCardListing/index.tsx new file mode 100644 index 000000000..2af4f0b9c --- /dev/null +++ b/components/HotelReservation/HotelCardListing/index.tsx @@ -0,0 +1,25 @@ +"use client" + +import Title from "@/components/TempDesignSystem/Text/Title" + +import HotelCard from "../HotelCard" + +import styles from "./hotelCardListing.module.css" + +import { HotelCardListingProps } from "@/types/components/hotelReservation/selectHotel/hotelCardListingProps" + +export default function HotelCardListing({ hotelData }: HotelCardListingProps) { + if (!hotelData) return null + + return ( +
+ {hotelData && hotelData.length ? ( + hotelData.map((hotel) => ( + + )) + ) : ( + HallÄ + )} +
+ ) +} diff --git a/components/HotelReservation/SelectHotel/HotelFilter/index.tsx b/components/HotelReservation/SelectHotel/HotelFilter/index.tsx index 81230461d..cc171f654 100644 --- a/components/HotelReservation/SelectHotel/HotelFilter/index.tsx +++ b/components/HotelReservation/SelectHotel/HotelFilter/index.tsx @@ -3,15 +3,15 @@ import { getIntl } from "@/i18n" import styles from "./hotelFilter.module.css" export default async function HotelFilter() { - const { formatMessage } = await getIntl() + const intl = await getIntl() return (