Files
web/app/[lang]/(live)/(public)/hotelreservation/[section]/page.tsx
2024-10-07 08:12:07 +02:00

199 lines
5.8 KiB
TypeScript

import { notFound } from "next/navigation"
import { getProfileSafely } from "@/lib/trpc/memoizedRequests"
import { serverClient } from "@/lib/trpc/server"
import Details from "@/components/HotelReservation/EnterDetails/Details"
import HotelSelectionHeader from "@/components/HotelReservation/HotelSelectionHeader"
import BedSelection from "@/components/HotelReservation/SelectRate/BedSelection"
import BreakfastSelection from "@/components/HotelReservation/SelectRate/BreakfastSelection"
import Payment from "@/components/HotelReservation/SelectRate/Payment"
import RoomSelection from "@/components/HotelReservation/SelectRate/RoomSelection"
import SectionAccordion from "@/components/HotelReservation/SelectRate/SectionAccordion"
import Summary from "@/components/HotelReservation/SelectRate/Summary"
import { getIntl } from "@/i18n"
import { setLang } from "@/i18n/serverContext"
import styles from "./page.module.css"
import { SectionPageProps } from "@/types/components/hotelReservation/selectRate/section"
import { LangParams, PageArgs } from "@/types/params"
const bedAlternatives = [
{
value: "queen",
name: "Queen bed",
payment: "160 cm",
pricePerNight: 0,
membersPricePerNight: 0,
currency: "SEK",
},
{
value: "king",
name: "King bed",
payment: "160 cm",
pricePerNight: 0,
membersPricePerNight: 0,
currency: "SEK",
},
{
value: "twin",
name: "Twin bed",
payment: "90 cm + 90 cm",
pricePerNight: 82,
membersPricePerNight: 67,
currency: "SEK",
},
]
const breakfastAlternatives = [
{
value: "no",
name: "No breakfast",
payment: "Always cheeper to get it online",
pricePerNight: 0,
currency: "SEK",
},
{
value: "buffe",
name: "Breakfast buffé",
payment: "Always cheeper to get it online",
pricePerNight: 150,
currency: "SEK",
},
]
const getFlexibilityMessage = (value: string) => {
switch (value) {
case "non-refundable":
return "Non refundable"
case "free-rebooking":
return "Free rebooking"
case "free-cancellation":
return "Free cancellation"
}
return undefined
}
export default async function SectionsPage({
params,
searchParams,
}: PageArgs<LangParams & { section: string }, SectionPageProps>) {
setLang(params.lang)
const profile = await getProfileSafely()
const hotel = await serverClient().hotel.hotelData.get({
hotelId: "811",
language: params.lang,
})
if (!hotel) {
// TODO: handle case with hotel missing
return notFound()
}
const rooms = await serverClient().hotel.rates.get({
// TODO: pass the correct hotel ID and all other parameters that should be included in the search
hotelId: hotel.data.id,
})
const intl = await getIntl()
const selectedBed = searchParams.bed
? bedAlternatives.find((a) => a.value === searchParams.bed)?.name
: undefined
const selectedBreakfast = searchParams.breakfast
? breakfastAlternatives.find((a) => a.value === searchParams.breakfast)
?.name
: undefined
const selectedRoom = searchParams.roomClass
? rooms.find((room) => room.id.toString() === searchParams.roomClass)?.name
: undefined
const selectedFlexibility = searchParams.flexibility
? getFlexibilityMessage(searchParams.flexibility)
: undefined
const currentSearchParams = new URLSearchParams(searchParams).toString()
let user = null
if (profile && !("error" in profile)) {
user = profile
}
return (
<div>
<HotelSelectionHeader hotel={hotel.data.attributes} />
<div className={styles.content}>
<div className={styles.main}>
<SectionAccordion
header={intl.formatMessage({ id: "Room & Terms" })}
selection={
selectedRoom
? [
selectedRoom,
intl.formatMessage({ id: selectedFlexibility }),
]
: undefined
}
path={`select-rate?${currentSearchParams}`}
>
{params.section === "select-rate" && (
<RoomSelection
alternatives={rooms}
nextPath="select-bed"
// TODO: Get real value
nrOfNights={1}
// TODO: Get real value
nrOfAdults={1}
/>
)}
</SectionAccordion>
<SectionAccordion
header={intl.formatMessage({ id: "Bed type" })}
selection={selectedBed}
path={`select-bed?${currentSearchParams}`}
>
{params.section === "select-bed" && (
<BedSelection
nextPath="breakfast"
alternatives={bedAlternatives}
/>
)}
</SectionAccordion>
<SectionAccordion
header={intl.formatMessage({ id: "Breakfast" })}
selection={selectedBreakfast}
path={`breakfast?${currentSearchParams}`}
>
{params.section === "breakfast" && (
<BreakfastSelection
alternatives={breakfastAlternatives}
nextPath="details"
/>
)}
</SectionAccordion>
<SectionAccordion
header={intl.formatMessage({ id: "Your details" })}
path={`details?${currentSearchParams}`}
>
{params.section === "details" ? <Details user={user} /> : null}
</SectionAccordion>
<SectionAccordion
header={intl.formatMessage({ id: "Payment info" })}
path={`payment?${currentSearchParams}`}
>
{params.section === "payment" && (
<Payment hotel={hotel.data.attributes} />
)}
</SectionAccordion>
</div>
<div className={styles.summary}>
<Summary />
</div>
</div>
</div>
)
}