fix: add hotel header to enter details flow

This commit is contained in:
Christel Westerberg
2024-11-27 13:23:36 +01:00
parent 6f8092d6ec
commit f5990998db
9 changed files with 128 additions and 95 deletions

View File

@@ -13,8 +13,8 @@ import {
import BedType from "@/components/HotelReservation/EnterDetails/BedType"
import Breakfast from "@/components/HotelReservation/EnterDetails/Breakfast"
import Details from "@/components/HotelReservation/EnterDetails/Details"
import HotelHeader from "@/components/HotelReservation/EnterDetails/Header"
import HistoryStateManager from "@/components/HotelReservation/EnterDetails/HistoryStateManager"
import HotelHeader from "@/components/HotelReservation/EnterDetails/HotelHeader"
import Payment from "@/components/HotelReservation/EnterDetails/Payment"
import SectionAccordion from "@/components/HotelReservation/EnterDetails/SectionAccordion"
import SelectedRoom from "@/components/HotelReservation/EnterDetails/SelectedRoom"
@@ -91,13 +91,13 @@ export default async function StepPage({
const packages = packageCodes
? await getPackages({
adults,
children: children?.length,
endDate: toDate,
hotelId,
packageCodes,
startDate: fromDate,
})
adults,
children: children?.length,
endDate: toDate,
hotelId,
packageCodes,
startDate: fromDate,
})
: null
const roomAvailability = await getSelectedRoomAvailability(
@@ -138,9 +138,9 @@ export default async function StepPage({
const memberPrice = roomAvailability.memberRate
? {
price: roomAvailability.memberRate.localPrice.pricePerStay,
currency: roomAvailability.memberRate.localPrice.currency,
}
price: roomAvailability.memberRate.localPrice.pricePerStay,
currency: roomAvailability.memberRate.localPrice.currency,
}
: undefined
return (
@@ -158,7 +158,7 @@ export default async function StepPage({
user={user}
>
<main>
<HotelHeader hotel={hotelData.data.attributes} />
<HotelHeader hotelData={hotelData} />
<div className={styles.container}>
<div className={styles.content}>
<section>

View File

@@ -0,0 +1,32 @@
"use client"
import { useIntl } from "react-intl"
import useSidePeekStore from "@/stores/sidepeek"
import ChevronRight from "@/components/Icons/ChevronRight"
import Button from "@/components/TempDesignSystem/Button"
import styles from "./header.module.css"
import { SidePeekEnum } from "@/types/components/hotelReservation/sidePeek"
import { ToggleSidePeekProps } from "@/types/components/hotelReservation/toggleSidePeekProps"
export default function ToggleSidePeek({ hotelId }: ToggleSidePeekProps) {
const intl = useIntl()
const openSidePeek = useSidePeekStore((state) => state.openSidePeek)
return (
<Button
onClick={() => openSidePeek({ key: SidePeekEnum.hotelDetails, hotelId })}
theme="base"
size="small"
variant="icon"
intent="textInverted"
wrapping
className={styles.toggle}
>
{intl.formatMessage({ id: "See hotel details" })}
<ChevronRight height="14" color="white" />
</Button>
)
}

View File

@@ -0,0 +1,53 @@
.header {
position: relative;
overflow: hidden;
}
.hero {
position: absolute;
top: 0;
left: 0;
right: 0;
height: 100%;
width: 100%;
object-fit: cover;
}
.wrapper {
position: relative;
padding: var(--Spacing-x3) var(--Spacing-x2);
background-color: rgba(57, 57, 57, 0.5);
display: flex;
flex-direction: column;
justify-content: center;
align-items: flex-start;
gap: var(--Spacing-x2);
}
.titleContainer {
display: flex;
flex-direction: column;
gap: var(--Spacing-x-half);
}
.address {
display: flex;
gap: var(--Spacing-x-one-and-half);
font-style: normal;
}
.toggle {
padding: 0px !important;
}
@media (min-width: 768px) {
.wrapper {
padding: var(--Spacing-x3) var(--Spacing-x3);
}
}
@media screen and (min-width: 1367px) {
.wrapper {
padding: var(--Spacing-x6) var(--Spacing-x5);
}
}

View File

@@ -1,31 +1,40 @@
import Divider from "@/components/TempDesignSystem/Divider"
import Body from "@/components/TempDesignSystem/Text/Body"
import Image from "@/components/Image"
import Caption from "@/components/TempDesignSystem/Text/Caption"
import Title from "@/components/TempDesignSystem/Text/Title"
import { getIntl } from "@/i18n"
import getSingleDecimal from "@/utils/numberFormatting"
import ToggleSidePeek from "./ToggleSidePeek"
import styles from "./header.module.css"
import type { HotelHeaderProps } from "@/types/components/hotelReservation/enterDetails/hotelHeader"
export default async function HotelHeader({ hotel }: HotelHeaderProps) {
export default async function HotelHeader({ hotelData }: HotelHeaderProps) {
const intl = await getIntl()
const hotel = hotelData.data.attributes
const image = hotel.hotelContent?.images
return (
<header className={styles.header}>
<Image
className={styles.hero}
alt={image.metaData.altText || image.metaData.altText_En || ""}
src={image.imageSizes.large}
height={200}
width={1196}
/>
<div className={styles.wrapper}>
<div className={styles.titleContainer}>
<Title as="h3" level="h1">
<Title as="h1" level="h1" color="white">
{hotel.name}
</Title>
<address className={styles.address}>
<Caption color="textMediumContrast">
<Caption color="white">
{hotel.address.streetAddress}, {hotel.address.city}
</Caption>
<div>
<Divider variant="vertical" color="subtle" />
</div>
<Caption color="textMediumContrast">
<Caption color="white"></Caption>
<Caption color="white">
{intl.formatMessage(
{ id: "Distance in km to city centre" },
{
@@ -37,14 +46,7 @@ export default async function HotelHeader({ hotel }: HotelHeaderProps) {
</Caption>
</address>
</div>
<div className={styles.dividerContainer}>
<Divider variant="vertical" color="subtle" />
</div>
<div className={styles.descriptionContainer}>
<Body color="baseTextHighContrast">
{hotel.hotelContent.texts.descriptions.short}
</Body>
</div>
<ToggleSidePeek hotelId={hotel.operaId} />
</div>
</header>
)

View File

@@ -1,64 +0,0 @@
.header {
background-color: var(--Base-Surface-Subtle-Normal);
padding: var(--Spacing-x3) var(--Spacing-x2);
}
.wrapper {
display: flex;
flex-direction: column;
gap: var(--Spacing-x3);
justify-content: center;
}
.titleContainer {
display: flex;
flex-direction: column;
align-items: flex-start;
justify-content: center;
gap: var(--Spacing-x1);
}
.descriptionContainer {
display: flex;
flex-direction: column;
gap: var(--Spacing-x-one-and-half);
}
.address {
display: flex;
gap: var(--Spacing-x-one-and-half);
font-style: normal;
}
.dividerContainer {
display: none;
}
@media (min-width: 768px) {
.header {
padding: var(--Spacing-x4) 0;
}
.wrapper {
flex-direction: row;
gap: var(--Spacing-x6);
margin: 0 auto;
/* simulates padding on viewport smaller than --max-width-navigation */
width: min(
calc(100dvw - (var(--Spacing-x2) * 2)),
var(--max-width-navigation)
);
}
.titleContainer > h1 {
white-space: nowrap;
}
.dividerContainer {
display: block;
}
.address {
gap: var(--Spacing-x3);
}
}

View File

@@ -265,6 +265,10 @@ a.default {
color: var(--Base-Button-Text-On-Fill-Normal);
}
.baseTextInverted {
color: var(--Base-Button-Primary-On-Fill-Normal);
}
.baseText:active,
.baseText:focus,
.baseText:hover {

View File

@@ -10,6 +10,7 @@ export const buttonVariants = cva(styles.btn, {
secondary: styles.secondary,
tertiary: styles.tertiary,
text: styles.text,
textInverted: styles.text,
},
size: {
small: styles.small,
@@ -140,5 +141,10 @@ export const buttonVariants = cva(styles.btn, {
intent: "text",
theme: "base",
},
{
className: styles.baseTextInverted,
intent: "textInverted",
theme: "base",
},
],
})

View File

@@ -3,5 +3,5 @@ import type { RouterOutput } from "@/lib/trpc/client"
type HotelDataGet = RouterOutput["hotel"]["hotelData"]["get"]
export interface HotelHeaderProps {
hotel: NonNullable<HotelDataGet>["data"]["attributes"]
hotelData: NonNullable<HotelDataGet>
}

View File

@@ -1,4 +1,4 @@
export type ToggleSidePeekProps = {
hotelId: string
roomTypeCode: string
roomTypeCode?: string
}