feat(sw-452): Implement select room form submit
This commit is contained in:
@@ -18,6 +18,7 @@ export default function FlexibilityOption({
|
||||
paymentTerm,
|
||||
priceInformation,
|
||||
roomType,
|
||||
roomTypeCode,
|
||||
handleSelectRate,
|
||||
}: FlexibilityOptionProps) {
|
||||
const [rootDiv, setRootDiv] = useState<Element | undefined>(undefined)
|
||||
@@ -46,6 +47,7 @@ export default function FlexibilityOption({
|
||||
|
||||
function onChange() {
|
||||
const rate = {
|
||||
roomTypeCode: roomTypeCode,
|
||||
roomType: roomType,
|
||||
priceName: name,
|
||||
public: publicPrice,
|
||||
|
||||
@@ -24,17 +24,15 @@ export default function RateSummary({
|
||||
</div>
|
||||
<div className={styles.summaryPrice}>
|
||||
<div className={styles.summaryPriceText}>
|
||||
<>
|
||||
<Subtitle color={isUserLoggedIn ? "red" : "uiTextHighContrast"}>
|
||||
{priceToShow?.localPrice.pricePerStay}{" "}
|
||||
{priceToShow?.localPrice.currency}
|
||||
</Subtitle>
|
||||
<Body color="uiTextMediumContrast">
|
||||
{intl.formatMessage({ id: "Approx." })}{" "}
|
||||
{priceToShow?.requestedPrice?.pricePerStay}{" "}
|
||||
{priceToShow?.requestedPrice?.currency}
|
||||
</Body>
|
||||
</>
|
||||
<Subtitle color={isUserLoggedIn ? "red" : "uiTextHighContrast"}>
|
||||
{priceToShow?.localPrice.pricePerStay}{" "}
|
||||
{priceToShow?.localPrice.currency}
|
||||
</Subtitle>
|
||||
<Body color="uiTextMediumContrast">
|
||||
{intl.formatMessage({ id: "Approx." })}{" "}
|
||||
{priceToShow?.requestedPrice?.pricePerStay}{" "}
|
||||
{priceToShow?.requestedPrice?.currency}
|
||||
</Body>
|
||||
</div>
|
||||
<Button type="submit" theme="base">
|
||||
{intl.formatMessage({ id: "Continue" })}
|
||||
|
||||
@@ -116,6 +116,7 @@ export default function RoomCard({
|
||||
priceInformation={getPriceForRate(saveRate)}
|
||||
handleSelectRate={handleSelectRate}
|
||||
roomType={roomConfiguration.roomType}
|
||||
roomTypeCode={roomConfiguration.roomTypeCode}
|
||||
/>
|
||||
<FlexibilityOption
|
||||
name={intl.formatMessage({ id: "Free rebooking" })}
|
||||
@@ -125,6 +126,7 @@ export default function RoomCard({
|
||||
priceInformation={getPriceForRate(changeRate)}
|
||||
handleSelectRate={handleSelectRate}
|
||||
roomType={roomConfiguration.roomType}
|
||||
roomTypeCode={roomConfiguration.roomTypeCode}
|
||||
/>
|
||||
<FlexibilityOption
|
||||
name={intl.formatMessage({ id: "Free cancellation" })}
|
||||
@@ -134,6 +136,7 @@ export default function RoomCard({
|
||||
priceInformation={getPriceForRate(flexRate)}
|
||||
handleSelectRate={handleSelectRate}
|
||||
roomType={roomConfiguration.roomType}
|
||||
roomTypeCode={roomConfiguration.roomTypeCode}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -4,6 +4,7 @@ import { useState } from "react"
|
||||
|
||||
import RateSummary from "./RateSummary"
|
||||
import RoomCard from "./RoomCard"
|
||||
import { getHotelReservationQueryParams } from "./utils"
|
||||
|
||||
import styles from "./roomSelection.module.css"
|
||||
|
||||
@@ -19,12 +20,43 @@ export default function RoomSelection({
|
||||
|
||||
const router = useRouter()
|
||||
const searchParams = useSearchParams()
|
||||
const isUserLoggedIn = !!user
|
||||
|
||||
function handleSubmit(e: React.FormEvent<HTMLFormElement>) {
|
||||
e.preventDefault()
|
||||
const searchParamsObject = getHotelReservationQueryParams(searchParams)
|
||||
|
||||
/**
|
||||
* These are the query params that are used on current web and should come from the Booking Widget Search Submit.
|
||||
* Might need to be changed when Search Submit in the Booking Widget is implemented.
|
||||
*/
|
||||
const queryParams = new URLSearchParams(searchParams)
|
||||
queryParams.set("roomClass", e.currentTarget.roomClass?.value)
|
||||
queryParams.set("flexibility", e.currentTarget.flexibility?.value)
|
||||
|
||||
searchParamsObject.room.forEach((item, index) => {
|
||||
queryParams.set(`room[${index}].adults`, item.adults.toString())
|
||||
|
||||
if (Array.isArray(item.child)) {
|
||||
item.child.forEach((child, childIndex) => {
|
||||
queryParams.set(
|
||||
`room[${index}].child[${childIndex}].age`,
|
||||
child.age.toString()
|
||||
)
|
||||
queryParams.set(`room[${index}].child[${childIndex}].bed`, child.bed)
|
||||
})
|
||||
}
|
||||
|
||||
queryParams.set(
|
||||
`room[${index}].roomtypecode`,
|
||||
rateSummary?.roomTypeCode || ""
|
||||
)
|
||||
queryParams.set(
|
||||
`room[${index}].ratecode`,
|
||||
isUserLoggedIn
|
||||
? rateSummary?.member?.rateCode || ""
|
||||
: rateSummary?.public?.rateCode || ""
|
||||
)
|
||||
})
|
||||
|
||||
router.push(`select-bed?${queryParams}`)
|
||||
}
|
||||
|
||||
@@ -48,7 +80,10 @@ export default function RoomSelection({
|
||||
))}
|
||||
</ul>
|
||||
{rateSummary && (
|
||||
<RateSummary rateSummary={rateSummary} isUserLoggedIn={!!user} />
|
||||
<RateSummary
|
||||
rateSummary={rateSummary}
|
||||
isUserLoggedIn={isUserLoggedIn}
|
||||
/>
|
||||
)}
|
||||
</form>
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
import { SelectRateSearchParams } from "@/types/components/hotelReservation/selectRate/selectRate"
|
||||
|
||||
function getHotelReservationQueryParams(searchParams: URLSearchParams) {
|
||||
const searchParamsObject: SelectRateSearchParams = Array.from(
|
||||
searchParams.entries()
|
||||
).reduce((acc, [key, value]) => {
|
||||
const keys = key.replace(/\]/g, "").split(/\[|\./) // Split keys by '[' or '.'
|
||||
keys.reduce((nestedAcc, k, i) => {
|
||||
if (i === keys.length - 1) {
|
||||
nestedAcc[k] = value // Assign value at the last key
|
||||
} else {
|
||||
if (!nestedAcc[k]) {
|
||||
nestedAcc[k] = isNaN(Number(keys[i + 1])) ? {} : [] // Initialize as array or object
|
||||
}
|
||||
}
|
||||
return nestedAcc[k]
|
||||
}, acc)
|
||||
return acc
|
||||
}, {} as SelectRateSearchParams)
|
||||
return searchParamsObject
|
||||
}
|
||||
|
||||
export { getHotelReservationQueryParams }
|
||||
@@ -1,6 +1,10 @@
|
||||
import { z } from "zod"
|
||||
|
||||
import { Product, productTypePriceSchema } from "@/server/routers/hotels/output"
|
||||
import {
|
||||
Product,
|
||||
productTypePriceSchema,
|
||||
RoomConfiguration,
|
||||
} from "@/server/routers/hotels/output"
|
||||
|
||||
import { Rate } from "./selectRate"
|
||||
|
||||
@@ -12,7 +16,8 @@ export type FlexibilityOptionProps = {
|
||||
value: string
|
||||
paymentTerm: string
|
||||
priceInformation?: Array<string>
|
||||
roomType: string
|
||||
roomType: RoomConfiguration["roomType"]
|
||||
roomTypeCode: RoomConfiguration["roomTypeCode"]
|
||||
handleSelectRate: (rate: Rate) => void
|
||||
}
|
||||
|
||||
|
||||
@@ -1,13 +1,28 @@
|
||||
import { Product } from "@/server/routers/hotels/output"
|
||||
import { Product, RoomConfiguration } from "@/server/routers/hotels/output"
|
||||
|
||||
interface Child {
|
||||
bed: string
|
||||
age: number
|
||||
}
|
||||
|
||||
interface Room {
|
||||
adults: number
|
||||
roomtypecode: string
|
||||
ratecode: string
|
||||
child: Child[]
|
||||
}
|
||||
|
||||
export interface SelectRateSearchParams {
|
||||
fromDate: string
|
||||
toDate: string
|
||||
hotel: string
|
||||
fromdate: string
|
||||
todate: string
|
||||
room: Room[]
|
||||
[key: string]: any
|
||||
}
|
||||
|
||||
export interface Rate {
|
||||
roomType: string
|
||||
roomType: RoomConfiguration["roomType"]
|
||||
roomTypeCode: RoomConfiguration["roomTypeCode"]
|
||||
priceName: string
|
||||
public: Product["productType"]["public"]
|
||||
member: Product["productType"]["member"]
|
||||
|
||||
Reference in New Issue
Block a user