fix(SW-1241): Adjusted amenities sidepeek on hotel pages and booking flow
Approved-by: Michael Zetterberg Approved-by: Matilda Landström
This commit is contained in:
@@ -0,0 +1,54 @@
|
||||
"use client"
|
||||
|
||||
import { useIntl } from "react-intl"
|
||||
|
||||
import { Typography } from "@scandic-hotels/design-system/Typography"
|
||||
|
||||
import ButtonLink from "@/components/ButtonLink"
|
||||
import { IconName } from "@/components/Icons/iconName"
|
||||
import AccordionItem from "@/components/TempDesignSystem/Accordion/AccordionItem"
|
||||
|
||||
import styles from "./sidePeekAccordion.module.css"
|
||||
|
||||
import type { AccessibilityAccordionItemProps } from "@/types/components/sidePeeks/amenities"
|
||||
|
||||
export default function AccessibilityAccordionItem({
|
||||
elevatorPitch,
|
||||
accessibilityPageUrl,
|
||||
}: AccessibilityAccordionItemProps) {
|
||||
const intl = useIntl()
|
||||
|
||||
if (!elevatorPitch && !accessibilityPageUrl) {
|
||||
return null
|
||||
}
|
||||
|
||||
return (
|
||||
<AccordionItem
|
||||
title={intl.formatMessage({
|
||||
defaultMessage: "Accessibility",
|
||||
})}
|
||||
iconName={IconName.Accessibility}
|
||||
className={styles.accordionItem}
|
||||
variant="sidepeek"
|
||||
trackingId="amenities:accessibility"
|
||||
>
|
||||
<div className={styles.accessibilityContent}>
|
||||
<Typography variant="Body/Paragraph/mdRegular">
|
||||
<p>{elevatorPitch}</p>
|
||||
</Typography>
|
||||
{accessibilityPageUrl && (
|
||||
<ButtonLink
|
||||
href={`/${accessibilityPageUrl}`}
|
||||
variant="Secondary"
|
||||
color="Primary"
|
||||
size="Medium"
|
||||
typography="Body/Paragraph/mdBold"
|
||||
appendToCurrentPath
|
||||
>
|
||||
{intl.formatMessage({ defaultMessage: "About accessibility" })}
|
||||
</ButtonLink>
|
||||
)}
|
||||
</div>
|
||||
</AccordionItem>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
"use client"
|
||||
|
||||
import { useIntl } from "react-intl"
|
||||
|
||||
import { Typography } from "@scandic-hotels/design-system/Typography"
|
||||
|
||||
import { isDefined } from "@/server/utils"
|
||||
|
||||
import { IconName } from "@/components/Icons/iconName"
|
||||
import OpeningHours from "@/components/OpeningHours"
|
||||
import AccordionItem from "@/components/TempDesignSystem/Accordion/AccordionItem"
|
||||
|
||||
import styles from "./sidePeekAccordion.module.css"
|
||||
|
||||
import type { BreakfastAccordionItemProps } from "@/types/components/sidePeeks/amenities"
|
||||
import { HotelTypeEnum } from "@/types/enums/hotelType"
|
||||
|
||||
export default function BreakfastAccordionItem({
|
||||
restaurants,
|
||||
hotelType,
|
||||
}: BreakfastAccordionItemProps) {
|
||||
const intl = useIntl()
|
||||
|
||||
const openingHours = restaurants
|
||||
?.map((restaurant) => {
|
||||
const breakfastDetail = restaurant.openingDetails.find(
|
||||
(details) =>
|
||||
details.openingHours.name === "Breakfast" ||
|
||||
details.openingHours.name ===
|
||||
intl.formatMessage({ defaultMessage: "Breakfast" })
|
||||
)
|
||||
return breakfastDetail
|
||||
})
|
||||
.filter(isDefined)[0]
|
||||
|
||||
if (!openingHours && hotelType !== HotelTypeEnum.ScandicGo) {
|
||||
return null
|
||||
}
|
||||
|
||||
return (
|
||||
<AccordionItem
|
||||
title={intl.formatMessage({ defaultMessage: "Breakfast" })}
|
||||
iconName={IconName.CoffeeAlt}
|
||||
variant="sidepeek"
|
||||
className={styles.accordionItem}
|
||||
trackingId="amenities:breakfast"
|
||||
>
|
||||
{openingHours ? (
|
||||
<OpeningHours
|
||||
openingHours={openingHours.openingHours}
|
||||
alternateOpeningHours={openingHours.alternateOpeningHours}
|
||||
heading={intl.formatMessage({ defaultMessage: "Opening hours" })}
|
||||
/>
|
||||
) : (
|
||||
<Typography variant="Body/Paragraph/mdRegular">
|
||||
<p>{intl.formatMessage({ defaultMessage: "All-day breakfast" })}</p>
|
||||
</Typography>
|
||||
)}
|
||||
</AccordionItem>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
"use client"
|
||||
|
||||
import { useIntl } from "react-intl"
|
||||
|
||||
import { Typography } from "@scandic-hotels/design-system/Typography"
|
||||
|
||||
import { IconName } from "@/components/Icons/iconName"
|
||||
import AccordionItem from "@/components/TempDesignSystem/Accordion/AccordionItem"
|
||||
import Divider from "@/components/TempDesignSystem/Divider"
|
||||
|
||||
import styles from "./sidePeekAccordion.module.css"
|
||||
|
||||
import type { CheckInCheckOutAccordionItemProps } from "@/types/components/sidePeeks/amenities"
|
||||
|
||||
export default function CheckInCheckOutAccordionItem({
|
||||
checkInData,
|
||||
}: CheckInCheckOutAccordionItemProps) {
|
||||
const intl = useIntl()
|
||||
|
||||
const { checkInTime, checkOutTime } = checkInData
|
||||
|
||||
return (
|
||||
<AccordionItem
|
||||
title={intl.formatMessage({ defaultMessage: "Check-in/Check-out" })}
|
||||
iconName={IconName.Business}
|
||||
variant="sidepeek"
|
||||
className={styles.accordionItem}
|
||||
trackingId="amenities:check-in"
|
||||
>
|
||||
<div className={styles.checkInCheckOutContent}>
|
||||
<Typography variant="Title/Overline/sm">
|
||||
<h4 className={styles.subheading}>
|
||||
{intl.formatMessage({ defaultMessage: "Hours" })}
|
||||
</h4>
|
||||
</Typography>
|
||||
<Divider color="Border/Divider/Default" />
|
||||
<Typography variant="Body/Paragraph/mdRegular">
|
||||
<div>
|
||||
<p>
|
||||
{intl.formatMessage(
|
||||
{ defaultMessage: "Check in from: {checkInTime}" },
|
||||
{
|
||||
checkInTime,
|
||||
}
|
||||
)}
|
||||
</p>
|
||||
<p>
|
||||
{intl.formatMessage(
|
||||
{ defaultMessage: "Check out at latest: {checkOutTime}" },
|
||||
{
|
||||
checkOutTime,
|
||||
}
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
</Typography>
|
||||
</div>
|
||||
</AccordionItem>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
"use client"
|
||||
|
||||
import { useIntl } from "react-intl"
|
||||
|
||||
import { Typography } from "@scandic-hotels/design-system/Typography"
|
||||
|
||||
import ButtonLink from "@/components/ButtonLink"
|
||||
import { IconName } from "@/components/Icons/iconName"
|
||||
import ParkingInformation from "@/components/ParkingInformation"
|
||||
import AccordionItem from "@/components/TempDesignSystem/Accordion/AccordionItem"
|
||||
|
||||
import styles from "./sidePeekAccordion.module.css"
|
||||
|
||||
import type { ParkingAccordionItemProps } from "@/types/components/sidePeeks/amenities"
|
||||
|
||||
export default function ParkingAccordionItem({
|
||||
parking,
|
||||
elevatorPitch,
|
||||
parkingPageUrl,
|
||||
}: ParkingAccordionItemProps) {
|
||||
const intl = useIntl()
|
||||
|
||||
return (
|
||||
<AccordionItem
|
||||
title={intl.formatMessage({
|
||||
defaultMessage: "Parking",
|
||||
})}
|
||||
iconName={IconName.Parking}
|
||||
variant="sidepeek"
|
||||
className={styles.accordionItem}
|
||||
trackingId="amenities:parking"
|
||||
>
|
||||
<div className={styles.parkingContent}>
|
||||
{elevatorPitch ? (
|
||||
<Typography variant="Body/Paragraph/mdRegular">
|
||||
<p>{elevatorPitch}</p>
|
||||
</Typography>
|
||||
) : null}
|
||||
{parking.map((data) => (
|
||||
<ParkingInformation key={data.type} parking={data} />
|
||||
))}
|
||||
{parkingPageUrl && (
|
||||
<ButtonLink
|
||||
href={`/${parkingPageUrl}`}
|
||||
variant="Secondary"
|
||||
color="Primary"
|
||||
size="Medium"
|
||||
typography="Body/Paragraph/mdBold"
|
||||
appendToCurrentPath
|
||||
>
|
||||
{intl.formatMessage({
|
||||
defaultMessage: "About parking",
|
||||
})}
|
||||
</ButtonLink>
|
||||
)}
|
||||
</div>
|
||||
</AccordionItem>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
.accordionItem {
|
||||
color: var(--Text-Default);
|
||||
}
|
||||
|
||||
.parkingContent,
|
||||
.accessibilityContent {
|
||||
display: grid;
|
||||
gap: var(--Space-x3);
|
||||
}
|
||||
|
||||
.checkInCheckOutContent {
|
||||
display: grid;
|
||||
gap: var(--Space-x15);
|
||||
}
|
||||
|
||||
.checkInCheckOutContent {
|
||||
display: grid;
|
||||
padding: var(--Space-x2) var(--Space-x3);
|
||||
gap: var(--Space-x1);
|
||||
border-radius: var(--Corner-radius-Medium);
|
||||
background: var(--Surface-Secondary-Default);
|
||||
}
|
||||
|
||||
.subheading {
|
||||
color: var(--Text-Secondary);
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
.wrapper {
|
||||
padding: var(--Spacing-x1) var(--Spacing-x0);
|
||||
border-bottom: 1px solid var(--Base-Border-Subtle);
|
||||
color: var(--Text-Interactive-Default);
|
||||
}
|
||||
|
||||
.amenity {
|
||||
display: flex;
|
||||
gap: var(--Spacing-x1);
|
||||
padding: var(--Spacing-x-one-and-half) var(--Spacing-x1);
|
||||
align-items: center;
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
import { Typography } from "@scandic-hotels/design-system/Typography"
|
||||
|
||||
import { FacilityToIcon } from "../../../ContentType/HotelPage/data"
|
||||
|
||||
import styles from "./additionalAmenities.module.css"
|
||||
|
||||
import type { AdditionalAmenitiesProps } from "@/types/components/sidePeeks/amenities"
|
||||
import { FacilityEnum } from "@/types/enums/facilities"
|
||||
|
||||
export default function AdditionalAmenities({
|
||||
amenities,
|
||||
}: AdditionalAmenitiesProps) {
|
||||
const amenitiesToIgnore = [
|
||||
FacilityEnum.ParkingAdditionalCost,
|
||||
FacilityEnum.ParkingElectricCharging,
|
||||
FacilityEnum.ParkingFreeParking,
|
||||
FacilityEnum.ParkingGarage,
|
||||
FacilityEnum.ParkingOutdoor,
|
||||
FacilityEnum.MeetingArea,
|
||||
FacilityEnum.ServesBreakfastAlwaysIncluded,
|
||||
FacilityEnum.LateCheckOutUntil1400Guaranteed,
|
||||
]
|
||||
|
||||
const filteredAmenities = amenities.filter(
|
||||
(amenity) => !amenitiesToIgnore.includes(amenity.id)
|
||||
)
|
||||
|
||||
return filteredAmenities?.map((amenity) => (
|
||||
<Typography key={amenity.name} variant="Title/Subtitle/md">
|
||||
<li className={styles.wrapper}>
|
||||
<div className={styles.amenity}>
|
||||
<FacilityToIcon
|
||||
id={amenity.id}
|
||||
color="Icon/Interactive/Default"
|
||||
size={24}
|
||||
/>
|
||||
{amenity.name}
|
||||
</div>
|
||||
</li>
|
||||
</Typography>
|
||||
))
|
||||
}
|
||||
Reference in New Issue
Block a user