Merged in feat(SW-1275)-cancel-booking-my-stay (pull request #1376)

Feat(SW-1275) cancel booking my stay

* feat(SW-1276) UI implementation Desktop part 1 for MyStay

* feat(SW-1276) UI implementation Desktop part 2 for MyStay

* feat(SW-1276) UI implementation Mobile part 1 for MyStay

* refactor: move files from MyStay/MyStay to MyStay

* feat(SW-1276) Sidepeek implementation

* feat(SW-1276): Refactoring

* feat(SW-1276) UI implementation Mobile part 2 for MyStay

* feat(SW-1276): translations

* feat(SW-1276) fixed skeleton

* feat(SW-1276): Added missing translations

* feat(SW-1276) fixed translations

* feat(SW-1275) cancel modal

* feat(SW-1275): Mutate cancel booking

* feat(SW-1275) added translations

* feat(SW-1275) match current cancellationReason

* feat(SW-1275) Added modal for manage stay

* feat(SW-1275) Added missing icon

* feat(SW-1275) New Dont cancel button

* feat(SW-1275) Added preperation for Cancellation number

* feat(SW-1275): added --modal-box-shadow

* feat(SW-1718) Add to calendar

* feat(SW-1718) general add to calendar


Approved-by: Niclas Edenvin
This commit is contained in:
Pontus Dreij
2025-02-21 09:06:15 +00:00
parent 8ed521de3f
commit a0286603db
45 changed files with 1358 additions and 104 deletions

View File

@@ -1,32 +1,46 @@
"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 { getIntl } from "@/i18n"
import { getLang } from "@/i18n/serverContext"
import useLang from "@/hooks/useLang"
import { formatPrice } from "@/utils/numberFormatting"
import ManageStay from "../ManageStay"
import styles from "./referenceCard.module.css"
import type { Hotel } from "@/types/hotel"
import type { BookingConfirmation } from "@/types/trpc/routers/booking/confirmation"
export async function ReferenceCard({
export function ReferenceCard({
booking,
hotel,
}: {
booking: BookingConfirmation["booking"]
hotel: Hotel
}) {
const intl = await getIntl()
const lang = getLang()
const [bookingStatus, setBookingStatus] = useState(booking.reservationStatus)
const intl = useIntl()
const lang = useLang()
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}`
return (
@@ -36,10 +50,15 @@ export async function ReferenceCard({
{intl.formatMessage({ id: "Reference" })}
</Subtitle>
<Subtitle color="uiTextHighContrast" className={styles.titleDesktop}>
{intl.formatMessage({ id: "Reference number" })}
{isCancelled
? intl.formatMessage({ id: "Cancellation number" })
: intl.formatMessage({ id: "Reference number" })}
</Subtitle>
<Subtitle color="uiTextHighContrast">
{booking.confirmationNumber}
{/* TODO: Implement this: https://scandichotels.atlassian.net/browse/API2-2883 to get correct cancellation number */}
{isCancelled
? booking.linkedReservations[0]?.cancellationNumber
: booking.confirmationNumber}
</Subtitle>
</div>
<Divider color="primaryLightSubtle" className={styles.divider} />
@@ -105,8 +124,26 @@ export async function ReferenceCard({
{formatPrice(intl, booking.totalPrice, booking.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}>
<Button fullWidth>{intl.formatMessage({ id: "Manage stay" })}</Button>
<ManageStay
booking={booking}
hotel={hotel}
setBookingStatus={setBookingStatus}
bookingStatus={bookingStatus}
/>
<Button fullWidth intent="secondary" asChild>
<Link href={directionsUrl} target="_blank">
{intl.formatMessage({ id: "Get directions" })}