feat: add mobile summary

This commit is contained in:
Christel Westerberg
2024-11-07 11:26:49 +01:00
parent c8ce61c855
commit 66b2dc0c78
19 changed files with 345 additions and 116 deletions

View File

@@ -0,0 +1,68 @@
.mobileSummary {
display: block;
}
.desktopSummary {
display: none;
}
.summary {
background-color: var(--Main-Grey-White);
border-color: var(--Primary-Light-On-Surface-Divider-subtle);
border-style: solid;
border-width: 1px;
border-bottom: none;
z-index: 10;
}
.hider {
display: none;
}
.shadow {
display: none;
}
@media screen and (min-width: 1367px) {
.mobileSummary {
display: none;
}
.desktopSummary {
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(--Spacing-x2) +
var(--Spacing-x-half)
);
z-index: 10;
border-radius: var(--Corner-radius-Large) var(--Corner-radius-Large) 0 0;
margin-top: calc(0px - var(--Spacing-x9));
}
.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;
}
.hider {
display: block;
background-color: var(--Scandic-Brand-Warm-White);
position: sticky;
top: calc(var(--booking-widget-desktop-height) - 6px);
margin-top: var(--Spacing-x4);
height: 40px;
}
}

View File

@@ -4,11 +4,14 @@ import {
} from "@/lib/trpc/memoizedRequests" } from "@/lib/trpc/memoizedRequests"
import Summary from "@/components/HotelReservation/EnterDetails/Summary" import Summary from "@/components/HotelReservation/EnterDetails/Summary"
import { SummaryBottomSheet } from "@/components/HotelReservation/EnterDetails/Summary/BottomSheet"
import { import {
generateChildrenString, generateChildrenString,
getQueryParamsForEnterDetails, getQueryParamsForEnterDetails,
} from "@/components/HotelReservation/SelectRate/RoomSelection/utils" } from "@/components/HotelReservation/SelectRate/RoomSelection/utils"
import styles from "./page.module.css"
import { SelectRateSearchParams } from "@/types/components/hotelReservation/selectRate/selectRate" import { SelectRateSearchParams } from "@/types/components/hotelReservation/selectRate/selectRate"
import { LangParams, PageArgs, SearchParams } from "@/types/params" import { LangParams, PageArgs, SearchParams } from "@/types/params"
@@ -62,16 +65,41 @@ export default async function SummaryPage({
} }
return ( return (
<Summary <>
showMemberPrice={!!(user && availability.memberRate)} <div className={styles.mobileSummary}>
room={{ <SummaryBottomSheet>
roomType: availability.selectedRoom.roomType, <div className={styles.summary}>
localPrice: prices.local, <Summary
euroPrice: prices.euro, showMemberPrice={!!(user && availability.memberRate)}
adults, room={{
children, roomType: availability.selectedRoom.roomType,
cancellationText: availability.cancellationText, localPrice: prices.local,
}} euroPrice: prices.euro,
/> adults,
children,
cancellationText: availability.cancellationText,
}}
/>
</div>
</SummaryBottomSheet>
</div>
<div className={styles.desktopSummary}>
<div className={styles.hider} />
<div className={styles.summary}>
<Summary
showMemberPrice={!!(user && availability.memberRate)}
room={{
roomType: availability.selectedRoom.roomType,
localPrice: prices.local,
euroPrice: prices.euro,
adults,
children,
cancellationText: availability.cancellationText,
}}
/>
</div>
<div className={styles.shadow} />
</div>
</>
) )
} }

View File

@@ -11,8 +11,6 @@
.enter-details-layout__content { .enter-details-layout__content {
display: grid; display: grid;
gap: var(--Spacing-x3) var(--Spacing-x9); gap: var(--Spacing-x3) var(--Spacing-x9);
grid-template-columns: 1fr 340px;
grid-template-rows: auto 1fr;
margin: var(--Spacing-x5) auto 0; margin: var(--Spacing-x5) auto 0;
/* simulates padding on viewport smaller than --max-width-navigation */ /* simulates padding on viewport smaller than --max-width-navigation */
width: min( width: min(
@@ -22,80 +20,23 @@
} }
.enter-details-layout__summaryContainer { .enter-details-layout__summaryContainer {
grid-column: 2 / 3; position: fixed;
grid-row: 1/-1;
}
.enter-details-layout__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; z-index: 1;
} bottom: 0;
left: 0;
.enter-details-layout__hider { right: 0;
display: none;
}
.enter-details-layout__shadow {
display: none;
}
@media screen and (min-width: 950px) {
.enter-details-layout__summaryContainer {
display: grid;
grid-template-rows: auto auto 1fr;
margin-top: calc(0px - var(--Spacing-x9));
}
.enter-details-layout__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;
}
.enter-details-layout__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;
}
.enter-details-layout__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) { @media screen and (min-width: 1367px) {
.enter-details-layout__summary { .enter-details-layout__content {
top: calc( grid-template-columns: 1fr 340px;
var(--booking-widget-desktop-height) + var(--Spacing-x2) + grid-template-rows: auto 1fr;
var(--Spacing-x-half)
);
} }
.enter-details-layout__hider { .enter-details-layout__summaryContainer {
top: calc(var(--booking-widget-desktop-height) - 6px); position: static;
display: grid;
grid-column: 2/3;
grid-row: 1/-1;
} }
} }

View File

@@ -30,11 +30,7 @@ export default async function StepLayout({
{hotelHeader} {hotelHeader}
<div className={"enter-details-layout__content"}> <div className={"enter-details-layout__content"}>
{children} {children}
<aside className="enter-details-layout__summaryContainer"> <aside className={"enter-details-layout__summaryContainer"}>{summary}</aside>
<div className="enter-details-layout__hider" />
<div className="enter-details-layout__summary">{summary}</div>
<div className="enter-details-layout__shadow" />
</aside>
</div> </div>
</main> </main>
</EnterDetailsProvider> </EnterDetailsProvider>

View File

@@ -45,7 +45,7 @@
.iconWrapper { .iconWrapper {
position: relative; position: relative;
top: var(--Spacing-x1); top: var(--Spacing-x1);
z-index: 2; z-index: 1;
} }
.circle { .circle {

View File

@@ -38,7 +38,7 @@
.iconWrapper { .iconWrapper {
position: relative; position: relative;
top: var(--Spacing-x1); top: var(--Spacing-x1);
z-index: 2; z-index: 1;
} }
.circle { .circle {

View File

@@ -0,0 +1,49 @@
.wrapper {
display: grid;
grid-template-rows: 0fr 7.5em;
transition: 0.5s ease-in-out;
border-top: 1px solid var(--Base-Border-Subtle);
background: var(--Base-Surface-Primary-light-Normal);
align-content: end;
}
.bottomSheet {
display: grid;
grid-template-columns: 1fr auto;
padding: var(--Spacing-x2) var(--Spacing-x3) var(--Spacing-x5)
var(--Spacing-x3);
justify-content: space-between;
width: auto;
align-items: flex-start;
transition: 0.5s ease-in-out;
}
.priceDetails {
display: block;
border: none;
background: none;
text-align: start;
opacity: 1;
transition:
opacity 0.5s ease-in-out,
padding 0.5s ease-in-out;
}
.wrapper[data-open="true"] {
grid-template-rows: 1fr 7.5em;
}
.wrapper[data-open="true"] .bottomSheet {
grid-template-columns: 0fr 1fr;
}
.wrapper[data-open="true"] .priceDetails {
opacity: 0;
padding: 0;
}
.content,
.priceDetails {
overflow: hidden;
}

View File

@@ -0,0 +1,55 @@
"use client"
import { PropsWithChildren, useState } from "react"
import { useIntl } from "react-intl"
import { useEnterDetailsStore } from "@/stores/enter-details"
import Button from "@/components/TempDesignSystem/Button"
import Caption from "@/components/TempDesignSystem/Text/Caption"
import Subtitle from "@/components/TempDesignSystem/Text/Subtitle"
import { formatNumber } from "@/utils/format"
import styles from "./bottomSheet.module.css"
export function SummaryBottomSheet({ children }: PropsWithChildren) {
const intl = useIntl()
const { isSummaryOpen, toggleSummaryOpen, totalPrice } = useEnterDetailsStore(
(state) => ({
isSummaryOpen: state.isSummaryOpen,
toggleSummaryOpen: state.toggleSummaryOpen,
totalPrice: state.totalPrice,
})
)
return (
<div className={styles.wrapper} data-open={isSummaryOpen}>
<div className={styles.content}>{children}</div>
<div className={styles.bottomSheet}>
<button
data-open={isSummaryOpen}
onClick={toggleSummaryOpen}
className={styles.priceDetails}
>
<Caption>{intl.formatMessage({ id: "Total price" })}:</Caption>
<Subtitle>
{intl.formatMessage(
{ id: "{amount} {currency}" },
{
amount: formatNumber(totalPrice.local.price),
currency: totalPrice.local.currency,
}
)}
</Subtitle>
<Caption color="baseTextHighContrast" type="underline">
{intl.formatMessage({ id: "See details" })}
</Caption>
</button>
<Button intent="primary" size="large" type="submit">
{intl.formatMessage({ id: "Complete booking" })}
</Button>
</div>
</div>
)
}

View File

@@ -6,7 +6,7 @@ import { useIntl } from "react-intl"
import { dt } from "@/lib/dt" import { dt } from "@/lib/dt"
import { useEnterDetailsStore } from "@/stores/enter-details" import { useEnterDetailsStore } from "@/stores/enter-details"
import { ArrowRightIcon } from "@/components/Icons" import { ArrowRightIcon, CloseIcon } from "@/components/Icons"
import Divider from "@/components/TempDesignSystem/Divider" import Divider from "@/components/TempDesignSystem/Divider"
import Link from "@/components/TempDesignSystem/Link" import Link from "@/components/TempDesignSystem/Link"
import Body from "@/components/TempDesignSystem/Text/Body" import Body from "@/components/TempDesignSystem/Text/Body"
@@ -36,20 +36,25 @@ export default function Summary({
const [chosenBreakfast, setChosenBreakfast] = useState< const [chosenBreakfast, setChosenBreakfast] = useState<
BreakfastPackage | BreakfastPackageEnum.NO_BREAKFAST BreakfastPackage | BreakfastPackageEnum.NO_BREAKFAST
>() >()
const [totalPrice, setTotalPrice] = useState({
local: parsePrice(room.localPrice.price),
euro: parsePrice(room.euroPrice.price),
})
const intl = useIntl() const intl = useIntl()
const lang = useLang() const lang = useLang()
const { fromDate, toDate, bedType, breakfast } = useEnterDetailsStore( const {
(state) => ({ fromDate,
fromDate: state.roomData.fromDate, toDate,
toDate: state.roomData.toDate, bedType,
bedType: state.userData.bedType, breakfast,
breakfast: state.userData.breakfast, setTotalPrice,
}) totalPrice,
) toggleSummaryOpen,
} = useEnterDetailsStore((state) => ({
fromDate: state.roomData.fromDate,
toDate: state.roomData.toDate,
bedType: state.userData.bedType,
breakfast: state.userData.breakfast,
toggleSummaryOpen: state.toggleSummaryOpen,
setTotalPrice: state.setTotalPrice,
totalPrice: state.totalPrice,
}))
const diff = dt(toDate).diff(fromDate, "days") const diff = dt(toDate).diff(fromDate, "days")
@@ -70,21 +75,48 @@ export default function Summary({
setChosenBreakfast(breakfast) setChosenBreakfast(breakfast)
if (breakfast === BreakfastPackageEnum.NO_BREAKFAST) { if (breakfast === BreakfastPackageEnum.NO_BREAKFAST) {
setTotalPrice({ setTotalPrice({
local: parsePrice(room.localPrice.price), local: {
euro: parsePrice(room.euroPrice.price), price: parsePrice(room.localPrice.price),
currency: room.localPrice.currency!,
},
euro: {
price: parsePrice(room.euroPrice.price),
currency: room.euroPrice.currency!,
},
}) })
} else { } else {
setTotalPrice({ setTotalPrice({
local: local: {
parsePrice(room.localPrice.price) + price:
parsePrice(breakfast.localPrice.totalPrice), parsePrice(room.localPrice.price) +
euro: parsePrice(breakfast.localPrice.totalPrice),
parsePrice(room.euroPrice.price) + currency: room.localPrice.currency!,
parsePrice(breakfast.requestedPrice.totalPrice), },
euro: {
price:
parsePrice(room.euroPrice.price) +
parsePrice(breakfast.requestedPrice.totalPrice),
currency: room.euroPrice.currency!,
},
}) })
} }
} }
}, [bedType, breakfast, room.localPrice, room.euroPrice]) }, [bedType, breakfast, room.localPrice, room.euroPrice, setTotalPrice])
useEffect(() => {
setTotalPrice({
local: {
price: parsePrice(room.localPrice.price),
currency: room.localPrice.currency!,
},
euro: {
price: parsePrice(room.euroPrice.price),
currency: room.euroPrice.currency!,
},
})
}, [room.localPrice, room.euroPrice, setTotalPrice])
const showToggleButton = true
return ( return (
<section className={styles.summary}> <section className={styles.summary}>
@@ -95,6 +127,7 @@ export default function Summary({
<ArrowRightIcon color="peach80" height={15} width={15} /> <ArrowRightIcon color="peach80" height={15} width={15} />
{dt(toDate).locale(lang).format("ddd, D MMM")} ({nights}) {dt(toDate).locale(lang).format("ddd, D MMM")} ({nights})
</Body> </Body>
{showToggleButton ? <CloseIcon onClick={toggleSummaryOpen} /> : null}
</header> </header>
<Divider color="primaryLightSubtle" /> <Divider color="primaryLightSubtle" />
<div className={styles.addOns}> <div className={styles.addOns}>
@@ -203,8 +236,8 @@ export default function Summary({
{intl.formatMessage( {intl.formatMessage(
{ id: "{amount} {currency}" }, { id: "{amount} {currency}" },
{ {
amount: intl.formatNumber(totalPrice.local), amount: intl.formatNumber(totalPrice.local.price),
currency: room.localPrice.currency, currency: totalPrice.local.currency,
} }
)} )}
</Body> </Body>
@@ -213,14 +246,14 @@ export default function Summary({
{intl.formatMessage( {intl.formatMessage(
{ id: "{amount} {currency}" }, { id: "{amount} {currency}" },
{ {
amount: intl.formatNumber(totalPrice.euro), amount: intl.formatNumber(totalPrice.euro.price),
currency: room.euroPrice.currency, currency: totalPrice.euro.currency,
} }
)} )}
</Caption> </Caption>
</div> </div>
</div> </div>
<Divider color="primaryLightSubtle" /> <Divider className={styles.bottomDivider} color="primaryLightSubtle" />
</div> </div>
</section> </section>
) )

View File

@@ -38,3 +38,13 @@
flex-direction: column; flex-direction: column;
gap: var(--Spacing-x2); gap: var(--Spacing-x2);
} }
.bottomDivider {
display: none;
}
@media screen and (min-width: 1367px) {
.bottomDivider {
display: block;
}
}

View File

@@ -25,6 +25,15 @@ p.caption {
text-decoration: var(--typography-Caption-Labels-textDecoration); text-decoration: var(--typography-Caption-Labels-textDecoration);
} }
.underline {
font-family: var(--typography-Caption-Underline-fontFamily);
font-size: var(--typography-Caption-Underline-fontSize);
font-weight: var(--typography-Caption-Underline-fontWeight);
letter-spacing: var(--typography-Caption-Underline-letterSpacing);
line-height: var(--typography-Caption-Underline-lineHeight);
text-decoration: underline; /* var(--typography-Caption-Underline-textDecoration) /* Commented till figma values are fixed to underline instead of "underline" */
}
.regular { .regular {
font-family: var(--typography-Caption-Regular-fontFamily); font-family: var(--typography-Caption-Regular-fontFamily);
font-size: var(--typography-Caption-Regular-fontSize); font-size: var(--typography-Caption-Regular-fontSize);
@@ -58,6 +67,10 @@ p.caption {
color: var(--Base-Text-Medium-contrast); color: var(--Base-Text-Medium-contrast);
} }
.baseTextHighContrast {
color: var(--Base-Text-High-contrast);
}
.red { .red {
color: var(--Scandic-Brand-Scandic-Red); color: var(--Scandic-Brand-Scandic-Red);
} }

View File

@@ -8,6 +8,7 @@ const config = {
regular: styles.regular, regular: styles.regular,
bold: styles.bold, bold: styles.bold,
label: styles.labels, label: styles.labels,
underline: styles.underline,
}, },
color: { color: {
baseTextAccent: styles.baseTextAccent, baseTextAccent: styles.baseTextAccent,
@@ -22,6 +23,7 @@ const config = {
uiTextMediumContrast: styles.uiTextMediumContrast, uiTextMediumContrast: styles.uiTextMediumContrast,
uiTextPlaceholder: styles.uiTextPlaceholder, uiTextPlaceholder: styles.uiTextPlaceholder,
disabled: styles.disabled, disabled: styles.disabled,
baseTextHighContrast: styles.baseTextHighContrast,
}, },
textTransform: { textTransform: {
uppercase: styles.uppercase, uppercase: styles.uppercase,
@@ -48,6 +50,7 @@ const fontOnlyConfig = {
regular: styles.regular, regular: styles.regular,
bold: styles.bold, bold: styles.bold,
label: styles.labels, label: styles.labels,
underline: styles.underline,
}, },
textTransform: { textTransform: {
uppercase: styles.uppercase, uppercase: styles.uppercase,

View File

@@ -53,6 +53,7 @@
"Bus terminal": "Busstation", "Bus terminal": "Busstation",
"Business": "Forretning", "Business": "Forretning",
"Cancel": "Afbestille", "Cancel": "Afbestille",
"Change room": "Skift værelse",
"Check in": "Check ind", "Check in": "Check ind",
"Check out": "Check ud", "Check out": "Check ud",
"Check out the credit cards saved to your profile. Pay with a saved card when signed in for a smoother web experience.": "Tjek de kreditkort, der er gemt på din profil. Betal med et gemt kort, når du er logget ind for en mere jævn weboplevelse.", "Check out the credit cards saved to your profile. Pay with a saved card when signed in for a smoother web experience.": "Tjek de kreditkort, der er gemt på din profil. Betal med et gemt kort, når du er logget ind for en mere jævn weboplevelse.",
@@ -71,6 +72,7 @@
"Code / Voucher": "Bookingkoder / voucher", "Code / Voucher": "Bookingkoder / voucher",
"Coming up": "Er lige om hjørnet", "Coming up": "Er lige om hjørnet",
"Compare all levels": "Sammenlign alle niveauer", "Compare all levels": "Sammenlign alle niveauer",
"Complete booking": "Fuldfør bookingen",
"Complete booking & go to payment": "Udfyld booking & gå til betaling", "Complete booking & go to payment": "Udfyld booking & gå til betaling",
"Complete the booking": "Fuldfør bookingen", "Complete the booking": "Fuldfør bookingen",
"Contact information": "Kontaktoplysninger", "Contact information": "Kontaktoplysninger",
@@ -285,6 +287,7 @@
"Search": "Søge", "Search": "Søge",
"See all FAQ": "Se alle FAQ", "See all FAQ": "Se alle FAQ",
"See all photos": "Se alle billeder", "See all photos": "Se alle billeder",
"See details": "Se detaljer",
"See hotel details": "Se hoteloplysninger", "See hotel details": "Se hoteloplysninger",
"See less FAQ": "Se mindre FAQ", "See less FAQ": "Se mindre FAQ",
"See on map": "Se på kort", "See on map": "Se på kort",

View File

@@ -53,6 +53,7 @@
"Bus terminal": "Busbahnhof", "Bus terminal": "Busbahnhof",
"Business": "Geschäft", "Business": "Geschäft",
"Cancel": "Stornieren", "Cancel": "Stornieren",
"Change room": "Zimmer ändern",
"Check in": "Einchecken", "Check in": "Einchecken",
"Check out": "Auschecken", "Check out": "Auschecken",
"Check out the credit cards saved to your profile. Pay with a saved card when signed in for a smoother web experience.": "Sehen Sie sich die in Ihrem Profil gespeicherten Kreditkarten an. Bezahlen Sie mit einer gespeicherten Karte, wenn Sie angemeldet sind, für ein reibungsloseres Web-Erlebnis.", "Check out the credit cards saved to your profile. Pay with a saved card when signed in for a smoother web experience.": "Sehen Sie sich die in Ihrem Profil gespeicherten Kreditkarten an. Bezahlen Sie mit einer gespeicherten Karte, wenn Sie angemeldet sind, für ein reibungsloseres Web-Erlebnis.",
@@ -71,6 +72,7 @@
"Code / Voucher": "Buchungscodes / Gutscheine", "Code / Voucher": "Buchungscodes / Gutscheine",
"Coming up": "Demnächst", "Coming up": "Demnächst",
"Compare all levels": "Vergleichen Sie alle Levels", "Compare all levels": "Vergleichen Sie alle Levels",
"Complete booking": "Buchung abschließen",
"Complete booking & go to payment": "Buchung abschließen & zur Bezahlung gehen", "Complete booking & go to payment": "Buchung abschließen & zur Bezahlung gehen",
"Complete the booking": "Buchung abschließen", "Complete the booking": "Buchung abschließen",
"Contact information": "Kontaktinformationen", "Contact information": "Kontaktinformationen",
@@ -284,6 +286,7 @@
"Search": "Suchen", "Search": "Suchen",
"See all FAQ": "Siehe alle FAQ", "See all FAQ": "Siehe alle FAQ",
"See all photos": "Alle Fotos ansehen", "See all photos": "Alle Fotos ansehen",
"See details": "Siehe Einzelheiten",
"See hotel details": "Hotelinformationen ansehen", "See hotel details": "Hotelinformationen ansehen",
"See less FAQ": "Weniger anzeigen FAQ", "See less FAQ": "Weniger anzeigen FAQ",
"See on map": "Karte ansehen", "See on map": "Karte ansehen",

View File

@@ -80,6 +80,7 @@
"Code / Voucher": "Code / Voucher", "Code / Voucher": "Code / Voucher",
"Coming up": "Coming up", "Coming up": "Coming up",
"Compare all levels": "Compare all levels", "Compare all levels": "Compare all levels",
"Complete booking": "Complete booking",
"Complete booking & go to payment": "Complete booking & go to payment", "Complete booking & go to payment": "Complete booking & go to payment",
"Complete the booking": "Complete the booking", "Complete the booking": "Complete the booking",
"Contact information": "Contact information", "Contact information": "Contact information",
@@ -314,6 +315,7 @@
"Search": "Search", "Search": "Search",
"See all FAQ": "See all FAQ", "See all FAQ": "See all FAQ",
"See all photos": "See all photos", "See all photos": "See all photos",
"See details": "See details",
"See hotel details": "See hotel details", "See hotel details": "See hotel details",
"See less FAQ": "See less FAQ", "See less FAQ": "See less FAQ",
"See on map": "See on map", "See on map": "See on map",

View File

@@ -53,6 +53,7 @@
"Bus terminal": "Bussiasema", "Bus terminal": "Bussiasema",
"Business": "Business", "Business": "Business",
"Cancel": "Peruuttaa", "Cancel": "Peruuttaa",
"Change room": "Vaihda huonetta",
"Check in": "Sisäänkirjautuminen", "Check in": "Sisäänkirjautuminen",
"Check out": "Uloskirjautuminen", "Check out": "Uloskirjautuminen",
"Check out the credit cards saved to your profile. Pay with a saved card when signed in for a smoother web experience.": "Tarkista profiiliisi tallennetut luottokortit. Maksa tallennetulla kortilla kirjautuneena, jotta verkkokokemus on sujuvampi.", "Check out the credit cards saved to your profile. Pay with a saved card when signed in for a smoother web experience.": "Tarkista profiiliisi tallennetut luottokortit. Maksa tallennetulla kortilla kirjautuneena, jotta verkkokokemus on sujuvampi.",
@@ -71,6 +72,7 @@
"Code / Voucher": "Varauskoodit / kupongit", "Code / Voucher": "Varauskoodit / kupongit",
"Coming up": "Tulossa", "Coming up": "Tulossa",
"Compare all levels": "Vertaa kaikkia tasoja", "Compare all levels": "Vertaa kaikkia tasoja",
"Complete booking": "Täydennä varaus",
"Complete booking & go to payment": "Täydennä varaus & siirry maksamaan", "Complete booking & go to payment": "Täydennä varaus & siirry maksamaan",
"Complete the booking": "Täydennä varaus", "Complete the booking": "Täydennä varaus",
"Contact information": "Yhteystiedot", "Contact information": "Yhteystiedot",
@@ -286,6 +288,7 @@
"Search": "Haku", "Search": "Haku",
"See all FAQ": "Katso kaikki UKK", "See all FAQ": "Katso kaikki UKK",
"See all photos": "Katso kaikki kuvat", "See all photos": "Katso kaikki kuvat",
"See details": "Katso tiedot",
"See hotel details": "Katso hotellin tiedot", "See hotel details": "Katso hotellin tiedot",
"See less FAQ": "Katso vähemmän UKK", "See less FAQ": "Katso vähemmän UKK",
"See on map": "Näytä kartalla", "See on map": "Näytä kartalla",

View File

@@ -53,6 +53,7 @@
"Bus terminal": "Bussterminal", "Bus terminal": "Bussterminal",
"Business": "Forretnings", "Business": "Forretnings",
"Cancel": "Avbryt", "Cancel": "Avbryt",
"Change room": "Endre rom",
"Check in": "Sjekk inn", "Check in": "Sjekk inn",
"Check out": "Sjekk ut", "Check out": "Sjekk ut",
"Check out the credit cards saved to your profile. Pay with a saved card when signed in for a smoother web experience.": "Sjekk ut kredittkortene som er lagret på profilen din. Betal med et lagret kort når du er pålogget for en jevnere nettopplevelse.", "Check out the credit cards saved to your profile. Pay with a saved card when signed in for a smoother web experience.": "Sjekk ut kredittkortene som er lagret på profilen din. Betal med et lagret kort når du er pålogget for en jevnere nettopplevelse.",
@@ -71,6 +72,7 @@
"Code / Voucher": "Bestillingskoder / kuponger", "Code / Voucher": "Bestillingskoder / kuponger",
"Coming up": "Kommer opp", "Coming up": "Kommer opp",
"Compare all levels": "Sammenlign alle nivåer", "Compare all levels": "Sammenlign alle nivåer",
"Complete booking": "Fullfør reservasjonen",
"Complete booking & go to payment": "Fullfør bestilling & gå til betaling", "Complete booking & go to payment": "Fullfør bestilling & gå til betaling",
"Complete the booking": "Fullfør reservasjonen", "Complete the booking": "Fullfør reservasjonen",
"Contact information": "Kontaktinformasjon", "Contact information": "Kontaktinformasjon",
@@ -283,6 +285,7 @@
"Search": "Søk", "Search": "Søk",
"See all FAQ": "Se alle FAQ", "See all FAQ": "Se alle FAQ",
"See all photos": "Se alle bilder", "See all photos": "Se alle bilder",
"See details": "Se detaljer",
"See hotel details": "Se hotellinformasjon", "See hotel details": "Se hotellinformasjon",
"See less FAQ": "Se mindre FAQ", "See less FAQ": "Se mindre FAQ",
"See on map": "Se på kart", "See on map": "Se på kart",

View File

@@ -53,6 +53,7 @@
"Bus terminal": "Bussterminal", "Bus terminal": "Bussterminal",
"Business": "Business", "Business": "Business",
"Cancel": "Avbryt", "Cancel": "Avbryt",
"Change room": "Ändra rum",
"Check in": "Checka in", "Check in": "Checka in",
"Check out": "Checka ut", "Check out": "Checka ut",
"Check out the credit cards saved to your profile. Pay with a saved card when signed in for a smoother web experience.": "Kolla in kreditkorten som sparats i din profil. Betala med ett sparat kort när du är inloggad för en smidigare webbupplevelse.", "Check out the credit cards saved to your profile. Pay with a saved card when signed in for a smoother web experience.": "Kolla in kreditkorten som sparats i din profil. Betala med ett sparat kort när du är inloggad för en smidigare webbupplevelse.",
@@ -71,6 +72,7 @@
"Code / Voucher": "Bokningskoder / kuponger", "Code / Voucher": "Bokningskoder / kuponger",
"Coming up": "Kommer härnäst", "Coming up": "Kommer härnäst",
"Compare all levels": "Jämför alla nivåer", "Compare all levels": "Jämför alla nivåer",
"Complete booking": "Slutför bokning",
"Complete booking & go to payment": "Fullför bokning & gå till betalning", "Complete booking & go to payment": "Fullför bokning & gå till betalning",
"Complete the booking": "Slutför bokningen", "Complete the booking": "Slutför bokningen",
"Contact information": "Kontaktinformation", "Contact information": "Kontaktinformation",
@@ -283,6 +285,7 @@
"Search": "Sök", "Search": "Sök",
"See all FAQ": "Se alla FAQ", "See all FAQ": "Se alla FAQ",
"See all photos": "Se alla foton", "See all photos": "Se alla foton",
"See details": "Se detaljer",
"See hotel details": "Se hotellinformation", "See hotel details": "Se hotellinformation",
"See less FAQ": "See färre FAQ", "See less FAQ": "See färre FAQ",
"See on map": "Se på karta", "See on map": "Se på karta",

View File

@@ -23,6 +23,11 @@ import { BreakfastPackageEnum } from "@/types/enums/breakfast"
const SESSION_STORAGE_KEY = "enterDetails" const SESSION_STORAGE_KEY = "enterDetails"
type TotalPrice = {
local: { price: number; currency: string }
euro: { price: number; currency: string }
}
interface EnterDetailsState { interface EnterDetailsState {
userData: { userData: {
bedType: BedTypeSchema | undefined bedType: BedTypeSchema | undefined
@@ -32,6 +37,8 @@ interface EnterDetailsState {
steps: StepEnum[] steps: StepEnum[]
selectRateUrl: string selectRateUrl: string
currentStep: StepEnum currentStep: StepEnum
totalPrice: TotalPrice
isSummaryOpen: boolean
isValid: Record<StepEnum, boolean> isValid: Record<StepEnum, boolean>
completeStep: (updatedData: Partial<EnterDetailsState["userData"]>) => void completeStep: (updatedData: Partial<EnterDetailsState["userData"]>) => void
navigate: ( navigate: (
@@ -42,6 +49,8 @@ interface EnterDetailsState {
> >
) => void ) => void
setCurrentStep: (step: StepEnum) => void setCurrentStep: (step: StepEnum) => void
toggleSummaryOpen: () => void
setTotalPrice: (totalPrice: TotalPrice) => void
} }
export function initEditDetailsState( export function initEditDetailsState(
@@ -129,6 +138,11 @@ export function initEditDetailsState(
roomData, roomData,
selectRateUrl, selectRateUrl,
steps: Object.values(StepEnum), steps: Object.values(StepEnum),
totalPrice: {
local: { price: 0, currency: "" },
euro: { price: 0, currency: "" },
},
isSummaryOpen: false,
setCurrentStep: (step) => set({ currentStep: step }), setCurrentStep: (step) => set({ currentStep: step }),
navigate: (step, updatedData) => navigate: (step, updatedData) =>
set( set(
@@ -166,6 +180,8 @@ export function initEditDetailsState(
get().navigate(nextStep, updatedData) get().navigate(nextStep, updatedData)
}) })
), ),
toggleSummaryOpen: () => set({ isSummaryOpen: !get().isSummaryOpen }),
setTotalPrice: (totalPrice) => set({ totalPrice: totalPrice }),
})) }))
} }