Merged in chore/move-enter-details (pull request #2778)
Chore/move enter details Approved-by: Anton Gunnarsson
This commit is contained in:
@@ -0,0 +1,164 @@
|
||||
import { Dialog, Modal, ModalOverlay } from "react-aria-components"
|
||||
import { useIntl } from "react-intl"
|
||||
|
||||
import { formatPrice } from "@scandic-hotels/common/utils/numberFormatting"
|
||||
import Body from "@scandic-hotels/design-system/Body"
|
||||
import Caption from "@scandic-hotels/design-system/Caption"
|
||||
import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon"
|
||||
import { OldDSButton as Button } from "@scandic-hotels/design-system/OldDSButton"
|
||||
import Subtitle from "@scandic-hotels/design-system/Subtitle"
|
||||
import Title from "@scandic-hotels/design-system/Title"
|
||||
|
||||
import { useEnterDetailsStore } from "../../../stores/enter-details"
|
||||
import { calculateTotalRoomPrice } from "../Payment/helpers"
|
||||
import PriceChangeSummary from "./PriceChangeSummary"
|
||||
|
||||
import styles from "./priceChangeDialog.module.css"
|
||||
|
||||
import type { PriceChangeData } from "../PriceChangeData"
|
||||
|
||||
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({
|
||||
defaultMessage: "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: [] }
|
||||
)
|
||||
|
||||
const roomSelectionMsg = intl.formatMessage(
|
||||
{
|
||||
defaultMessage: "{totalRooms, plural, one {room} other {rooms}}",
|
||||
},
|
||||
{
|
||||
totalRooms: rooms.length,
|
||||
}
|
||||
)
|
||||
|
||||
const newRoomSelectionMsg = intl.formatMessage(
|
||||
{
|
||||
defaultMessage:
|
||||
"{totalRooms, plural, one {a new room} other {new rooms}}",
|
||||
},
|
||||
{
|
||||
totalRooms: rooms.length,
|
||||
}
|
||||
)
|
||||
|
||||
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(
|
||||
{
|
||||
defaultMessage:
|
||||
"Prices have increased since you selected your {roomSelection}.{linebreak} To continue your booking, accept the updated price,{linebreak} or go back to select {newRoomSelection}.",
|
||||
},
|
||||
{
|
||||
roomSelection: roomSelectionMsg,
|
||||
newRoomSelection: newRoomSelectionMsg,
|
||||
linebreak: <br />,
|
||||
}
|
||||
)}
|
||||
</Body>
|
||||
<div>
|
||||
<Subtitle textAlign="center" color="burgundy">
|
||||
{intl.formatMessage({
|
||||
defaultMessage: "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({
|
||||
defaultMessage: "Back to select room",
|
||||
})}
|
||||
</Button>
|
||||
<Button onClick={onAccept}>
|
||||
{intl.formatMessage({
|
||||
defaultMessage: "Continue with new price",
|
||||
})}
|
||||
</Button>
|
||||
</footer>
|
||||
</Dialog>
|
||||
</Modal>
|
||||
</ModalOverlay>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user