Files
web/packages/booking-flow/lib/components/SelectRate/RoomsContainer/RateSummary/MobileSummary/index.tsx
Bianca Widstam 200cf3f617 Merged in fix/BOOK-584-red-price-strikethrough (pull request #3298)
fix(BOOK-584): show discounted if specialrate or member

* fix(BOOK-584): show discounted if specialrate or member


Approved-by: Anton Gunnarsson
2025-12-08 14:23:44 +00:00

154 lines
4.7 KiB
TypeScript

"use client"
import { cx } from "class-variance-authority"
import { useEffect, useRef, useState } from "react"
import { Button as ButtonRAC } from "react-aria-components"
import { useIntl } from "react-intl"
import { formatPrice } from "@scandic-hotels/common/utils/numberFormatting"
import { Button } from "@scandic-hotels/design-system/Button"
import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon"
import { Typography } from "@scandic-hotels/design-system/Typography"
import { useSelectRateContext } from "../../../../../contexts/SelectRate/SelectRateContext"
import { useIsLoggedIn } from "../../../../../hooks/useIsLoggedIn"
import { isSpecialRate } from "../utils"
import SummaryContent from "./Content"
import styles from "./mobileSummary.module.css"
export function MobileSummary() {
const intl = useIntl()
const scrollY = useRef(0)
const [isSummaryOpen, setIsSummaryOpen] = useState<boolean | undefined>(
undefined
)
const isUserLoggedIn = useIsLoggedIn()
const { selectedRates } = useSelectRateContext()
function toggleSummaryOpen() {
setIsSummaryOpen(!isSummaryOpen)
}
useEffect(() => {
if (isSummaryOpen === undefined) {
return
}
if (isSummaryOpen) {
scrollY.current = window.scrollY
document.body.style.position = "fixed"
document.body.style.top = `-${scrollY.current}px`
document.body.style.width = "100%"
} else {
document.body.style.position = ""
document.body.style.top = ""
document.body.style.width = ""
window.scrollTo({
top: scrollY.current,
left: 0,
behavior: "instant",
})
}
return () => {
document.body.style.position = ""
document.body.style.top = ""
document.body.style.width = ""
}
}, [isSummaryOpen])
const hasSpecialRate = selectedRates.rates.find((r) => r && isSpecialRate(r))
const showDiscounted = hasSpecialRate || isUserLoggedIn
if (!selectedRates.totalPrice) {
return null
}
return (
<div className={styles.wrapper} data-open={isSummaryOpen}>
<div className={styles.content}>
<div className={styles.summaryAccordion}>
<SummaryContent
isUserLoggedIn={isUserLoggedIn}
toggleSummaryOpen={toggleSummaryOpen}
/>
</div>
</div>
<div className={styles.bottomSheet}>
<ButtonRAC
data-open={isSummaryOpen}
onPress={toggleSummaryOpen}
className={styles.priceDetailsButton}
>
<Typography variant="Body/Supporting text (caption)/smRegular">
<span className={styles.priceLabel}>
{intl.formatMessage({
id: "common.totalPrice",
defaultMessage: "Total price",
})}
</span>
</Typography>
<Typography variant="Title/Subtitle/lg">
<span
className={cx(styles.price, {
[styles.discounted]: showDiscounted,
})}
>
{formatPrice(
intl,
selectedRates.totalPrice.local.price,
selectedRates.totalPrice.local.currency,
selectedRates.totalPrice.local.additionalPrice,
selectedRates.totalPrice.local.additionalPriceCurrency
)}
</span>
</Typography>
{showDiscounted && selectedRates.totalPrice.local?.regularPrice ? (
<Typography variant="Body/Paragraph/mdRegular">
<p>
<s className={styles.strikeThroughRate}>
{formatPrice(
intl,
selectedRates.totalPrice.local?.regularPrice,
selectedRates.totalPrice.local.currency
)}
</s>
</p>
</Typography>
) : null}
<Typography variant="Body/Supporting text (caption)/smBold">
<span className={styles.seeDetails}>
<span>
{intl.formatMessage({
id: "booking.seeDetails",
defaultMessage: "See details",
})}
</span>
<MaterialIcon
icon="chevron_right"
color="CurrentColor"
size={20}
/>
</span>
</Typography>
</ButtonRAC>
<Button
variant="Primary"
color="Primary"
size="Large"
type="submit"
typography="Body/Paragraph/mdBold"
isDisabled={selectedRates.state !== "ALL_SELECTED"}
>
{intl.formatMessage({
id: "common.continue",
defaultMessage: "Continue",
})}
</Button>
</div>
</div>
)
}