diff --git a/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-rate/page.module.css b/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-rate/page.module.css deleted file mode 100644 index 464c8ce65..000000000 --- a/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-rate/page.module.css +++ /dev/null @@ -1,24 +0,0 @@ -.page { - min-height: 100dvh; - padding-top: var(--Spacing-x6); - padding-left: var(--Spacing-x2); - padding-right: var(--Spacing-x2); - background-color: var(--Scandic-Brand-Warm-White); -} - -.content { - max-width: var(--max-width); - margin: 0 auto; - display: flex; - flex-direction: column; - gap: var(--Spacing-x7); - padding: var(--Spacing-x2); -} - -.main { - flex-grow: 1; -} - -.summary { - max-width: 340px; -} diff --git a/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-rate/page.tsx b/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-rate/page.tsx index 05103acf3..d43330adb 100644 --- a/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-rate/page.tsx +++ b/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-rate/page.tsx @@ -1,14 +1,12 @@ import { getProfileSafely } from "@/lib/trpc/memoizedRequests" import { serverClient } from "@/lib/trpc/server" +import { RoomPackageCode } from "@/server/routers/hotels/schemas/packages" import HotelInfoCard from "@/components/HotelReservation/SelectRate/HotelInfoCard" -import RoomFilter from "@/components/HotelReservation/SelectRate/RoomFilter" -import RoomSelection from "@/components/HotelReservation/SelectRate/RoomSelection" +import Rooms from "@/components/HotelReservation/SelectRate/Rooms" import getHotelReservationQueryParams from "@/components/HotelReservation/SelectRate/RoomSelection/utils" import { setLang } from "@/i18n/serverContext" -import styles from "./page.module.css" - import { SelectRateSearchParams } from "@/types/components/hotelReservation/selectRate/selectRate" import { LangParams, PageArgs } from "@/types/params" @@ -24,7 +22,7 @@ export default async function SelectRatePage({ const adults = selectRoomParamsObject.room?.[0].adults // TODO: Handle multiple rooms const children = selectRoomParamsObject.room?.[0].child?.length // TODO: Handle multiple rooms - const [hotelData, roomsAvailability, user] = await Promise.all([ + const [hotelData, roomsAvailability, packages, user] = await Promise.all([ serverClient().hotel.hotelData.get({ hotelId: searchParams.hotel, language: params.lang, @@ -37,6 +35,18 @@ export default async function SelectRatePage({ adults, children, }), + serverClient().hotel.packages.get({ + hotelId: searchParams.hotel, + startDate: searchParams.fromDate, + endDate: searchParams.toDate, + adults: adults, + children: children, + packageCodes: [ + RoomPackageCode.ACCE, + RoomPackageCode.PETR, + RoomPackageCode.ALLG, + ], + }), getProfileSafely(), ]) @@ -51,20 +61,14 @@ export default async function SelectRatePage({ const roomCategories = hotelData?.included return ( -
+ <> -
-
- - -
-
-
+ + ) } diff --git a/components/HotelReservation/EnterDetails/Payment/index.tsx b/components/HotelReservation/EnterDetails/Payment/index.tsx index 0da2b79e2..ba126c1f2 100644 --- a/components/HotelReservation/EnterDetails/Payment/index.tsx +++ b/components/HotelReservation/EnterDetails/Payment/index.tsx @@ -22,7 +22,7 @@ import { useEnterDetailsStore } from "@/stores/enter-details" import LoadingSpinner from "@/components/LoadingSpinner" import Button from "@/components/TempDesignSystem/Button" -import Checkbox from "@/components/TempDesignSystem/Checkbox" +import Checkbox from "@/components/TempDesignSystem/Form/Checkbox" import Link from "@/components/TempDesignSystem/Link" import Body from "@/components/TempDesignSystem/Text/Body" import Caption from "@/components/TempDesignSystem/Text/Caption" diff --git a/components/HotelReservation/SelectRate/RoomFilter/index.tsx b/components/HotelReservation/SelectRate/RoomFilter/index.tsx index d775f8f46..3c3586994 100644 --- a/components/HotelReservation/SelectRate/RoomFilter/index.tsx +++ b/components/HotelReservation/SelectRate/RoomFilter/index.tsx @@ -1,49 +1,60 @@ "use client" import { zodResolver } from "@hookform/resolvers/zod" -import { useRef } from "react" +import { useCallback, useEffect, useMemo } from "react" import { FormProvider, useForm } from "react-hook-form" import { useIntl } from "react-intl" +import { z } from "zod" -import { roomFilterSchema } from "@/server/routers/hotels/schemas/room" +import { RoomPackageCode } from "@/server/routers/hotels/schemas/packages" +import Chip from "@/components/TempDesignSystem/Chip" import Checkbox from "@/components/TempDesignSystem/Form/Checkbox" import Body from "@/components/TempDesignSystem/Text/Body" import Caption from "@/components/TempDesignSystem/Text/Caption" import styles from "./roomFilter.module.css" -import { - RoomFilterFormData, - RoomFilterProps, -} from "@/types/components/hotelReservation/selectRate/roomFilter" +import { RoomFilterProps } from "@/types/components/hotelReservation/selectRate/roomFilter" + +export default function RoomFilter({ + numberOfRooms, + onFilter, + filterOptions, +}: RoomFilterProps) { + const initialFilterValues = useMemo( + () => + filterOptions.reduce( + (acc, option) => { + acc[option.code] = false + return acc + }, + {} as Record + ), + [filterOptions] + ) -function RoomFilter({ numberOfRooms }: RoomFilterProps) { const intl = useIntl() - const methods = useForm({ - defaultValues: { - allergyFriendly: false, - petFriendly: false, - accessibility: false, - }, + const methods = useForm>({ + defaultValues: initialFilterValues, mode: "all", reValidateMode: "onChange", - resolver: zodResolver(roomFilterSchema), + resolver: zodResolver(z.object({})), }) - const formRef = useRef(null) - const { watch, setValue } = methods - const petFriendly = watch("petFriendly") - const allergyFriendly = watch("allergyFriendly") + const { watch, getValues, handleSubmit } = methods + const petFriendly = watch(RoomPackageCode.PETR) + const allergyFriendly = watch(RoomPackageCode.ALLG) - const onSubmit = (data: RoomFilterFormData) => { - if (data.petFriendly) { - setValue("allergyFriendly", false) - } else if (data.allergyFriendly) { - setValue("petFriendly", false) - } - console.log("Form submitted with data:", data) - } + const submitFilter = useCallback(() => { + const data = getValues() + onFilter(data) + }, [onFilter, getValues]) + + useEffect(() => { + const subscription = watch(() => handleSubmit(submitFilter)()) + return () => subscription.unsubscribe() + }, [handleSubmit, watch, submitFilter]) return (
@@ -51,45 +62,27 @@ function RoomFilter({ numberOfRooms }: RoomFilterProps) { {intl.formatMessage({ id: "Room types available" }, { numberOfRooms })} -
+
- formRef.current?.requestSubmit()} - > - - {intl.formatMessage({ id: "Accessibility room" })} - - - { - setValue("petFriendly", !petFriendly) - formRef.current?.requestSubmit() - }} - registerOptions={{ disabled: allergyFriendly }} - > - - {intl.formatMessage({ id: "Pet room" })} - - - { - setValue("allergyFriendly", !allergyFriendly) - formRef.current?.requestSubmit() - }} - registerOptions={{ disabled: petFriendly }} - > - - {intl.formatMessage({ id: "Allergy room" })} - - + {filterOptions.map((option) => ( + + + {intl.formatMessage({ id: option.description })} + + + ))}
) } - -export default RoomFilter diff --git a/components/HotelReservation/SelectRate/Rooms/index.tsx b/components/HotelReservation/SelectRate/Rooms/index.tsx new file mode 100644 index 000000000..963f266d4 --- /dev/null +++ b/components/HotelReservation/SelectRate/Rooms/index.tsx @@ -0,0 +1,53 @@ +"use client" + +import { useState } from "react" + +import { RoomsAvailability } from "@/server/routers/hotels/output" + +import RoomFilter from "../RoomFilter" +import RoomSelection from "../RoomSelection" + +import styles from "./rooms.module.css" + +import { RoomProps } from "@/types/components/hotelReservation/selectRate/room" +import { RoomPackageCodes } from "@/types/components/hotelReservation/selectRate/roomFilter" + +export default function Rooms({ + roomsAvailability, + roomCategories = [], + user, + packages, +}: RoomProps) { + const [rooms, setRooms] = useState(roomsAvailability) + + function handleFilter(filter: Record) { + const selectedCodes = Object.keys(filter).filter((key) => filter[key]) + + if (selectedCodes.length === 0) { + setRooms(roomsAvailability) + return + } + + const filteredRooms = roomsAvailability.roomConfigurations.filter((room) => + room.features.some((feature) => + selectedCodes.includes(feature.code as RoomPackageCodes) + ) + ) + setRooms({ ...roomsAvailability, roomConfigurations: filteredRooms }) + } + + return ( +
+ + +
+ ) +} diff --git a/components/HotelReservation/SelectRate/Rooms/rooms.module.css b/components/HotelReservation/SelectRate/Rooms/rooms.module.css new file mode 100644 index 000000000..a8e573530 --- /dev/null +++ b/components/HotelReservation/SelectRate/Rooms/rooms.module.css @@ -0,0 +1,8 @@ +.content { + max-width: var(--max-width); + margin: 0 auto; + display: flex; + flex-direction: column; + gap: var(--Spacing-x7); + padding: var(--Spacing-x2); +} diff --git a/i18n/dictionaries/da.json b/i18n/dictionaries/da.json index adf12745e..af4c667b8 100644 --- a/i18n/dictionaries/da.json +++ b/i18n/dictionaries/da.json @@ -5,7 +5,7 @@ "A photo of the room": "Et foto af værelset", "About meetings & conferences": "About meetings & conferences", "About the hotel": "About the hotel", - "Accessibility room": "Handicapvenligt værelse", + "Accessible Room": "Tilgængelighedsrum", "Activities": "Aktiviteter", "Add code": "Tilføj kode", "Add new card": "Tilføj nyt kort", @@ -14,7 +14,7 @@ "Adults": "voksne", "Airport": "Lufthavn", "All our breakfast buffets offer gluten free, vegan, and allergy-friendly options.": "Alle vores morgenmadsbuffeter tilbyder glutenfrie, veganske og allergivenlige muligheder.", - "Allergy room": "Allergivenligt værelse", + "Allergy Room": "Allergirum", "Already a friend?": "Allerede en ven?", "Amenities": "Faciliteter", "Amusement park": "Forlystelsespark", @@ -217,7 +217,7 @@ "Pay later": "Betal senere", "Pay now": "Betal nu", "Payment info": "Betalingsoplysninger", - "Pet room": "Kæledyrsrum", + "Pet Room": "Kæledyrsrum", "Phone": "Telefon", "Phone is required": "Telefonnummer er påkrævet", "Phone number": "Telefonnummer", diff --git a/i18n/dictionaries/de.json b/i18n/dictionaries/de.json index e7c3ee819..c9483e349 100644 --- a/i18n/dictionaries/de.json +++ b/i18n/dictionaries/de.json @@ -5,7 +5,7 @@ "A photo of the room": "Ein Foto des Zimmers", "About meetings & conferences": "About meetings & conferences", "About the hotel": "Über das Hotel", - "Accessibility room": "Barrierefreies Zimmer", + "Accessible Room": "Barrierefreies Zimmer", "Activities": "Aktivitäten", "Add code": "Code hinzufügen", "Add new card": "Neue Karte hinzufügen", @@ -14,7 +14,7 @@ "Adults": "Erwachsene", "Airport": "Flughafen", "All our breakfast buffets offer gluten free, vegan, and allergy-friendly options.": "Alle unsere Frühstücksbuffets bieten glutenfreie, vegane und allergikerfreundliche Speisen.", - "Allergy room": "Allergiefreundliches Zimmer", + "Allergy Room": "Allergikerzimmer", "Already a friend?": "Sind wir schon Freunde?", "Amenities": "Annehmlichkeiten", "Amusement park": "Vergnügungspark", @@ -217,7 +217,7 @@ "Pay later": "Später bezahlen", "Pay now": "Jetzt bezahlen", "Payment info": "Zahlungsinformationen", - "Pet room": "Haustierfreundliches Zimmer", + "Pet Room": "Haustierzimmer", "Phone": "Telefon", "Phone is required": "Telefon ist erforderlich", "Phone number": "Telefonnummer", diff --git a/i18n/dictionaries/en.json b/i18n/dictionaries/en.json index cb2f91ecc..0511cf5a9 100644 --- a/i18n/dictionaries/en.json +++ b/i18n/dictionaries/en.json @@ -5,7 +5,7 @@ "A photo of the room": "A photo of the room", "About meetings & conferences": "About meetings & conferences", "About the hotel": "About the hotel", - "Accessibility room": "Accessibility room", + "Accessible Room": "Accessibility room", "Activities": "Activities", "Add Room": "Add room", "Add code": "Add code", @@ -17,7 +17,7 @@ "Age": "Age", "Airport": "Airport", "All our breakfast buffets offer gluten free, vegan, and allergy-friendly options.": "All our breakfast buffets offer gluten free, vegan, and allergy-friendly options.", - "Allergy room": "Allergy room", + "Allergy Room": "Allergy room", "Already a friend?": "Already a friend?", "Amenities": "Amenities", "Amusement park": "Amusement park", @@ -227,7 +227,7 @@ "Pay now": "Pay now", "Payment info": "Payment info", "Payment received": "Payment received", - "Pet room": "Pet room", + "Pet Room": "Pet room", "Phone": "Phone", "Phone is required": "Phone is required", "Phone number": "Phone number", @@ -258,6 +258,7 @@ "Restaurant & Bar": "Restaurant & Bar", "Restaurants & Bars": "Restaurants & Bars", "Retype new password": "Retype new password", + "Room": "Room", "Room & Terms": "Room & Terms", "Room facilities": "Room facilities", "Room types available": "{numberOfRooms, plural, one {# room type} other {# room types}} available", diff --git a/i18n/dictionaries/fi.json b/i18n/dictionaries/fi.json index 9307bd321..c8427a306 100644 --- a/i18n/dictionaries/fi.json +++ b/i18n/dictionaries/fi.json @@ -5,7 +5,7 @@ "A photo of the room": "Kuva huoneesta", "About meetings & conferences": "About meetings & conferences", "About the hotel": "Tietoja hotellista", - "Accessibility room": "Esteettömyyshuone", + "Accessible Room": "Esteetön huone", "Activities": "Aktiviteetit", "Add code": "Lisää koodi", "Add new card": "Lisää uusi kortti", @@ -14,7 +14,7 @@ "Adults": "Aikuista", "Airport": "Lentokenttä", "All our breakfast buffets offer gluten free, vegan, and allergy-friendly options.": "Kaikki aamiaisbuffettimme tarjoavat gluteenittomia, vegaanisia ja allergiaystävällisiä vaihtoehtoja.", - "Allergy room": "Allergiahuone", + "Allergy Room": "Allergiahuone", "Already a friend?": "Oletko jo ystävä?", "Amenities": "Mukavuudet", "Amusement park": "Huvipuisto", @@ -217,7 +217,7 @@ "Pay later": "Maksa myöhemmin", "Pay now": "Maksa nyt", "Payment info": "Maksutiedot", - "Pet room": "Lemmikkihuone", + "Pet Room": "Lemmikkihuone", "Phone": "Puhelin", "Phone is required": "Puhelin vaaditaan", "Phone number": "Puhelinnumero", diff --git a/i18n/dictionaries/no.json b/i18n/dictionaries/no.json index e7b95db27..69a1fbec4 100644 --- a/i18n/dictionaries/no.json +++ b/i18n/dictionaries/no.json @@ -5,7 +5,7 @@ "A photo of the room": "Et bilde av rommet", "About meetings & conferences": "About meetings & conferences", "About the hotel": "Om hotellet", - "Accessibility room": "Tilgjengelighetsrom", + "Accessible Room": "Tilgjengelighetsrom", "Activities": "Aktiviteter", "Add code": "Legg til kode", "Add new card": "Legg til nytt kort", @@ -14,7 +14,7 @@ "Adults": "Voksne", "Airport": "Flyplass", "All our breakfast buffets offer gluten free, vegan, and allergy-friendly options.": "Alle våre frokostbufféer tilbyr glutenfrie, veganske og allergivennlige alternativer.", - "Allergy room": "Allergihus", + "Allergy Room": "Allergirom", "Already a friend?": "Allerede Friend?", "Amenities": "Fasiliteter", "Amusement park": "Tivoli", @@ -215,7 +215,7 @@ "Pay later": "Betal senere", "Pay now": "Betal nå", "Payment info": "Betalingsinformasjon", - "Pet room": "Kjæledyrrom", + "Pet Room": "Kjæledyrsrom", "Phone": "Telefon", "Phone is required": "Telefon kreves", "Phone number": "Telefonnummer", diff --git a/i18n/dictionaries/sv.json b/i18n/dictionaries/sv.json index 5ee85ccde..c2f90d520 100644 --- a/i18n/dictionaries/sv.json +++ b/i18n/dictionaries/sv.json @@ -5,7 +5,7 @@ "A photo of the room": "Ett foto av rummet", "About meetings & conferences": "About meetings & conferences", "About the hotel": "Om hotellet", - "Accessibility room": "Tillgänglighetsrum", + "Accessible Room": "Tillgänglighetsrum", "Activities": "Aktiviteter", "Add code": "Lägg till kod", "Add new card": "Lägg till nytt kort", @@ -14,7 +14,7 @@ "Adults": "Vuxna", "Airport": "Flygplats", "All our breakfast buffets offer gluten free, vegan, and allergy-friendly options.": "Alla våra frukostbufféer erbjuder glutenfria, veganska och allergivänliga alternativ.", - "Allergy room": "Allergirum", + "Allergy Room": "Allergirum", "Already a friend?": "Är du redan en vän?", "Amenities": "Bekvämligheter", "Amusement park": "Nöjespark", @@ -215,7 +215,7 @@ "Pay later": "Betala senare", "Pay now": "Betala nu", "Payment info": "Betalningsinformation", - "Pet room": "Husdjursrum", + "Pet Room": "Husdjursrum", "Phone": "Telefon", "Phone is required": "Telefonnummer är obligatorisk", "Phone number": "Telefonnummer", diff --git a/lib/api/endpoints.ts b/lib/api/endpoints.ts index 66bc36ec3..be1aee2fd 100644 --- a/lib/api/endpoints.ts +++ b/lib/api/endpoints.ts @@ -23,6 +23,7 @@ export namespace endpoints { rewards = `${profile}/reward`, tierRewards = `${profile}/TierRewards`, subscriberId = `${profile}/SubscriberId`, + packages = "package/v1/packages/hotel", } } diff --git a/lib/api/index.ts b/lib/api/index.ts index 9e32ac0cc..475e0da4e 100644 --- a/lib/api/index.ts +++ b/lib/api/index.ts @@ -37,7 +37,7 @@ export async function get( const searchParams = new URLSearchParams(params) if (searchParams.size) { searchParams.forEach((value, key) => { - url.searchParams.set(key, value) + url.searchParams.append(key, value) }) url.searchParams.sort() } diff --git a/server/routers/hotels/query.ts b/server/routers/hotels/query.ts index 289429ca7..883b3a3ee 100644 --- a/server/routers/hotels/query.ts +++ b/server/routers/hotels/query.ts @@ -25,6 +25,10 @@ import { getHotelPageCounter, validateHotelPageRefs, } from "../contentstack/hotelPage/utils" +import { + getRoomPackagesInputSchema, + getRoomPackagesSchema, +} from "./schemas/packages" import { getHotelInputSchema, getHotelsAvailabilityInputSchema, @@ -57,6 +61,14 @@ const getHotelCounter = meter.createCounter("trpc.hotel.get") const getHotelSuccessCounter = meter.createCounter("trpc.hotel.get-success") const getHotelFailCounter = meter.createCounter("trpc.hotel.get-fail") +const getPackagesCounter = meter.createCounter("trpc.hotel.packages.get") +const getPackagesSuccessCounter = meter.createCounter( + "trpc.hotel.packages.get-success" +) +const getPackagesFailCounter = meter.createCounter( + "trpc.hotel.packages.get-fail" +) + const hotelsAvailabilityCounter = meter.createCounter( "trpc.hotel.availability.hotels" ) @@ -694,4 +706,89 @@ export const hotelQueryRouter = router({ return locations }), }), + packages: router({ + get: serviceProcedure + .input(getRoomPackagesInputSchema) + .query(async ({ input, ctx }) => { + const { hotelId, startDate, endDate, adults, children, packageCodes } = + input + + const searchParams = new URLSearchParams({ + startDate, + endDate, + adults: adults.toString(), + children: children.toString(), + }) + + packageCodes.forEach((code) => { + searchParams.append("packageCodes", code) + }) + + const params = searchParams.toString() + + getPackagesCounter.add(1, { + hotelId, + }) + console.info( + "api.hotels.packages start", + JSON.stringify({ query: { hotelId, params } }) + ) + + const apiResponse = await api.get( + `${api.endpoints.v1.packages}/${hotelId}`, + { + headers: { + Authorization: `Bearer ${ctx.serviceToken}`, + }, + }, + params + ) + + if (!apiResponse.ok) { + getPackagesFailCounter.add(1, { + hotelId, + error_type: "http_error", + error: JSON.stringify({ + status: apiResponse.status, + statusText: apiResponse.statusText, + }), + }) + console.error( + "api.hotels.packages error", + JSON.stringify({ query: { hotelId, params } }) + ) + throw serverErrorByStatus(apiResponse.status, apiResponse) + } + + const apiJson = await apiResponse.json() + const validatedPackagesData = getRoomPackagesSchema.safeParse(apiJson) + + if (!validatedPackagesData.success) { + getHotelFailCounter.add(1, { + hotelId, + error_type: "validation_error", + error: JSON.stringify(validatedPackagesData.error), + }) + + console.error( + "api.hotels.packages validation error", + JSON.stringify({ + query: { hotelId, params }, + error: validatedPackagesData.error, + }) + ) + throw badRequestError() + } + + getPackagesSuccessCounter.add(1, { + hotelId, + }) + console.info( + "api.hotels.packages success", + JSON.stringify({ query: { hotelId, params: params } }) + ) + + return validatedPackagesData.data + }), + }), }) diff --git a/server/routers/hotels/schemas/packages.ts b/server/routers/hotels/schemas/packages.ts new file mode 100644 index 000000000..d7ff6a4e1 --- /dev/null +++ b/server/routers/hotels/schemas/packages.ts @@ -0,0 +1,59 @@ +import { z } from "zod" + +export enum RoomPackageCode { + PETR = "PETR", + ALLG = "ALLG", + ACCE = "ACCE", +} + +export const getRoomPackagesInputSchema = z.object({ + hotelId: z.string(), + startDate: z.string(), + endDate: z.string(), + adults: z.number(), + children: z.number().optional().default(0), + packageCodes: z.array(z.string()).optional().default([]), +}) + +const packagesSchema = z.array( + z.object({ + code: z.enum([ + RoomPackageCode.PETR, + RoomPackageCode.ALLG, + RoomPackageCode.ACCE, + ]), + itemCode: z.string(), + description: z.string(), + currency: z.string(), + calculatedPrice: z.number(), + inventories: z.array( + z.object({ + date: z.string(), + total: z.number(), + available: z.number(), + }) + ), + }) +) + +export const getRoomPackagesSchema = z + .object({ + data: z.object({ + attributes: z.object({ + hotelId: z.number(), + packages: packagesSchema, + }), + relationships: z + .object({ + links: z.array( + z.object({ + url: z.string(), + type: z.string(), + }) + ), + }) + .optional(), + type: z.string(), + }), + }) + .transform((data) => data.data.attributes.packages) diff --git a/server/routers/hotels/schemas/room.ts b/server/routers/hotels/schemas/room.ts index af3a3e8bc..19f922db0 100644 --- a/server/routers/hotels/schemas/room.ts +++ b/server/routers/hotels/schemas/room.ts @@ -92,9 +92,3 @@ export const roomSchema = z roomFacilities: data.attributes.roomFacilities, } }) - -export const roomFilterSchema = z.object({ - accessibility: z.boolean(), - petFriendly: z.boolean(), - allergyFriendly: z.boolean(), -}) diff --git a/server/tokenManager.ts b/server/tokenManager.ts index 24180d017..980ca071d 100644 --- a/server/tokenManager.ts +++ b/server/tokenManager.ts @@ -74,7 +74,7 @@ export async function getServiceToken() { if (env.HIDE_FOR_NEXT_RELEASE) { scopes = ["profile"] } else { - scopes = ["profile", "hotel", "booking"] + scopes = ["profile", "hotel", "booking", "package"] } const tag = generateServiceTokenTag(scopes) const getCachedJwt = unstable_cache( diff --git a/types/components/hotelReservation/selectRate/room.ts b/types/components/hotelReservation/selectRate/room.ts new file mode 100644 index 000000000..b84e5c667 --- /dev/null +++ b/types/components/hotelReservation/selectRate/room.ts @@ -0,0 +1,6 @@ +import { RoomPackageData } from "./roomFilter" +import { RoomSelectionProps } from "./roomSelection" + +export interface RoomProps extends RoomSelectionProps { + packages: RoomPackageData +} diff --git a/types/components/hotelReservation/selectRate/roomFilter.ts b/types/components/hotelReservation/selectRate/roomFilter.ts index ac31cfdbd..c70f8f1d0 100644 --- a/types/components/hotelReservation/selectRate/roomFilter.ts +++ b/types/components/hotelReservation/selectRate/roomFilter.ts @@ -1,9 +1,14 @@ import { z } from "zod" -import { roomFilterSchema } from "@/server/routers/hotels/schemas/room" +import { getRoomPackagesSchema } from "@/server/routers/hotels/schemas/packages" export interface RoomFilterProps { numberOfRooms: number + onFilter: (filter: Record) => void + filterOptions: RoomPackageData } -export interface RoomFilterFormData extends z.output {} +export interface RoomPackageData + extends z.output {} + +export type RoomPackageCodes = RoomPackageData[number]["code"]