256 lines
7.4 KiB
TypeScript
256 lines
7.4 KiB
TypeScript
"use client"
|
|
import { useIntl } from "react-intl"
|
|
|
|
import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon"
|
|
import { Typography } from "@scandic-hotels/design-system/Typography"
|
|
|
|
import { CancellationRuleEnum } from "@/constants/booking"
|
|
import { customerService } from "@/constants/currentWebHrefs"
|
|
import { preliminaryReceipt } from "@/constants/routes/myStay"
|
|
import { useManageStayStore } from "@/stores/my-stay/manageStayStore"
|
|
import { useMyStayRoomDetailsStore } from "@/stores/my-stay/myStayRoomDetailsStore"
|
|
|
|
import AddToCalendar from "@/components/HotelReservation/AddToCalendar"
|
|
import { generateDateTime } from "@/components/HotelReservation/BookingConfirmation/Header/Actions/helpers"
|
|
import Button from "@/components/TempDesignSystem/Button"
|
|
import Link from "@/components/TempDesignSystem/Link"
|
|
import Body from "@/components/TempDesignSystem/Text/Body"
|
|
import Caption from "@/components/TempDesignSystem/Text/Caption"
|
|
import Subtitle from "@/components/TempDesignSystem/Text/Subtitle"
|
|
import useLang from "@/hooks/useLang"
|
|
import { trackMyStayPageLink } from "@/utils/tracking"
|
|
|
|
import AddToCalendarButton from "./Actions/AddToCalendarButton"
|
|
import {
|
|
checkCancelable,
|
|
checkCanDownloadInvoice,
|
|
checkDateModifiable,
|
|
checkGuaranteeable,
|
|
isDatetimePast,
|
|
} from "./utils"
|
|
|
|
import styles from "./actionPanel.module.css"
|
|
|
|
import type { EventAttributes } from "ics"
|
|
|
|
import type { Hotel } from "@/types/hotel"
|
|
|
|
interface ActionPanelProps {
|
|
hotel: Hotel
|
|
}
|
|
|
|
export default function ActionPanel({ hotel }: ActionPanelProps) {
|
|
const intl = useIntl()
|
|
const lang = useLang()
|
|
const {
|
|
actions: { setActiveView },
|
|
} = useManageStayStore()
|
|
|
|
const bookedRoom = useMyStayRoomDetailsStore((state) => state.bookedRoom)
|
|
const linkedReservationRooms = useMyStayRoomDetailsStore(
|
|
(state) => state.linkedReservationRooms
|
|
)
|
|
|
|
const {
|
|
confirmationNumber,
|
|
checkInDate,
|
|
checkOutDate,
|
|
createDateTime,
|
|
canChangeDate,
|
|
priceType,
|
|
} = bookedRoom
|
|
|
|
const datetimeIsInThePast = isDatetimePast(checkInDate)
|
|
|
|
const isDateModifyable = checkDateModifiable(
|
|
canChangeDate,
|
|
datetimeIsInThePast,
|
|
bookedRoom.isCancelled,
|
|
priceType === "points"
|
|
)
|
|
|
|
const isCancelable = checkCancelable(
|
|
bookedRoom.isCancelable,
|
|
datetimeIsInThePast,
|
|
linkedReservationRooms
|
|
)
|
|
|
|
const isGuaranteeable = checkGuaranteeable(
|
|
!!bookedRoom.guaranteeInfo,
|
|
bookedRoom.isCancelled,
|
|
datetimeIsInThePast
|
|
)
|
|
|
|
const canDownloadInvoice = checkCanDownloadInvoice(
|
|
bookedRoom.isCancelled,
|
|
bookedRoom.rateDefinition.cancellationRule ===
|
|
CancellationRuleEnum.CancellableBefore6PM
|
|
)
|
|
|
|
const calendarEvent: EventAttributes = {
|
|
busyStatus: "FREE",
|
|
categories: ["booking", "hotel", "stay"],
|
|
created: generateDateTime(createDateTime),
|
|
description: hotel.hotelContent.texts.descriptions?.medium,
|
|
end: generateDateTime(checkOutDate),
|
|
endInputType: "utc",
|
|
geo: {
|
|
lat: hotel.location.latitude,
|
|
lon: hotel.location.longitude,
|
|
},
|
|
location: `${hotel.address.streetAddress}, ${hotel.address.zipCode} ${hotel.address.city} ${hotel.address.country}`,
|
|
start: generateDateTime(checkInDate),
|
|
startInputType: "utc",
|
|
status: "CONFIRMED",
|
|
title: hotel.name,
|
|
url: hotel.contactInformation.websiteUrl,
|
|
}
|
|
|
|
const handleModifyStay = () => {
|
|
trackMyStayPageLink("modify dates")
|
|
setActiveView("modifyStay")
|
|
}
|
|
|
|
const handleCancelStay = () => {
|
|
trackMyStayPageLink("cancel booking")
|
|
setActiveView("cancelStay")
|
|
}
|
|
|
|
const handleDownloadInvoice = () => {
|
|
trackMyStayPageLink("download invoice")
|
|
}
|
|
|
|
const handleGuaranteeLateArrival = () => {
|
|
trackMyStayPageLink("guarantee late arrival")
|
|
setActiveView("guaranteeLateArrival")
|
|
}
|
|
|
|
const handleCustomerSupport = () => {
|
|
trackMyStayPageLink("customer support")
|
|
}
|
|
|
|
return (
|
|
<div className={styles.actionPanel}>
|
|
<div className={styles.menu}>
|
|
<Button
|
|
variant="icon"
|
|
onClick={handleModifyStay}
|
|
intent="text"
|
|
className={styles.button}
|
|
disabled={!isDateModifyable}
|
|
>
|
|
{intl.formatMessage({
|
|
defaultMessage: "Modify dates",
|
|
})}
|
|
<MaterialIcon icon="calendar_month" color="CurrentColor" />
|
|
</Button>
|
|
|
|
<Button
|
|
variant="icon"
|
|
onClick={handleGuaranteeLateArrival}
|
|
intent="text"
|
|
className={styles.button}
|
|
disabled={!isGuaranteeable}
|
|
>
|
|
{intl.formatMessage({
|
|
defaultMessage: "Guarantee late arrival",
|
|
})}
|
|
<MaterialIcon icon="credit_card" color="CurrentColor" />
|
|
</Button>
|
|
|
|
<AddToCalendar
|
|
checkInDate={checkInDate}
|
|
event={calendarEvent}
|
|
hotelName={hotel.name}
|
|
renderButton={(onPress) => (
|
|
<AddToCalendarButton
|
|
onPress={onPress}
|
|
disabled={datetimeIsInThePast}
|
|
/>
|
|
)}
|
|
/>
|
|
{canDownloadInvoice ? (
|
|
<Link
|
|
href={preliminaryReceipt[lang]}
|
|
target="_blank"
|
|
keepSearchParams
|
|
className={styles.actionLink}
|
|
onClick={handleDownloadInvoice}
|
|
>
|
|
{intl.formatMessage({
|
|
defaultMessage: "Download invoice",
|
|
})}
|
|
<MaterialIcon icon="download" color="CurrentColor" />
|
|
</Link>
|
|
) : (
|
|
<div className={styles.disabledLink}>
|
|
<Typography variant="Body/Paragraph/mdBold">
|
|
<p>
|
|
{intl.formatMessage({
|
|
defaultMessage: "Download invoice",
|
|
})}
|
|
</p>
|
|
</Typography>
|
|
|
|
<MaterialIcon icon="download" color="CurrentColor" />
|
|
</div>
|
|
)}
|
|
|
|
<Button
|
|
variant="icon"
|
|
onClick={handleCancelStay}
|
|
intent="text"
|
|
className={styles.button}
|
|
disabled={!isCancelable}
|
|
>
|
|
{intl.formatMessage({
|
|
defaultMessage: "Cancel stay",
|
|
})}
|
|
<MaterialIcon icon="cancel" color="CurrentColor" />
|
|
</Button>
|
|
</div>
|
|
<div className={styles.info}>
|
|
<div>
|
|
<span className={styles.tag}>
|
|
{intl.formatMessage({
|
|
defaultMessage: "Reference number",
|
|
})}
|
|
</span>
|
|
<Subtitle color="burgundy" textAlign="right">
|
|
{confirmationNumber}
|
|
</Subtitle>
|
|
</div>
|
|
<div>
|
|
<Body color="uiTextHighContrast" textAlign="right">
|
|
{hotel.name}
|
|
</Body>
|
|
<Body color="uiTextHighContrast" textAlign="right">
|
|
{hotel.address.streetAddress}
|
|
</Body>
|
|
<Body color="uiTextHighContrast" textAlign="right">
|
|
{hotel.address.city}
|
|
</Body>
|
|
<Body color="uiTextHighContrast" asChild>
|
|
<Link href={`tel:${hotel.contactInformation.phoneNumber}`}>
|
|
{hotel.contactInformation.phoneNumber}
|
|
</Link>
|
|
</Body>
|
|
</div>
|
|
<Link
|
|
href={customerService[lang]}
|
|
variant="icon"
|
|
className={styles.link}
|
|
onClick={handleCustomerSupport}
|
|
>
|
|
<Caption color="burgundy">
|
|
{intl.formatMessage({
|
|
defaultMessage: "Customer support",
|
|
})}
|
|
</Caption>
|
|
<MaterialIcon icon="chevron_right" size={20} color="CurrentColor" />
|
|
</Link>
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|