Fix(SW-1711)/(SW-2077): Export icons individually * fix(SW-1711): export icons individually Approved-by: Michael Zetterberg Approved-by: Erik Tiekstra
135 lines
4.3 KiB
TypeScript
135 lines
4.3 KiB
TypeScript
import { Dialog, Modal, ModalOverlay } from "react-aria-components"
|
|
import { useIntl } from "react-intl"
|
|
|
|
import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon"
|
|
|
|
import { useEnterDetailsStore } from "@/stores/enter-details"
|
|
|
|
import Button from "@/components/TempDesignSystem/Button"
|
|
import Body from "@/components/TempDesignSystem/Text/Body"
|
|
import Caption from "@/components/TempDesignSystem/Text/Caption"
|
|
import Subtitle from "@/components/TempDesignSystem/Text/Subtitle"
|
|
import Title from "@/components/TempDesignSystem/Text/Title"
|
|
import { formatPrice } from "@/utils/numberFormatting"
|
|
|
|
import { calculateTotalRoomPrice } from "../Payment/helpers"
|
|
import PriceChangeSummary from "./PriceChangeSummary"
|
|
|
|
import styles from "./priceChangeDialog.module.css"
|
|
|
|
import type { PriceChangeData } from "@/types/components/hotelReservation/enterDetails/payment"
|
|
|
|
type PriceDetailsState = {
|
|
newTotalPrice: number
|
|
roomPrices: { prevPrice: number; newPrice?: number }[]
|
|
}
|
|
|
|
type PriceChangeDialogProps = {
|
|
isOpen: boolean
|
|
priceChangeData: PriceChangeData
|
|
prevTotalPrice: number
|
|
currency: string
|
|
onCancel: () => void
|
|
onAccept: () => void
|
|
}
|
|
|
|
export default function PriceChangeDialog({
|
|
isOpen,
|
|
priceChangeData,
|
|
prevTotalPrice,
|
|
currency,
|
|
onCancel,
|
|
onAccept,
|
|
}: PriceChangeDialogProps) {
|
|
const intl = useIntl()
|
|
const title = intl.formatMessage({ id: "Price change" })
|
|
const rooms = useEnterDetailsStore((state) => state.rooms)
|
|
|
|
const { newTotalPrice, roomPrices } = rooms.reduce<PriceDetailsState>(
|
|
(acc, room, idx) => {
|
|
const roomPrice = room.room.roomPrice.perStay.local.price
|
|
const priceChange = priceChangeData[idx]
|
|
|
|
const { totalPrice } = calculateTotalRoomPrice(
|
|
room,
|
|
priceChange?.roomPrice
|
|
)
|
|
acc.newTotalPrice += totalPrice
|
|
|
|
acc.roomPrices.push({
|
|
prevPrice: roomPrice,
|
|
newPrice: priceChange?.roomPrice,
|
|
})
|
|
|
|
return acc
|
|
},
|
|
{ newTotalPrice: 0, roomPrices: [] }
|
|
)
|
|
|
|
return (
|
|
<ModalOverlay
|
|
className={styles.overlay}
|
|
isOpen={isOpen}
|
|
isKeyboardDismissDisabled
|
|
>
|
|
<Modal className={styles.modal}>
|
|
<Dialog aria-label={title} className={styles.dialog}>
|
|
<header className={styles.header}>
|
|
<div className={styles.titleContainer}>
|
|
<MaterialIcon
|
|
icon="info"
|
|
size={48}
|
|
color="Icon/Interactive/Default"
|
|
/>
|
|
<Title
|
|
level="h1"
|
|
as="h3"
|
|
textAlign="center"
|
|
textTransform="uppercase"
|
|
>
|
|
{title}
|
|
</Title>
|
|
</div>
|
|
<Body textAlign="center">
|
|
{intl.formatMessage(
|
|
{
|
|
id: "Prices have increased since you selected your {totalRooms, plural, one {room} other {rooms}}.{br} To continue your booking, accept the updated price,{br} or go back to select {totalRooms, plural, one {a new room} other {new rooms}}.",
|
|
},
|
|
{ totalRooms: rooms.length, br: <br /> }
|
|
)}
|
|
</Body>
|
|
<div>
|
|
<Subtitle textAlign="center" color="burgundy">
|
|
{intl.formatMessage({ id: "New total" })}
|
|
</Subtitle>
|
|
<div className={styles.prices}>
|
|
<Caption striked>
|
|
{formatPrice(intl, prevTotalPrice, currency)}
|
|
</Caption>
|
|
<Body textAlign="center" textTransform="bold">
|
|
{formatPrice(intl, newTotalPrice, currency)}
|
|
</Body>
|
|
</div>
|
|
</div>
|
|
<PriceChangeSummary
|
|
rooms={rooms}
|
|
roomPrices={roomPrices}
|
|
newTotalPrice={{ price: newTotalPrice, currency }}
|
|
onAccept={onAccept}
|
|
onCancel={onCancel}
|
|
/>
|
|
</header>
|
|
<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>
|
|
</Dialog>
|
|
</Modal>
|
|
</ModalOverlay>
|
|
)
|
|
}
|