feat(SW-750): add about the hotel sidepeek

This commit is contained in:
Fredrik Thorsson
2024-11-18 13:15:25 +01:00
parent be3716bb1a
commit 9344db7876
10 changed files with 268 additions and 8 deletions

View File

@@ -0,0 +1,47 @@
.wrapper {
display: flex;
flex-direction: column;
gap: var(--Spacing-x-one-and-half);
}
.placeholder {
display: grid;
grid-template-columns: 1fr 1fr;
gap: var(--Spacing-x2);
grid-template-areas:
"address drivingDirections"
"contact socials"
"email email"
"ecoLabel ecoLabel";
}
.address {
grid-area: address;
}
.drivingDirections {
grid-area: drivingDirections;
}
.contact {
grid-area: contact;
}
.socials {
grid-area: socials;
}
.socialIcons {
display: flex;
gap: var(--Spacing-x1);
}
.email {
grid-area: email;
}
.ecoLabel {
grid-area: ecoLabel;
display: flex;
gap: var(--Spacing-x-one-and-half);
}

View File

@@ -0,0 +1,116 @@
import { InstagramIcon } from "@/components/Icons"
import FacebookIcon from "@/components/Icons/Facebook"
import Image from "@/components/Image"
import Link from "@/components/TempDesignSystem/Link"
import Body from "@/components/TempDesignSystem/Text/Body"
import Caption from "@/components/TempDesignSystem/Text/Caption"
import Subtitle from "@/components/TempDesignSystem/Text/Subtitle"
import { getIntl } from "@/i18n"
import { getLang } from "@/i18n/serverContext"
import styles from "./contactInformation.module.css"
import type { ContactInformationProps } from "@/types/components/hotelPage/sidepeek/contactInformation"
export default async function ContactInformation({
adress,
coordinates,
contact,
socials,
ecoLabels,
}: ContactInformationProps) {
const intl = await getIntl()
const lang = getLang()
return (
<div className={styles.wrapper}>
<Subtitle color="burgundy">
{intl.formatMessage({ id: "Practical information" })}
</Subtitle>
<div className={styles.placeholder}>
<div className={styles.address}>
<Body textTransform="bold">
{intl.formatMessage({ id: "Address" })}
</Body>
<Body color="uiTextHighContrast">{adress.streetAddress}</Body>
<Body color="uiTextHighContrast">{adress.city}</Body>
</div>
<div className={styles.drivingDirections}>
<Body textTransform="bold">
{intl.formatMessage({ id: "Driving directions" })}
</Body>
<Link
href={`https://www.google.com/maps/dir/?api=1&destination=${coordinates.lat},${coordinates.lng}`}
target="_blank"
color="peach80"
textDecoration="underline"
>
Google Maps
</Link>
</div>
<div className={styles.contact}>
<Body textTransform="bold">
{intl.formatMessage({ id: "Contact us" })}
</Body>
<Body>
<Link
href={`tel:+${contact.phoneNumber}`}
color="peach80"
textDecoration="underline"
>
{contact.phoneNumber}
</Link>
</Body>
</div>
<div className={styles.socials}>
<Body textTransform="bold">
{intl.formatMessage({ id: "Follow us" })}
</Body>
<div className={styles.socialIcons}>
<Link
href={
socials.instagram || "https://www.instagram.com/scandichotels/"
}
>
<InstagramIcon color="burgundy" />
</Link>
<Link
href={socials.facebook || "https://www.facebook.com/Scandic/"}
>
<FacebookIcon color="burgundy" />
</Link>
</div>
</div>
<div className={styles.email}>
<Body textTransform="bold">
{intl.formatMessage({ id: "Email" })}
</Body>
<Link
href={`mailto:${contact.email}`}
color="peach80"
textDecoration="underline"
>
{contact.email}
</Link>
</div>
{ecoLabels.nordicEcoLabel ? (
<div className={styles.ecoLabel}>
<Image
height={38}
width={38}
alt={intl.formatMessage({ id: "Nordic Swan Ecolabel" })}
src={`/_static/img/icons/swan-eco/swan_eco_dark_${lang}.png`}
/>
<div>
<Caption color="uiTextPlaceholder">
{intl.formatMessage({ id: "Nordic Swan Ecolabel" })}
</Caption>
<Caption color="uiTextPlaceholder">
{ecoLabels.svanenEcoLabelCertificateNumber}
</Caption>
</div>
</div>
) : null}
</div>
</div>
)
}

View File

@@ -0,0 +1,5 @@
.wrapper {
display: flex;
flex-direction: column;
gap: var(--Spacing-x3);
}

View File

@@ -0,0 +1,53 @@
import { about } from "@/constants/routes/hotelPageParams"
import Button from "@/components/TempDesignSystem/Button"
import Divider from "@/components/TempDesignSystem/Divider"
import Link from "@/components/TempDesignSystem/Link"
import SidePeek from "@/components/TempDesignSystem/SidePeek"
import Body from "@/components/TempDesignSystem/Text/Body"
import Preamble from "@/components/TempDesignSystem/Text/Preamble"
import { getIntl } from "@/i18n"
import { getLang } from "@/i18n/serverContext"
import ContactInformation from "./ContactInformation"
import styles from "./aboutTheHotel.module.css"
import type { AboutTheHotelSidePeekProps } from "@/types/components/hotelPage/sidepeek/aboutTheHotel"
export default async function AboutTheHotelSidePeek({
hotelAdress,
coordinates,
contact,
socials,
ecoLabels,
descriptions,
}: AboutTheHotelSidePeekProps) {
const lang = getLang()
const intl = await getIntl()
return (
<SidePeek
contentKey={about[lang]}
title={intl.formatMessage({ id: "About the hotel" })}
>
<section className={styles.wrapper}>
<ContactInformation
adress={hotelAdress}
coordinates={coordinates}
contact={contact}
socials={socials}
ecoLabels={ecoLabels}
/>
<Divider color="baseSurfaceSutbleHover" />
<Preamble>{descriptions.short}</Preamble>
<Body>{descriptions.medium}</Body>
<Button fullWidth theme="base" intent="secondary" asChild>
<Link href="#" color="burgundy" weight="bold">
{intl.formatMessage({ id: "Read more about the hotel" })}
</Link>
</Button>
</section>
</SidePeek>
)
}

View File

@@ -16,6 +16,7 @@ import MapCard from "./Map/MapCard"
import MapWithCardWrapper from "./Map/MapWithCard"
import MobileMapToggle from "./Map/MobileMapToggle"
import StaticMap from "./Map/StaticMap"
import AboutTheHotelSidePeek from "./SidePeeks/AboutTheHotel"
import WellnessAndExerciseSidePeek from "./SidePeeks/WellnessAndExercise"
import AmenitiesList from "./AmenitiesList"
import Facilities from "./Facilities"
@@ -54,6 +55,9 @@ export default async function HotelPage() {
faq,
alerts,
healthFacilities,
contact,
socials,
ecoLabels,
} = hotelData
const topThreePois = pointsOfInterest.slice(0, 3)
@@ -80,7 +84,7 @@ export default async function HotelPage() {
<div className={styles.introContainer}>
<IntroSection
hotelName={hotelName}
hotelDescription={hotelDescription}
hotelDescription={hotelDescription.short}
location={hotelLocation}
address={hotelAddress}
tripAdvisor={hotelRatings?.tripAdvisor}
@@ -134,12 +138,14 @@ export default async function HotelPage() {
{/* TODO: Render amenities as per the design. */}
Read more about the amenities here
</SidePeek>
<SidePeek
contentKey={hotelPageParams.about[lang]}
title={intl.formatMessage({ id: "Read more about the hotel" })}
>
Some additional information about the hotel
</SidePeek>
<AboutTheHotelSidePeek
hotelAdress={hotelAddress}
coordinates={coordinates}
contact={contact}
socials={socials}
ecoLabels={ecoLabels}
descriptions={hotelDescription}
/>
<SidePeek
contentKey={hotelPageParams.restaurantAndBar[lang]}
title={intl.formatMessage({ id: "Restaurant & Bar" })}

View File

@@ -51,3 +51,7 @@
.opacity8 {
opacity: 0.08;
}
.baseSurfaceSubtleHover {
background-color: var(--Base-Surface-Subtle-Hover);
}

View File

@@ -13,6 +13,7 @@ export const dividerVariants = cva(styles.divider, {
primaryLightSubtle: styles.primaryLightSubtle,
subtle: styles.subtle,
white: styles.white,
baseSurfaceSutbleHover: styles.baseSurfaceSubtleHover,
},
opacity: {
100: styles.opacity100,

View File

@@ -342,7 +342,7 @@ export const hotelQueryRouter = router({
return {
hotelId,
hotelName: hotelAttributes.name,
hotelDescription: hotelAttributes.hotelContent.texts.descriptions.short,
hotelDescription: hotelAttributes.hotelContent.texts.descriptions,
hotelLocation: hotelAttributes.location,
hotelAddress: hotelAttributes.address,
hotelRatings: hotelAttributes.ratings,
@@ -355,6 +355,9 @@ export const hotelQueryRouter = router({
alerts: hotelAlerts,
faq: contentstackData?.faq,
healthFacilities: hotelAttributes.healthFacilities,
contact: hotelAttributes.contactInformation,
socials: hotelAttributes.socialMedia,
ecoLabels: hotelAttributes.hotelFacts.ecoLabels,
}
}),
availability: router({

View File

@@ -0,0 +1,13 @@
import type { Hotel, HotelAddress } from "@/types/hotel"
export type AboutTheHotelSidePeekProps = {
hotelAdress: HotelAddress
coordinates: {
lat: number
lng: number
}
contact: Hotel["contactInformation"]
socials: Hotel["socialMedia"]
ecoLabels: Hotel["hotelFacts"]["ecoLabels"]
descriptions: Hotel["hotelContent"]["texts"]["descriptions"]
}

View File

@@ -0,0 +1,12 @@
import type { Hotel, HotelAddress } from "@/types/hotel"
export type ContactInformationProps = {
adress: HotelAddress
coordinates: {
lat: number
lng: number
}
contact: Hotel["contactInformation"]
socials: Hotel["socialMedia"]
ecoLabels: Hotel["hotelFacts"]["ecoLabels"]
}