Merged in feat/SW-1652-confirmation-page-multiroom (pull request #1404)

feat(SW-1652): Fetching additional rooms on confirmation page

* feat(SW-1652): Fetching additional rooms on confirmation page


Approved-by: Tobias Johansson
This commit is contained in:
Arvid Norlin
2025-02-26 12:42:54 +00:00
parent a15936688b
commit d5e5b9a526
24 changed files with 606 additions and 425 deletions

View File

@@ -0,0 +1,33 @@
import SkeletonShimmer from "@/components/SkeletonShimmer"
import styles from "./linkedReservationCardSkeleton.module.css"
export function LinkedReservationCardSkeleton() {
return (
<div className={styles.card}>
<div className={styles.content}>
<div className={styles.img}>
<SkeletonShimmer height={"204px"} width={"100%"} />
</div>
<div className={styles.roomDetails}>
<div className={styles.roomName}>
<SkeletonShimmer height={"24px"} width={"130px"} />
<SkeletonShimmer height={"20px"} width={"140px"} />
</div>
<div className={styles.details}>
<SkeletonShimmer height={"20px"} width={"300px"} />
<SkeletonShimmer height={"20px"} width={"300px"} />
<SkeletonShimmer height={"20px"} width={"300px"} />
<SkeletonShimmer height={"20px"} width={"300px"} />
</div>
<div className={styles.guest}>
<SkeletonShimmer height={"20px"} width={"100px"} />
<SkeletonShimmer height={"20px"} width={"200px"} />
<SkeletonShimmer height={"20px"} width={"150px"} />
<SkeletonShimmer height={"20px"} width={"300px"} />
</div>
</div>
</div>
</div>
)
}

View File

@@ -1,92 +1,22 @@
"use client "
import { useIntl } from "react-intl"
import { serverClient } from "@/lib/trpc/server"
import { dt } from "@/lib/dt"
import Room from "../Room"
import Body from "@/components/TempDesignSystem/Text/Body"
import Subtitle from "@/components/TempDesignSystem/Text/Subtitle"
import useLang from "@/hooks/useLang"
export async function LinkedReservation({
confirmationNumber,
}: {
confirmationNumber: string
}) {
const confirmation = await serverClient().booking.confirmation({
confirmationNumber,
})
import styles from "./linkedReservation.module.css"
const room = confirmation?.room
const booking = confirmation?.booking
import type { LinkedReservationSchema } from "@/types/components/hotelReservation/bookingConfirmation/rooms"
if (!booking || !room) {
return <div>Something went wrong, try again</div>
}
interface LinkedReservationProps {
linkedReservation: LinkedReservationSchema
roomIndex: number
}
export function LinkedReservation({
linkedReservation,
roomIndex,
}: LinkedReservationProps) {
const intl = useIntl()
const lang = useLang()
const { checkinDate, checkoutDate, confirmationNumber, adults, children } =
linkedReservation
const fromDate = dt(checkinDate).locale(lang)
const toDate = dt(checkoutDate).locale(lang)
return (
<div className={styles.reservation}>
<Subtitle color="uiTextHighContrast" type="two">
{intl.formatMessage(
{
id: "Room {roomIndex}",
},
{
roomIndex: roomIndex + 2,
}
)}
</Subtitle>
<ul className={styles.details}>
<li className={styles.listItem}>
<Body color="uiTextPlaceholder">
{intl.formatMessage({ id: "Booking number" })}
</Body>
<Body color="uiTextHighContrast">{confirmationNumber}</Body>
</li>
<li className={styles.listItem}>
<Body color="uiTextPlaceholder">
{intl.formatMessage({ id: "Check-in" })}
</Body>
<Body color="uiTextHighContrast">
{intl.formatMessage(
{ id: "{checkInDate} from {checkInTime}" },
{
checkInDate: fromDate.format("ddd, D MMM"),
checkInTime: fromDate.format("HH:mm"),
}
)}
</Body>
</li>
<li className={styles.listItem}>
<Body color="uiTextPlaceholder">
{intl.formatMessage({ id: "Check-out" })}
</Body>
<Body color="uiTextHighContrast">
{intl.formatMessage(
{ id: "{checkOutDate} from {checkOutTime}" },
{
checkOutDate: toDate.format("ddd, D MMM"),
checkOutTime: toDate.format("HH:mm"),
}
)}
</Body>
</li>
<li className={styles.listItem}>
<Body color="uiTextPlaceholder">
{intl.formatMessage({ id: "Adults" })}
</Body>
<Body color="uiTextHighContrast">{adults}</Body>
</li>
<li className={styles.listItem}>
<Body color="uiTextPlaceholder">
{intl.formatMessage({ id: "Children" })}
</Body>
<Body color="uiTextHighContrast">{children}</Body>
</li>
</ul>
</div>
)
return <Room booking={booking} img={room.images[0]} roomName={room.name} />
}

View File

@@ -1,19 +0,0 @@
.reservation {
background-color: var(--Base-Background-Primary-Normal);
border-radius: var(--Corner-radius-Large);
display: grid;
gap: var(--Spacing-x2);
padding: var(--Spacing-x2) var(--Spacing-x2) var(--Spacing-x3)
var(--Spacing-x2);
}
.details {
display: grid;
gap: var(--Spacing-x-half) var(--Spacing-x3);
list-style: none;
}
.listItem {
display: flex;
gap: var(--Spacing-x1);
}

View File

@@ -0,0 +1,66 @@
.card {
display: flex;
flex-direction: column;
gap: var(--Spacing-x2);
}
.content {
background-color: var(--Base-Background-Primary-Normal);
border-radius: var(--Corner-radius-Large);
display: grid;
gap: var(--Spacing-x2);
padding: var(--Spacing-x2) var(--Spacing-x2) var(--Spacing-x3)
var(--Spacing-x2);
}
.img {
border-radius: var(--Corner-radius-Medium);
overflow: hidden;
}
.roomDetails {
display: grid;
gap: var(--Spacing-x2);
}
.roomName {
display: flex;
flex-direction: column;
gap: var(--Spacing-x1);
grid-column: 1/-1;
justify-content: space-evenly;
}
.details {
display: flex;
flex-direction: column;
gap: var(--Spacing-x1);
justify-content: space-evenly;
}
.guest {
display: flex;
flex-direction: column;
gap: var(--Spacing-x1);
justify-content: space-evenly;
}
@media screen and (min-width: 1367px) {
.content {
gap: var(--Spacing-x3);
grid-template-columns: auto 1fr;
padding: var(--Spacing-x2) var(--Spacing-x3) var(--Spacing-x2)
var(--Spacing-x2);
}
.img {
min-width: 306px;
}
.roomDetails {
grid-template-columns: 1fr 1fr;
}
.guest {
align-items: flex-end;
}
}

View File

@@ -1,5 +1,6 @@
"use client"
import { Suspense } from "react"
import { LinkedReservationCardSkeleton } from "./LinkedReservation/LinkedReservationCardSkeleton"
import { LinkedReservation } from "./LinkedReservation"
import Room from "./Room"
@@ -19,12 +20,16 @@ export default function Rooms({
img={mainRoom.images[0]}
roomName={mainRoom.name}
/>
{linkedReservations?.map((reservation, idx) => (
<LinkedReservation
{linkedReservations?.map((reservation) => (
<Suspense
key={reservation.confirmationNumber}
linkedReservation={reservation}
roomIndex={idx}
/>
fallback={<LinkedReservationCardSkeleton />}
>
<LinkedReservation
confirmationNumber={reservation.confirmationNumber}
/>
</Suspense>
))}
</section>
)