Merged in fix/SW-2717-select-hotel-booking-codes- (pull request #2270)

fix: SW-2717 Updated filter display rules

* fix: SW-2717 Updated filter display rules

* fix: SW-2717 Fixed chip button trigger popover after next upgrade

* SW-2717 Optimised code


Approved-by: Erik Tiekstra
This commit is contained in:
Hrishikesh Vaipurkar
2025-06-05 07:14:49 +00:00
parent 9fb5f82d92
commit e3f4cfb738
9 changed files with 32 additions and 37 deletions

View File

@@ -124,6 +124,7 @@ export default async function AlternativeHotelsPage(
city={city} city={city}
hotels={hotels} hotels={hotels}
isAlternative={!!isAlternativeFor} isAlternative={!!isAlternativeFor}
isBookingCodeRateAvailable={isBookingCodeRateAvailable}
mapHref={mapHref} mapHref={mapHref}
title={title} title={title}
/> />

View File

@@ -101,6 +101,7 @@ export default async function SelectHotelPage(
<> <>
<SelectHotel <SelectHotel
bookingCode={bookingCode} bookingCode={bookingCode}
isBookingCodeRateAvailable={isBookingCodeRateAvailable}
city={city} city={city}
hotels={hotels} hotels={hotels}
mapHref={mapHref} mapHref={mapHref}

View File

@@ -1,6 +1,6 @@
"use client" "use client"
import { useState } from "react" import { useEffect, useState } from "react"
import { import {
Dialog, Dialog,
DialogTrigger, DialogTrigger,
@@ -27,6 +27,7 @@ import { BookingCodeFilterEnum } from "@/types/enums/bookingCodeFilter"
export default function BookingCodeFilter() { export default function BookingCodeFilter() {
const intl = useIntl() const intl = useIntl()
const [isOpen, setIsOpen] = useState(false) const [isOpen, setIsOpen] = useState(false)
const [isDesktop, setIsDesktop] = useState(false)
const activeCodeFilter = useBookingCodeFilterStore( const activeCodeFilter = useBookingCodeFilterStore(
(state) => state.activeCodeFilter (state) => state.activeCodeFilter
) )
@@ -52,6 +53,11 @@ export default function BookingCodeFilter() {
setFilter(selectedFilter as BookingCodeFilterEnum) setFilter(selectedFilter as BookingCodeFilterEnum)
} }
// To fix the hyderation error
useEffect(() => {
setIsDesktop(displayAsPopover)
}, [displayAsPopover])
return ( return (
<div className={styles.bookingCodeFilter}> <div className={styles.bookingCodeFilter}>
<DialogTrigger isOpen={isOpen} onOpenChange={setIsOpen}> <DialogTrigger isOpen={isOpen} onOpenChange={setIsOpen}>
@@ -67,7 +73,7 @@ export default function BookingCodeFilter() {
color="CurrentColor" color="CurrentColor"
/> />
</ChipButton> </ChipButton>
{displayAsPopover ? ( {isDesktop ? (
<Popover placement="bottom end" isNonModal> <Popover placement="bottom end" isNonModal>
<Dialog className={styles.dialog}> <Dialog className={styles.dialog}>
{({ close }) => { {({ close }) => {

View File

@@ -139,10 +139,6 @@ export default function SelectHotelContent({
</Button> </Button>
) )
const isRegularRateAvailable = bookingCode
? hotels.some((hotel) => !hotel.availability.bookingCode)
: false
const isSpecialRate = bookingCode const isSpecialRate = bookingCode
? hotels.some( ? hotels.some(
(hotel) => (hotel) =>
@@ -152,10 +148,7 @@ export default function SelectHotelContent({
: false : false
const showBookingCodeFilter = const showBookingCodeFilter =
bookingCode && bookingCode && isBookingCodeRateAvailable && !isSpecialRate
isBookingCodeRateAvailable &&
isRegularRateAvailable &&
!isSpecialRate
return ( return (
<div className={styles.container}> <div className={styles.container}>

View File

@@ -23,6 +23,7 @@ interface SelectHotelProps {
bookingCode?: string bookingCode?: string
city: Location city: Location
hotels: HotelResponse[] hotels: HotelResponse[]
isBookingCodeRateAvailable?: boolean
mapHref: string mapHref: string
title: string title: string
} }
@@ -32,43 +33,28 @@ export default async function SelectHotel({
city, city,
hotels, hotels,
isAlternative = false, isAlternative = false,
isBookingCodeRateAvailable = false,
mapHref, mapHref,
title, title,
}: SelectHotelProps) { }: SelectHotelProps) {
const intl = await getIntl() const intl = await getIntl()
const isAllUnavailable = !hotels.length const isAllUnavailable = hotels.every(
(hotel) => hotel.availability.status !== "Available"
)
const isCityWithCountry = (city: any): city is { country: string } => const isCityWithCountry = (city: any): city is { country: string } =>
"country" in city "country" in city
const isBookingCodeRateAvailable = bookingCode // Special rates (corporate cheque, voucher) will not have regular rate hotels availability
? hotels.some(
(hotel) =>
hotel.availability.bookingCode &&
hotel.availability.status === "Available"
)
: false
const isFullPriceHotelAvailable = bookingCode
? hotels?.some(
(hotel) =>
!hotel.availability.bookingCode &&
hotel.availability.status === "Available"
)
: false
// Special rates (corporate cheque, voucher and reward nights) will not have regular rate hotels availability
const isSpecialRate = hotels.some( const isSpecialRate = hotels.some(
(hotel) => (hotel) =>
hotel.availability.productType?.bonusCheque || hotel.availability.productType?.bonusCheque ||
hotel.availability.productType?.voucher || hotel.availability.productType?.voucher
hotel.availability.productType?.redemptions
) )
const filterList = getFiltersFromHotels(hotels) const filterList = getFiltersFromHotels(hotels)
const showBookingCodeFilter = const showBookingCodeFilter = isBookingCodeRateAvailable && !isSpecialRate
isBookingCodeRateAvailable && isFullPriceHotelAvailable && !isSpecialRate
return ( return (
<> <>

View File

@@ -1,7 +1,7 @@
.main { .main {
display: flex; display: flex;
background-color: var(--Scandic-Brand-Warm-White); background-color: var(--Scandic-Brand-Warm-White);
min-height: 100dvh; min-height: min(100dvh, 750px);
flex-direction: column; flex-direction: column;
max-width: var(--max-width-page); max-width: var(--max-width-page);
margin: 0 auto; margin: 0 auto;
@@ -141,4 +141,4 @@
.skeletonContainer .sideBar { .skeletonContainer .sideBar {
gap: var(--Spacing-x3); gap: var(--Spacing-x3);
} }
} }

View File

@@ -1,6 +1,6 @@
"use client" "use client"
import { useState } from "react" import { useEffect, useState } from "react"
import { import {
Dialog, Dialog,
DialogTrigger, DialogTrigger,
@@ -33,6 +33,7 @@ export default function BookingCodeFilter() {
const intl = useIntl() const intl = useIntl()
const lang = useLang() const lang = useLang()
const [isOpen, setIsOpen] = useState(false) const [isOpen, setIsOpen] = useState(false)
const [isDesktop, setIsDesktop] = useState(false)
const displayAsPopover = useMediaQuery("(min-width: 768px)") const displayAsPopover = useMediaQuery("(min-width: 768px)")
const utils = trpc.useUtils() const utils = trpc.useUtils()
const { const {
@@ -95,6 +96,11 @@ export default function BookingCodeFilter() {
}) })
) )
// To fix the hyderation error
useEffect(() => {
setIsDesktop(displayAsPopover)
}, [displayAsPopover])
if (hideFilter || !booking.bookingCode) { if (hideFilter || !booking.bookingCode) {
return null return null
} }
@@ -115,8 +121,8 @@ export default function BookingCodeFilter() {
color="CurrentColor" color="CurrentColor"
/> />
</ChipButton> </ChipButton>
{displayAsPopover ? ( {isDesktop ? (
<Popover placement="bottom end"> <Popover placement="bottom end" isNonModal>
<Dialog className={styles.dialog}> <Dialog className={styles.dialog}>
{({ close }) => { {({ close }) => {
function handleChangeFilterValue(value: string) { function handleChangeFilterValue(value: string) {

View File

@@ -19,6 +19,7 @@ import styles from "./roomPackageFilter.module.css"
export default function RoomPackageFilterModal() { export default function RoomPackageFilterModal() {
const intl = useIntl() const intl = useIntl()
const [isOpen, setIsOpen] = useState(false) const [isOpen, setIsOpen] = useState(false)
return ( return (
<DialogTrigger isOpen={isOpen} onOpenChange={setIsOpen}> <DialogTrigger isOpen={isOpen} onOpenChange={setIsOpen}>
<ChipButton variant="Outlined"> <ChipButton variant="Outlined">

View File

@@ -12,6 +12,7 @@ import styles from "./roomPackageFilter.module.css"
export default function RoomPackageFilterPopover() { export default function RoomPackageFilterPopover() {
const intl = useIntl() const intl = useIntl()
const [isOpen, setIsOpen] = useState(false) const [isOpen, setIsOpen] = useState(false)
return ( return (
<DialogTrigger isOpen={isOpen} onOpenChange={setIsOpen}> <DialogTrigger isOpen={isOpen} onOpenChange={setIsOpen}>
<ChipButton variant="Outlined"> <ChipButton variant="Outlined">