Files
web/packages/booking-flow/lib/hooks/useBookingWidgetState.ts
Emma Zettervall f443bae46e Merged in feat/LOY-400-create-spend-points-modal (pull request #3131)
Feat/LOY-400 create spend points modal

* feat(LOY-400): Added custom button to my pages overview and skeleton file to custom modal for my points.

* feat(LOY-400): Added custom button to my pages overview and components for custom modal for my points.

* feat(LOY-400): Changed some style and infogridcardover

* feat(LOY-400):Removed custom card components and changed in infoCard: Added imagePosition top, added optional height prop. In Card: Changed Text-wrap styling, added min-width styling to buttons, added optional Icon prop, added optional height prop

* feat(LOY-400):Added linkList, LinkListItem component and messageBanner component. Added granola illustration.

* feat(LOY-400): Removed background in several illustrations. Added component for illustration. Fixed LinkedList and styling for UsePointsButton.

* feat(LOY-400): Added modal to PointsToSpendCard and fixed UsePointsButton.

* fix(LOY-400):added some styling

* feat(LOY-400): Linked Modal to contentstack and fetch the data in cards with UsePointsModal for now

* feat(LOY-400): changed link to aria-component, cleaned up a bit

* feat(LOY-400): Changed height for larger modals in mobile, fixed zod schema for no illustration input, cleaned up

* fix(LOY-400): fixed graphql after rebase

* fix(LOY-400): mini fix

* fix(LOY-400): fixed pr-comments

* fix(LOY-400): fixed some PR-comments

* fix(LOY-400): fixed a PR-comment

* feat(LOY-400): added size prop to ilustration in LinkListItem to be able to use illustrations in IllustrationByIconName

* fix(LOY-400): fixed pr-comments

* Merged in feat/LOY-402-pre-ticked-book-reward-night-in-booking-flow (pull request #3210)

Feat/LOY-402 pre ticked book reward night in booking flow

* feat(LOY-402): Changed UsePointsModal structure to handle button actions in card.

* feat(LOY-402): added functionality for book now button

* feat(LOY-400): pr comment fix

* feat(LOY-402): transformed the contentstack data

* fix(LOY-402): fixed pr comments

Approved-by: Chuma Mcphoy (We Ahead)
Approved-by: Anton Gunnarsson
Approved-by: Matilda Landström

* Merged in feat/LOY-404-add-tracking-for-spend-points-modal (pull request #3229)

Feat/LOY-404 add tracking for spend points modal

* feat(LOY-402): Changed UsePointsModal structure to handle button actions in card.

* feat(LOY-402): added functionality for book now button

* feat(LOY-400): pr comment fix

* feat(LOY-402): transformed the contentstack data

* feat(LOY-404): added tracking

* fix(LOY-404): fix for session storage removal of bookNowFromPointsModal

* feat(LOY-404): added consts

* fix(LOY-404): moved foxusWidget const

* fix(LOY-404): moved BOOKING_WIDGET_STATE const

* fix(LOY-404):fix


Approved-by: Matilda Landström

* fix(LOY-400): some fixes

* feat(LOY-400): created linkList storybook


Approved-by: Chuma Mcphoy (We Ahead)
Approved-by: Matilda Landström
2025-11-28 15:08:06 +00:00

102 lines
2.4 KiB
TypeScript

import { useEffect, useState } from "react"
import { z } from "zod"
import { BOOKING_WIDGET_STATE } from "@scandic-hotels/common/constants/sessionKeys"
import { dt } from "@scandic-hotels/common/dt"
import { adultsSchema, childAgeSchema, childBedSchema } from "../utils/url"
const DEFAULT_ROOMS = [{ adults: 1, childrenInRoom: [] }]
const stateSchema = z.object({
fromDate: z.string(),
toDate: z.string(),
rooms: z.array(
z.object({
adults: adultsSchema,
childrenInRoom: z
.array(
z.object({
bed: childBedSchema,
age: childAgeSchema,
})
)
.optional(),
})
),
})
type BookingWidgetState = z.infer<typeof stateSchema>
export function useBookingWidgetState() {
const [bookingState, setBookingState] = useState<BookingWidgetState>({
fromDate: dt().format("YYYY-MM-DD"),
toDate: dt().add(1, "day").format("YYYY-MM-DD"),
rooms: DEFAULT_ROOMS,
})
useEffect(() => {
const now = dt()
const stored = getBookingWidgetState()
if (!stored) {
return
}
const storedFrom = dt(stored.fromDate)
const storedTo = dt(stored.toDate)
const isDateParamValid =
storedFrom.isValid() &&
storedTo.isValid() &&
storedFrom.isSameOrAfter(now, "day") &&
storedTo.isAfter(storedFrom)
if (isDateParamValid && stored.rooms?.length) {
setBookingState({
fromDate: storedFrom.format("YYYY-MM-DD"),
toDate: storedTo.format("YYYY-MM-DD"),
rooms: stored.rooms,
})
}
}, [])
return bookingState
}
function getBookingWidgetState(): BookingWidgetState | null {
if (typeof window === "undefined") {
return null
}
try {
const savedBookingWidgetState = sessionStorage.getItem(BOOKING_WIDGET_STATE)
if (savedBookingWidgetState) {
const stored = JSON.parse(savedBookingWidgetState)
return stateSchema.parse(stored)
}
} catch {
try {
sessionStorage.removeItem(BOOKING_WIDGET_STATE)
} catch {}
}
return null
}
export function setBookingWidgetState(state: BookingWidgetState): void {
if (typeof window === "undefined") {
return
}
try {
sessionStorage.setItem(
BOOKING_WIDGET_STATE,
JSON.stringify(stateSchema.parse(state))
)
} catch {}
}
export function clearBookingWidgetState(): void {
if (typeof window === "undefined") {
return
}
try {
sessionStorage.removeItem(BOOKING_WIDGET_STATE)
} catch {}
}