Files
web/apps/scandic-web/components/HotelReservation/MyStay/ManageStay/ActionPanel/index.tsx

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>
)
}