Merged in feat/LOY-421-Next-Stay (pull request #3026)

Feat(LOY-421): Next Stay

* feat(LOY-421): Next stay WIP

* fix(LOY-421): clean upp css and jsx

* chore(LOY-421): css cleanup

* fix(LOY-421): fix test

* only show button if isWebAppOrigin is true

* chore(LOY-421): update section header component

* chore(LOY-421): remove redundant test case


Approved-by: Matilda Landström
This commit is contained in:
Chuma Mcphoy (We Ahead)
2025-11-05 09:09:57 +00:00
parent 3a38e99a71
commit 94f6af563d
9 changed files with 678 additions and 0 deletions

View File

@@ -0,0 +1,153 @@
import { dt } from "@scandic-hotels/common/dt"
import ButtonLink from "@scandic-hotels/design-system/ButtonLink"
import { Divider } from "@scandic-hotels/design-system/Divider"
import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon"
import Image from "@scandic-hotels/design-system/Image"
import { Typography } from "@scandic-hotels/design-system/Typography"
import { getIntl } from "@/i18n"
import { getLang } from "@/i18n/serverContext"
import { getDaysUntilText } from "./utils"
import styles from "./nextStay.module.css"
import type { Stay } from "@scandic-hotels/trpc/routers/user/output"
interface NextStayContentProps {
nextStay: Stay
}
export default async function NextStayContent({
nextStay,
}: NextStayContentProps) {
const lang = await getLang()
const intl = await getIntl()
const { attributes } = nextStay
const {
checkinDate,
checkoutDate,
confirmationNumber,
hotelInformation,
isWebAppOrigin,
bookingUrl,
} = attributes
const daysUntilText = getDaysUntilText(checkinDate, lang, intl)
return (
<article className={styles.nextStayCard}>
<div className={styles.imageContainer}>
<Image
className={styles.image}
alt={
hotelInformation.hotelContent.images.altText ||
hotelInformation.hotelContent.images.altText_En ||
hotelInformation.hotelName
}
src={hotelInformation.hotelContent.images.src}
width={600}
height={338}
priority
/>
<div className={styles.imageOverlay}>
<Typography variant="Title/Decorative/lg">
<span className={styles.overlayText}>
{intl.formatMessage({
id: "nextStay.myStayAt",
defaultMessage: "My Stay at",
})}
</span>
</Typography>
<Typography variant="Title/lg">
<span className={styles.overlayText}>
{hotelInformation.hotelName}
</span>
</Typography>
</div>
</div>
<div className={styles.content}>
<div className={styles.header}>
<Typography variant="Title/sm">
<span className={styles.daysUntil}>
<MaterialIcon
className={styles.daysUntilIcon}
icon="calendar_clock"
color="Icon/Interactive/Default"
/>
{daysUntilText}
</span>
</Typography>
<Typography variant="Title/Subtitle/lg">
<p className={styles.address}>
<MaterialIcon
icon="location_on"
color="Icon/Interactive/Default"
className={styles.addressIcon}
/>
{hotelInformation.cityName}
</p>
</Typography>
</div>
<div className={styles.booking}>
<div className={styles.bookingInfo}>
<Typography variant="Body/Paragraph/mdRegular">
<p>
{intl.formatMessage({
id: "common.bookingNumber",
defaultMessage: "Booking number",
})}
</p>
</Typography>
<Typography variant="Title/Subtitle/md">
<p>{confirmationNumber}</p>
</Typography>
</div>
<Divider variant="horizontal" color="Border/Divider/Default" />
<div className={styles.bookingInfo}>
<Typography variant="Body/Paragraph/mdRegular">
<span>
<MaterialIcon icon="calendar_month" color="Icon/Default" />
{intl.formatMessage({
id: "common.dates",
defaultMessage: "Dates",
})}
</span>
</Typography>
<Typography variant="Body/Paragraph/mdRegular">
<span className={styles.fromToDates}>
<time>{dt(checkinDate).locale(lang).format("D MMM YYYY")}</time>
{/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}
{"→"}
<time>
{dt(checkoutDate).locale(lang).format("D MMM YYYY")}
</time>
</span>
</Typography>
</div>
</div>
{isWebAppOrigin ? (
<div className={styles.actions}>
<ButtonLink
variant="Tertiary"
color="Inverted"
size="Medium"
href={bookingUrl}
>
{intl.formatMessage({
id: "nextStay.seeDetailsAndExtras",
defaultMessage: "See details & extras",
})}
</ButtonLink>
</div>
) : null}
</div>
</article>
)
}