Merged in feat/sw-2857-refactor-booking-flow-url-updates (pull request #2302)
feat(SW-2857): Refactor booking flow url updates * Add support for removing parameters when using initial values in serializeSearchParams * Don't manually write search params in rate store * Booking is already from live search params so no need * Fix input type in serializeBookingSearchParams Approved-by: Linus Flood
This commit is contained in:
@@ -45,9 +45,9 @@ export function findProduct(
|
||||
}
|
||||
|
||||
export function findProductInRoom(
|
||||
rateCode: string | undefined,
|
||||
rateCode: string | undefined | null,
|
||||
room: RoomConfiguration,
|
||||
counterRateCode = ""
|
||||
counterRateCode: string | undefined | null
|
||||
) {
|
||||
if (!rateCode) {
|
||||
return null
|
||||
@@ -55,7 +55,7 @@ export function findProductInRoom(
|
||||
|
||||
if (room.campaign.length) {
|
||||
const campaignProduct = room.campaign.find((product) =>
|
||||
findProduct(rateCode, product, counterRateCode)
|
||||
findProduct(rateCode, product, counterRateCode || "")
|
||||
)
|
||||
if (campaignProduct) {
|
||||
return campaignProduct
|
||||
@@ -63,7 +63,7 @@ export function findProductInRoom(
|
||||
}
|
||||
if (room.code.length) {
|
||||
const codeProduct = room.code.find((product) =>
|
||||
findProduct(rateCode, product, counterRateCode)
|
||||
findProduct(rateCode, product, counterRateCode || "")
|
||||
)
|
||||
if (codeProduct) {
|
||||
return codeProduct
|
||||
@@ -79,7 +79,7 @@ export function findProductInRoom(
|
||||
}
|
||||
if (room.regular.length) {
|
||||
const regularProduct = room.regular.find((product) =>
|
||||
findProduct(rateCode, product, counterRateCode)
|
||||
findProduct(rateCode, product, counterRateCode || "")
|
||||
)
|
||||
if (regularProduct) {
|
||||
return regularProduct
|
||||
@@ -88,9 +88,9 @@ export function findProductInRoom(
|
||||
}
|
||||
|
||||
export function findSelectedRate(
|
||||
rateCode: string | undefined,
|
||||
counterRateCode: string | undefined,
|
||||
roomTypeCode: string | undefined,
|
||||
rateCode: string | undefined | null,
|
||||
counterRateCode: string | undefined | null,
|
||||
roomTypeCode: string | undefined | null,
|
||||
rooms: RoomConfiguration[] | AvailabilityError
|
||||
) {
|
||||
if (!Array.isArray(rooms)) {
|
||||
@@ -109,17 +109,6 @@ export function findSelectedRate(
|
||||
})
|
||||
}
|
||||
|
||||
export function clearRoomSelectionFromUrl(
|
||||
roomIdx: number,
|
||||
searchParams: URLSearchParams
|
||||
) {
|
||||
searchParams.delete(`room[${roomIdx}].bookingCode`)
|
||||
searchParams.delete(`room[${roomIdx}].counterratecode`)
|
||||
searchParams.delete(`room[${roomIdx}].ratecode`)
|
||||
searchParams.delete(`room[${roomIdx}].roomtype`)
|
||||
return searchParams
|
||||
}
|
||||
|
||||
export function findDefaultCurrency(
|
||||
roomsAvailability: (RoomsAvailability | AvailabilityError)[] | undefined
|
||||
) {
|
||||
|
||||
@@ -5,9 +5,9 @@ import { create, useStore } from "zustand"
|
||||
import { REDEMPTION } from "@/constants/booking"
|
||||
|
||||
import { RatesContext } from "@/contexts/Rates"
|
||||
import { serializeBookingSearchParams } from "@/utils/url"
|
||||
|
||||
import {
|
||||
clearRoomSelectionFromUrl,
|
||||
findDefaultCurrency,
|
||||
findProductInRoom,
|
||||
findSelectedRate,
|
||||
@@ -27,9 +27,16 @@ export function createRatesStore({
|
||||
pathname,
|
||||
roomCategories,
|
||||
roomsAvailability,
|
||||
searchParams,
|
||||
initialActiveRoom,
|
||||
vat,
|
||||
}: InitialState) {
|
||||
function updateUrl(booking: RatesState["booking"]) {
|
||||
const searchParams = serializeBookingSearchParams(booking, {
|
||||
initialSearchParams: new URLSearchParams(window.location.search),
|
||||
})
|
||||
window.history.replaceState({}, "", `${pathname}?${searchParams}`)
|
||||
}
|
||||
|
||||
const packageOptions = [
|
||||
{
|
||||
code: RoomPackageCodeEnum.ACCESSIBILITY_ROOM,
|
||||
@@ -73,13 +80,8 @@ export function createRatesStore({
|
||||
)
|
||||
|
||||
if (!selectedRoom) {
|
||||
const updatedSearchParams = clearRoomSelectionFromUrl(idx, searchParams)
|
||||
searchParams = updatedSearchParams
|
||||
window.history.replaceState(
|
||||
{},
|
||||
"",
|
||||
`${pathname}?${updatedSearchParams}`
|
||||
)
|
||||
booking.rooms[idx] = roomWithoutSelection(room)
|
||||
updateUrl(booking)
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -108,8 +110,8 @@ export function createRatesStore({
|
||||
}
|
||||
|
||||
let activeRoom = rateSummary.length
|
||||
if (searchParams.has("modifyRateIndex")) {
|
||||
activeRoom = Number(searchParams.get("modifyRateIndex"))
|
||||
if (initialActiveRoom) {
|
||||
activeRoom = initialActiveRoom
|
||||
} else if (rateSummary.length === booking.rooms.length) {
|
||||
// Finds the first unselected room and sets that to active
|
||||
// if no unselected rooms it will return -1 and close all rooms
|
||||
@@ -128,13 +130,11 @@ export function createRatesStore({
|
||||
packageOptions,
|
||||
hotelType,
|
||||
isRedemptionBooking,
|
||||
pathname,
|
||||
rateSummary,
|
||||
roomConfigurations,
|
||||
roomCategories,
|
||||
roomsPackages,
|
||||
roomsAvailability,
|
||||
searchParams,
|
||||
vat,
|
||||
defaultCurrency,
|
||||
rooms: booking.rooms.map((room, idx) => {
|
||||
@@ -266,23 +266,14 @@ export function createRatesStore({
|
||||
BookingCodeFilterEnum.Discounted
|
||||
}
|
||||
|
||||
const searchParams = state.searchParams
|
||||
if (filteredSelectedPackages.length) {
|
||||
searchParams.set(
|
||||
`room[${idx}].packages`,
|
||||
filteredSelectedPackages.map((pkg) => pkg.code).join(",")
|
||||
)
|
||||
state.booking.rooms[idx].packages =
|
||||
filteredSelectedPackages.map((pkg) => pkg.code)
|
||||
} else {
|
||||
searchParams.delete(`room[${idx}].packages`)
|
||||
state.booking.rooms[idx].packages = null
|
||||
}
|
||||
|
||||
state.searchParams = searchParams
|
||||
|
||||
window.history.replaceState(
|
||||
{},
|
||||
"",
|
||||
`${state.pathname}?${searchParams}`
|
||||
)
|
||||
updateUrl(state.booking)
|
||||
})
|
||||
)
|
||||
},
|
||||
@@ -300,36 +291,8 @@ export function createRatesStore({
|
||||
BookingCodeFilterEnum.Discounted
|
||||
}
|
||||
|
||||
const searchParams = state.searchParams
|
||||
searchParams.delete(`room[${idx}].packages`)
|
||||
|
||||
state.searchParams = searchParams
|
||||
|
||||
window.history.replaceState(
|
||||
{},
|
||||
"",
|
||||
`${state.pathname}?${searchParams}`
|
||||
)
|
||||
})
|
||||
)
|
||||
},
|
||||
removeSelectedRoom() {
|
||||
return set(
|
||||
produce((state: RatesState) => {
|
||||
state.rateSummary[idx] = null
|
||||
|
||||
const searchParams = state.searchParams
|
||||
searchParams.delete(`room[${idx}].counterratecode`)
|
||||
searchParams.delete(`room[${idx}].ratecode`)
|
||||
searchParams.delete(`room[${idx}].roomtype`)
|
||||
|
||||
state.searchParams = searchParams
|
||||
|
||||
window.history.replaceState(
|
||||
{},
|
||||
"",
|
||||
`${state.pathname}?${searchParams}`
|
||||
)
|
||||
state.booking.rooms[idx].packages = null
|
||||
updateUrl(state.booking)
|
||||
})
|
||||
)
|
||||
},
|
||||
@@ -408,43 +371,33 @@ export function createRatesStore({
|
||||
state.rooms[idx].bookingRoom.bookingCode =
|
||||
selectedRate.product.bookingCode
|
||||
|
||||
const searchParams = new URLSearchParams(state.searchParams)
|
||||
const counterratecode = isMemberRate
|
||||
? productRateCode
|
||||
: memberRateCode
|
||||
if (counterratecode) {
|
||||
searchParams.set(
|
||||
`room[${idx}].counterratecode`,
|
||||
counterratecode
|
||||
)
|
||||
state.booking.rooms[idx].counterRateCode = counterratecode
|
||||
} else {
|
||||
if (searchParams.has(`room[${idx}].counterratecode`)) {
|
||||
searchParams.delete(`room[${idx}].counterratecode`)
|
||||
}
|
||||
state.booking.rooms[idx].counterRateCode = null
|
||||
}
|
||||
|
||||
const rateCode = isMemberRate
|
||||
? memberRateCode
|
||||
: productRateCode
|
||||
if (rateCode) {
|
||||
searchParams.set(`room[${idx}].ratecode`, rateCode)
|
||||
state.booking.rooms[idx].rateCode = rateCode
|
||||
}
|
||||
|
||||
if (selectedRate.product.bookingCode) {
|
||||
searchParams.set(
|
||||
`room[${idx}].bookingCode`,
|
||||
state.booking.rooms[idx].bookingCode =
|
||||
selectedRate.product.bookingCode
|
||||
)
|
||||
} else {
|
||||
if (searchParams.has(`room[${idx}].bookingCode`)) {
|
||||
searchParams.delete(`room[${idx}].bookingCode`)
|
||||
if (state.booking.rooms[idx].bookingCode) {
|
||||
state.booking.rooms[idx].bookingCode = null
|
||||
}
|
||||
}
|
||||
|
||||
searchParams.set(
|
||||
`room[${idx}].roomtype`,
|
||||
state.booking.rooms[idx].roomTypeCode =
|
||||
selectedRate.roomTypeCode
|
||||
)
|
||||
|
||||
if (state.rateSummary.length === state.booking.rooms.length) {
|
||||
state.activeRoom = -1
|
||||
@@ -452,13 +405,7 @@ export function createRatesStore({
|
||||
state.activeRoom = idx + 1
|
||||
}
|
||||
|
||||
state.searchParams = searchParams
|
||||
|
||||
window.history.replaceState(
|
||||
{},
|
||||
"",
|
||||
`${state.pathname}?${searchParams}`
|
||||
)
|
||||
updateUrl(state.booking)
|
||||
})
|
||||
)
|
||||
},
|
||||
@@ -479,23 +426,13 @@ export function createRatesStore({
|
||||
BookingCodeFilterEnum.Discounted
|
||||
}
|
||||
|
||||
const searchParams = state.searchParams
|
||||
if (selectedPackages.length) {
|
||||
searchParams.set(
|
||||
`room[${idx}].packages`,
|
||||
selectedPackages.join(",")
|
||||
)
|
||||
state.booking.rooms[idx].packages = selectedPackages
|
||||
} else {
|
||||
searchParams.delete(`room[${idx}].packages`)
|
||||
state.booking.rooms[idx].packages = null
|
||||
}
|
||||
|
||||
state.searchParams = searchParams
|
||||
|
||||
window.history.replaceState(
|
||||
{},
|
||||
"",
|
||||
`${state.pathname}?${searchParams}`
|
||||
)
|
||||
updateUrl(state.booking)
|
||||
})
|
||||
)
|
||||
},
|
||||
@@ -519,36 +456,27 @@ export function createRatesStore({
|
||||
rateSummaryRoom.packages =
|
||||
state.rooms[idx].selectedPackages
|
||||
} else {
|
||||
const searchParams = clearRoomSelectionFromUrl(
|
||||
idx,
|
||||
state.searchParams
|
||||
state.booking.rooms[idx] = roomWithoutSelection(
|
||||
state.booking.rooms[idx]
|
||||
)
|
||||
state.searchParams = searchParams
|
||||
|
||||
state.rateSummary[idx] = null
|
||||
state.rooms[idx].selectedRate = null
|
||||
|
||||
window.history.replaceState(
|
||||
{},
|
||||
"",
|
||||
`${pathname}?${searchParams}`
|
||||
)
|
||||
updateUrl(state.booking)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
state.rooms[idx].rooms = []
|
||||
if (state.rateSummary[idx]) {
|
||||
const searchParams = clearRoomSelectionFromUrl(
|
||||
idx,
|
||||
state.searchParams
|
||||
state.booking.rooms[idx] = roomWithoutSelection(
|
||||
state.booking.rooms[idx]
|
||||
)
|
||||
state.searchParams = searchParams
|
||||
|
||||
state.rateSummary[idx] = null
|
||||
state.rooms[idx].selectedRate = null
|
||||
window.history.replaceState(
|
||||
{},
|
||||
"",
|
||||
`${pathname}?${searchParams}`
|
||||
)
|
||||
|
||||
updateUrl(state.booking)
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -587,3 +515,15 @@ export function useRatesStore<T>(selector: (store: RatesState) => T) {
|
||||
|
||||
return useStore(store, selector)
|
||||
}
|
||||
|
||||
function roomWithoutSelection(
|
||||
room: RatesState["booking"]["rooms"][number]
|
||||
): RatesState["booking"]["rooms"][number] {
|
||||
return {
|
||||
...room,
|
||||
rateCode: null,
|
||||
counterRateCode: null,
|
||||
roomTypeCode: null,
|
||||
bookingCode: null,
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user