Merged in feat/sw-2874-move-select-rate (pull request #2750)
Approved-by: Joakim Jäderberg
This commit is contained in:
@@ -0,0 +1,136 @@
|
||||
import { useEffect } from "react"
|
||||
import { useIntl } from "react-intl"
|
||||
|
||||
import useStickyPosition from "@scandic-hotels/common/hooks/useStickyPosition"
|
||||
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 { useSelectRateContext } from "../../../../../contexts/SelectRate/SelectRateContext"
|
||||
import { SelectedRoomPanel } from "./SelectedRoomPanel"
|
||||
import { roomSelectionPanelVariants } from "./variants"
|
||||
|
||||
import styles from "./multiRoomWrapper.module.css"
|
||||
|
||||
type Props = {
|
||||
children: React.ReactNode
|
||||
isMultiRoom: boolean
|
||||
roomIndex: number
|
||||
}
|
||||
export function MultiRoomWrapper({ children, isMultiRoom, roomIndex }: Props) {
|
||||
const intl = useIntl()
|
||||
|
||||
const { getTopOffset } = useStickyPosition()
|
||||
const {
|
||||
activeRoomIndex,
|
||||
selectedRates,
|
||||
actions: { setActiveRoom },
|
||||
input: { data },
|
||||
} = useSelectRateContext()
|
||||
const roomNr = roomIndex + 1
|
||||
const adultCount = data?.booking.rooms[roomIndex]?.adults || 0
|
||||
const childCount = data?.booking.rooms[roomIndex]?.childrenInRoom?.length || 0
|
||||
const isActiveRoom = activeRoomIndex === roomIndex
|
||||
|
||||
const roomMsg = intl.formatMessage(
|
||||
{
|
||||
defaultMessage: "Room {roomIndex}",
|
||||
},
|
||||
{ roomIndex: roomNr }
|
||||
)
|
||||
|
||||
const adultsMsg = intl.formatMessage(
|
||||
{
|
||||
defaultMessage: "{adults, plural, one {# adult} other {# adults}}",
|
||||
},
|
||||
{ adults: adultCount }
|
||||
)
|
||||
|
||||
const childrenMsg = intl.formatMessage(
|
||||
{
|
||||
defaultMessage: "{children, plural, one {# child} other {# children}}",
|
||||
},
|
||||
{
|
||||
children: childCount,
|
||||
}
|
||||
)
|
||||
|
||||
const onlyAdultsMsg = adultsMsg
|
||||
const adultsAndChildrenMsg = [adultsMsg, childrenMsg].join(", ")
|
||||
const guestsMsg = childCount ? adultsAndChildrenMsg : onlyAdultsMsg
|
||||
|
||||
const title = [roomMsg, guestsMsg].join(", ")
|
||||
|
||||
useEffect(() => {
|
||||
requestAnimationFrame(() => {
|
||||
const SCROLL_OFFSET = 12 + getTopOffset()
|
||||
const roomElements = document.querySelectorAll(`.${styles.roomContainer}`)
|
||||
|
||||
// If no room is active we will show all rooms collapsed, hence we want
|
||||
// to scroll to the first room.
|
||||
const selectedRoom =
|
||||
activeRoomIndex === -1 ? roomElements[0] : roomElements[activeRoomIndex]
|
||||
|
||||
if (selectedRoom) {
|
||||
const elementPosition = selectedRoom.getBoundingClientRect().top
|
||||
const offsetPosition = elementPosition + window.scrollY - SCROLL_OFFSET
|
||||
|
||||
// Setting a tiny delay for the scrolling. Without it the browser sometimes doesn't scroll up
|
||||
// after modifying the first room.
|
||||
setTimeout(() => {
|
||||
window.scrollTo({
|
||||
top: offsetPosition,
|
||||
behavior: "smooth",
|
||||
})
|
||||
}, 5)
|
||||
}
|
||||
})
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [activeRoomIndex])
|
||||
|
||||
const selectedRate = selectedRates.rateSelectedForRoom(roomIndex)
|
||||
|
||||
if (isMultiRoom) {
|
||||
const classNames = roomSelectionPanelVariants({
|
||||
active: isActiveRoom,
|
||||
selected: !!selectedRate && !isActiveRoom,
|
||||
})
|
||||
return (
|
||||
<div className={styles.roomContainer} data-multiroom="true">
|
||||
<div className={styles.header}>
|
||||
{selectedRate && !isActiveRoom ? null : (
|
||||
<Subtitle color="uiTextHighContrast">{title}</Subtitle>
|
||||
)}
|
||||
{selectedRate && isActiveRoom ? (
|
||||
<Button
|
||||
intent="text"
|
||||
onClick={() => {
|
||||
setActiveRoom("deselect")
|
||||
}}
|
||||
size="medium"
|
||||
theme="base"
|
||||
variant="icon"
|
||||
>
|
||||
{intl.formatMessage({
|
||||
defaultMessage: "Close",
|
||||
})}
|
||||
<MaterialIcon
|
||||
icon="keyboard_arrow_up"
|
||||
size={20}
|
||||
color="CurrentColor"
|
||||
/>
|
||||
</Button>
|
||||
) : null}
|
||||
</div>
|
||||
<div className={classNames}>
|
||||
<div className={styles.roomPanel}>
|
||||
<SelectedRoomPanel roomIndex={roomIndex} />
|
||||
</div>
|
||||
<div className={styles.roomSelectionPanel}>{children}</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
return children
|
||||
}
|
||||
Reference in New Issue
Block a user