fix: make summary sticky
This commit is contained in:
@@ -14,7 +14,10 @@ export default async function HotelHeader({
|
||||
if (!searchParams.hotel) {
|
||||
redirect(home)
|
||||
}
|
||||
const hotel = await getHotelData(searchParams.hotel, params.lang)
|
||||
const hotel = await getHotelData({
|
||||
hotelId: searchParams.hotel,
|
||||
language: params.lang,
|
||||
})
|
||||
if (!hotel?.data) {
|
||||
redirect(home)
|
||||
}
|
||||
|
||||
@@ -13,7 +13,10 @@ export default async function HotelSidePeek({
|
||||
if (!searchParams.hotel) {
|
||||
redirect(`/${params.lang}`)
|
||||
}
|
||||
const hotel = await getHotelData(searchParams.hotel, params.lang)
|
||||
const hotel = await getHotelData({
|
||||
hotelId: searchParams.hotel,
|
||||
language: params.lang,
|
||||
})
|
||||
if (!hotel?.data) {
|
||||
redirect(`/${params.lang}`)
|
||||
}
|
||||
|
||||
@@ -20,23 +20,31 @@ export default async function SummaryPage({
|
||||
const { hotel, adults, children, roomTypeCode, rateCode, fromDate, toDate } =
|
||||
getQueryParamsForEnterDetails(selectRoomParams)
|
||||
|
||||
const user = await getProfileSafely()
|
||||
const hotelData = await getHotelData(hotel, params.lang, undefined, [HotelIncludeEnum.RoomCategories])
|
||||
const availability = await getRoomAvailability({
|
||||
hotelId: parseInt(hotel),
|
||||
adults,
|
||||
children,
|
||||
roomStayStartDate: fromDate,
|
||||
roomStayEndDate: toDate,
|
||||
})
|
||||
const [user, hotelData, availability] = await Promise.all([
|
||||
getProfileSafely(),
|
||||
getHotelData({
|
||||
hotelId: hotel,
|
||||
language: params.lang,
|
||||
include: [HotelIncludeEnum.RoomCategories],
|
||||
}),
|
||||
getRoomAvailability({
|
||||
hotelId: parseInt(hotel),
|
||||
adults,
|
||||
children,
|
||||
roomStayStartDate: fromDate,
|
||||
roomStayEndDate: toDate,
|
||||
}),
|
||||
])
|
||||
|
||||
if (!hotelData?.data || !hotelData?.included || !availability) {
|
||||
console.error("No hotel or availability data", hotelData, availability)
|
||||
|
||||
// TODO: handle this case
|
||||
return null
|
||||
}
|
||||
|
||||
const cancellationText =
|
||||
availability?.rateDefinitions.find((rate) => rate.rateCode === rateCode)
|
||||
?.cancellationText ?? ""
|
||||
const chosenRoom = availability.roomConfigurations.find(
|
||||
(availRoom) => availRoom.roomTypeCode === roomTypeCode
|
||||
)
|
||||
@@ -47,28 +55,31 @@ export default async function SummaryPage({
|
||||
return null
|
||||
}
|
||||
|
||||
const cancellationText =
|
||||
availability?.rateDefinitions.find((rate) => rate.rateCode === rateCode)
|
||||
?.cancellationText ?? ""
|
||||
const memberRate = chosenRoom.products.find(
|
||||
(rate) => rate.productType.member?.rateCode === rateCode
|
||||
)?.productType.member
|
||||
|
||||
const memberPrice =
|
||||
chosenRoom.products.find(
|
||||
(rate) => rate.productType.member?.rateCode === rateCode
|
||||
)?.productType.member?.localPrice.pricePerStay ?? "0"
|
||||
const publicRate = chosenRoom.products.find(
|
||||
(rate) => rate.productType.public?.rateCode === rateCode
|
||||
)?.productType.public
|
||||
|
||||
const publicPrice =
|
||||
chosenRoom.products.find(
|
||||
(rate) => rate.productType.public?.rateCode === rateCode
|
||||
)?.productType.public?.localPrice.pricePerStay ?? "0"
|
||||
|
||||
const price = user ? memberPrice : publicPrice
|
||||
const prices = user
|
||||
? {
|
||||
local: memberRate?.localPrice.pricePerStay,
|
||||
euro: memberRate?.requestedPrice?.pricePerStay,
|
||||
}
|
||||
: {
|
||||
local: publicRate?.localPrice.pricePerStay,
|
||||
euro: publicRate?.requestedPrice?.pricePerStay,
|
||||
}
|
||||
|
||||
return (
|
||||
<Summary
|
||||
isMember={!!user}
|
||||
room={{
|
||||
roomType: chosenRoom.roomType,
|
||||
price: formatNumber(parseInt(price)),
|
||||
localPrice: formatNumber(parseInt(prices.local ?? "0")),
|
||||
euroPrice: formatNumber(parseInt(prices.euro ?? "0")),
|
||||
adults,
|
||||
cancellationText,
|
||||
}}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
.layout {
|
||||
min-height: 100dvh;
|
||||
background-color: var(--Scandic-Brand-Warm-White);
|
||||
}
|
||||
|
||||
@@ -9,7 +8,6 @@
|
||||
grid-template-columns: 1fr 340px;
|
||||
grid-template-rows: auto 1fr;
|
||||
margin: var(--Spacing-x5) auto 0;
|
||||
padding-top: var(--Spacing-x6);
|
||||
/* simulates padding on viewport smaller than --max-width-navigation */
|
||||
width: min(
|
||||
calc(100dvw - (var(--Spacing-x2) * 2)),
|
||||
@@ -17,8 +15,81 @@
|
||||
);
|
||||
}
|
||||
|
||||
.summary {
|
||||
align-self: flex-start;
|
||||
.summaryContainer {
|
||||
grid-column: 2 / 3;
|
||||
grid-row: 1/-1;
|
||||
}
|
||||
|
||||
.summary {
|
||||
background-color: var(--Main-Grey-White);
|
||||
|
||||
border-color: var(--Primary-Light-On-Surface-Divider-subtle);
|
||||
border-style: solid;
|
||||
border-width: 1px;
|
||||
border-radius: var(--Corner-radius-Large);
|
||||
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.hider {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.shadow {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@media screen and (min-width: 950px) {
|
||||
.summaryContainer {
|
||||
display: grid;
|
||||
grid-template-rows: auto auto 1fr;
|
||||
margin-top: calc(0px - var(--Spacing-x9));
|
||||
}
|
||||
|
||||
.summary {
|
||||
position: sticky;
|
||||
top: calc(
|
||||
var(--booking-widget-desktop-height) +
|
||||
var(--booking-widget-desktop-height) + var(--Spacing-x-one-and-half)
|
||||
);
|
||||
margin-top: calc(0px - var(--Spacing-x9));
|
||||
border-bottom: none;
|
||||
border-radius: var(--Corner-radius-Large) var(--Corner-radius-Large) 0 0;
|
||||
}
|
||||
|
||||
.hider {
|
||||
display: block;
|
||||
background-color: var(--Scandic-Brand-Warm-White);
|
||||
position: sticky;
|
||||
margin-top: var(--Spacing-x4);
|
||||
top: calc(
|
||||
var(--booking-widget-desktop-height) +
|
||||
var(--booking-widget-desktop-height) - 6px
|
||||
);
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
.shadow {
|
||||
display: block;
|
||||
background-color: var(--Main-Grey-White);
|
||||
border-color: var(--Primary-Light-On-Surface-Divider-subtle);
|
||||
border-style: solid;
|
||||
border-left-width: 1px;
|
||||
border-right-width: 1px;
|
||||
border-top: none;
|
||||
border-bottom: none;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (min-width: 1367px) {
|
||||
.summary {
|
||||
top: calc(
|
||||
var(--booking-widget-desktop-height) + var(--Spacing-x2) +
|
||||
var(--Spacing-x-half)
|
||||
);
|
||||
}
|
||||
|
||||
.hider {
|
||||
top: calc(var(--booking-widget-desktop-height) - 6px);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,7 +30,11 @@ export default async function StepLayout({
|
||||
<div className={styles.content}>
|
||||
<SelectedRoom />
|
||||
{children}
|
||||
<aside className={styles.summary}>{summary}</aside>
|
||||
<aside className={styles.summaryContainer}>
|
||||
<div className={styles.hider} />
|
||||
<div className={styles.summary}>{summary}</div>
|
||||
<div className={styles.shadow} />
|
||||
</aside>
|
||||
</div>
|
||||
{sidePeek}
|
||||
</main>
|
||||
|
||||
@@ -20,7 +20,7 @@ import { getIntl } from "@/i18n"
|
||||
|
||||
import { StepEnum } from "@/types/components/hotelReservation/enterDetails/step"
|
||||
import { SelectRateSearchParams } from "@/types/components/hotelReservation/selectRate/selectRate"
|
||||
import type { LangParams, PageArgs, } from "@/types/params"
|
||||
import type { LangParams, PageArgs } from "@/types/params"
|
||||
|
||||
export function preload() {
|
||||
void getProfileSafely()
|
||||
@@ -34,12 +34,10 @@ function isValidStep(step: string): step is StepEnum {
|
||||
export default async function StepPage({
|
||||
params,
|
||||
searchParams,
|
||||
}: PageArgs<
|
||||
LangParams & { step: StepEnum },
|
||||
SelectRateSearchParams
|
||||
>) {
|
||||
}: PageArgs<LangParams & { step: StepEnum }, SelectRateSearchParams>) {
|
||||
const { lang } = params
|
||||
if (!searchParams.hotel) {
|
||||
redirect(`/${params.lang}`)
|
||||
redirect(`/${lang}`)
|
||||
}
|
||||
void getBreakfastPackages(searchParams.hotel)
|
||||
|
||||
@@ -64,7 +62,11 @@ export default async function StepPage({
|
||||
rateCode
|
||||
})
|
||||
|
||||
const hotelData = await getHotelData(hotelId, params.lang, undefined, [HotelIncludeEnum.RoomCategories])
|
||||
const hotelData = await getHotelData({
|
||||
hotelId,
|
||||
language: lang,
|
||||
include: [HotelIncludeEnum.RoomCategories],
|
||||
})
|
||||
|
||||
const user = await getProfileSafely()
|
||||
const savedCreditCards = await getCreditCardsSafely()
|
||||
@@ -153,6 +155,6 @@ export default async function StepPage({
|
||||
mustBeGuaranteed={mustBeGuaranteed}
|
||||
/>
|
||||
</SectionAccordion>
|
||||
</section >
|
||||
</section>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
.layout {
|
||||
min-height: 100dvh;
|
||||
background-color: var(--Base-Background-Primary-Normal);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user