Merged in feat/SW-1051-amenities-in-sidepeek (pull request #1007)

feat(SW-1051): fix sidepeek select hotel page

* feat(SW-1051): fix sidepeek select hotel page


Approved-by: Niclas Edenvin
This commit is contained in:
Bianca Widstam
2024-12-02 13:45:31 +00:00
parent 403e1e7cf8
commit 4f871a3220
27 changed files with 359 additions and 138 deletions

View File

@@ -13,7 +13,7 @@ export default function FooterMainNav({ mainLinks }: FooterMainNavProps) {
<ul className={styles.mainNavigationList}> <ul className={styles.mainNavigationList}>
{mainLinks.map((link) => ( {mainLinks.map((link) => (
<li key={link.title} className={styles.mainNavigationItem}> <li key={link.title} className={styles.mainNavigationItem}>
<Subtitle color="baseTextMediumContrast" type="two" asChild> <Subtitle color="baseTextHighContrast" type="two" asChild>
<Link <Link
color="burgundy" color="burgundy"
href={link.url} href={link.url}
@@ -40,7 +40,7 @@ export function FooterMainNavSkeleton() {
<ul className={styles.mainNavigationList}> <ul className={styles.mainNavigationList}>
{items.map((x) => ( {items.map((x) => (
<li key={x} className={styles.mainNavigationItem}> <li key={x} className={styles.mainNavigationItem}>
<Subtitle color="baseTextMediumContrast" type="two" asChild> <Subtitle color="baseTextHighContrast" type="two" asChild>
<span className={styles.mainNavigationLink}> <span className={styles.mainNavigationLink}>
<SkeletonShimmer width="80%" /> <SkeletonShimmer width="80%" />
<ArrowRightIcon color="peach80" /> <ArrowRightIcon color="peach80" />

View File

@@ -22,10 +22,6 @@
flex-direction: column; flex-direction: column;
} }
.heading {
font-weight: 500;
}
.soMeIcons { .soMeIcons {
display: flex; display: flex;
gap: var(--Spacing-x-one-and-half); gap: var(--Spacing-x-one-and-half);
@@ -35,14 +31,20 @@
display: flex; display: flex;
align-items: center; align-items: center;
column-gap: var(--Spacing-x-one-and-half); column-gap: var(--Spacing-x-one-and-half);
grid-column: 2 / 3; grid-column: 1 / 3;
grid-row: 3 / 4; grid-row: 4 / 4;
font-size: var(--typography-Footnote-Regular-fontSize); font-size: var(--typography-Footnote-Regular-fontSize);
line-height: (); line-height: ();
margin-bottom: var(--Spacing-x1);
}
.ecoLabel img {
flex-shrink: 0;
} }
.ecoLabelText { .ecoLabelText {
display: flex; display: flex;
color: var(--UI-Text-Medium-contrast);
flex-direction: column; flex-direction: column;
justify-content: center; justify-content: center;
} }

View File

@@ -5,6 +5,7 @@ import { useIntl } from "react-intl"
import { FacebookIcon, InstagramIcon } from "@/components/Icons" import { FacebookIcon, InstagramIcon } from "@/components/Icons"
import Image from "@/components/Image" import Image from "@/components/Image"
import Link from "@/components/TempDesignSystem/Link" import Link from "@/components/TempDesignSystem/Link"
import Body from "@/components/TempDesignSystem/Text/Body"
import useLang from "@/hooks/useLang" import useLang from "@/hooks/useLang"
import styles from "./contact.module.css" import styles from "./contact.module.css"
@@ -20,17 +21,17 @@ export default function Contact({ hotel }: ContactProps) {
<address className={styles.address}> <address className={styles.address}>
<ul className={styles.contactInfo}> <ul className={styles.contactInfo}>
<li> <li>
<span className={styles.heading}> <Body textTransform="bold">
{intl.formatMessage({ id: "Address" })} {intl.formatMessage({ id: "Address" })}
</span> </Body>
<span> <Body>
{`${hotel.address.streetAddress}, ${hotel.address.city}`} {`${hotel.address.streetAddress}, ${hotel.address.city}`}
</span> </Body>
</li> </li>
<li> <li>
<span className={styles.heading}> <Body textTransform="bold">
{intl.formatMessage({ id: "Driving directions" })} {intl.formatMessage({ id: "Driving directions" })}
</span> </Body>
<a <a
href={`https://www.google.com/maps/dir/?api=1&destination=${hotel.location.latitude},${hotel.location.longitude}`} href={`https://www.google.com/maps/dir/?api=1&destination=${hotel.location.latitude},${hotel.location.longitude}`}
className={styles.googleMaps} className={styles.googleMaps}
@@ -40,20 +41,9 @@ export default function Contact({ hotel }: ContactProps) {
</a> </a>
</li> </li>
<li> <li>
<span className={styles.heading}> <Body textTransform="bold">
{intl.formatMessage({ id: "Email" })}
</span>
<Link
href={`mailto:${hotel.contactInformation.email}`}
color="peach80"
>
{hotel.contactInformation.email}
</Link>
</li>
<li>
<span className={styles.heading}>
{intl.formatMessage({ id: "Contact us" })} {intl.formatMessage({ id: "Contact us" })}
</span> </Body>
<Link <Link
href={`tel:${hotel.contactInformation.phoneNumber}`} href={`tel:${hotel.contactInformation.phoneNumber}`}
color="peach80" color="peach80"
@@ -62,25 +52,44 @@ export default function Contact({ hotel }: ContactProps) {
</Link> </Link>
</li> </li>
<li> <li>
<span className={styles.heading}> {(hotel.socialMedia.facebook || hotel.socialMedia.instagram) && (
{intl.formatMessage({ id: "Follow us" })} <>
</span> <Body textTransform="bold">
<div className={styles.soMeIcons}> {intl.formatMessage({ id: "Follow us" })}
<Link href="#" target="_blank"> </Body>
<InstagramIcon color="burgundy" /> <div className={styles.soMeIcons}>
</Link> {hotel.socialMedia.instagram && (
<Link href="#" target="_blank"> <Link href={hotel.socialMedia.instagram} target="_blank">
<FacebookIcon color="burgundy" /> <InstagramIcon color="burgundy" />
</Link> </Link>
</div> )}
{hotel.socialMedia.facebook && (
<Link href={hotel.socialMedia.facebook} target="_blank">
<FacebookIcon color="burgundy" />
</Link>
)}
</div>
</>
)}
</li>
<li>
<Body textTransform="bold">
{intl.formatMessage({ id: "Email" })}
</Body>
<Link
href={`mailto:${hotel.contactInformation.email}`}
color="peach80"
>
{hotel.contactInformation.email}
</Link>
</li> </li>
</ul> </ul>
</address> </address>
{hotel.hotelFacts.ecoLabels.nordicEcoLabel ? ( {hotel.hotelFacts.ecoLabels?.nordicEcoLabel ? (
<div className={styles.ecoLabel}> <div className={styles.ecoLabel}>
<Image <Image
height={38} height={38}
width={38} width={43}
alt={intl.formatMessage({ id: "Nordic Swan Ecolabel" })} alt={intl.formatMessage({ id: "Nordic Swan Ecolabel" })}
src={`/_static/img/icons/swan-eco/swan_eco_dark_${lang}.png`} src={`/_static/img/icons/swan-eco/swan_eco_dark_${lang}.png`}
/> />

View File

@@ -0,0 +1,27 @@
import { iconVariants } from "./variants"
import type { IconProps } from "@/types/components/icon"
export default function FilledHeartIcon({
className,
color,
...props
}: IconProps) {
const classNames = iconVariants({ className, color })
return (
<svg
className={classNames}
width="16"
height="16"
viewBox="0 0 16 16"
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}
>
<path
d="M8.00091 13.4171L7.23424 12.7255C6.1424 11.7524 5.24166 10.9189 4.53203 10.2249C3.82239 9.53081 3.26322 8.91489 2.85451 8.37709C2.44579 7.8393 2.16246 7.34774 2.00451 6.90241C1.84656 6.45708 1.76758 6.00088 1.76758 5.53379C1.76758 4.57813 2.09533 3.77255 2.75083 3.11704C3.40634 2.46154 4.21192 2.13379 5.16758 2.13379C5.70411 2.13379 6.22436 2.25046 6.72831 2.48379C7.23227 2.71712 7.65647 3.05046 8.00091 3.48379C8.36202 3.05046 8.7898 2.71712 9.28425 2.48379C9.77869 2.25046 10.2954 2.13379 10.8342 2.13379C11.7899 2.13379 12.5955 2.46154 13.251 3.11704C13.9065 3.77255 14.2342 4.57813 14.2342 5.53379C14.2342 6.00088 14.158 6.45153 14.0056 6.88574C13.8533 7.31996 13.5727 7.80319 13.164 8.33542C12.7553 8.86767 12.1933 9.48637 11.4781 10.1915C10.7629 10.8967 9.84831 11.7524 8.73425 12.7588L8.00091 13.4171Z"
fill="#B05B65"
/>
</svg>
)
}

View File

@@ -0,0 +1,21 @@
import { useIntl } from "react-intl"
import AccordionItem from "@/components/TempDesignSystem/Accordion/AccordionItem"
import Body from "@/components/TempDesignSystem/Text/Body"
import { AccessibilityProps } from "@/types/components/hotelReservation/selectHotel/selectHotel"
import { IconName } from "@/types/components/icon"
export default function Accessibility({
accessibilityElevatorPitchText,
}: AccessibilityProps) {
const intl = useIntl()
return (
<AccordionItem
title={intl.formatMessage({ id: "Accessibility" })}
icon={IconName.Accessibility}
>
<Body>{accessibilityElevatorPitchText}</Body>
</AccordionItem>
)
}

View File

@@ -0,0 +1,22 @@
import { useIntl } from "react-intl"
import AccordionItem from "@/components/TempDesignSystem/Accordion/AccordionItem"
import Body from "@/components/TempDesignSystem/Text/Body"
import { CheckInCheckOutProps } from "@/types/components/hotelReservation/selectHotel/selectHotel"
import { IconName } from "@/types/components/icon"
export default function CheckinCheckOut({ checkin }: CheckInCheckOutProps) {
const intl = useIntl()
return (
<AccordionItem
title={intl.formatMessage({ id: "Check-in/Check-out" })}
icon={IconName.Calendar}
>
<Body textTransform="bold">{intl.formatMessage({ id: "Hours" })}</Body>
<Body>{`${intl.formatMessage({ id: "Check in from" })}: ${checkin.checkInTime}`}</Body>
<Body>{`${intl.formatMessage({ id: "Check out at latest" })}: ${checkin.checkOutTime}`}</Body>
</AccordionItem>
)
}

View File

@@ -0,0 +1,21 @@
import { useIntl } from "react-intl"
import AccordionItem from "@/components/TempDesignSystem/Accordion/AccordionItem"
import Body from "@/components/TempDesignSystem/Text/Body"
import { MeetingsAndConferencesProps } from "@/types/components/hotelReservation/selectHotel/selectHotel"
import { IconName } from "@/types/components/icon"
export default function MeetingsAndConferences({
meetingDescription,
}: MeetingsAndConferencesProps) {
const intl = useIntl()
return (
<AccordionItem
title={intl.formatMessage({ id: "Meetings & Conferences" })}
icon={IconName.Business}
>
<Body>{meetingDescription}</Body>
</AccordionItem>
)
}

View File

@@ -0,0 +1,55 @@
import { useIntl } from "react-intl"
import FilledHeartIcon from "@/components/Icons/FilledHeart"
import AccordionItem from "@/components/TempDesignSystem/Accordion/AccordionItem"
import Subtitle from "@/components/TempDesignSystem/Text/Subtitle"
import styles from "./sidePeekAccordion.module.css"
import { ParkingProps } from "@/types/components/hotelReservation/selectHotel/selectHotel"
import { IconName } from "@/types/components/icon"
export default function Parking({ parking }: ParkingProps) {
const intl = useIntl()
return (
<AccordionItem
title={intl.formatMessage({ id: "Parking" })}
icon={IconName.Parking}
className={styles.parking}
>
{parking.map((p) => (
<div key={p.name}>
<Subtitle type="two">
{`${intl.formatMessage({ id: p.type })} ${p?.name ? ` (${p.name})` : ""}`}
</Subtitle>
<ul className={styles.list}>
{p?.address && (
<li>
<FilledHeartIcon color="baseIconLowContrast" />
{`${intl.formatMessage({ id: "Address" })}: ${p.address}`}
</li>
)}
{p?.numberOfParkingSpots !== undefined && (
<li>
<FilledHeartIcon color="baseIconLowContrast" />
{intl.formatMessage(
{ id: "Number of parking spots" },
{ number: p.numberOfParkingSpots }
)}
</li>
)}
{p?.numberOfChargingSpaces !== undefined && (
<li>
<FilledHeartIcon color="baseIconLowContrast" />
{intl.formatMessage(
{ id: "Number of charging points for electric cars" },
{ number: p.numberOfChargingSpaces }
)}
</li>
)}
</ul>
</div>
))}
</AccordionItem>
)
}

View File

@@ -0,0 +1,22 @@
import { useIntl } from "react-intl"
import AccordionItem from "@/components/TempDesignSystem/Accordion/AccordionItem"
import Body from "@/components/TempDesignSystem/Text/Body"
import { RestaurantProps } from "@/types/components/hotelReservation/selectHotel/selectHotel"
import { IconName } from "@/types/components/icon"
export default function Restaurant({
restaurantsContentDescriptionMedium,
}: RestaurantProps) {
const intl = useIntl()
return (
<AccordionItem
title={intl.formatMessage({ id: "Restaurant" }, { count: 1 })}
icon={IconName.Restaurant}
>
<Body>{restaurantsContentDescriptionMedium}</Body>
</AccordionItem>
)
}

View File

@@ -0,0 +1,23 @@
.list {
font-family: var(--typography-Body-Regular-fontFamily);
list-style-position: inside;
list-style-type: none;
margin-top: var(--Spacing-x-one-and-half);
}
.list li {
display: flex;
align-items: center;
gap: var(--Spacing-x1);
padding-left: var(--Spacing-x1);
}
.list li svg {
flex-shrink: 0;
}
.parking details > div {
display: flex;
flex-direction: column;
gap: var(--Spacing-x2);
}

View File

@@ -22,8 +22,3 @@
.noIcon { .noIcon {
margin-left: var(--Spacing-x4); margin-left: var(--Spacing-x4);
} }
.list {
font-family: var(--typography-Body-Regular-fontFamily);
list-style: inside;
}

View File

@@ -2,29 +2,21 @@ import { useIntl } from "react-intl"
import { mapFacilityToIcon } from "@/components/ContentType/HotelPage/data" import { mapFacilityToIcon } from "@/components/ContentType/HotelPage/data"
import Contact from "@/components/HotelReservation/Contact" import Contact from "@/components/HotelReservation/Contact"
import { AccessibilityIcon } from "@/components/Icons"
import Accordion from "@/components/TempDesignSystem/Accordion" import Accordion from "@/components/TempDesignSystem/Accordion"
import AccordionItem from "@/components/TempDesignSystem/Accordion/AccordionItem"
import Button from "@/components/TempDesignSystem/Button"
import SidePeek from "@/components/TempDesignSystem/SidePeek" import SidePeek from "@/components/TempDesignSystem/SidePeek"
import Body from "@/components/TempDesignSystem/Text/Body" import Body from "@/components/TempDesignSystem/Text/Body"
import Subtitle from "@/components/TempDesignSystem/Text/Subtitle" import Subtitle from "@/components/TempDesignSystem/Text/Subtitle"
import Accessibility from "./Accordions/Accessibility"
import CheckinCheckOut from "./Accordions/CheckInCheckOut"
import MeetingsAndConferences from "./Accordions/MeetingsAndConferences"
import Parking from "./Accordions/Parking"
import Restaurant from "./Accordions/Restaurant"
import styles from "./hotelSidePeek.module.css" import styles from "./hotelSidePeek.module.css"
import type { HotelSidePeekProps } from "@/types/components/hotelReservation/hotelSidePeek" import type { HotelSidePeekProps } from "@/types/components/hotelReservation/hotelSidePeek"
import type { ParkingProps } from "@/types/components/hotelReservation/selectHotel/selectHotel"
import { SidePeekEnum } from "@/types/components/hotelReservation/sidePeek" import { SidePeekEnum } from "@/types/components/hotelReservation/sidePeek"
import { IconName } from "@/types/components/icon"
import type { Amenities, Hotel } from "@/types/hotel"
function getAmenitiesList(hotel: Hotel) {
const detailedAmenities: Amenities = hotel.detailedFacilities.filter(
// Remove Parking facilities since parking accordion is based on hotel.parking
(facility) => !facility.name.startsWith("Parking") && facility.public
)
return detailedAmenities
}
export default function HotelSidePeek({ export default function HotelSidePeek({
hotel, hotel,
@@ -33,7 +25,12 @@ export default function HotelSidePeek({
showCTA, showCTA,
}: HotelSidePeekProps) { }: HotelSidePeekProps) {
const intl = useIntl() const intl = useIntl()
const amenitiesList = getAmenitiesList(hotel) const amenitiesList = hotel.detailedFacilities.filter(
(facility) => facility.public
)
const parking = hotel.parking.filter(
(p) => p?.numberOfParkingSpots || p?.numberOfChargingSpaces || p?.address
)
return ( return (
<SidePeek <SidePeek
@@ -42,30 +39,38 @@ export default function HotelSidePeek({
handleClose={close} handleClose={close}
> >
<div className={styles.content}> <div className={styles.content}>
<Subtitle> <Subtitle color="baseTextHighContrast">
{intl.formatMessage({ id: "Practical information" })} {intl.formatMessage({ id: "Practical information" })}
</Subtitle> </Subtitle>
<Contact hotel={hotel} /> <Contact hotel={hotel} />
<Accordion> <Accordion>
{/* parking */} {parking?.length > 0 && <Parking parking={parking} />}
{hotel.parking.length ? ( {hotel.hotelContent?.restaurantsOverviewPage
<AccordionItem ?.restaurantsContentDescriptionMedium && (
title={intl.formatMessage({ id: "Parking" })} <Restaurant
icon={IconName.Parking} restaurantsContentDescriptionMedium={
> hotel.hotelContent.restaurantsOverviewPage
{hotel.parking.map((p) => ( .restaurantsContentDescriptionMedium
<Parking key={p.name} parking={p} /> }
))}
</AccordionItem>
) : null}
<div className={styles.amenity}>
<AccessibilityIcon
width={24}
height={24}
color="uiTextMediumContrast"
/> />
{intl.formatMessage({ id: "Accessibility" })} )}
</div> {hotel?.accessibilityElevatorPitchText && (
<Accessibility
accessibilityElevatorPitchText={
hotel.accessibilityElevatorPitchText
}
/>
)}
{hotel.hotelFacts?.checkin && (
<CheckinCheckOut checkin={hotel.hotelFacts.checkin} />
)}
{hotel.hotelContent.texts?.meetingDescription?.medium && (
<MeetingsAndConferences
meetingDescription={
hotel.hotelContent.texts.meetingDescription.medium
}
/>
)}
{amenitiesList.map((amenity) => { {amenitiesList.map((amenity) => {
const Icon = mapFacilityToIcon(amenity.id) const Icon = mapFacilityToIcon(amenity.id)
return ( return (
@@ -84,54 +89,13 @@ export default function HotelSidePeek({
) )
})} })}
</Accordion> </Accordion>
{showCTA && ( {/* TODO: handle linking to Hotel Page */}
/* TODO: handle linking to Hotel Page */ {/* {showCTA && (
<Button theme={"base"}>To the hotel</Button> <Button theme="base" intent="secondary" size="large">
)} Read more about the hotel
</Button>
)} */}
</div> </div>
</SidePeek> </SidePeek>
) )
} }
function Parking({ parking }: ParkingProps) {
const intl = useIntl()
return (
<div>
<Body>
{`${intl.formatMessage({ id: parking.type })}${parking?.name ? ` (${parking.name})` : ""}`}
</Body>
<ul className={styles.list}>
{parking?.numberOfChargingSpaces !== undefined && (
<li>
{intl.formatMessage(
{ id: "Number of charging points for electric cars" },
{ number: parking.numberOfChargingSpaces }
)}
</li>
)}
{parking?.canMakeReservation && (
<li>{`${intl.formatMessage({ id: "Parking can be reserved in advance" })}: ${parking.canMakeReservation ? intl.formatMessage({ id: "Yes" }) : intl.formatMessage({ id: "No" })}`}</li>
)}
{parking?.numberOfParkingSpots !== undefined && (
<li>
{intl.formatMessage(
{ id: "Number of parking spots" },
{ number: parking.numberOfParkingSpots }
)}
</li>
)}
{parking?.distanceToHotel !== undefined && (
<li>
{intl.formatMessage(
{ id: "Distance to hotel" },
{ distance: parking.distanceToHotel }
)}
</li>
)}
{parking?.address && (
<li>{`${intl.formatMessage({ id: "Address" })}: ${parking.address}`}</li>
)}
</ul>
</div>
)
}

View File

@@ -5,6 +5,8 @@ import { useRef } from "react"
import { ChevronDownIcon } from "@/components/Icons" import { ChevronDownIcon } from "@/components/Icons"
import { getIconByIconName } from "@/components/Icons/get-icon-by-icon-name" import { getIconByIconName } from "@/components/Icons/get-icon-by-icon-name"
import Body from "../../Text/Body"
import Subtitle from "../../Text/Subtitle"
import { accordionItemVariants } from "./variants" import { accordionItemVariants } from "./variants"
import styles from "./accordionItem.module.css" import styles from "./accordionItem.module.css"
@@ -49,7 +51,23 @@ export default function AccordionItem({
<details ref={detailsRef} onToggle={toggleAccordion}> <details ref={detailsRef} onToggle={toggleAccordion}>
<summary className={styles.summary}> <summary className={styles.summary}>
{IconComp && <IconComp className={styles.icon} color="burgundy" />} {IconComp && <IconComp className={styles.icon} color="burgundy" />}
<span className={styles.title}>{title}</span> {variant === "card" ? (
<Body
textTransform="bold"
color="baseTextHighContrast"
className={styles.title}
>
{title}
</Body>
) : (
<Subtitle
className={styles.title}
type="two"
color="baseTextHighContrast"
>
{title}
</Subtitle>
)}
<ChevronDownIcon <ChevronDownIcon
className={styles.chevron} className={styles.chevron}
color="burgundy" color="burgundy"

View File

@@ -63,7 +63,7 @@
color: var(--Scandic-Brand-Pale-Peach); color: var(--Scandic-Brand-Pale-Peach);
} }
.baseTextMediumContrast { .baseTextHighContrast {
color: var(--Base-Text-High-contrast); color: var(--Base-Text-High-contrast);
} }

View File

@@ -9,7 +9,7 @@ const config = {
burgundy: styles.burgundy, burgundy: styles.burgundy,
baseTextDisabled: styles.baseTextDisabled, baseTextDisabled: styles.baseTextDisabled,
pale: styles.pale, pale: styles.pale,
baseTextMediumContrast: styles.baseTextMediumContrast, baseTextHighContrast: styles.baseTextHighContrast,
uiTextHighContrast: styles.uiTextHighContrast, uiTextHighContrast: styles.uiTextHighContrast,
uiTextMediumContrast: styles.uiTextMediumContrast, uiTextMediumContrast: styles.uiTextMediumContrast,
uiTextPlaceholder: styles.uiTextPlaceholder, uiTextPlaceholder: styles.uiTextPlaceholder,

View File

@@ -64,6 +64,7 @@
"Check out": "Check ud", "Check out": "Check ud",
"Check out at latest": "Udtjekning senest", "Check out at latest": "Udtjekning senest",
"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.",
"Check-in/Check-out": "Indtjekning/Udtjekning",
"Children": "børn", "Children": "børn",
"Choose room": "Vælg rum", "Choose room": "Vælg rum",
"Cities": "Byer", "Cities": "Byer",
@@ -164,6 +165,7 @@
"Hotel surroundings": "Hotel omgivelser", "Hotel surroundings": "Hotel omgivelser",
"Hotel(s)": "{amount} {amount, plural, one {hotel} other {hoteller}}", "Hotel(s)": "{amount} {amount, plural, one {hotel} other {hoteller}}",
"Hotels": "Hoteller", "Hotels": "Hoteller",
"Hours": "Tider",
"How do you want to sleep?": "Hvordan vil du sove?", "How do you want to sleep?": "Hvordan vil du sove?",
"How it works": "Hvordan det virker", "How it works": "Hvordan det virker",
"Hurry up and use them before they expire!": "Skynd dig og brug dem, før de udløber!", "Hurry up and use them before they expire!": "Skynd dig og brug dem, før de udløber!",
@@ -257,6 +259,7 @@
"Open menu": "Åbn menuen", "Open menu": "Åbn menuen",
"Open my pages menu": "Åbn mine sider menuen", "Open my pages menu": "Åbn mine sider menuen",
"Opening Hours": "Åbningstider", "Opening Hours": "Åbningstider",
"Outdoor": "Udendørs",
"OutdoorPool": "Udendørs pool", "OutdoorPool": "Udendørs pool",
"Overview": "Oversigt", "Overview": "Oversigt",
"PETR": "Kæledyr", "PETR": "Kæledyr",
@@ -305,7 +308,7 @@
"Relax": "Slap af", "Relax": "Slap af",
"Remove card from member profile": "Fjern kortet fra medlemsprofilen", "Remove card from member profile": "Fjern kortet fra medlemsprofilen",
"Request bedtype": "Anmod om sengetype", "Request bedtype": "Anmod om sengetype",
"Restaurant": "{count, plural, one {#Restaurant} other {#Restaurants}}", "Restaurant": "{count, plural, one {Restaurant} other {Restauranter}}",
"Restaurant & Bar": "Restaurant & Bar", "Restaurant & Bar": "Restaurant & Bar",
"Restaurants & Bars": "Restaurants & Bars", "Restaurants & Bars": "Restaurants & Bars",
"Retype new password": "Gentag den nye adgangskode", "Retype new password": "Gentag den nye adgangskode",

View File

@@ -64,6 +64,7 @@
"Check out": "Auschecken", "Check out": "Auschecken",
"Check out at latest": "Check-out spätestens", "Check out at latest": "Check-out spätestens",
"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.",
"Check-in/Check-out": "Einchecken/Auschecken",
"Children": "Kinder", "Children": "Kinder",
"Choose room": "Zimmer wählen", "Choose room": "Zimmer wählen",
"Cities": "Städte", "Cities": "Städte",
@@ -164,6 +165,7 @@
"Hotel surroundings": "Umgebung des Hotels", "Hotel surroundings": "Umgebung des Hotels",
"Hotel(s)": "{amount} {amount, plural, one {hotel} other {hotels}}", "Hotel(s)": "{amount} {amount, plural, one {hotel} other {hotels}}",
"Hotels": "Hotels", "Hotels": "Hotels",
"Hours": "Zeiten",
"How do you want to sleep?": "Wie möchtest du schlafen?", "How do you want to sleep?": "Wie möchtest du schlafen?",
"How it works": "Wie es funktioniert", "How it works": "Wie es funktioniert",
"Hurry up and use them before they expire!": "Beeilen Sie sich und nutzen Sie sie, bevor sie ablaufen!", "Hurry up and use them before they expire!": "Beeilen Sie sich und nutzen Sie sie, bevor sie ablaufen!",
@@ -256,6 +258,7 @@
"Open menu": "Menü öffnen", "Open menu": "Menü öffnen",
"Open my pages menu": "Meine Seiten Menü öffnen", "Open my pages menu": "Meine Seiten Menü öffnen",
"Opening Hours": "Öffnungszeiten", "Opening Hours": "Öffnungszeiten",
"Outdoor": "Im Freien",
"OutdoorPool": "Außenpool", "OutdoorPool": "Außenpool",
"Overview": "Übersicht", "Overview": "Übersicht",
"PETR": "Haustier", "PETR": "Haustier",
@@ -304,7 +307,7 @@
"Relax": "Entspannen", "Relax": "Entspannen",
"Remove card from member profile": "Karte aus dem Mitgliedsprofil entfernen", "Remove card from member profile": "Karte aus dem Mitgliedsprofil entfernen",
"Request bedtype": "Bettentyp anfragen", "Request bedtype": "Bettentyp anfragen",
"Restaurant": "{count, plural, one {#Restaurant} other {#Restaurants}}", "Restaurant": "{count, plural, one {Restaurant} other {Restaurants}}",
"Restaurant & Bar": "Restaurant & Bar", "Restaurant & Bar": "Restaurant & Bar",
"Restaurants & Bars": "Restaurants & Bars", "Restaurants & Bars": "Restaurants & Bars",
"Retype new password": "Neues Passwort erneut eingeben", "Retype new password": "Neues Passwort erneut eingeben",

View File

@@ -72,6 +72,7 @@
"Check out at latest": "Check out at latest", "Check out at latest": "Check out at latest",
"Check out the credit cards saved to your profile. Pay with a saved card when signed in for a smoother web experience.": "Check out the credit cards saved to your profile. Pay with a saved card when signed in for a smoother web experience.", "Check out the credit cards saved to your profile. Pay with a saved card when signed in for a smoother web experience.": "Check out the credit cards saved to your profile. Pay with a saved card when signed in for a smoother web experience.",
"Check-in": "Check-in", "Check-in": "Check-in",
"Check-in/Check-out": "Check-in/Check-out",
"Check-out": "Check-out", "Check-out": "Check-out",
"Child age is required": "Child age is required", "Child age is required": "Child age is required",
"Children": "Children", "Children": "Children",
@@ -182,6 +183,7 @@
"Hotel surroundings": "Hotel surroundings", "Hotel surroundings": "Hotel surroundings",
"Hotel(s)": "{amount} {amount, plural, one {hotel} other {hotels}}", "Hotel(s)": "{amount} {amount, plural, one {hotel} other {hotels}}",
"Hotels": "Hotels", "Hotels": "Hotels",
"Hours": "Hours",
"How do you want to sleep?": "How do you want to sleep?", "How do you want to sleep?": "How do you want to sleep?",
"How it works": "How it works", "How it works": "How it works",
"Hurry up and use them before they expire!": "Hurry up and use them before they expire!", "Hurry up and use them before they expire!": "Hurry up and use them before they expire!",
@@ -284,6 +286,7 @@
"Open menu": "Open menu", "Open menu": "Open menu",
"Open my pages menu": "Open my pages menu", "Open my pages menu": "Open my pages menu",
"Opening Hours": "Opening Hours", "Opening Hours": "Opening Hours",
"Outdoor": "Outdoor",
"OutdoorPool": "Outdoor pool", "OutdoorPool": "Outdoor pool",
"Overview": "Overview", "Overview": "Overview",
"PETR": "Pet", "PETR": "Pet",
@@ -344,7 +347,7 @@
"Request bedtype": "Request bedtype", "Request bedtype": "Request bedtype",
"Reservation number": "Reservation number", "Reservation number": "Reservation number",
"Reservation policy": "Reservation policy", "Reservation policy": "Reservation policy",
"Restaurant": "{count, plural, one {#Restaurant} other {#Restaurants}}", "Restaurant": "{count, plural, one {Restaurant} other {Restaurants}}",
"Restaurant & Bar": "Restaurant & Bar", "Restaurant & Bar": "Restaurant & Bar",
"Restaurants & Bars": "Restaurants & Bars", "Restaurants & Bars": "Restaurants & Bars",
"Retype new password": "Retype new password", "Retype new password": "Retype new password",

View File

@@ -64,6 +64,7 @@
"Check out": "Uloskirjautuminen", "Check out": "Uloskirjautuminen",
"Check out at latest": "Uloskirjautuminen viimeistään", "Check out at latest": "Uloskirjautuminen viimeistään",
"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.",
"Check-in/Check-out": "Sisäänkirjautuminen/Uloskirjautuminen",
"Children": "Lasta", "Children": "Lasta",
"Choose room": "Valitse huone", "Choose room": "Valitse huone",
"Cities": "Kaupungit", "Cities": "Kaupungit",
@@ -164,6 +165,7 @@
"Hotel surroundings": "Hotellin ympäristö", "Hotel surroundings": "Hotellin ympäristö",
"Hotel(s)": "{amount} {amount, plural, one {hotelli} other {hotellit}}", "Hotel(s)": "{amount} {amount, plural, one {hotelli} other {hotellit}}",
"Hotels": "Hotellit", "Hotels": "Hotellit",
"Hours": "Ajat",
"How do you want to sleep?": "Kuinka haluat nukkua?", "How do you want to sleep?": "Kuinka haluat nukkua?",
"How it works": "Kuinka se toimii", "How it works": "Kuinka se toimii",
"Hurry up and use them before they expire!": "Ole nopea ja käytä ne ennen kuin ne vanhenevat!", "Hurry up and use them before they expire!": "Ole nopea ja käytä ne ennen kuin ne vanhenevat!",
@@ -257,6 +259,7 @@
"Open menu": "Avaa valikko", "Open menu": "Avaa valikko",
"Open my pages menu": "Avaa omat sivut -valikko", "Open my pages menu": "Avaa omat sivut -valikko",
"Opening Hours": "Aukioloajat", "Opening Hours": "Aukioloajat",
"Outdoor": "Ulkona",
"OutdoorPool": "Ulkouima-allas", "OutdoorPool": "Ulkouima-allas",
"Overview": "Yleiskatsaus", "Overview": "Yleiskatsaus",
"PETR": "Lemmikki", "PETR": "Lemmikki",
@@ -305,7 +308,7 @@
"Relax": "Rentoutua", "Relax": "Rentoutua",
"Remove card from member profile": "Poista kortti jäsenprofiilista", "Remove card from member profile": "Poista kortti jäsenprofiilista",
"Request bedtype": "Pyydä sänkytyyppiä", "Request bedtype": "Pyydä sänkytyyppiä",
"Restaurant": "{count, plural, one {#Ravintola} other {#Restaurants}}", "Restaurant": "{count, plural, one {Ravintola} other {Ravintolat}}",
"Restaurant & Bar": "Ravintola & Baari", "Restaurant & Bar": "Ravintola & Baari",
"Restaurants & Bars": "Restaurants & Bars", "Restaurants & Bars": "Restaurants & Bars",
"Retype new password": "Kirjoita uusi salasana uudelleen", "Retype new password": "Kirjoita uusi salasana uudelleen",

View File

@@ -64,6 +64,7 @@
"Check out": "Sjekk ut", "Check out": "Sjekk ut",
"Check out at latest": "Utsjekking senest", "Check out at latest": "Utsjekking senest",
"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.",
"Check-in/Check-out": "Innsjekking/Utsjekking",
"Children": "Barn", "Children": "Barn",
"Choose room": "Velg rom", "Choose room": "Velg rom",
"Cities": "Byer", "Cities": "Byer",
@@ -163,6 +164,7 @@
"Hotel surroundings": "Hotellomgivelser", "Hotel surroundings": "Hotellomgivelser",
"Hotel(s)": "{amount} {amount, plural, one {hotell} other {hoteller}}", "Hotel(s)": "{amount} {amount, plural, one {hotell} other {hoteller}}",
"Hotels": "Hoteller", "Hotels": "Hoteller",
"Hours": "Tider",
"How do you want to sleep?": "Hvordan vil du sove?", "How do you want to sleep?": "Hvordan vil du sove?",
"How it works": "Hvordan det fungerer", "How it works": "Hvordan det fungerer",
"Hurry up and use them before they expire!": "Skynd deg og bruk dem før de utløper!", "Hurry up and use them before they expire!": "Skynd deg og bruk dem før de utløper!",
@@ -255,6 +257,7 @@
"Open menu": "Åpne menyen", "Open menu": "Åpne menyen",
"Open my pages menu": "Åpne mine sider menyen", "Open my pages menu": "Åpne mine sider menyen",
"Opening Hours": "Åpningstider", "Opening Hours": "Åpningstider",
"Outdoor": "Utendørs",
"OutdoorPool": "Utendørs basseng", "OutdoorPool": "Utendørs basseng",
"Overview": "Oversikt", "Overview": "Oversikt",
"PETR": "Kjæledyr", "PETR": "Kjæledyr",
@@ -303,7 +306,7 @@
"Relax": "Slappe av", "Relax": "Slappe av",
"Remove card from member profile": "Fjern kortet fra medlemsprofilen", "Remove card from member profile": "Fjern kortet fra medlemsprofilen",
"Request bedtype": "Be om sengetype", "Request bedtype": "Be om sengetype",
"Restaurant": "{count, plural, one {#Restaurant} other {#Restaurants}}", "Restaurant": "{count, plural, one {Restaurant} other {Restauranter}}",
"Restaurant & Bar": "Restaurant & Bar", "Restaurant & Bar": "Restaurant & Bar",
"Restaurants & Bars": "Restaurants & Bars", "Restaurants & Bars": "Restaurants & Bars",
"Retype new password": "Skriv inn nytt passord på nytt", "Retype new password": "Skriv inn nytt passord på nytt",

View File

@@ -64,6 +64,7 @@
"Check out": "Checka ut", "Check out": "Checka ut",
"Check out at latest": "Utcheckning senast", "Check out at latest": "Utcheckning senast",
"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.",
"Check-in/Check-out": "Inchecking/Utcheckning",
"Children": "Barn", "Children": "Barn",
"Choose room": "Välj rum", "Choose room": "Välj rum",
"Cities": "Städer", "Cities": "Städer",
@@ -163,6 +164,7 @@
"Hotel surroundings": "Hotellomgivning", "Hotel surroundings": "Hotellomgivning",
"Hotel(s)": "{amount} hotell", "Hotel(s)": "{amount} hotell",
"Hotels": "Hotell", "Hotels": "Hotell",
"Hours": "Tider",
"How do you want to sleep?": "Hur vill du sova?", "How do you want to sleep?": "Hur vill du sova?",
"How it works": "Hur det fungerar", "How it works": "Hur det fungerar",
"Hurry up and use them before they expire!": "Skynda dig och använd dem innan de går ut!", "Hurry up and use them before they expire!": "Skynda dig och använd dem innan de går ut!",
@@ -255,6 +257,7 @@
"Open menu": "Öppna menyn", "Open menu": "Öppna menyn",
"Open my pages menu": "Öppna mina sidor menyn", "Open my pages menu": "Öppna mina sidor menyn",
"Opening Hours": "Öppettider", "Opening Hours": "Öppettider",
"Outdoor": "Utomhus",
"OutdoorPool": "Utomhuspool", "OutdoorPool": "Utomhuspool",
"Overview": "Översikt", "Overview": "Översikt",
"PETR": "Husdjur", "PETR": "Husdjur",
@@ -303,7 +306,7 @@
"Relax": "Koppla av", "Relax": "Koppla av",
"Remove card from member profile": "Ta bort kortet från medlemsprofilen", "Remove card from member profile": "Ta bort kortet från medlemsprofilen",
"Request bedtype": "Request bedtype", "Request bedtype": "Request bedtype",
"Restaurant": "{count, plural, one {#Restaurang} other {#Restauranger}}", "Restaurant": "{count, plural, one {Restaurang} other {Restauranger}}",
"Restaurant & Bar": "Restaurang & Bar", "Restaurant & Bar": "Restaurang & Bar",
"Restaurants & Bars": "Restaurants & Bars", "Restaurants & Bars": "Restaurants & Bars",
"Retype new password": "Upprepa nytt lösenord", "Retype new password": "Upprepa nytt lösenord",

View File

Before

Width:  |  Height:  |  Size: 64 KiB

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 115 KiB

View File

Before

Width:  |  Height:  |  Size: 96 KiB

After

Width:  |  Height:  |  Size: 96 KiB

View File

@@ -56,7 +56,7 @@ const contactInformationSchema = z.object({
websiteUrl: z.string(), websiteUrl: z.string(),
}) })
const checkinSchema = z.object({ export const checkinSchema = z.object({
checkInTime: z.string(), checkInTime: z.string(),
checkOutTime: z.string(), checkOutTime: z.string(),
onlineCheckOutAvailableFrom: z.string().nullable().optional(), onlineCheckOutAvailableFrom: z.string().nullable().optional(),
@@ -110,6 +110,12 @@ const hotelContentSchema = z.object({
short: z.string(), short: z.string(),
medium: z.string(), medium: z.string(),
}), }),
meetingDescription: z
.object({
short: z.string().optional(),
medium: z.string().optional(),
})
.optional(),
}), }),
restaurantsOverviewPage: z.object({ restaurantsOverviewPage: z.object({
restaurantsOverviewPageLinkText: z.string().optional(), restaurantsOverviewPageLinkText: z.string().optional(),

View File

@@ -1,4 +1,4 @@
import { Hotel, ParkingData } from "@/types/hotel" import { CheckInData, Hotel, ParkingData } from "@/types/hotel"
export enum AvailabilityEnum { export enum AvailabilityEnum {
Available = "Available", Available = "Available",
@@ -17,5 +17,21 @@ export interface ContactProps {
} }
export interface ParkingProps { export interface ParkingProps {
parking: ParkingData parking: ParkingData[]
}
export interface AccessibilityProps {
accessibilityElevatorPitchText: string
}
export interface RestaurantProps {
restaurantsContentDescriptionMedium: string
}
export interface CheckInCheckOutProps {
checkin: CheckInData
}
export interface MeetingsAndConferencesProps {
meetingDescription: string
} }

View File

@@ -1,6 +1,7 @@
import { z } from "zod" import { z } from "zod"
import { import {
checkinSchema,
facilitySchema, facilitySchema,
getHotelDataSchema, getHotelDataSchema,
imageSchema, imageSchema,
@@ -23,6 +24,7 @@ export type HotelTripAdvisor =
export type RoomData = z.infer<typeof roomSchema> export type RoomData = z.infer<typeof roomSchema>
export type GalleryImage = z.infer<typeof imageSchema> export type GalleryImage = z.infer<typeof imageSchema>
export type CheckInData = z.infer<typeof checkinSchema>
export type PointOfInterest = z.output<typeof pointOfInterestSchema> export type PointOfInterest = z.output<typeof pointOfInterestSchema>