Files
web/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/index.tsx
Pontus Dreij 31a536b1f7 Merged in feat(SW-1722)-mystay-multiroom-view (pull request #1396)
Feat(SW-1722) mystay multiroom view

* feat(SW-1722) View all rooms on my stay

* feat(sW-1722) Show linked reservation

* feat(SW-1722) merged monorepo

* feat(SW-1722) yarn install

* feat(SW-1722) removed unused data

* feat(SW-1722) Streaming data from the server to the client


Approved-by: Niclas Edenvin
2025-02-27 07:24:56 +00:00

181 lines
6.1 KiB
TypeScript

"use client"
import { useState } from "react"
import { useIntl } from "react-intl"
import { BookingStatusEnum } from "@/constants/booking"
import { dt } from "@/lib/dt"
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">
{/* TODO: Implement this: https://scandichotels.atlassian.net/browse/API2-2883 to get correct cancellation number */}
{isCancelled ? "" : 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">
{booking.childrenAges.length > 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>
{!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>
)
}