Merged in feat/SW-1740-final-design-subpages (pull request #1435)
feat/SW-1740 final design subpages * feat(SW-1740): update design for subpages * feat(SW-1740): add padding * feat(SW-1740): use not pseudo class Approved-by: Erik Tiekstra Approved-by: Matilda Landström
This commit is contained in:
@@ -22,23 +22,25 @@ export default async function MeetingsSidebar({
|
||||
|
||||
return (
|
||||
<aside className={styles.sidebar}>
|
||||
<Title level="h3" as="h4">
|
||||
{intl.formatMessage({ id: "Contact us" })}
|
||||
</Title>
|
||||
<div>
|
||||
<Link href={`tel:${phoneNumber}`}>{phoneNumber}</Link>
|
||||
{country === Country.Finland ? (
|
||||
<Body>
|
||||
{intl.formatMessage({
|
||||
id: "Price 0,16 €/min + local call charges",
|
||||
})}
|
||||
</Body>
|
||||
) : null}
|
||||
{email && (
|
||||
<Link textDecoration="underline" href={`mailto:${email}`}>
|
||||
{email}
|
||||
</Link>
|
||||
)}
|
||||
<div className={styles.content}>
|
||||
<Title level="h3" as="h4">
|
||||
{intl.formatMessage({ id: "Contact us" })}
|
||||
</Title>
|
||||
<div>
|
||||
<Link href={`tel:${phoneNumber}`}>{phoneNumber}</Link>
|
||||
{country === Country.Finland ? (
|
||||
<Body>
|
||||
{intl.formatMessage({
|
||||
id: "Price 0,16 €/min + local call charges",
|
||||
})}
|
||||
</Body>
|
||||
) : null}
|
||||
{email && (
|
||||
<Link textDecoration="underline" href={`mailto:${email}`}>
|
||||
{email}
|
||||
</Link>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</aside>
|
||||
)
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
import NextLink from "next/link"
|
||||
|
||||
import { OpenInNewIcon } from "@/components/Icons"
|
||||
import Button from "@/components/TempDesignSystem/Button"
|
||||
import Link from "@/components/TempDesignSystem/Link"
|
||||
import Body from "@/components/TempDesignSystem/Text/Body"
|
||||
import Title from "@/components/TempDesignSystem/Text/Title"
|
||||
@@ -18,43 +14,29 @@ interface HotelSidebarProps {
|
||||
export default async function ParkingSidebar({ hotel }: HotelSidebarProps) {
|
||||
const intl = await getIntl()
|
||||
|
||||
const parking = hotel.parking
|
||||
.map((parking) => ({ url: parking.externalParkingUrl, type: parking.type }))
|
||||
.filter(
|
||||
(parking): parking is { type: string; url: string } => !!parking.url
|
||||
)
|
||||
|
||||
return (
|
||||
<aside className={styles.sidebar}>
|
||||
<Title level="h3" as="h4">
|
||||
{intl.formatMessage({ id: "Address" })}
|
||||
</Title>
|
||||
<div>
|
||||
<Body color="uiTextHighContrast">{hotel.address.streetAddress}</Body>
|
||||
<Body color="uiTextHighContrast">
|
||||
{hotel.address.zipCode} {hotel.address.city}
|
||||
</Body>
|
||||
<Body color="uiTextHighContrast">{hotel.address.country}</Body>
|
||||
<div className={styles.content}>
|
||||
<Title level="h3" as="h4">
|
||||
{intl.formatMessage({ id: "Address" })}
|
||||
</Title>
|
||||
<div>
|
||||
<Body color="uiTextHighContrast">{hotel.address.streetAddress}</Body>
|
||||
<Body color="uiTextHighContrast">
|
||||
{hotel.address.zipCode} {hotel.address.city}
|
||||
</Body>
|
||||
<Body color="uiTextHighContrast">{hotel.address.country}</Body>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Title level="h3" as="h4">
|
||||
{intl.formatMessage({ id: "Contact us" })}
|
||||
</Title>
|
||||
<Link href={`tel:${hotel.contactInformation.phoneNumber}`}>
|
||||
{hotel.contactInformation.phoneNumber}
|
||||
</Link>
|
||||
|
||||
{parking.map(({ url, type }) => (
|
||||
<Button key={type} theme="base" intent="primary" variant="icon" asChild>
|
||||
<NextLink href={url} target="_blank">
|
||||
{intl.formatMessage(
|
||||
{ id: "Book {type} parking" },
|
||||
{ type: type.toLowerCase() }
|
||||
)}
|
||||
<OpenInNewIcon />
|
||||
</NextLink>
|
||||
</Button>
|
||||
))}
|
||||
<div className={styles.content}>
|
||||
<Title level="h3" as="h4">
|
||||
{intl.formatMessage({ id: "Contact us" })}
|
||||
</Title>
|
||||
<Link href={`tel:${hotel.contactInformation.phoneNumber}`}>
|
||||
{hotel.contactInformation.phoneNumber}
|
||||
</Link>
|
||||
</div>
|
||||
</aside>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ import Body from "@/components/TempDesignSystem/Text/Body"
|
||||
import Title from "@/components/TempDesignSystem/Text/Title"
|
||||
import { getIntl } from "@/i18n"
|
||||
|
||||
import styles from "./restaurantSiderbar.module.css"
|
||||
import styles from "./sidebar.module.css"
|
||||
|
||||
import type { Hotel, Restaurant } from "@/types/hotel"
|
||||
|
||||
@@ -42,11 +42,13 @@ export default async function RestaurantSidebar({
|
||||
</div>
|
||||
) : null}
|
||||
{bookTableUrl && (
|
||||
<Button intent="primary" theme="base" asChild>
|
||||
<a href={bookTableUrl}>
|
||||
{intl.formatMessage({ id: "Book a table online" })}
|
||||
</a>
|
||||
</Button>
|
||||
<div className={styles.buttonContainer}>
|
||||
<Button intent="primary" theme="base" asChild>
|
||||
<a href={bookTableUrl}>
|
||||
{intl.formatMessage({ id: "Book a table online" })}
|
||||
</a>
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
{restaurant.menus.length ? (
|
||||
<div className={styles.content}>
|
||||
@@ -1,15 +0,0 @@
|
||||
.sidebar {
|
||||
display: grid;
|
||||
gap: var(--Spacing-x3);
|
||||
}
|
||||
|
||||
.content {
|
||||
display: grid;
|
||||
gap: var(--Spacing-x-one-and-half);
|
||||
}
|
||||
|
||||
.menuList {
|
||||
display: grid;
|
||||
gap: var(--Spacing-x-half);
|
||||
list-style-type: none;
|
||||
}
|
||||
@@ -19,59 +19,69 @@ export default async function WellnessSidebar({ hotel }: WellnessSidebarProps) {
|
||||
|
||||
return (
|
||||
<aside className={styles.sidebar}>
|
||||
<Title level="h3" as="h4">
|
||||
{intl.formatMessage({ id: "Opening hours" })}
|
||||
</Title>
|
||||
{hotel.healthFacilities.map((facility) => (
|
||||
<div key={facility.type}>
|
||||
<Subtitle type="two" color="uiTextHighContrast" asChild>
|
||||
<h4>{translateWellnessType(facility.type, intl)}</h4>
|
||||
</Subtitle>
|
||||
<div className={styles.content}>
|
||||
<Title level="h3" as="h4">
|
||||
{intl.formatMessage({ id: "Opening hours" })}
|
||||
</Title>
|
||||
{hotel.healthFacilities.map((facility) => (
|
||||
<div key={facility.type}>
|
||||
<Subtitle type="two" color="uiTextHighContrast" asChild>
|
||||
<h4>{translateWellnessType(facility.type, intl)}</h4>
|
||||
</Subtitle>
|
||||
<Body color="uiTextHighContrast">
|
||||
{facility.openingDetails.openingHours.ordinary.alwaysOpen
|
||||
? intl.formatMessage({ id: "Mon-Fri Always open" })
|
||||
: intl.formatMessage(
|
||||
{ id: "Mon-Fri {openingTime}-{closingTime}" },
|
||||
{
|
||||
openingTime:
|
||||
facility.openingDetails.openingHours.ordinary
|
||||
.openingTime,
|
||||
closingTime:
|
||||
facility.openingDetails.openingHours.ordinary
|
||||
.closingTime,
|
||||
}
|
||||
)}
|
||||
</Body>
|
||||
<Body color="uiTextHighContrast">
|
||||
{facility.openingDetails.openingHours.weekends.alwaysOpen
|
||||
? intl.formatMessage({ id: "Sat-Sun Always open" })
|
||||
: intl.formatMessage(
|
||||
{ id: "Sat-Sun {openingTime}-{closingTime}" },
|
||||
{
|
||||
openingTime:
|
||||
facility.openingDetails.openingHours.weekends
|
||||
.openingTime,
|
||||
closingTime:
|
||||
facility.openingDetails.openingHours.weekends
|
||||
.closingTime,
|
||||
}
|
||||
)}
|
||||
</Body>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<div className={styles.content}>
|
||||
<Title level="h3" as="h4">
|
||||
{intl.formatMessage({ id: "Address" })}
|
||||
</Title>
|
||||
<div>
|
||||
<Body color="uiTextHighContrast">{hotel.address.streetAddress}</Body>
|
||||
<Body color="uiTextHighContrast">
|
||||
{facility.openingDetails.openingHours.ordinary.alwaysOpen
|
||||
? intl.formatMessage({ id: "Mon-Fri Always open" })
|
||||
: intl.formatMessage(
|
||||
{ id: "Mon-Fri {openingTime}-{closingTime}" },
|
||||
{
|
||||
openingTime:
|
||||
facility.openingDetails.openingHours.ordinary.openingTime,
|
||||
closingTime:
|
||||
facility.openingDetails.openingHours.ordinary.closingTime,
|
||||
}
|
||||
)}
|
||||
</Body>
|
||||
<Body color="uiTextHighContrast">
|
||||
{facility.openingDetails.openingHours.weekends.alwaysOpen
|
||||
? intl.formatMessage({ id: "Sat-Sun Always open" })
|
||||
: intl.formatMessage(
|
||||
{ id: "Sat-Sun {openingTime}-{closingTime}" },
|
||||
{
|
||||
openingTime:
|
||||
facility.openingDetails.openingHours.weekends.openingTime,
|
||||
closingTime:
|
||||
facility.openingDetails.openingHours.weekends.closingTime,
|
||||
}
|
||||
)}
|
||||
{hotel.address.zipCode} {hotel.address.city}
|
||||
</Body>
|
||||
<Body color="uiTextHighContrast">{hotel.address.country}</Body>
|
||||
</div>
|
||||
))}
|
||||
<Title level="h3" as="h4">
|
||||
{intl.formatMessage({ id: "Address" })}
|
||||
</Title>
|
||||
<div>
|
||||
<Body color="uiTextHighContrast">{hotel.address.streetAddress}</Body>
|
||||
<Body color="uiTextHighContrast">
|
||||
{hotel.address.zipCode} {hotel.address.city}
|
||||
</Body>
|
||||
<Body color="uiTextHighContrast">{hotel.address.country}</Body>
|
||||
</div>
|
||||
|
||||
<Title level="h3" as="h4">
|
||||
{intl.formatMessage({ id: "Contact us" })}
|
||||
</Title>
|
||||
<Link href={`tel:${hotel.contactInformation.phoneNumber}`}>
|
||||
{hotel.contactInformation.phoneNumber}
|
||||
</Link>
|
||||
<div className={styles.content}>
|
||||
<Title level="h3" as="h4">
|
||||
{intl.formatMessage({ id: "Contact us" })}
|
||||
</Title>
|
||||
<Link href={`tel:${hotel.contactInformation.phoneNumber}`}>
|
||||
{hotel.contactInformation.phoneNumber}
|
||||
</Link>
|
||||
</div>
|
||||
</aside>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import RestaurantSidebar from "./RestaurantSidebar/RestaurantSidebar"
|
||||
import MeetingsSidebar from "./MeetingsSidebar"
|
||||
import ParkingSidebar from "./ParkingSidebar"
|
||||
import RestaurantSidebar from "./RestaurantSidebar"
|
||||
import WellnessSidebar from "./WellnessSidebar"
|
||||
|
||||
import type { MeetingRooms } from "@/types/components/hotelPage/meetingRooms"
|
||||
|
||||
@@ -1,13 +1,32 @@
|
||||
.sidebar {
|
||||
display: grid;
|
||||
gap: var(--Spacing-x2);
|
||||
gap: var(--Spacing-x3);
|
||||
grid-column: 1;
|
||||
}
|
||||
|
||||
.content {
|
||||
display: grid;
|
||||
gap: var(--Spacing-x-one-and-half);
|
||||
}
|
||||
|
||||
.menuList {
|
||||
display: grid;
|
||||
gap: var(--Spacing-x-half);
|
||||
list-style-type: none;
|
||||
}
|
||||
|
||||
.buttonContainer {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@media (min-width: 1367px) {
|
||||
.sidebar {
|
||||
grid-column: 2;
|
||||
grid-row: 1;
|
||||
grid-row: 1 / span 2;
|
||||
align-items: start;
|
||||
}
|
||||
|
||||
.buttonContainer {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.hotelSubpage {
|
||||
.hotelSubpage:not(.hasStickyButton) {
|
||||
padding-bottom: var(--Spacing-x9);
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
.contentContainer {
|
||||
display: grid;
|
||||
gap: var(--Spacing-x4);
|
||||
gap: var(--Spacing-x3);
|
||||
align-items: start;
|
||||
width: 100%;
|
||||
max-width: var(--max-width-content);
|
||||
@@ -49,19 +49,43 @@
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.buttonContainer {
|
||||
position: sticky;
|
||||
padding: var(--Spacing-x3) var(--Spacing-x2);
|
||||
background-color: var(--Base-Surface-Secondary-light-Normal);
|
||||
border-top: 1px solid var(--Base-Border-Subtle);
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
@media (min-width: 1367px) {
|
||||
.hotelSubpage {
|
||||
padding-bottom: var(--Spacing-x9);
|
||||
}
|
||||
|
||||
.contentContainer {
|
||||
grid-template-columns: var(--max-width-text-block) 1fr;
|
||||
grid-template-rows: auto 1fr;
|
||||
row-gap: var(--Spacing-x2);
|
||||
column-gap: var(--Spacing-x9);
|
||||
padding: var(--Spacing-x4) 0 0;
|
||||
}
|
||||
|
||||
.divider {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.mainContent {
|
||||
padding: 0;
|
||||
max-width: none;
|
||||
margin: 0;
|
||||
gap: var(--Spacing-x3);
|
||||
max-width: none;
|
||||
}
|
||||
|
||||
.meetingsContent {
|
||||
grid-column: 1 / span 2;
|
||||
}
|
||||
|
||||
.buttonContainer {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,6 +10,8 @@ import {
|
||||
import Breadcrumbs from "@/components/Breadcrumbs"
|
||||
import Hero from "@/components/Hero"
|
||||
import BreadcrumbsSkeleton from "@/components/TempDesignSystem/Breadcrumbs/BreadcrumbsSkeleton"
|
||||
import Button from "@/components/TempDesignSystem/Button"
|
||||
import Divider from "@/components/TempDesignSystem/Divider"
|
||||
import Preamble from "@/components/TempDesignSystem/Text/Preamble"
|
||||
import Title from "@/components/TempDesignSystem/Text/Title"
|
||||
import { getIntl } from "@/i18n"
|
||||
@@ -56,6 +58,10 @@ export default async function HotelSubpage({
|
||||
meetingRooms = await getMeetingRooms({ hotelId: hotelId, language: lang })
|
||||
}
|
||||
|
||||
const restaurantButton = restaurants.find(
|
||||
(restaurant) => restaurant.nameInUrl === subpage
|
||||
)
|
||||
|
||||
const meetingBookingWidget = meetingRooms ? (
|
||||
<div className={styles.meetingBookingWidget}>
|
||||
Booking Widget Placeholder
|
||||
@@ -64,7 +70,9 @@ export default async function HotelSubpage({
|
||||
|
||||
return (
|
||||
<>
|
||||
<section className={styles.hotelSubpage}>
|
||||
<section
|
||||
className={`${styles.hotelSubpage} ${restaurantButton?.bookTableUrl ? styles.hasStickyButton : ""} `}
|
||||
>
|
||||
<div className={styles.header}>
|
||||
<Suspense fallback={<BreadcrumbsSkeleton />}>
|
||||
<Breadcrumbs
|
||||
@@ -87,11 +95,20 @@ export default async function HotelSubpage({
|
||||
</div>
|
||||
|
||||
<div className={styles.contentContainer}>
|
||||
<Title as="h2" level="h1">
|
||||
{pageData.heading}
|
||||
</Title>
|
||||
|
||||
<HotelSubpageSidebar
|
||||
subpage={subpage}
|
||||
hotel={hotel}
|
||||
additionalData={additionalData}
|
||||
restaurants={restaurants}
|
||||
meetingRooms={meetingRooms}
|
||||
/>
|
||||
<Divider color="baseSurfaceSubtleHover" className={styles.divider} />
|
||||
<main className={styles.mainContent}>
|
||||
<div className={styles.intro}>
|
||||
<Title as="h2" level="h1">
|
||||
{pageData.heading}
|
||||
</Title>
|
||||
<Preamble>{pageData.elevatorPitch}</Preamble>
|
||||
</div>
|
||||
|
||||
@@ -103,21 +120,21 @@ export default async function HotelSubpage({
|
||||
additionalData={additionalData}
|
||||
/>
|
||||
</main>
|
||||
|
||||
{meetingRooms && (
|
||||
<div className={styles.meetingsContent}>
|
||||
<MeetingsAdditionalContent rooms={meetingRooms} />
|
||||
</div>
|
||||
)}
|
||||
|
||||
<HotelSubpageSidebar
|
||||
subpage={subpage}
|
||||
hotel={hotel}
|
||||
additionalData={additionalData}
|
||||
restaurants={restaurants}
|
||||
meetingRooms={meetingRooms}
|
||||
/>
|
||||
</div>
|
||||
{restaurantButton?.bookTableUrl && (
|
||||
<div className={styles.buttonContainer}>
|
||||
<Button intent="primary" theme="base" asChild>
|
||||
<a href={restaurantButton.bookTableUrl}>
|
||||
{intl.formatMessage({ id: "Book a table online" })}
|
||||
</a>
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
</section>
|
||||
{/* Tracking */}
|
||||
</>
|
||||
|
||||
@@ -21,31 +21,31 @@ export default async function OpeningHours({
|
||||
const weekdayDefinitions = [
|
||||
{
|
||||
key: "monday",
|
||||
label: intl.formatMessage({ id: "monday" }),
|
||||
label: intl.formatMessage({ id: "Monday" }),
|
||||
},
|
||||
{
|
||||
key: "tuesday",
|
||||
label: intl.formatMessage({ id: "tuesday" }),
|
||||
label: intl.formatMessage({ id: "Tuesday" }),
|
||||
},
|
||||
{
|
||||
key: "wednesday",
|
||||
label: intl.formatMessage({ id: "wednesday" }),
|
||||
label: intl.formatMessage({ id: "Wednesday" }),
|
||||
},
|
||||
{
|
||||
key: "thursday",
|
||||
label: intl.formatMessage({ id: "thursday" }),
|
||||
label: intl.formatMessage({ id: "Thursday" }),
|
||||
},
|
||||
{
|
||||
key: "friday",
|
||||
label: intl.formatMessage({ id: "friday" }),
|
||||
label: intl.formatMessage({ id: "Friday" }),
|
||||
},
|
||||
{
|
||||
key: "saturday",
|
||||
label: intl.formatMessage({ id: "saturday" }),
|
||||
label: intl.formatMessage({ id: "Saturday" }),
|
||||
},
|
||||
{
|
||||
key: "sunday",
|
||||
label: intl.formatMessage({ id: "sunday" }),
|
||||
label: intl.formatMessage({ id: "Sunday" }),
|
||||
},
|
||||
] as const
|
||||
|
||||
|
||||
Reference in New Issue
Block a user