Merged in fix/SW-2739-map-reward-night-not-enough-points (pull request #2435)

fix(SW-2739): remove tooltip and add correct CTA on map for reward nights

* fix(SW-2739): remove tooltip and add correct CTA on map for reward nights

* fix(SW-2739): fix pr comment


Approved-by: Arvid Norlin
This commit is contained in:
Bianca Widstam
2025-06-25 13:30:43 +00:00
parent 94fc5cabb3
commit 9e3d82b62c
7 changed files with 106 additions and 49 deletions

View File

@@ -22,7 +22,6 @@ import { FacilityToIcon } from "@/components/ContentType/HotelPage/data"
import ImageGallery from "@/components/ImageGallery" import ImageGallery from "@/components/ImageGallery"
import Link from "@/components/TempDesignSystem/Link" import Link from "@/components/TempDesignSystem/Link"
import Caption from "@/components/TempDesignSystem/Text/Caption" import Caption from "@/components/TempDesignSystem/Text/Caption"
import { Tooltip } from "@/components/TempDesignSystem/Tooltip"
import { mapApiImagesToGalleryImages } from "@/utils/imageGallery" import { mapApiImagesToGalleryImages } from "@/utils/imageGallery"
import { getSingleDecimal } from "@/utils/numberFormatting" import { getSingleDecimal } from "@/utils/numberFormatting"
@@ -245,17 +244,11 @@ function HotelCard({
</div> </div>
) : null} ) : null}
{isDisabled ? ( {isDisabled ? (
<Tooltip
arrow="left"
position="bottom"
text={notEnoughPointsLabel}
>
<div className={cx(styles.fakeButton, styles.disabled)}> <div className={cx(styles.fakeButton, styles.disabled)}>
<Typography variant="Body/Paragraph/mdBold"> <Typography variant="Body/Paragraph/mdBold">
<span>{notEnoughPointsLabel}</span> <span>{notEnoughPointsLabel}</span>
</Typography> </Typography>
</div> </div>
</Tooltip>
) : ( ) : (
<div className={styles.fakeButton}> <div className={styles.fakeButton}>
<Typography variant="Body/Paragraph/mdBold"> <Typography variant="Body/Paragraph/mdBold">

View File

@@ -54,11 +54,15 @@ export default function ListingHotelCardDialog({
redemptionPrice, redemptionPrice,
chequePrice, chequePrice,
voucherPrice, voucherPrice,
hasEnoughPoints,
} = data } = data
const firstImage = images[0]?.imageSizes?.small const firstImage = images[0]?.imageSizes?.small
const altText = images[0]?.metaData?.altText const altText = images[0]?.metaData?.altText
const notEnoughPointsLabel = intl.formatMessage({
defaultMessage: "Not enough points",
})
return ( return (
<div className={styles.container}> <div className={styles.container}>
<IconButton <IconButton
@@ -212,7 +216,13 @@ export default function ListingHotelCardDialog({
)} )}
</div> </div>
</div> </div>
<Button asChild theme="base" size="small" className={styles.button}> {hasEnoughPoints ? (
<Button
asChild
theme="base"
size="small"
className={styles.button}
>
<Link <Link
href={`${selectRate(lang)}?hotel=${operaId}`} href={`${selectRate(lang)}?hotel=${operaId}`}
color="none" color="none"
@@ -223,6 +233,13 @@ export default function ListingHotelCardDialog({
})} })}
</Link> </Link>
</Button> </Button>
) : (
<div className={styles.notEnoughPointsButton}>
<Typography variant="Body/Paragraph/mdBold">
<span>{notEnoughPointsLabel}</span>
</Typography>
</div>
)}
</div> </div>
) : ( ) : (
<NoPriceAvailableCard /> <NoPriceAvailableCard />

View File

@@ -74,3 +74,18 @@
top: 8px; top: 8px;
right: 8px; right: 8px;
} }
.notEnoughPointsButton {
border-radius: var(--Corner-radius-rounded);
border-width: 2px;
border-style: solid;
display: flex;
align-items: center;
justify-content: center;
gap: var(--Space-x05);
padding: 10px var(--Space-x2);
background-color: var(--Component-Button-Brand-Primary-Fill-Disabled);
border-color: var(--Component-Button-Brand-Primary-Border-Disabled);
color: var(--Component-Button-Brand-Primary-On-fill-Disabled);
}

View File

@@ -5,6 +5,7 @@ import { useIntl } from "react-intl"
import { IconButton } from "@scandic-hotels/design-system/IconButton" import { IconButton } from "@scandic-hotels/design-system/IconButton"
import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon" import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon"
import { Typography } from "@scandic-hotels/design-system/Typography"
import { selectRate } from "@/constants/routes/hotelReservation" import { selectRate } from "@/constants/routes/hotelReservation"
@@ -53,10 +54,14 @@ export default function StandaloneHotelCardDialog({
images, images,
ratings, ratings,
operaId, operaId,
hasEnoughPoints,
} = data } = data
const firstImage = images[0]?.imageSizes?.small const firstImage = images[0]?.imageSizes?.small
const altText = images[0]?.metaData?.altText const altText = images[0]?.metaData?.altText
const notEnoughPointsLabel = intl.formatMessage({
defaultMessage: "Not enough points",
})
return ( return (
<div className={styles.container}> <div className={styles.container}>
@@ -224,6 +229,7 @@ export default function StandaloneHotelCardDialog({
<HotelPointsRow pointsPerStay={redemptionPrice} /> <HotelPointsRow pointsPerStay={redemptionPrice} />
)} )}
</div> </div>
{hasEnoughPoints ? (
<Button <Button
asChild asChild
theme="base" theme="base"
@@ -251,6 +257,13 @@ export default function StandaloneHotelCardDialog({
})} })}
</Link> </Link>
</Button> </Button>
) : (
<div className={styles.notEnoughPointsButton}>
<Typography variant="Body/Paragraph/mdBold">
<span>{notEnoughPointsLabel}</span>
</Typography>
</div>
)}
</> </>
) : ( ) : (
<NoPriceAvailableCard /> <NoPriceAvailableCard />

View File

@@ -65,3 +65,18 @@
right: 8px; right: 8px;
z-index: 1; z-index: 1;
} }
.notEnoughPointsButton {
border-radius: var(--Corner-radius-rounded);
border-width: 2px;
border-style: solid;
display: flex;
align-items: center;
justify-content: center;
gap: var(--Space-x05);
padding: 10px var(--Space-x2);
background-color: var(--Component-Button-Brand-Primary-Fill-Disabled);
border-color: var(--Component-Button-Brand-Primary-Border-Disabled);
color: var(--Component-Button-Brand-Primary-On-fill-Disabled);
}

View File

@@ -51,6 +51,9 @@ export function getHotelPins(
ratings: hotel.ratings?.tripAdvisor.rating ?? null, ratings: hotel.ratings?.tripAdvisor.rating ?? null,
operaId: hotel.operaId, operaId: hotel.operaId,
facilityIds: hotel.detailedFacilities.map((facility) => facility.id), facilityIds: hotel.detailedFacilities.map((facility) => facility.id),
hasEnoughPoints: !!availability.productType?.redemptions?.some(
(r) => r.hasEnoughPoints
),
} }
}) })
} }

View File

@@ -46,6 +46,7 @@ export type HotelPin = {
ratings: number | null ratings: number | null
operaId: string operaId: string
facilityIds: number[] facilityIds: number[]
hasEnoughPoints: boolean
} }
export interface HotelListingMapContentProps { export interface HotelListingMapContentProps {