Merged in feat/sw-3218-move-hotelreservationsidepeek-to-booking-flow (pull request #2600)

feat(SW-2873): Move HotelReservationSidePeek to booking-flow

* Move sidepeek store to booking-flow

* Begin move of HotelReservationSidePeek to booking-flow

* Copy Link

* Update AccessibilityAccordionItem

* Split AccessibilityAccordionItem into two components

* Fix tracking for Accordion

* Duplicate ButtonLink to booking-flow TEMP

* AdditionalAmeneties

* wip

* Move sidepeek accordion items

* Remove temp ButtonLink

* Merge branch 'master' into feat/sw-3218-move-hotelreservationsidepeek-to-booking-flow

* Fix accordion tracking

* Merge branch 'master' into feat/sw-3218-move-hotelreservationsidepeek-to-booking-flow

* Update exports

* Fix self-referencing import

* Merge branch 'master' into feat/sw-3218-move-hotelreservationsidepeek-to-booking-flow

* Add 'use client' to tracking function

* Merge branch 'master' into feat/sw-3218-move-hotelreservationsidepeek-to-booking-flow

* Fix TEMP folder

* Refactor sidepeek tracking

* Merge branch 'master' into feat/sw-3218-move-hotelreservationsidepeek-to-booking-flow


Approved-by: Joakim Jäderberg
This commit is contained in:
Anton Gunnarsson
2025-08-14 12:25:40 +00:00
parent f04e476a6e
commit 322268595d
53 changed files with 826 additions and 425 deletions

View File

@@ -0,0 +1,67 @@
"use client"
import { useIntl } from "react-intl"
import { isDefined } from "@scandic-hotels/common/utils/isDefined"
import AccordionItem from "@scandic-hotels/design-system/Accordion/AccordionItem"
import { IconName } from "@scandic-hotels/design-system/Icons/iconName"
import OpeningHours from "@scandic-hotels/design-system/OpeningHours"
import { Typography } from "@scandic-hotels/design-system/Typography"
import { HotelTypeEnum } from "@scandic-hotels/trpc/enums/hotelType"
import { useTrackingContext } from "../../trackingContext"
import styles from "./sidePeekAccordion.module.css"
import type { Restaurant } from "@scandic-hotels/trpc/types/hotel"
interface BreakfastAccordionItemProps {
restaurants?: Restaurant[]
hotelType: string
}
export default function BreakfastAccordionItem({
restaurants,
hotelType,
}: BreakfastAccordionItemProps) {
const intl = useIntl()
const tracking = useTrackingContext()
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}
onOpen={() => tracking.trackAccordionItemOpen("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>
)
}

View File

@@ -0,0 +1,66 @@
"use client"
import { useIntl } from "react-intl"
import AccordionItem from "@scandic-hotels/design-system/Accordion/AccordionItem"
import { Divider } from "@scandic-hotels/design-system/Divider"
import { IconName } from "@scandic-hotels/design-system/Icons/iconName"
import { Typography } from "@scandic-hotels/design-system/Typography"
import { useTrackingContext } from "../../trackingContext"
import styles from "./sidePeekAccordion.module.css"
import type { CheckInData } from "@scandic-hotels/trpc/types/hotel"
interface CheckInCheckOutAccordionItemProps {
checkInData: CheckInData
}
export default function CheckInCheckOutAccordionItem({
checkInData,
}: CheckInCheckOutAccordionItemProps) {
const intl = useIntl()
const tracking = useTrackingContext()
const { checkInTime, checkOutTime } = checkInData
return (
<AccordionItem
title={intl.formatMessage({ defaultMessage: "Check-in/Check-out" })}
iconName={IconName.Business}
variant="sidepeek"
className={styles.accordionItem}
onOpen={() => tracking.trackAccordionItemOpen("amenities:check-in")}
>
<div className={styles.checkInCheckOutContent}>
<Typography variant="Title/Overline/sm">
<h4 className={styles.subheading}>
{intl.formatMessage({ defaultMessage: "Hours" })}
</h4>
</Typography>
<Divider />
<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>
)
}

View File

@@ -0,0 +1,70 @@
"use client"
import { useIntl } from "react-intl"
import AccordionItem from "@scandic-hotels/design-system/Accordion/AccordionItem"
import ButtonLink from "@scandic-hotels/design-system/ButtonLink"
import { IconName } from "@scandic-hotels/design-system/Icons/iconName"
import ParkingInformation from "@scandic-hotels/design-system/ParkingInformation"
import { Typography } from "@scandic-hotels/design-system/Typography"
import { useTrackingContext } from "../../trackingContext"
import styles from "./sidePeekAccordion.module.css"
import type { Parking } from "@scandic-hotels/trpc/types/hotel"
interface ParkingAccordionItemProps {
parkingPageHref?: string | null
parking: Parking[]
elevatorPitch?: string
}
export default function ParkingAccordionItem({
parking,
elevatorPitch,
parkingPageHref,
}: ParkingAccordionItemProps) {
const intl = useIntl()
const tracking = useTrackingContext()
if (!parking.length && !elevatorPitch && !parkingPageHref) {
return null
}
return (
<AccordionItem
title={intl.formatMessage({
defaultMessage: "Parking",
})}
iconName={IconName.Parking}
variant="sidepeek"
className={styles.accordionItem}
onOpen={() => tracking.trackAccordionItemOpen("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} />
))}
{parkingPageHref ? (
<ButtonLink
href={parkingPageHref}
variant="Secondary"
color="Primary"
size="Medium"
typography="Body/Paragraph/mdBold"
>
{intl.formatMessage({
defaultMessage: "About parking",
})}
</ButtonLink>
) : null}
</div>
</AccordionItem>
)
}

View File

@@ -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-md);
background: var(--Surface-Secondary-Default);
}
.subheading {
color: var(--Text-Secondary);
}