Files
web/apps/scandic-web/components/HotelReservation/EnterDetails/Summary/Mobile/BottomSheet/index.tsx

108 lines
3.1 KiB
TypeScript

"use client"
import { useSearchParams } from "next/navigation"
import { type PropsWithChildren, useEffect, useRef } from "react"
import { useIntl } from "react-intl"
import { Button } from "@scandic-hotels/design-system/Button"
import { useEnterDetailsStore } from "@/stores/enter-details"
import { formId } from "@/components/HotelReservation/EnterDetails/Payment/PaymentClient"
import Caption from "@/components/TempDesignSystem/Text/Caption"
import Subtitle from "@/components/TempDesignSystem/Text/Subtitle"
import { formatPrice } from "@/utils/numberFormatting"
import styles from "./bottomSheet.module.css"
export default function SummaryBottomSheet({ children }: PropsWithChildren) {
const intl = useIntl()
const scrollY = useRef(0)
const searchParams = useSearchParams()
const errorCode = searchParams.get("errorCode")
const {
isSummaryOpen,
toggleSummaryOpen,
totalPrice,
isSubmittingDisabled,
isSubmitting,
} = useEnterDetailsStore((state) => ({
isSummaryOpen: state.isSummaryOpen,
toggleSummaryOpen: state.actions.toggleSummaryOpen,
totalPrice: state.totalPrice,
isSubmittingDisabled: state.isSubmittingDisabled,
isSubmitting: state.isSubmitting,
}))
useEffect(() => {
if (isSummaryOpen) {
scrollY.current = window.scrollY
document.body.style.position = "fixed"
document.body.style.top = `-${scrollY.current}px`
} else {
document.body.style.position = ""
document.body.style.top = ""
if (!errorCode) {
window.scrollTo({
top: scrollY.current,
left: 0,
behavior: "instant",
})
}
}
return () => {
document.body.style.position = ""
document.body.style.top = ""
}
}, [isSummaryOpen, errorCode])
return (
<div className={styles.wrapper} data-open={isSummaryOpen}>
<div className={styles.content}>{children}</div>
<div className={styles.bottomSheet}>
<button
data-open={isSummaryOpen}
onClick={toggleSummaryOpen}
className={styles.priceDetailsButton}
>
<Caption>
{intl.formatMessage({
defaultMessage: "Total price",
})}
</Caption>
<Subtitle>
{formatPrice(
intl,
totalPrice.local.price,
totalPrice.local.currency,
totalPrice.local.additionalPrice,
totalPrice.local.additionalPriceCurrency
)}
</Subtitle>
<Caption color="baseTextHighContrast" type="underline">
{intl.formatMessage({
defaultMessage: "See details",
})}
</Caption>
</button>
<Button
variant="Primary"
size="Large"
type="submit"
isDisabled={isSubmittingDisabled}
isPending={isSubmitting}
typography="Body/Supporting text (caption)/smBold"
form={formId}
>
{intl.formatMessage({
defaultMessage: "Complete booking",
})}
</Button>
</div>
</div>
)
}