From 744af22b08b2e524e6fa8fa2c66db81eec8b85da Mon Sep 17 00:00:00 2001 From: Simon Emanuelsson Date: Tue, 19 Nov 2024 11:24:17 +0100 Subject: [PATCH] fix: make sure all searchparams are used in redirect --- .../(standard)/step/@summary/page.tsx | 6 +- .../hotelreservation/(standard)/step/page.tsx | 5 +- .../EnterDetails/Summary/index.tsx | 58 +++++++++---------- .../SelectRate/Rooms/utils.ts | 7 ++- providers/StepsProvider.tsx | 7 ++- server/routers/hotels/output.ts | 11 +++- server/routers/hotels/query.ts | 2 +- stores/steps.ts | 17 +++--- types/providers/steps.ts | 1 + 9 files changed, 65 insertions(+), 49 deletions(-) diff --git a/app/[lang]/(live)/(public)/hotelreservation/(standard)/step/@summary/page.tsx b/app/[lang]/(live)/(public)/hotelreservation/(standard)/step/@summary/page.tsx index 337d501b3..0444913f1 100644 --- a/app/[lang]/(live)/(public)/hotelreservation/(standard)/step/@summary/page.tsx +++ b/app/[lang]/(live)/(public)/hotelreservation/(standard)/step/@summary/page.tsx @@ -83,10 +83,10 @@ export default async function SummaryPage({ price: availability.publicRate.localPrice.pricePerStay, currency: availability.publicRate.localPrice.currency, }, - euro: availability.publicRate.requestedPrice + euro: availability.publicRate?.requestedPrice ? { - price: availability.publicRate.requestedPrice.pricePerStay, - currency: availability.publicRate.requestedPrice.currency, + price: availability.publicRate?.requestedPrice.pricePerStay, + currency: availability.publicRate?.requestedPrice.currency, } : undefined, } diff --git a/app/[lang]/(live)/(public)/hotelreservation/(standard)/step/page.tsx b/app/[lang]/(live)/(public)/hotelreservation/(standard)/step/page.tsx index 7ffe57562..d175fc25f 100644 --- a/app/[lang]/(live)/(public)/hotelreservation/(standard)/step/page.tsx +++ b/app/[lang]/(live)/(public)/hotelreservation/(standard)/step/page.tsx @@ -1,6 +1,6 @@ import "./enterDetailsLayout.css" -import { notFound, redirect, RedirectType } from "next/navigation" +import { notFound } from "next/navigation" import { getBreakfastPackages, @@ -38,6 +38,8 @@ export default async function StepPage({ }: PageArgs) { const intl = await getIntl() const selectRoomParams = new URLSearchParams(searchParams) + selectRoomParams.delete("step") + const searchParamsString = selectRoomParams.toString() const { hotel: hotelId, rooms, @@ -123,6 +125,7 @@ export default async function StepPage({ bedTypes={roomAvailability.bedTypes} breakfastPackages={breakfastPackages} isMember={!!user} + searchParams={searchParamsString} step={searchParams.step} >
diff --git a/components/HotelReservation/EnterDetails/Summary/index.tsx b/components/HotelReservation/EnterDetails/Summary/index.tsx index 7507a6945..5b0a6a420 100644 --- a/components/HotelReservation/EnterDetails/Summary/index.tsx +++ b/components/HotelReservation/EnterDetails/Summary/index.tsx @@ -81,7 +81,6 @@ export default function Summary({ showMemberPrice, room }: SummaryProps) { useEffect(() => { setChosenBed(bedType) - setChosenBreakfast(breakfast) if (breakfast || breakfast === false) { setChosenBreakfast(breakfast) @@ -94,9 +93,9 @@ export default function Summary({ showMemberPrice, room }: SummaryProps) { euro: room.euroPrice && roomsPriceEuro ? { - price: roomsPriceEuro, - currency: room.euroPrice.currency, - } + price: roomsPriceEuro, + currency: room.euroPrice.currency, + } : undefined, }) } else { @@ -108,11 +107,11 @@ export default function Summary({ showMemberPrice, room }: SummaryProps) { euro: room.euroPrice && roomsPriceEuro ? { - price: - roomsPriceEuro + - parseInt(breakfast.requestedPrice.totalPrice), - currency: room.euroPrice.currency, - } + price: + roomsPriceEuro + + parseInt(breakfast.requestedPrice.totalPrice), + currency: room.euroPrice.currency, + } : undefined, }) } @@ -199,24 +198,24 @@ export default function Summary({ showMemberPrice, room }: SummaryProps) { {room.packages ? room.packages.map((roomPackage) => ( -
-
- - {roomPackage.description} - -
+
+
+ + {roomPackage.description} + +
- - {intl.formatMessage( - { id: "{amount} {currency}" }, - { - amount: roomPackage.localPrice.price, - currency: roomPackage.localPrice.currency, - } - )} - -
- )) + + {intl.formatMessage( + { id: "{amount} {currency}" }, + { + amount: roomPackage.localPrice.price, + currency: roomPackage.localPrice.currency, + } + )} + +
+ )) : null} {chosenBed ? (
@@ -263,9 +262,8 @@ export default function Summary({ showMemberPrice, room }: SummaryProps) { )}
- ) : null - } - + ) : null} +
@@ -306,6 +304,6 @@ export default function Summary({ showMemberPrice, room }: SummaryProps) {
-
+ ) } diff --git a/components/HotelReservation/SelectRate/Rooms/utils.ts b/components/HotelReservation/SelectRate/Rooms/utils.ts index af80e1f4d..71b2149cc 100644 --- a/components/HotelReservation/SelectRate/Rooms/utils.ts +++ b/components/HotelReservation/SelectRate/Rooms/utils.ts @@ -31,7 +31,10 @@ export function filterDuplicateRoomTypesByLowestPrice( products.forEach((product) => { const { productType } = product - const publicProduct = productType.public + const publicProduct = productType.public || { + requestedPrice: null, + localPrice: null, + } const memberProduct = productType.member || { requestedPrice: null, localPrice: null, @@ -53,7 +56,7 @@ export function filterDuplicateRoomTypesByLowestPrice( Number(memberRequestedPrice?.pricePerNight) ?? Infinity ) const currentLocalPrice = Math.min( - Number(publicLocalPrice.pricePerNight) ?? Infinity, + Number(publicLocalPrice?.pricePerNight) ?? Infinity, Number(memberLocalPrice?.pricePerNight) ?? Infinity ) diff --git a/providers/StepsProvider.tsx b/providers/StepsProvider.tsx index 87594be02..9aaf6166f 100644 --- a/providers/StepsProvider.tsx +++ b/providers/StepsProvider.tsx @@ -1,4 +1,5 @@ "use client" +import { useRouter } from "next/navigation" import { useRef } from "react" import { useDetailsStore } from "@/stores/details" @@ -14,6 +15,7 @@ export default function StepsProvider({ breakfastPackages, children, isMember, + searchParams, step, }: StepsProviderProps) { const storeRef = useRef() @@ -21,6 +23,7 @@ export default function StepsProvider({ const updateBreakfast = useDetailsStore( (state) => state.actions.updateBreakfast ) + const router = useRouter() if (!storeRef.current) { const noBedChoices = bedTypes.length === 1 @@ -41,7 +44,9 @@ export default function StepsProvider({ step, isMember, noBedChoices, - noBreakfast + noBreakfast, + searchParams, + router.push ) } diff --git a/server/routers/hotels/output.ts b/server/routers/hotels/output.ts index 1af9ba44c..41f9a6b52 100644 --- a/server/routers/hotels/output.ts +++ b/server/routers/hotels/output.ts @@ -512,7 +512,16 @@ export const productTypePriceSchema = z.object({ const productSchema = z.object({ productType: z.object({ - public: productTypePriceSchema, + public: productTypePriceSchema.default({ + rateCode: "", + rateType: "", + localPrice: { + currency: "SEK", + pricePerNight: 0, + pricePerStay: 0, + }, + requestedPrice: undefined, + }), member: productTypePriceSchema.optional(), }), }) diff --git a/server/routers/hotels/query.ts b/server/routers/hotels/query.ts index 7f2ef84c0..34a1b3722 100644 --- a/server/routers/hotels/query.ts +++ b/server/routers/hotels/query.ts @@ -731,7 +731,7 @@ export const hotelQueryRouter = router({ const rateTypes = selectedRoom.products.find( (rate) => - rate.productType.public.rateCode === rateCode || + rate.productType.public?.rateCode === rateCode || rate.productType.member?.rateCode === rateCode ) diff --git a/stores/steps.ts b/stores/steps.ts index f1e456af2..cf14f6768 100644 --- a/stores/steps.ts +++ b/stores/steps.ts @@ -1,6 +1,7 @@ "use client" import merge from "deepmerge" import { produce } from "immer" +import { AppRouterInstance } from "next/dist/shared/lib/app-router-context.shared-runtime" import { useContext } from "react" import { create, useStore } from "zustand" @@ -18,17 +19,13 @@ import { StepEnum } from "@/types/enums/step" import type { DetailsState } from "@/types/stores/details" import type { StepState } from "@/types/stores/steps" -function push(data: Record, url: string) { - if (typeof window !== "undefined") { - window.history.pushState(data, "", url + window.location.search) - } -} - export function createStepsStore( currentStep: StepEnum, isMember: boolean, noBedChoices: boolean, - noBreakfast: boolean + noBreakfast: boolean, + searchParams: string, + push: AppRouterInstance["push"] ) { const isBrowser = typeof window !== "undefined" const steps = [ @@ -51,14 +48,14 @@ export function createStepsStore( steps.splice(1, 1) if (currentStep === StepEnum.breakfast) { currentStep = steps[1] - push({ step: currentStep }, currentStep) + push(`${currentStep}?${searchParams}`) } } if (noBedChoices) { if (currentStep === StepEnum.selectBed) { currentStep = steps[1] - push({ step: currentStep }, currentStep) + push(`${currentStep}?${searchParams}`) } } @@ -94,7 +91,7 @@ export function createStepsStore( if (!validPaths.includes(currentStep) && isBrowser) { // We will always have at least one valid path currentStep = validPaths.pop()! - push({ step: currentStep }, currentStep) + push(`${currentStep}?${searchParams}`) } } diff --git a/types/providers/steps.ts b/types/providers/steps.ts index 8c24fdc8f..9ba0361eb 100644 --- a/types/providers/steps.ts +++ b/types/providers/steps.ts @@ -6,5 +6,6 @@ export interface StepsProviderProps extends React.PropsWithChildren { bedTypes: BedTypeSelection[] breakfastPackages: BreakfastPackage[] | null isMember: boolean + searchParams: string step: StepEnum }