feat(SW-1648): add booking code on my stay * feat(SW-1648): add booking code on my stay Approved-by: Niclas Edenvin
194 lines
6.6 KiB
TypeScript
194 lines
6.6 KiB
TypeScript
"use client"
|
|
|
|
import { useState } from "react"
|
|
import { useIntl } from "react-intl"
|
|
|
|
import { BookingStatusEnum } from "@/constants/booking"
|
|
import { dt } from "@/lib/dt"
|
|
|
|
import { BookingCodeIcon } from "@/components/Icons"
|
|
import CrossCircleIcon from "@/components/Icons/CrossCircle"
|
|
import Button from "@/components/TempDesignSystem/Button"
|
|
import Divider from "@/components/TempDesignSystem/Divider"
|
|
import IconChip from "@/components/TempDesignSystem/IconChip"
|
|
import Link from "@/components/TempDesignSystem/Link"
|
|
import Caption from "@/components/TempDesignSystem/Text/Caption"
|
|
import Subtitle from "@/components/TempDesignSystem/Text/Subtitle"
|
|
import useLang from "@/hooks/useLang"
|
|
import { formatPrice } from "@/utils/numberFormatting"
|
|
|
|
import ManageStay from "../ManageStay"
|
|
import { useMyStayTotalPriceStore } from "../stores/myStayTotalPrice"
|
|
|
|
import styles from "./referenceCard.module.css"
|
|
|
|
import type { Hotel } from "@/types/hotel"
|
|
import type { BookingConfirmation } from "@/types/trpc/routers/booking/confirmation"
|
|
|
|
interface ReferenceCardProps {
|
|
booking: BookingConfirmation["booking"]
|
|
hotel: Hotel
|
|
}
|
|
|
|
export function ReferenceCard({ booking, hotel }: ReferenceCardProps) {
|
|
const [bookingStatus, setBookingStatus] = useState(booking.reservationStatus)
|
|
const intl = useIntl()
|
|
const lang = useLang()
|
|
const { totalPrice, currencyCode } = useMyStayTotalPriceStore()
|
|
|
|
const fromDate = dt(booking.checkInDate).locale(lang)
|
|
const toDate = dt(booking.checkOutDate).locale(lang)
|
|
|
|
const isCancelled = bookingStatus === BookingStatusEnum.Cancelled
|
|
|
|
const showCancelButton = !isCancelled && booking.isCancelable
|
|
|
|
const directionsUrl = `https://www.google.com/maps/dir/?api=1&destination=${hotel.location.latitude},${hotel.location.longitude}`
|
|
|
|
const adults =
|
|
booking.adults +
|
|
(booking.linkedReservations?.reduce(
|
|
(acc, linkedReservation) => acc + linkedReservation.adults,
|
|
0
|
|
) ?? 0)
|
|
const children =
|
|
booking.childrenAges.length +
|
|
(booking.linkedReservations?.reduce(
|
|
(acc, linkedReservation) => acc + linkedReservation.children,
|
|
0
|
|
) ?? 0)
|
|
|
|
return (
|
|
<div className={styles.referenceCard}>
|
|
<div className={styles.referenceRow}>
|
|
<Subtitle color="uiTextHighContrast" className={styles.titleMobile}>
|
|
{intl.formatMessage({ id: "Reference" })}
|
|
</Subtitle>
|
|
<Subtitle color="uiTextHighContrast" className={styles.titleDesktop}>
|
|
{isCancelled
|
|
? intl.formatMessage({ id: "Cancellation number" })
|
|
: intl.formatMessage({ id: "Reference number" })}
|
|
</Subtitle>
|
|
<Subtitle color="uiTextHighContrast">
|
|
{isCancelled
|
|
? booking.cancellationNumber
|
|
: booking.confirmationNumber}
|
|
</Subtitle>
|
|
</div>
|
|
<Divider color="primaryLightSubtle" className={styles.divider} />
|
|
<div className={styles.referenceRow}>
|
|
<Caption
|
|
textTransform="uppercase"
|
|
type="bold"
|
|
color="uiTextHighContrast"
|
|
>
|
|
{intl.formatMessage({ id: "Guests" })}
|
|
</Caption>
|
|
<Caption type="bold" color="uiTextHighContrast">
|
|
{children > 0
|
|
? intl.formatMessage(
|
|
{ id: "{adults} adults, {children} children" },
|
|
{
|
|
adults: adults,
|
|
children: children,
|
|
}
|
|
)
|
|
: intl.formatMessage(
|
|
{ id: "{adults} adults" },
|
|
{
|
|
adults: adults,
|
|
}
|
|
)}
|
|
</Caption>
|
|
</div>
|
|
<div className={styles.referenceRow}>
|
|
<Caption
|
|
textTransform="uppercase"
|
|
type="bold"
|
|
color="uiTextHighContrast"
|
|
>
|
|
{intl.formatMessage({ id: "Check-in" })}
|
|
</Caption>
|
|
<Caption type="bold" color="uiTextHighContrast">
|
|
{`${fromDate.format("dddd, D MMMM")} ${intl.formatMessage({ id: "from" })} ${fromDate.format("HH:mm")}`}
|
|
</Caption>
|
|
</div>
|
|
<div className={styles.referenceRow}>
|
|
<Caption
|
|
textTransform="uppercase"
|
|
type="bold"
|
|
color="uiTextHighContrast"
|
|
>
|
|
{intl.formatMessage({ id: "Check-out" })}
|
|
</Caption>
|
|
<Caption type="bold" color="uiTextHighContrast">
|
|
{`${toDate.format("dddd, D MMMM")} ${intl.formatMessage({ id: "from" })} ${toDate.format("HH:mm")}`}
|
|
</Caption>
|
|
</div>
|
|
<Divider color="primaryLightSubtle" className={styles.divider} />
|
|
<div className={styles.referenceRow}>
|
|
<Caption
|
|
textTransform="uppercase"
|
|
type="bold"
|
|
color="uiTextHighContrast"
|
|
>
|
|
{intl.formatMessage({ id: "Total paid" })}
|
|
</Caption>
|
|
<Caption type="bold" color="uiTextHighContrast">
|
|
{formatPrice(intl, totalPrice, currencyCode)}
|
|
</Caption>
|
|
</div>
|
|
{booking?.bookingCode && (
|
|
<div className={styles.referenceRow}>
|
|
<Caption>{intl.formatMessage({ id: "Booking code" })}</Caption>
|
|
<IconChip color={"blue"} icon={<BookingCodeIcon color="blue" />}>
|
|
<Caption className={styles.bookingCode} color="blue">
|
|
<strong>{intl.formatMessage({ id: "Booking code" })}</strong>
|
|
{booking.bookingCode}
|
|
</Caption>
|
|
</IconChip>
|
|
</div>
|
|
)}
|
|
{!showCancelButton && (
|
|
<div className={styles.referenceRow}>
|
|
<IconChip
|
|
color={"red"}
|
|
icon={<CrossCircleIcon width={20} height={20} color="red" />}
|
|
>
|
|
<Caption color={"red"}>
|
|
<strong>{intl.formatMessage({ id: "Status" })}:</strong>{" "}
|
|
{intl.formatMessage({ id: "Cancelled" })}
|
|
</Caption>
|
|
</IconChip>
|
|
</div>
|
|
)}
|
|
<div className={styles.actionArea}>
|
|
<ManageStay
|
|
booking={booking}
|
|
hotel={hotel}
|
|
setBookingStatus={setBookingStatus}
|
|
bookingStatus={bookingStatus}
|
|
/>
|
|
<Button fullWidth intent="secondary" asChild>
|
|
<Link href={directionsUrl} target="_blank">
|
|
{intl.formatMessage({ id: "Get directions" })}
|
|
</Link>
|
|
</Button>
|
|
</div>
|
|
{booking.isModifiable && (
|
|
<Caption className={styles.note} color="uiTextHighContrast">
|
|
{intl.formatMessage(
|
|
{
|
|
id: "Changes can be made until {time} on {date}, subject to availability. Room rates may vary.",
|
|
},
|
|
{
|
|
date: fromDate.format("D MMMM"),
|
|
time: "18:00",
|
|
}
|
|
)}
|
|
</Caption>
|
|
)}
|
|
</div>
|
|
)
|
|
}
|