Merged in feat/sw-3587-add-partner-copy-for-member-price (pull request #3053)

feat(SW-3587): Add new member price copy to partner variants

* Add new member price copy to partner variants


Approved-by: Joakim Jäderberg
This commit is contained in:
Anton Gunnarsson
2025-11-03 07:57:23 +00:00
parent a7593597a6
commit b2398dba4a
7 changed files with 57 additions and 13 deletions

View File

@@ -13,7 +13,10 @@ import { useScrollToTop } from "@scandic-hotels/common/hooks/useScrollToTop"
import { BackToTopButton } from "@scandic-hotels/design-system/BackToTopButton" import { BackToTopButton } from "@scandic-hotels/design-system/BackToTopButton"
import { HotelCard } from "@scandic-hotels/design-system/HotelCard" import { HotelCard } from "@scandic-hotels/design-system/HotelCard"
import { useGetPointsCurrency } from "../../bookingFlowConfig/bookingFlowConfigContext" import {
useBookingFlowConfig,
useGetPointsCurrency,
} from "../../bookingFlowConfig/bookingFlowConfigContext"
import { useIsLoggedIn } from "../../hooks/useIsLoggedIn" import { useIsLoggedIn } from "../../hooks/useIsLoggedIn"
import useLang from "../../hooks/useLang" import useLang from "../../hooks/useLang"
import { mapApiImagesToGalleryImages } from "../../misc/imageGallery" import { mapApiImagesToGalleryImages } from "../../misc/imageGallery"
@@ -60,6 +63,7 @@ export default function HotelCardListing({
const { showBackToTop, scrollToTop } = useScrollToTop({ threshold: 490 }) const { showBackToTop, scrollToTop } = useScrollToTop({ threshold: 490 })
const activeCardRef = useRef<HTMLDivElement | null>(null) const activeCardRef = useRef<HTMLDivElement | null>(null)
const pointsCurrency = useGetPointsCurrency() const pointsCurrency = useGetPointsCurrency()
const config = useBookingFlowConfig()
const sortBy = searchParams.get("sort") ?? DEFAULT_SORT const sortBy = searchParams.get("sort") ?? DEFAULT_SORT
@@ -250,6 +254,7 @@ export default function HotelCardListing({
bookingCode={bookingCode} bookingCode={bookingCode}
isCampaignWithBookingCode={isCampaignWithBookingCode} isCampaignWithBookingCode={isCampaignWithBookingCode}
isAlternative={isAlternative} isAlternative={isAlternative}
isPartnerBrand={config.variant !== "scandic"}
/> />
</div> </div>
))} ))}

View File

@@ -4,6 +4,7 @@ import { useIntl } from "react-intl"
import CampaignRateCard from "@scandic-hotels/design-system/CampaignRateCard" import CampaignRateCard from "@scandic-hotels/design-system/CampaignRateCard"
import NoRateAvailableCard from "@scandic-hotels/design-system/NoRateAvailableCard" import NoRateAvailableCard from "@scandic-hotels/design-system/NoRateAvailableCard"
import { useBookingFlowConfig } from "../../../../../../../bookingFlowConfig/bookingFlowConfigContext"
import { useSelectRateContext } from "../../../../../../../contexts/SelectRate/SelectRateContext" import { useSelectRateContext } from "../../../../../../../contexts/SelectRate/SelectRateContext"
import { useIsLoggedIn } from "../../../../../../../hooks/useIsLoggedIn" import { useIsLoggedIn } from "../../../../../../../hooks/useIsLoggedIn"
import { BookingCodeFilterEnum } from "../../../../../../../stores/bookingCode-filter" import { BookingCodeFilterEnum } from "../../../../../../../stores/bookingCode-filter"
@@ -12,6 +13,7 @@ import {
sumPackagesRequestedPrice, sumPackagesRequestedPrice,
} from "../../../../../../../utils/SelectRate" } from "../../../../../../../utils/SelectRate"
import { calculatePricePerNightPriceProduct } from "./totalPricePerNight" import { calculatePricePerNightPriceProduct } from "./totalPricePerNight"
import { getMemberPriceMessage } from "./translation-utils"
import { useRateTitles } from "./useRateTitles" import { useRateTitles } from "./useRateTitles"
import type { import type {
@@ -82,6 +84,7 @@ function Inner({
isRateSelected, isRateSelected,
actions: { selectRate }, actions: { selectRate },
} = useSelectRateContext() } = useSelectRateContext()
const config = useBookingFlowConfig()
const rateTitles = useRateTitles() const rateTitles = useRateTitles()
const isUserLoggedIn = useIsLoggedIn() const isUserLoggedIn = useIsLoggedIn()
@@ -98,10 +101,7 @@ function Inner({
defaultMessage: "Standard price", defaultMessage: "Standard price",
}) })
const memberPriceMsg = intl.formatMessage({ const memberPriceMsg = getMemberPriceMessage(intl, config)
id: "booking.memberPrice",
defaultMessage: "Member price",
})
if (!product.public || (isUserLoggedIn && !product.member)) { if (!product.public || (isUserLoggedIn && !product.member)) {
return ( return (

View File

@@ -4,6 +4,7 @@ import { useIntl } from "react-intl"
import NoRateAvailableCard from "@scandic-hotels/design-system/NoRateAvailableCard" import NoRateAvailableCard from "@scandic-hotels/design-system/NoRateAvailableCard"
import RegularRateCard from "@scandic-hotels/design-system/RegularRateCard" import RegularRateCard from "@scandic-hotels/design-system/RegularRateCard"
import { useBookingFlowConfig } from "../../../../../../../bookingFlowConfig/bookingFlowConfigContext"
import { useSelectRateContext } from "../../../../../../../contexts/SelectRate/SelectRateContext" import { useSelectRateContext } from "../../../../../../../contexts/SelectRate/SelectRateContext"
import { useIsLoggedIn } from "../../../../../../../hooks/useIsLoggedIn" import { useIsLoggedIn } from "../../../../../../../hooks/useIsLoggedIn"
import { BookingCodeFilterEnum } from "../../../../../../../stores/bookingCode-filter" import { BookingCodeFilterEnum } from "../../../../../../../stores/bookingCode-filter"
@@ -12,6 +13,7 @@ import {
sumPackagesRequestedPrice, sumPackagesRequestedPrice,
} from "../../../../../../../utils/SelectRate" } from "../../../../../../../utils/SelectRate"
import { calculatePricePerNightPriceProduct } from "./totalPricePerNight" import { calculatePricePerNightPriceProduct } from "./totalPricePerNight"
import { getMemberPriceMessage } from "./translation-utils"
import { useRateTitles } from "./useRateTitles" import { useRateTitles } from "./useRateTitles"
import type { Package } from "@scandic-hotels/trpc/types/packages" import type { Package } from "@scandic-hotels/trpc/types/packages"
@@ -81,6 +83,7 @@ function Inner({
bookingCodeFilter, bookingCodeFilter,
actions: { selectRate }, actions: { selectRate },
} = useSelectRateContext() } = useSelectRateContext()
const config = useBookingFlowConfig()
const isMainRoom = roomIndex === 0 const isMainRoom = roomIndex === 0
@@ -102,10 +105,7 @@ function Inner({
defaultMessage: "Standard price", defaultMessage: "Standard price",
}) })
const memberPriceMsg = intl.formatMessage({ const memberPriceMsg = getMemberPriceMessage(intl, config)
id: "booking.memberPrice",
defaultMessage: "Member price",
})
const approxMsg = intl.formatMessage({ const approxMsg = intl.formatMessage({
id: "booking.approx", id: "booking.approx",

View File

@@ -0,0 +1,23 @@
import type { IntlShape } from "react-intl"
import type { BookingFlowConfig } from "../../../../../../../bookingFlowConfig/bookingFlowConfig"
export function getMemberPriceMessage(
intl: IntlShape,
config: BookingFlowConfig
) {
if (config.variant !== "scandic") {
return intl.formatMessage({
id: "booking.scandicFriendsMemberPrice",
defaultMessage: "Scandic Friends member price",
description: {
context: "Member price label in white label partner sites",
},
})
}
return intl.formatMessage({
id: "booking.memberPrice",
defaultMessage: "Member price",
})
}

View File

@@ -62,6 +62,7 @@ export const Default: Story = {
}, },
state: 'default', state: 'default',
isAlternative: false, isAlternative: false,
isPartnerBrand: false,
type: 'pageListing', type: 'pageListing',
isUserLoggedIn: false, isUserLoggedIn: false,
distanceToCityCenter: 0, distanceToCityCenter: 0,

View File

@@ -21,6 +21,7 @@ export type PriceCardProps = {
isMemberPrice?: boolean isMemberPrice?: boolean
className?: string className?: string
isCampaign?: boolean isCampaign?: boolean
isPartnerBrand: boolean
} }
export function HotelPriceCard({ export function HotelPriceCard({
@@ -28,6 +29,7 @@ export function HotelPriceCard({
isMemberPrice = false, isMemberPrice = false,
className, className,
isCampaign = false, isCampaign = false,
isPartnerBrand,
}: PriceCardProps) { }: PriceCardProps) {
const intl = useIntl() const intl = useIntl()
const isRegularOrPublicPromotionRate = const isRegularOrPublicPromotionRate =
@@ -45,10 +47,19 @@ export function HotelPriceCard({
className={styles.redColor} className={styles.redColor}
> >
<p> <p>
{intl.formatMessage({ {isPartnerBrand
id: 'booking.memberPrice', ? intl.formatMessage({
defaultMessage: 'Member price', id: 'booking.scandicFriendsMemberPrice',
})} defaultMessage: 'Scandic Friends member price',
description: {
context:
'Member price label in white label partner sites',
},
})
: intl.formatMessage({
id: 'booking.memberPrice',
defaultMessage: 'Member price',
})}
</p> </p>
</Typography> </Typography>
</dt> </dt>

View File

@@ -106,6 +106,7 @@ export type HotelCardProps = {
state?: 'default' | 'active' state?: 'default' | 'active'
bookingCode?: string | null bookingCode?: string | null
isAlternative?: boolean isAlternative?: boolean
isPartnerBrand: boolean
pointsCurrency?: CurrencyEnum pointsCurrency?: CurrencyEnum
fullPrice: boolean fullPrice: boolean
isCampaignWithBookingCode: boolean isCampaignWithBookingCode: boolean
@@ -128,6 +129,7 @@ export const HotelCard = memo(
type = 'pageListing', type = 'pageListing',
bookingCode = '', bookingCode = '',
isAlternative, isAlternative,
isPartnerBrand,
pointsCurrency, pointsCurrency,
images, images,
lang, lang,
@@ -288,6 +290,7 @@ export const HotelCard = memo(
prices?.public && ( prices?.public && (
<HotelPriceCard <HotelPriceCard
productTypePrices={prices.public} productTypePrices={prices.public}
isPartnerBrand={isPartnerBrand}
className={styles.priceCard} className={styles.priceCard}
isCampaign={isCampaign} isCampaign={isCampaign}
/> />
@@ -295,6 +298,7 @@ export const HotelCard = memo(
{prices.member && ( {prices.member && (
<HotelPriceCard <HotelPriceCard
productTypePrices={prices.member} productTypePrices={prices.member}
isPartnerBrand={isPartnerBrand}
className={styles.priceCard} className={styles.priceCard}
isMemberPrice isMemberPrice
/> />