Files
2025-03-17 09:47:42 +01:00

197 lines
7.8 KiB
TypeScript

"use client"
import { Fragment, useState } from "react"
import {
Dialog,
DialogTrigger,
Modal,
ModalOverlay,
} from "react-aria-components"
import { useIntl } from "react-intl"
import { ChevronRightSmallIcon, CloseLargeIcon } from "@/components/Icons"
import Button from "@/components/TempDesignSystem/Button"
import Divider from "@/components/TempDesignSystem/Divider"
import Body from "@/components/TempDesignSystem/Text/Body"
import Caption from "@/components/TempDesignSystem/Text/Caption"
import Subtitle from "@/components/TempDesignSystem/Text/Subtitle"
import { formatPrice } from "@/utils/numberFormatting"
import styles from "./priceChangeSummary.module.css"
import type { RoomState } from "@/types/stores/enter-details"
interface PriceChangeSummaryProps {
rooms: RoomState[]
roomPrices: { prevPrice: number; newPrice?: number }[]
newTotalPrice: { price: number; currency: string }
onAccept: () => void
onCancel: () => void
}
export default function PriceChangeSummary({
rooms,
roomPrices,
newTotalPrice,
onAccept,
onCancel,
}: PriceChangeSummaryProps) {
const intl = useIntl()
const [isOpen, toggleOpen] = useState(false)
return (
<DialogTrigger>
<Button
intent="text"
size="small"
theme="base"
variant="icon"
wrapping
onClick={() => toggleOpen((isOpen) => !isOpen)}
>
{intl.formatMessage({ id: "See price details" })}
<ChevronRightSmallIcon />
</Button>
<ModalOverlay isOpen={isOpen} onOpenChange={toggleOpen}>
<Modal>
<Dialog className={styles.dialog}>
{({ close }) => (
<div className={styles.content}>
<header className={styles.header}>
<Subtitle>
{intl.formatMessage({ id: "Price details" })}
</Subtitle>
<Button
onPress={close}
variant="clean"
className={styles.closeButton}
>
<CloseLargeIcon height={20} width={20} />
</Button>
</header>
<section>
<div>
{rooms.map(({ room }, idx) => {
const roomNumber = idx + 1
const newPrice = roomPrices[idx].newPrice
return (
<Fragment key={idx}>
<div className={styles.rowContainer}>
<Body textTransform="bold">
{rooms.length > 1
? intl.formatMessage(
{ id: "Room {roomIndex}" },
{ roomIndex: roomNumber }
)
: intl.formatMessage({ id: "Room" })}
</Body>
<Body>{room.roomType}</Body>
<div className={styles.priceRow}>
<Caption color="uiTextMediumContrast">
{intl.formatMessage({ id: "Room charge" })}
</Caption>
{newPrice ? (
<div className={styles.updatedPrice}>
<Caption color="uiTextMediumContrast" striked>
{formatPrice(
intl,
room.roomPrice.perStay.local.price,
room.roomPrice.perStay.local.currency
)}
</Caption>
<Body
color="uiTextMediumContrast"
textTransform="bold"
>
{formatPrice(
intl,
newPrice,
room.roomPrice.perStay.local.currency
)}
</Body>
</div>
) : (
<Caption color="uiTextMediumContrast">
{formatPrice(
intl,
room.roomPrice.perStay.local.price,
room.roomPrice.perStay.local.currency
)}
</Caption>
)}
</div>
{room.breakfast && (
<div className={styles.priceRow}>
<Caption color="uiTextMediumContrast">
{intl.formatMessage({
id: "Breakfast charge",
})}
</Caption>
<Caption color="uiTextMediumContrast">
{formatPrice(
intl,
Number(
room.breakfast.localPrice.totalPrice
),
room.breakfast.localPrice.currency
)}
</Caption>
</div>
)}
{room.roomFeatures?.map((feature) => (
<div
className={styles.priceRow}
key={feature.itemCode}
>
<Caption color="uiTextMediumContrast">
{feature.description}
</Caption>
<Caption color="uiTextMediumContrast">
{formatPrice(
intl,
Number(feature.localPrice.totalPrice),
feature.localPrice.currency
)}
</Caption>
</div>
))}
</div>
<Divider color="primaryLightSubtle" />
</Fragment>
)
})}
</div>
<div className={styles.rowContainer}>
<Body>{intl.formatMessage({ id: "Total" })}</Body>
<div className={styles.priceRow}>
<Body textTransform="bold">
{intl.formatMessage({ id: "Price including VAT" })}
</Body>
<Body textTransform="bold">
{formatPrice(
intl,
newTotalPrice.price,
newTotalPrice.currency
)}
</Body>
</div>
</div>
</section>
<footer className={styles.footer}>
<Button intent="secondary" onClick={onCancel}>
{intl.formatMessage({ id: "Back to select room" })}
</Button>
<Button onClick={onAccept}>
{intl.formatMessage({ id: "Continue with new price" })}
</Button>
</footer>
</div>
)}
</Dialog>
</Modal>
</ModalOverlay>
</DialogTrigger>
)
}