diff --git a/apps/scandic-web/components/ContentType/HotelPage/IntroSection/TripAdvisorLink/index.tsx b/apps/scandic-web/components/ContentType/HotelPage/IntroSection/TripAdvisorLink/index.tsx new file mode 100644 index 000000000..c96d91e95 --- /dev/null +++ b/apps/scandic-web/components/ContentType/HotelPage/IntroSection/TripAdvisorLink/index.tsx @@ -0,0 +1,58 @@ +import TripadvisorIcon from "@scandic-hotels/design-system/Icons/TripadvisorIcon" + +import Link from "@/components/TempDesignSystem/Link" +import { getIntl } from "@/i18n" +import { appendSlugToPathname } from "@/utils/appendSlugToPathname" + +import styles from "./tripAdvisorLink.module.css" + +import type { HotelTripAdvisor } from "@/types/hotel" + +interface TripAdvisorLinkProps { + tripAdvisor: NonNullable +} + +export default async function TripAdvisorLink({ + tripAdvisor, +}: TripAdvisorLinkProps) { + const intl = await getIntl() + const { rating, numberOfReviews, reviews } = tripAdvisor + const hasTripAdvisorData = !!(rating && numberOfReviews) + + if (!hasTripAdvisorData) { + return null + } + + const formattedTripAdvisorText = intl.formatMessage( + { + defaultMessage: "{rating} ({count} reviews on Tripadvisor)", + }, + { rating, count: numberOfReviews } + ) + + const hasTripAdvisorIframeSrc = !!reviews.widgetScriptEmbedUrlIframe + const tripAdvisorHref = hasTripAdvisorIframeSrc + ? appendSlugToPathname("reviews") + : null + + if (!tripAdvisorHref) { + return ( + + + {formattedTripAdvisorText} + + ) + } + + return ( + + + {formattedTripAdvisorText} + + ) +} diff --git a/apps/scandic-web/components/ContentType/HotelPage/IntroSection/TripAdvisorLink/tripAdvisorLink.module.css b/apps/scandic-web/components/ContentType/HotelPage/IntroSection/TripAdvisorLink/tripAdvisorLink.module.css new file mode 100644 index 000000000..d96f63339 --- /dev/null +++ b/apps/scandic-web/components/ContentType/HotelPage/IntroSection/TripAdvisorLink/tripAdvisorLink.module.css @@ -0,0 +1,6 @@ +.tripAdvisorText { + display: flex; + gap: var(--Space-x05); + align-items: center; + color: var(--Text-Secondary); +} diff --git a/apps/scandic-web/components/ContentType/HotelPage/IntroSection/index.tsx b/apps/scandic-web/components/ContentType/HotelPage/IntroSection/index.tsx index 102024b52..ff2d10b94 100644 --- a/apps/scandic-web/components/ContentType/HotelPage/IntroSection/index.tsx +++ b/apps/scandic-web/components/ContentType/HotelPage/IntroSection/index.tsx @@ -1,11 +1,12 @@ import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon" -import TripadvisorIcon from "@scandic-hotels/design-system/Icons/TripadvisorIcon" import { Typography } from "@scandic-hotels/design-system/Typography" import Link from "@/components/TempDesignSystem/Link" import { getIntl } from "@/i18n" import { getSingleDecimal } from "@/utils/numberFormatting" +import TripAdvisorLink from "./TripAdvisorLink" + import styles from "./introSection.module.css" import { SidepeekSlugs } from "@/types/components/hotelPage/hotelPage" @@ -29,17 +30,6 @@ export default async function IntroSection({ ) const formattedLocationText = `${streetAddress}, ${city} (${formattedDistanceText})` - const hasTripAdvisorData = !!( - tripAdvisor?.rating && tripAdvisor?.numberOfReviews - ) - const formattedTripAdvisorText = hasTripAdvisorData - ? intl.formatMessage( - { - defaultMessage: "{rating} ({count} reviews on Tripadvisor)", - }, - { rating: tripAdvisor.rating, count: tripAdvisor.numberOfReviews } - ) - : "" return (
@@ -59,12 +49,8 @@ export default async function IntroSection({

{formattedLocationText}

- {formattedTripAdvisorText && ( - - - {formattedTripAdvisorText} - - )} + + {tripAdvisor ? : null}
diff --git a/apps/scandic-web/components/ContentType/HotelPage/IntroSection/introSection.module.css b/apps/scandic-web/components/ContentType/HotelPage/IntroSection/introSection.module.css index 4af9f917d..7f7fd53bf 100644 --- a/apps/scandic-web/components/ContentType/HotelPage/IntroSection/introSection.module.css +++ b/apps/scandic-web/components/ContentType/HotelPage/IntroSection/introSection.module.css @@ -8,6 +8,7 @@ .mainContent { display: grid; gap: var(--Spacing-x1); + justify-items: start; } .subtitleContent { @@ -15,18 +16,6 @@ gap: var(--Spacing-x-one-and-half); } -.tripAdvisorText { - display: flex; - gap: var(--Space-x05); - align-items: center; - color: var(--Text-Secondary); -} - -.tripAdvisorText svg, -.tripAdvisorText svg * { - fill: var(--Icon-Default); -} - .title { color: var(--Text-Heading); } diff --git a/apps/scandic-web/components/ContentType/HotelSubpage/AccessibilitySubpage/accessibilitySubpage.module.css b/apps/scandic-web/components/ContentType/HotelSubpage/AccessibilitySubpage/accessibilitySubpage.module.css new file mode 100644 index 000000000..b7db3bd3d --- /dev/null +++ b/apps/scandic-web/components/ContentType/HotelSubpage/AccessibilitySubpage/accessibilitySubpage.module.css @@ -0,0 +1,61 @@ +.accessibilitySubpage { + padding-bottom: var(--Space-x8); + color: var(--Text-Default); + display: grid; + gap: var(--Space-x4); +} + +.contentContainer { + display: grid; + gap: var(--Space-x3); + width: var(--max-width-content); + margin: 0 auto; + color: var(--Text-Default); +} + +.mainContent { + display: grid; + width: 100%; + gap: var(--Space-x4); + max-width: var(--max-width-text-block); + align-content: start; +} + +.heading { + color: var(--Text-Heading); +} + +.intro { + display: grid; + gap: var(--Space-x2); +} + +.accessibilityInformation { + display: grid; + gap: var(--Space-x2); +} + +.accessibilityGroup { + display: grid; + gap: var(--Space-x1); +} + +.list { + display: grid; + gap: var(--Space-x1); + list-style-type: none; +} + +.listItem::before { + content: url("/_static/icons/heart.svg"); + position: relative; + height: 8px; + top: 3px; + margin-right: var(--Space-x1); +} + +@media screen and (min-width: 1367px) { + .divider { + display: none; + } +} diff --git a/apps/scandic-web/components/ContentType/HotelSubpage/AccessibilitySubpage/index.tsx b/apps/scandic-web/components/ContentType/HotelSubpage/AccessibilitySubpage/index.tsx new file mode 100644 index 000000000..4a956785f --- /dev/null +++ b/apps/scandic-web/components/ContentType/HotelSubpage/AccessibilitySubpage/index.tsx @@ -0,0 +1,96 @@ +import { Typography } from "@scandic-hotels/design-system/Typography" + +import Divider from "@/components/TempDesignSystem/Divider" +import { getIntl } from "@/i18n" + +import HeroHeader from "../HeroHeader" +import HtmlContent from "../HtmlContent" + +import styles from "./accessibilitySubpage.module.css" + +import type { AdditionalData } from "@/types/hotel" + +interface AccessibilitySubpageProps { + hotelName: string + additionalData: AdditionalData +} + +export default async function AccessibilitySubpage({ + hotelName, + additionalData, +}: AccessibilitySubpageProps) { + const intl = await getIntl() + const { hotelSpecialNeeds, specialNeedGroups, accessibility } = additionalData + const { mainBody, elevatorPitch } = hotelSpecialNeeds + const heroImage = accessibility?.heroImages[0] + + return ( + <> +
+ + +
+ +

+ {intl.formatMessage( + { + defaultMessage: "Accessibility at {hotel}", + }, + { + hotel: hotelName, + } + )} +

+
+ + + +
+ {elevatorPitch ? ( +
+ +

{elevatorPitch}

+
+
+ ) : null} + + {mainBody ? : null} + +
+ {specialNeedGroups.map((accessibilityGroup) => ( +
+ +

{accessibilityGroup.name}

+
+
    + {accessibilityGroup.specialNeeds.map((groupItem) => ( + +
  • + {groupItem.details + ? // eslint-disable-next-line formatjs/no-literal-string-in-jsx + `${groupItem.name}: ${groupItem.details}` + : groupItem.name} +
  • +
    + ))} +
+
+ ))} +
+
+
+
+ + ) +} diff --git a/apps/scandic-web/components/ContentType/HotelSubpage/AdditionalContent/Accessibility/accessibilityAdditionalContent.module.css b/apps/scandic-web/components/ContentType/HotelSubpage/AdditionalContent/Accessibility/accessibilityAdditionalContent.module.css deleted file mode 100644 index 6a7f5b2fe..000000000 --- a/apps/scandic-web/components/ContentType/HotelSubpage/AdditionalContent/Accessibility/accessibilityAdditionalContent.module.css +++ /dev/null @@ -1,23 +0,0 @@ -.container { - display: grid; - gap: var(--Spacing-x2); -} - -.accessibilityGroup { - display: grid; - gap: var(--Spacing-x1); -} - -.list { - display: grid; - gap: var(--Spacing-x1); - list-style-type: none; -} - -.list > li::before { - content: url("/_static/icons/heart.svg"); - position: relative; - height: 8px; - top: 3px; - margin-right: var(--Spacing-x1); -} diff --git a/apps/scandic-web/components/ContentType/HotelSubpage/AdditionalContent/Accessibility/index.tsx b/apps/scandic-web/components/ContentType/HotelSubpage/AdditionalContent/Accessibility/index.tsx deleted file mode 100644 index 3f36455c3..000000000 --- a/apps/scandic-web/components/ContentType/HotelSubpage/AdditionalContent/Accessibility/index.tsx +++ /dev/null @@ -1,41 +0,0 @@ -import Body from "@/components/TempDesignSystem/Text/Body" -import Subtitle from "@/components/TempDesignSystem/Text/Subtitle" - -import styles from "./accessibilityAdditionalContent.module.css" - -import type { AdditionalData } from "@/types/hotel" - -interface AccessibilityAdditionalContentProps { - additionalData: AdditionalData -} - -export default function AccessibilityAdditionalContent({ - additionalData, -}: AccessibilityAdditionalContentProps) { - return ( -
- {additionalData.specialNeedGroups.map((accessibilityGroup) => ( -
- -

{accessibilityGroup.name}

-
-
    - {accessibilityGroup.specialNeeds.map((groupItem) => ( - -
  • - {groupItem.details - ? // eslint-disable-next-line formatjs/no-literal-string-in-jsx - `${groupItem.name}: ${groupItem.details}` - : groupItem.name} -
  • - - ))} -
-
- ))} -
- ) -} diff --git a/apps/scandic-web/components/ContentType/HotelSubpage/AdditionalContent/Parking/index.tsx b/apps/scandic-web/components/ContentType/HotelSubpage/AdditionalContent/Parking/index.tsx deleted file mode 100644 index 92e7ceab5..000000000 --- a/apps/scandic-web/components/ContentType/HotelSubpage/AdditionalContent/Parking/index.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import ParkingInformation from "@/components/ParkingInformation" - -import styles from "./parkingAdditionalContent.module.css" - -import type { Hotel } from "@/types/hotel" - -interface ParkingAdditionalContentProps { - hotel: Hotel -} - -export default async function ParkingAdditionalContent({ - hotel, -}: ParkingAdditionalContentProps) { - const parking = hotel.parking - - return ( -
- {parking.map((data) => ( - - ))} -
- ) -} diff --git a/apps/scandic-web/components/ContentType/HotelSubpage/AdditionalContent/Parking/parkingAdditionalContent.module.css b/apps/scandic-web/components/ContentType/HotelSubpage/AdditionalContent/Parking/parkingAdditionalContent.module.css deleted file mode 100644 index 3011afbbc..000000000 --- a/apps/scandic-web/components/ContentType/HotelSubpage/AdditionalContent/Parking/parkingAdditionalContent.module.css +++ /dev/null @@ -1,4 +0,0 @@ -.additionalContent { - display: grid; - gap: var(--Spacing-x4); -} diff --git a/apps/scandic-web/components/ContentType/HotelSubpage/AdditionalContent/index.tsx b/apps/scandic-web/components/ContentType/HotelSubpage/AdditionalContent/index.tsx deleted file mode 100644 index 677998c12..000000000 --- a/apps/scandic-web/components/ContentType/HotelSubpage/AdditionalContent/index.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import AccessibilityAdditionalContent from "./Accessibility" -import ParkingAdditionalContent from "./Parking" - -import type { AdditionalData, Hotel } from "@/types/hotel" - -interface HotelSubpageAdditionalContentProps { - subpage: string - hotel: Hotel - additionalData: AdditionalData -} - -export default function HotelSubpageAdditionalContent({ - subpage, - hotel, - additionalData, -}: HotelSubpageAdditionalContentProps) { - switch (subpage) { - case additionalData.hotelParking.nameInUrl: - return - case additionalData.healthAndFitness.nameInUrl: - return null - case additionalData.hotelSpecialNeeds.nameInUrl: - return - default: - return null - } -} diff --git a/apps/scandic-web/components/ContentType/HotelSubpage/HeroHeader/heroHeader.module.css b/apps/scandic-web/components/ContentType/HotelSubpage/HeroHeader/heroHeader.module.css new file mode 100644 index 000000000..809182ac9 --- /dev/null +++ b/apps/scandic-web/components/ContentType/HotelSubpage/HeroHeader/heroHeader.module.css @@ -0,0 +1,10 @@ +.header { + display: grid; + background-color: var(--Base-Surface-Subtle-Normal); + padding-bottom: var(--Space-x4); +} + +.heroWrapper { + width: var(--max-width-content); + margin: 0 auto; +} diff --git a/apps/scandic-web/components/ContentType/HotelSubpage/HeroHeader/index.tsx b/apps/scandic-web/components/ContentType/HotelSubpage/HeroHeader/index.tsx new file mode 100644 index 000000000..98f94fb95 --- /dev/null +++ b/apps/scandic-web/components/ContentType/HotelSubpage/HeroHeader/index.tsx @@ -0,0 +1,36 @@ +import { Suspense } from "react" + +import Breadcrumbs from "@/components/Breadcrumbs" +import Hero from "@/components/Hero" +import BreadcrumbsSkeleton from "@/components/TempDesignSystem/Breadcrumbs/BreadcrumbsSkeleton" + +import styles from "./heroHeader.module.css" + +import type { ApiImage } from "@/types/hotel" + +interface HeroHeaderProps { + breadcrumbsTitle: string + heroImage?: ApiImage +} + +export default async function HeroHeader({ + breadcrumbsTitle, + heroImage, +}: HeroHeaderProps) { + return ( +
+ }> + + + + {heroImage ? ( +
+ +
+ ) : null} +
+ ) +} diff --git a/apps/scandic-web/components/ContentType/HotelSubpage/HtmlContent/htmlContent.module.css b/apps/scandic-web/components/ContentType/HotelSubpage/HtmlContent/htmlContent.module.css index 56a7645b7..df51f40e2 100644 --- a/apps/scandic-web/components/ContentType/HotelSubpage/HtmlContent/htmlContent.module.css +++ b/apps/scandic-web/components/ContentType/HotelSubpage/HtmlContent/htmlContent.module.css @@ -1,9 +1,9 @@ .ul, .ol { - padding: var(--Spacing-x2) var(--Spacing-x0); + padding: var(--Space-x2) var(--Space-x0); display: grid; - gap: var(--Spacing-x1); - margin-left: var(--Spacing-x2); + gap: var(--Space-x1); + margin-left: var(--Space-x2); } .ol > li::marker { @@ -11,7 +11,7 @@ } .li { - margin-left: var(--Spacing-x3); + margin-left: var(--Space-x3); } .li > p { diff --git a/apps/scandic-web/components/ContentType/HotelSubpage/AdditionalContent/Meetings/index.tsx b/apps/scandic-web/components/ContentType/HotelSubpage/MeetingsSubpage/MeetingRooms/index.tsx similarity index 85% rename from apps/scandic-web/components/ContentType/HotelSubpage/AdditionalContent/Meetings/index.tsx rename to apps/scandic-web/components/ContentType/HotelSubpage/MeetingsSubpage/MeetingRooms/index.tsx index 28639343c..6e68dc2f8 100644 --- a/apps/scandic-web/components/ContentType/HotelSubpage/AdditionalContent/Meetings/index.tsx +++ b/apps/scandic-web/components/ContentType/HotelSubpage/MeetingsSubpage/MeetingRooms/index.tsx @@ -5,17 +5,15 @@ import Grids from "@/components/TempDesignSystem/Grids" import MeetingRoomCard from "@/components/TempDesignSystem/MeetingRoomCard" import ShowMoreButton from "@/components/TempDesignSystem/ShowMoreButton" -import styles from "./meetingsAdditionalContent.module.css" +import styles from "./meetingRooms.module.css" import type { MeetingRooms } from "@/types/components/hotelPage/meetingRooms" -interface MeetingsAdditionalContentProps { +interface MeetingRoomsProps { rooms: MeetingRooms } -export default function MeetingsAdditionalContent({ - rooms, -}: MeetingsAdditionalContentProps) { +export default function MeetingRooms({ rooms }: MeetingRoomsProps) { const showToggleButton = rooms.length > 3 const [allRoomsVisible, setAllRoomsVisible] = useState(!showToggleButton) diff --git a/apps/scandic-web/components/ContentType/HotelSubpage/AdditionalContent/Meetings/meetingsAdditionalContent.module.css b/apps/scandic-web/components/ContentType/HotelSubpage/MeetingsSubpage/MeetingRooms/meetingRooms.module.css similarity index 84% rename from apps/scandic-web/components/ContentType/HotelSubpage/AdditionalContent/Meetings/meetingsAdditionalContent.module.css rename to apps/scandic-web/components/ContentType/HotelSubpage/MeetingsSubpage/MeetingRooms/meetingRooms.module.css index b66948ef8..7ae5122b9 100644 --- a/apps/scandic-web/components/ContentType/HotelSubpage/AdditionalContent/Meetings/meetingsAdditionalContent.module.css +++ b/apps/scandic-web/components/ContentType/HotelSubpage/MeetingsSubpage/MeetingRooms/meetingRooms.module.css @@ -8,6 +8,6 @@ .section { display: grid; - gap: var(--Spacing-x4); + gap: var(--Space-x4); z-index: 0; } diff --git a/apps/scandic-web/components/ContentType/HotelSubpage/MeetingsSubpage/index.tsx b/apps/scandic-web/components/ContentType/HotelSubpage/MeetingsSubpage/index.tsx new file mode 100644 index 000000000..d2e8a79fb --- /dev/null +++ b/apps/scandic-web/components/ContentType/HotelSubpage/MeetingsSubpage/index.tsx @@ -0,0 +1,86 @@ +import { Typography } from "@scandic-hotels/design-system/Typography" + +import { getMeetingRooms } from "@/lib/trpc/memoizedRequests" + +import { meetingPackageDestinationByHotelId } from "@/components/MeetingPackageWidget/utils" +import StickyMeetingPackageWidget from "@/components/StickyMeetingPackageWidget" +import Divider from "@/components/TempDesignSystem/Divider" +import { getIntl } from "@/i18n" +import { getLang } from "@/i18n/serverContext" +import { safeTry } from "@/utils/safeTry" + +import HeroHeader from "../HeroHeader" +import HtmlContent from "../HtmlContent" +import MeetingsSidebar from "../Sidebar/MeetingsSidebar" +import MeetingsAdditionalContent from "./MeetingRooms" + +import styles from "./meetingsSubpage.module.css" + +import type { AdditionalData, Hotel } from "@/types/hotel" + +interface MeetingsSubpageProps { + hotelId: string + hotel: Hotel + additionalData: AdditionalData +} + +export default async function MeetingsSubpage({ + hotelId, + hotel, + additionalData, +}: MeetingsSubpageProps) { + const intl = await getIntl() + const lang = getLang() + const heading = intl.formatMessage({ + defaultMessage: "Meetings, Conferences & Events", + }) + const mainBody = additionalData.meetingRooms.mainBody + const elevatorPitch = hotel.hotelContent.texts.meetingDescription?.medium + const heroImage = additionalData.conferencesAndMeetings?.heroImages[0] + const [meetingRooms] = await safeTry( + getMeetingRooms({ hotelId, language: lang }) + ) + const meetingPackageDestination = meetingPackageDestinationByHotelId[hotelId] + + return ( + <> + +
+ + +
+ +

{heading}

+
+ + + +
+ {elevatorPitch ? ( +
+ +

{elevatorPitch}

+
+
+ ) : null} + + {mainBody ? : null} +
+ {meetingRooms ? ( +
+ +
+ ) : null} +
+
+ + ) +} diff --git a/apps/scandic-web/components/ContentType/HotelSubpage/MeetingsSubpage/meetingsSubpage.module.css b/apps/scandic-web/components/ContentType/HotelSubpage/MeetingsSubpage/meetingsSubpage.module.css new file mode 100644 index 000000000..10842b35a --- /dev/null +++ b/apps/scandic-web/components/ContentType/HotelSubpage/MeetingsSubpage/meetingsSubpage.module.css @@ -0,0 +1,64 @@ +.meetingsSubpage { + padding-bottom: var(--Space-x8); + color: var(--Text-Default); + display: grid; + gap: var(--Space-x4); +} + +.contentContainer { + display: grid; + gap: var(--Space-x3); + width: var(--max-width-content); + margin: 0 auto; + color: var(--Text-Default); +} + +.mainContent { + display: grid; + width: 100%; + gap: var(--Space-x4); + align-content: start; +} + +.heading { + color: var(--Text-Heading); +} + +.intro { + display: grid; + gap: var(--Space-x2); +} + +.sidebar { + display: grid; + gap: var(--Space-x3); + align-content: start; +} + +.parkingInformation { + display: grid; + gap: var(--Space-x4); +} + +@media screen and (min-width: 1367px) { + .contentContainer { + grid-template-columns: var(--max-width-text-block) 1fr; + grid-template-rows: auto 1fr; + row-gap: var(--Space-x2); + column-gap: var(--Space-x8); + } + + .divider { + display: none; + } + + .sidebar { + grid-column: 2; + grid-row: 1 / span 2; + align-items: start; + } + + .meetingsInformation { + grid-column: 1 / span 2; + } +} diff --git a/apps/scandic-web/components/ContentType/HotelSubpage/ParkingSubpage/index.tsx b/apps/scandic-web/components/ContentType/HotelSubpage/ParkingSubpage/index.tsx new file mode 100644 index 000000000..14f56ab4a --- /dev/null +++ b/apps/scandic-web/components/ContentType/HotelSubpage/ParkingSubpage/index.tsx @@ -0,0 +1,73 @@ +import { Typography } from "@scandic-hotels/design-system/Typography" + +import ParkingInformation from "@/components/ParkingInformation" +import Divider from "@/components/TempDesignSystem/Divider" +import { getIntl } from "@/i18n" + +import HeroHeader from "../HeroHeader" +import HtmlContent from "../HtmlContent" +import ParkingSidebar from "../Sidebar/ParkingSidebar" + +import styles from "./parkingSubpage.module.css" + +import type { AdditionalData, Hotel } from "@/types/hotel" + +interface ParkingSubpageProps { + hotel: Hotel + additionalData: AdditionalData +} + +export default async function ParkingSubpage({ + hotel, + additionalData, +}: ParkingSubpageProps) { + const intl = await getIntl() + const heading = intl.formatMessage({ + defaultMessage: "Parking", + }) + const { mainBody, elevatorPitch } = additionalData.hotelParking + const heroImage = additionalData.parkingImages?.heroImages[0] + + return ( + <> +
+ + +
+ +

{heading}

+
+ + + +
+ {elevatorPitch ? ( +
+ +

{elevatorPitch}

+
+
+ ) : null} + + {mainBody ? : null} + +
+ {hotel.parking.map((data) => ( + + ))} +
+
+
+
+ + ) +} diff --git a/apps/scandic-web/components/ContentType/HotelSubpage/ParkingSubpage/parkingSubpage.module.css b/apps/scandic-web/components/ContentType/HotelSubpage/ParkingSubpage/parkingSubpage.module.css new file mode 100644 index 000000000..6ab377a97 --- /dev/null +++ b/apps/scandic-web/components/ContentType/HotelSubpage/ParkingSubpage/parkingSubpage.module.css @@ -0,0 +1,60 @@ +.parkingSubpage { + padding-bottom: var(--Space-x8); + color: var(--Text-Default); + display: grid; + gap: var(--Space-x4); +} + +.contentContainer { + display: grid; + gap: var(--Space-x3); + width: var(--max-width-content); + margin: 0 auto; + color: var(--Text-Default); +} + +.mainContent { + display: grid; + width: 100%; + gap: var(--Space-x4); + align-content: start; +} + +.heading { + color: var(--Text-Heading); +} + +.intro { + display: grid; + gap: var(--Space-x2); +} + +.sidebar { + display: grid; + gap: var(--Space-x3); + align-content: start; +} + +.parkingInformation { + display: grid; + gap: var(--Space-x4); +} + +@media screen and (min-width: 1367px) { + .contentContainer { + grid-template-columns: var(--max-width-text-block) 1fr; + grid-template-rows: auto 1fr; + row-gap: var(--Space-x2); + column-gap: var(--Space-x8); + } + + .divider { + display: none; + } + + .sidebar { + grid-column: 2; + grid-row: 1 / span 2; + align-items: start; + } +} diff --git a/apps/scandic-web/components/ContentType/HotelSubpage/RestaurantSubpage/index.tsx b/apps/scandic-web/components/ContentType/HotelSubpage/RestaurantSubpage/index.tsx new file mode 100644 index 000000000..5073adfa1 --- /dev/null +++ b/apps/scandic-web/components/ContentType/HotelSubpage/RestaurantSubpage/index.tsx @@ -0,0 +1,73 @@ +import { Typography } from "@scandic-hotels/design-system/Typography" + +import ButtonLink from "@/components/ButtonLink" +import Divider from "@/components/TempDesignSystem/Divider" +import { getIntl } from "@/i18n" + +import HeroHeader from "../HeroHeader" +import HtmlContent from "../HtmlContent" +import RestaurantSidebar from "../Sidebar/RestaurantSidebar" + +import styles from "./restaurantSubpage.module.css" + +import type { Hotel, Restaurant } from "@/types/hotel" + +interface RestaurantSubpageProps { + restaurant: Restaurant + hotelAddress: Hotel["address"] +} + +export default async function RestaurantSubpage({ + restaurant, + hotelAddress, +}: RestaurantSubpageProps) { + const intl = await getIntl() + const { mainBody, elevatorPitch, name, bookTableUrl } = restaurant + const heroImage = restaurant.content.images[0] + + return ( + <> +
+ + +
+ +

{name}

+
+ + + +
+ {elevatorPitch ? ( +
+ +

{elevatorPitch}

+
+
+ ) : null} + + {mainBody ? : null} +
+
+ {bookTableUrl ? ( +
+ + {intl.formatMessage({ + defaultMessage: "Book a table", + })} + +
+ ) : null} +
+ + ) +} diff --git a/apps/scandic-web/components/ContentType/HotelSubpage/RestaurantSubpage/restaurantSubpage.module.css b/apps/scandic-web/components/ContentType/HotelSubpage/RestaurantSubpage/restaurantSubpage.module.css new file mode 100644 index 000000000..f42aa69a8 --- /dev/null +++ b/apps/scandic-web/components/ContentType/HotelSubpage/RestaurantSubpage/restaurantSubpage.module.css @@ -0,0 +1,67 @@ +.restaurantSubpage { + padding-bottom: var(--Space-x8); + color: var(--Text-Default); + display: grid; + gap: var(--Space-x4); +} + +.contentContainer { + display: grid; + gap: var(--Space-x3); + width: var(--max-width-content); + margin: 0 auto; + color: var(--Text-Default); +} + +.mainContent { + display: grid; + width: 100%; + gap: var(--Space-x4); + align-content: start; +} + +.heading { + color: var(--Text-Heading); +} + +.intro { + display: grid; + gap: var(--Space-x2); +} + +.sidebar { + display: grid; + gap: var(--Space-x3); + align-content: start; +} + +.buttonContainer { + position: sticky; + padding: var(--Space-x3) var(--Space-x2); + background-color: var(--Base-Surface-Secondary-light-Normal); + border-top: 1px solid var(--Base-Border-Subtle); + bottom: 0; +} + +@media screen and (min-width: 1367px) { + .contentContainer { + grid-template-columns: var(--max-width-text-block) 1fr; + grid-template-rows: auto 1fr; + row-gap: var(--Space-x2); + column-gap: var(--Space-x8); + } + + .divider { + display: none; + } + + .sidebar { + grid-column: 2; + grid-row: 1 / span 2; + align-items: start; + } + + .buttonContainer { + display: none; + } +} diff --git a/apps/scandic-web/components/ContentType/HotelSubpage/ReviewsSubpage/index.tsx b/apps/scandic-web/components/ContentType/HotelSubpage/ReviewsSubpage/index.tsx new file mode 100644 index 000000000..8a95f4c08 --- /dev/null +++ b/apps/scandic-web/components/ContentType/HotelSubpage/ReviewsSubpage/index.tsx @@ -0,0 +1,121 @@ +import NextImage from "next/image" +import { notFound } from "next/navigation" +import { Suspense } from "react" + +import { Typography } from "@scandic-hotels/design-system/Typography" + +import Breadcrumbs from "@/components/Breadcrumbs" +import BreadcrumbsSkeleton from "@/components/TempDesignSystem/Breadcrumbs/BreadcrumbsSkeleton" +import { getIntl } from "@/i18n" +import { getLang } from "@/i18n/serverContext" + +import styles from "./reviewsSubpage.module.css" + +import type { Hotel } from "@/types/hotel" + +interface ReviewsSubpageProps { + hotel: Hotel +} + +export default async function ReviewsSubpage({ hotel }: ReviewsSubpageProps) { + const intl = await getIntl() + const lang = getLang() + const tripAdvisorData = hotel.ratings?.tripAdvisor + + if (!tripAdvisorData?.reviews.widgetScriptEmbedUrlIframe) { + notFound() + } + + const awardsLogos = tripAdvisorData.awards + .map((award) => ({ + imageUrl: award.images.small, + altText: award.displayName, + })) + .filter((award) => !!award.imageUrl) + const showNordicEcoLabel = !!hotel.hotelFacts?.ecoLabels.nordicEcoLabel + + return ( + <> +
+ + } + > + + +
+ +

{hotel.name}

+
+ +

+ {intl.formatMessage({ + defaultMessage: "Ratings and reviews", + })} +

+
+
+ +
+ +
+