feat: Add AmenitiesList and IntroSection components to Hotel Page

This commit is contained in:
Chuma McPhoy
2024-07-05 19:26:34 +02:00
parent 1e3bbed6d1
commit 26815cc9bc
17 changed files with 257 additions and 7 deletions

View File

@@ -0,0 +1,18 @@
.amenitiesContainer {
display: grid;
gap: var(--Spacing-x-one-and-half);
height: fit-content;
}
.showAllButton {
padding: var(--Spacing-x-one-and-half) var(--Spacing-x0) !important;
}
@media screen and (min-width: 1367px) {
.amenitiesContainer {
background-color: var(--Scandic-Beige-10);
padding: var(--Spacing-x3) var(--Spacing-x3) var(--Spacing-x-one-and-half)
var(--Spacing-x3);
border-radius: var(--Corner-radius-Large);
}
}

View File

@@ -0,0 +1,39 @@
import { ChevronRightIcon } from "@/components/Icons"
import Button from "@/components/TempDesignSystem/Button"
import Body from "@/components/TempDesignSystem/Text/Body"
import Subtitle from "@/components/TempDesignSystem/Text/Subtitle"
import styles from "./amenitiesList.module.css"
import { HotelData } from "@/types/hotel"
export default function AmenitiesList({
detailedFacilities,
}: {
detailedFacilities: HotelData["data"]["attributes"]["detailedFacilities"]
}) {
const sortedAmenities = detailedFacilities
.sort((a, b) => b.sortOrder - a.sortOrder)
.slice(0, 5)
return (
<section className={styles.amenitiesContainer}>
<Subtitle color="black">At the hotel</Subtitle>
<div>
{sortedAmenities.map((facility, index) => (
<Body color="textMediumContrast" key={facility.id}>
{facility.name}
</Body>
))}
</div>
<Button
className={styles.showAllButton}
theme="base"
variant="icon"
intent="text"
>
Show all amenities
<ChevronRightIcon />
</Button>
</section>
)
}

View File

@@ -1,6 +1,7 @@
import { serverClient } from "@/lib/trpc/server"
import Title from "@/components/TempDesignSystem/Text/Title"
import AmenitiesList from "./AmenitiesList"
import IntroSection from "./IntroSection"
import styles from "./hotelPage.module.css"
@@ -18,9 +19,23 @@ export default async function HotelPage({ lang }: LangParams) {
hotelId: hotelPageIdentifierData.hotel_page_id,
language: lang,
})
return (
<section className={styles.content}>
<Title>{hotelPageData.data.attributes.name}</Title>
</section>
<main className={styles.pageContainer}>
<div className={styles.introContainer}>
<IntroSection
hotelName={hotelPageData.data.attributes.name}
hotelDescription={
hotelPageData.data.attributes.hotelContent.texts.descriptions.short
}
location={hotelPageData.data.attributes.location}
address={hotelPageData.data.attributes.address}
tripAdvisor={hotelPageData.data.attributes.ratings.tripAdvisor}
/>
<AmenitiesList
detailedFacilities={hotelPageData.data.attributes.detailedFacilities}
/>
</div>
</main>
)
}

View File

@@ -0,0 +1,73 @@
import ArrowRight from "@/components/Icons/ArrowRight"
import TripAdvisorIcon from "@/components/Icons/TripAdvisor"
import Link from "@/components/TempDesignSystem/Link"
import BiroScript from "@/components/TempDesignSystem/Text/BiroScript"
import Body from "@/components/TempDesignSystem/Text/Body"
import Subtitle from "@/components/TempDesignSystem/Text/Subtitle"
import Title from "@/components/TempDesignSystem/Text/Title"
import { getIntl } from "@/i18n"
import styles from "./introSection.module.css"
import { HotelAddress, HotelData, HotelLocation } from "@/types/hotel"
export default async function IntroSection({
hotelName,
hotelDescription,
location,
address,
tripAdvisor,
}: {
hotelName: HotelData["data"]["attributes"]["name"]
hotelDescription: HotelData["data"]["attributes"]["hotelContent"]["texts"]["descriptions"]["short"]
location: HotelLocation
address: HotelAddress
tripAdvisor: HotelData["data"]["attributes"]["ratings"]["tripAdvisor"]
}) {
const intl = await getIntl()
const { formatMessage } = intl
const { streetAddress, city } = address
const { distanceToCentre } = location
const formattedDistanceText = formatMessage(
{ id: "Distance to city centre" },
{ number: distanceToCentre }
)
const formattedLocationText = `${streetAddress}, ${city} (${formattedDistanceText})`
const formattedTripAdvisorText = `${tripAdvisor.rating} (${tripAdvisor.numberOfReviews} reviews on tripadvisor)`
return (
<section className={styles.introSection}>
<BiroScript className={styles.welcomeLabel} color="red">
{formatMessage({ id: "Welcome to" })}:
</BiroScript>
<div className={styles.mainContent}>
<Title level="h2">{hotelName}</Title>
<Body color="textMediumContrast">{formattedLocationText}</Body>
<Link
className={styles.introLink}
target="_blank"
variant="icon"
color="peach80"
href={tripAdvisor.webUrl}
>
<TripAdvisorIcon color="peach80" />
{formattedTripAdvisorText}
</Link>
</div>
<div className={styles.subtitleContent}>
<Subtitle color="black">{hotelDescription}</Subtitle>
<Link
className={styles.introLink}
target="_blank"
color="peach80"
variant="icon"
href="#"
>
{/*TODO: Ask content team where this should link to. */}
Read more about the hotel
<ArrowRight color="peach80" />
</Link>
</div>
</section>
)
}

View File

@@ -0,0 +1,27 @@
.introSection {
margin-top: var(--Spacing-x3);
display: grid;
gap: var(--Spacing-x3);
position: relative;
}
.mainContent {
display: grid;
gap: var(--Spacing-x1);
}
.subtitleContent {
display: grid;
gap: var(--Spacing-x-one-and-half);
}
.welcomeLabel {
/* TODO: Update and use absolute position. */
transform: rotate(-3.378deg) translate(0px, -15px);
}
.introLink {
text-decoration: underline !important;
text-decoration-color: var(--Scandic-Peach-80);
width: fit-content;
}

View File

@@ -1,11 +1,23 @@
.content {
.pageContainer {
display: grid;
gap: var(--Spacing-x4);
gap: var(--Spacing-x9);
padding: var(--Spacing-x3) var(--Spacing-x3) var(--Spacing-x4);
}
.introContainer {
display: grid;
grid-template-columns: 1fr;
gap: var(--Spacing-x4);
}
@media screen and (min-width: 1367px) {
.content {
.pageContainer {
gap: var(--Spacing-x3);
padding-left: var(--Spacing-x5);
}
.introContainer {
display: grid;
gap: 105px;
grid-template-columns: 607px 340px;
}
}