Merged in fix/SW-925-select-rate-page-public-rates (pull request #937)
fix(SW-925): Don't throw error if api for packages throws error Approved-by: Niclas Edenvin
This commit is contained in:
@@ -108,7 +108,7 @@ export default async function SelectRatePage({
|
|||||||
roomsAvailability={roomsAvailability}
|
roomsAvailability={roomsAvailability}
|
||||||
roomCategories={roomCategories ?? []}
|
roomCategories={roomCategories ?? []}
|
||||||
user={user}
|
user={user}
|
||||||
packages={packages ?? []}
|
availablePackages={packages ?? []}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -99,11 +99,13 @@ export default function RoomFilter({
|
|||||||
<form onSubmit={handleSubmit(submitFilter)}>
|
<form onSubmit={handleSubmit(submitFilter)}>
|
||||||
<div className={styles.roomsFilter}>
|
<div className={styles.roomsFilter}>
|
||||||
{filterOptions.map((option) => {
|
{filterOptions.map((option) => {
|
||||||
const { code, description } = option
|
const { code, description, itemCode } = option
|
||||||
const isPetRoom = code === RoomPackageCodeEnum.PET_ROOM
|
const isPetRoom = code === RoomPackageCodeEnum.PET_ROOM
|
||||||
const isAllergyRoom = code === RoomPackageCodeEnum.ALLERGY_ROOM
|
const isAllergyRoom = code === RoomPackageCodeEnum.ALLERGY_ROOM
|
||||||
const isDisabled =
|
const isDisabled =
|
||||||
(isAllergyRoom && petFriendly) || (isPetRoom && allergyFriendly)
|
(isAllergyRoom && petFriendly) ||
|
||||||
|
(isPetRoom && allergyFriendly) ||
|
||||||
|
!itemCode
|
||||||
|
|
||||||
const checkboxChip = (
|
const checkboxChip = (
|
||||||
<CheckboxChip
|
<CheckboxChip
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ export default function RoomSelection({
|
|||||||
roomsAvailability,
|
roomsAvailability,
|
||||||
roomCategories,
|
roomCategories,
|
||||||
user,
|
user,
|
||||||
packages,
|
availablePackages,
|
||||||
selectedPackages,
|
selectedPackages,
|
||||||
setRateSummary,
|
setRateSummary,
|
||||||
rateSummary,
|
rateSummary,
|
||||||
@@ -72,7 +72,7 @@ export default function RoomSelection({
|
|||||||
roomCategories={roomCategories}
|
roomCategories={roomCategories}
|
||||||
handleSelectRate={setRateSummary}
|
handleSelectRate={setRateSummary}
|
||||||
selectedPackages={selectedPackages}
|
selectedPackages={selectedPackages}
|
||||||
packages={packages}
|
packages={availablePackages}
|
||||||
/>
|
/>
|
||||||
</li>
|
</li>
|
||||||
))}
|
))}
|
||||||
@@ -81,7 +81,7 @@ export default function RoomSelection({
|
|||||||
<RateSummary
|
<RateSummary
|
||||||
rateSummary={rateSummary}
|
rateSummary={rateSummary}
|
||||||
isUserLoggedIn={isUserLoggedIn}
|
isUserLoggedIn={isUserLoggedIn}
|
||||||
packages={packages}
|
packages={availablePackages}
|
||||||
roomsAvailability={roomsAvailability}
|
roomsAvailability={roomsAvailability}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import { filterDuplicateRoomTypesByLowestPrice } from "./utils"
|
|||||||
import styles from "./rooms.module.css"
|
import styles from "./rooms.module.css"
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
DefaultFilterOptions,
|
||||||
RoomPackageCodeEnum,
|
RoomPackageCodeEnum,
|
||||||
type RoomPackageCodes,
|
type RoomPackageCodes,
|
||||||
} from "@/types/components/hotelReservation/selectRate/roomFilter"
|
} from "@/types/components/hotelReservation/selectRate/roomFilter"
|
||||||
@@ -25,7 +26,7 @@ export default function Rooms({
|
|||||||
roomsAvailability,
|
roomsAvailability,
|
||||||
roomCategories = [],
|
roomCategories = [],
|
||||||
user,
|
user,
|
||||||
packages,
|
availablePackages,
|
||||||
}: SelectRateProps) {
|
}: SelectRateProps) {
|
||||||
const visibleRooms: RoomConfiguration[] =
|
const visibleRooms: RoomConfiguration[] =
|
||||||
filterDuplicateRoomTypesByLowestPrice(roomsAvailability.roomConfigurations)
|
filterDuplicateRoomTypesByLowestPrice(roomsAvailability.roomConfigurations)
|
||||||
@@ -47,6 +48,30 @@ export default function Rooms({
|
|||||||
(state) => state.setRoomsAvailable
|
(state) => state.setRoomsAvailable
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const defaultPackages: DefaultFilterOptions[] = [
|
||||||
|
{
|
||||||
|
code: RoomPackageCodeEnum.ACCESSIBILITY_ROOM,
|
||||||
|
description: "Accessible Room",
|
||||||
|
itemCode: availablePackages.find(
|
||||||
|
(pkg) => pkg.code === RoomPackageCodeEnum.ACCESSIBILITY_ROOM
|
||||||
|
)?.itemCode,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: RoomPackageCodeEnum.ALLERGY_ROOM,
|
||||||
|
description: "Allergy Room",
|
||||||
|
itemCode: availablePackages.find(
|
||||||
|
(pkg) => pkg.code === RoomPackageCodeEnum.ALLERGY_ROOM
|
||||||
|
)?.itemCode,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: RoomPackageCodeEnum.PET_ROOM,
|
||||||
|
description: "Pet Room",
|
||||||
|
itemCode: availablePackages.find(
|
||||||
|
(pkg) => pkg.code === RoomPackageCodeEnum.PET_ROOM
|
||||||
|
)?.itemCode,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
const handleFilter = useCallback(
|
const handleFilter = useCallback(
|
||||||
(filter: Record<RoomPackageCodeEnum, boolean | undefined>) => {
|
(filter: Record<RoomPackageCodeEnum, boolean | undefined>) => {
|
||||||
const filteredPackages = Object.keys(filter).filter(
|
const filteredPackages = Object.keys(filter).filter(
|
||||||
@@ -80,20 +105,10 @@ export default function Rooms({
|
|||||||
room.features.some((feature) => feature.code === filteredPackage)
|
room.features.some((feature) => feature.code === filteredPackage)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
let notAvailableRooms = visibleRooms.filter((room) =>
|
|
||||||
filteredPackages.every(
|
|
||||||
(filteredPackage) =>
|
|
||||||
!room.features.some((feature) => feature.code === filteredPackage)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
// Clone nested object to keep original object intact and not messup the room data
|
|
||||||
notAvailableRooms = JSON.parse(JSON.stringify(notAvailableRooms))
|
|
||||||
notAvailableRooms.forEach((room) => {
|
|
||||||
room.status = "NotAvailable"
|
|
||||||
})
|
|
||||||
setRooms({
|
setRooms({
|
||||||
...roomsAvailability,
|
...roomsAvailability,
|
||||||
roomConfigurations: [...filteredRooms, ...notAvailableRooms],
|
roomConfigurations: [...filteredRooms],
|
||||||
})
|
})
|
||||||
|
|
||||||
if (filteredRooms.length == 0) {
|
if (filteredRooms.length == 0) {
|
||||||
@@ -104,7 +119,9 @@ export default function Rooms({
|
|||||||
|
|
||||||
const petRoomPackage =
|
const petRoomPackage =
|
||||||
(filteredPackages.includes(RoomPackageCodeEnum.PET_ROOM) &&
|
(filteredPackages.includes(RoomPackageCodeEnum.PET_ROOM) &&
|
||||||
packages.find((pkg) => pkg.code === RoomPackageCodeEnum.PET_ROOM)) ||
|
availablePackages.find(
|
||||||
|
(pkg) => pkg.code === RoomPackageCodeEnum.PET_ROOM
|
||||||
|
)) ||
|
||||||
undefined
|
undefined
|
||||||
|
|
||||||
const features = filteredRooms.find((room) =>
|
const features = filteredRooms.find((room) =>
|
||||||
@@ -124,7 +141,7 @@ export default function Rooms({
|
|||||||
roomsAvailability,
|
roomsAvailability,
|
||||||
visibleRooms,
|
visibleRooms,
|
||||||
rateSummary,
|
rateSummary,
|
||||||
packages,
|
availablePackages,
|
||||||
noRoomsAvailable,
|
noRoomsAvailable,
|
||||||
setNoRoomsAvailable,
|
setNoRoomsAvailable,
|
||||||
setRoomsAvailable,
|
setRoomsAvailable,
|
||||||
@@ -136,13 +153,13 @@ export default function Rooms({
|
|||||||
<RoomFilter
|
<RoomFilter
|
||||||
numberOfRooms={rooms.roomConfigurations.length}
|
numberOfRooms={rooms.roomConfigurations.length}
|
||||||
onFilter={handleFilter}
|
onFilter={handleFilter}
|
||||||
filterOptions={packages}
|
filterOptions={defaultPackages}
|
||||||
/>
|
/>
|
||||||
<RoomSelection
|
<RoomSelection
|
||||||
roomsAvailability={rooms}
|
roomsAvailability={rooms}
|
||||||
roomCategories={roomCategories}
|
roomCategories={roomCategories}
|
||||||
user={user}
|
user={user}
|
||||||
packages={packages}
|
availablePackages={availablePackages}
|
||||||
selectedPackages={selectedPackages}
|
selectedPackages={selectedPackages}
|
||||||
setRateSummary={setRateSummary}
|
setRateSummary={setRateSummary}
|
||||||
rateSummary={rateSummary}
|
rateSummary={rateSummary}
|
||||||
|
|||||||
@@ -2,11 +2,13 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: var(--Spacing-x-half);
|
gap: var(--Spacing-x-half);
|
||||||
padding: var(--Spacing-x1) var(--Spacing-x-one-and-half);
|
padding: calc(var(--Spacing-x1) - 2px) var(--Spacing-x-one-and-half);
|
||||||
border: 1px solid var(--Base-Border-Subtle);
|
border: 1px solid var(--Base-Border-Subtle);
|
||||||
border-radius: var(--Corner-radius-Small);
|
border-radius: var(--Corner-radius-Small);
|
||||||
background-color: var(--Base-Surface-Secondary-light-Normal);
|
background-color: var(--Base-Surface-Secondary-light-Normal);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
height: 32px;
|
||||||
|
background-color: var(--Base-Surface-Secondary-light-Normal);
|
||||||
}
|
}
|
||||||
|
|
||||||
.label[data-selected="true"],
|
.label[data-selected="true"],
|
||||||
@@ -21,8 +23,9 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.label[data-disabled="true"] {
|
.label[data-disabled="true"] {
|
||||||
background-color: var(--Base-Button-Primary-Fill-Disabled);
|
background-color: var(--UI-Input-Controls-Surface-Disabled);
|
||||||
border-color: var(--Base-Button-Primary-Fill-Disabled);
|
border-color: var(--UI-Input-Controls-Border-Disabled);
|
||||||
|
color: var(--Base-Text-Disabled);
|
||||||
cursor: not-allowed;
|
cursor: not-allowed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -864,22 +864,24 @@ export const packagesSchema = z.object({
|
|||||||
|
|
||||||
export const getRoomPackagesSchema = z
|
export const getRoomPackagesSchema = z
|
||||||
.object({
|
.object({
|
||||||
data: z.object({
|
data: z
|
||||||
attributes: z.object({
|
.object({
|
||||||
hotelId: z.number(),
|
attributes: z.object({
|
||||||
packages: z.array(packagesSchema).optional().default([]),
|
hotelId: z.number(),
|
||||||
}),
|
packages: z.array(packagesSchema).optional().default([]),
|
||||||
relationships: z
|
}),
|
||||||
.object({
|
relationships: z
|
||||||
links: z.array(
|
.object({
|
||||||
z.object({
|
links: z.array(
|
||||||
url: z.string(),
|
z.object({
|
||||||
type: z.string(),
|
url: z.string(),
|
||||||
})
|
type: z.string(),
|
||||||
),
|
})
|
||||||
})
|
),
|
||||||
.optional(),
|
})
|
||||||
type: z.string(),
|
.optional(),
|
||||||
}),
|
type: z.string(),
|
||||||
|
})
|
||||||
|
.optional(),
|
||||||
})
|
})
|
||||||
.transform((data) => data.data.attributes.packages)
|
.transform((data) => data.data?.attributes?.packages ?? [])
|
||||||
|
|||||||
@@ -939,12 +939,10 @@ export const hotelQueryRouter = router({
|
|||||||
"api.hotels.packages error",
|
"api.hotels.packages error",
|
||||||
JSON.stringify({ query: { hotelId, params } })
|
JSON.stringify({ query: { hotelId, params } })
|
||||||
)
|
)
|
||||||
throw serverErrorByStatus(apiResponse.status, apiResponse)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const apiJson = await apiResponse.json()
|
const apiJson = await apiResponse.json()
|
||||||
const validatedPackagesData = getRoomPackagesSchema.safeParse(apiJson)
|
const validatedPackagesData = getRoomPackagesSchema.safeParse(apiJson)
|
||||||
|
|
||||||
if (!validatedPackagesData.success) {
|
if (!validatedPackagesData.success) {
|
||||||
getHotelFailCounter.add(1, {
|
getHotelFailCounter.add(1, {
|
||||||
hotelId,
|
hotelId,
|
||||||
|
|||||||
@@ -1,19 +1,22 @@
|
|||||||
import { z } from "zod"
|
import { z } from "zod"
|
||||||
|
|
||||||
import {
|
import { packagesSchema } from "@/server/routers/hotels/output"
|
||||||
getRoomPackagesSchema,
|
|
||||||
packagesSchema,
|
|
||||||
} from "@/server/routers/hotels/output"
|
|
||||||
|
|
||||||
export enum RoomPackageCodeEnum {
|
export enum RoomPackageCodeEnum {
|
||||||
PET_ROOM = "PETR",
|
PET_ROOM = "PETR",
|
||||||
ALLERGY_ROOM = "ALLG",
|
ALLERGY_ROOM = "ALLG",
|
||||||
ACCESSIBILITY_ROOM = "ACCE",
|
ACCESSIBILITY_ROOM = "ACCE",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface DefaultFilterOptions {
|
||||||
|
code: RoomPackageCodeEnum
|
||||||
|
description: string
|
||||||
|
itemCode: string | undefined
|
||||||
|
}
|
||||||
export interface RoomFilterProps {
|
export interface RoomFilterProps {
|
||||||
numberOfRooms: number
|
numberOfRooms: number
|
||||||
onFilter: (filter: Record<string, boolean | undefined>) => void
|
onFilter: (filter: Record<string, boolean | undefined>) => void
|
||||||
filterOptions: RoomPackageData
|
filterOptions: DefaultFilterOptions[]
|
||||||
}
|
}
|
||||||
|
|
||||||
export type RoomPackage = z.output<typeof packagesSchema>
|
export type RoomPackage = z.output<typeof packagesSchema>
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ export interface RoomSelectionProps {
|
|||||||
roomsAvailability: RoomsAvailability
|
roomsAvailability: RoomsAvailability
|
||||||
roomCategories: RoomData[]
|
roomCategories: RoomData[]
|
||||||
user: SafeUser
|
user: SafeUser
|
||||||
packages: RoomPackageData | undefined
|
availablePackages: RoomPackageData | undefined
|
||||||
selectedPackages: RoomPackageCodes[]
|
selectedPackages: RoomPackageCodes[]
|
||||||
setRateSummary: (rateSummary: Rate) => void
|
setRateSummary: (rateSummary: Rate) => void
|
||||||
rateSummary: Rate | null
|
rateSummary: Rate | null
|
||||||
@@ -18,5 +18,5 @@ export interface SelectRateProps {
|
|||||||
roomsAvailability: RoomsAvailability
|
roomsAvailability: RoomsAvailability
|
||||||
roomCategories: RoomData[]
|
roomCategories: RoomData[]
|
||||||
user: SafeUser
|
user: SafeUser
|
||||||
packages: RoomPackageData
|
availablePackages: RoomPackageData
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user