Merged in feat/SW-3002-new-hotel-move-tripadvisor (pull request #2375)
feat: SW-3002 Changed tripadvisor review subpage to Sidepeek * feat: SW-3002 Changed tripadvisor review subpage to Sidepeek * feat: SW-3002 Optimised styles Approved-by: Erik Tiekstra
This commit is contained in:
@@ -2,10 +2,10 @@ import TripadvisorIcon from "@scandic-hotels/design-system/Icons/TripadvisorIcon
|
|||||||
|
|
||||||
import Link from "@/components/TempDesignSystem/Link"
|
import Link from "@/components/TempDesignSystem/Link"
|
||||||
import { getIntl } from "@/i18n"
|
import { getIntl } from "@/i18n"
|
||||||
import { appendSlugToPathname } from "@/utils/appendSlugToPathname"
|
|
||||||
|
|
||||||
import styles from "./tripAdvisorLink.module.css"
|
import styles from "./tripAdvisorLink.module.css"
|
||||||
|
|
||||||
|
import { SidepeekSlugs } from "@/types/components/hotelPage/hotelPage"
|
||||||
import type { HotelTripAdvisor } from "@/types/hotel"
|
import type { HotelTripAdvisor } from "@/types/hotel"
|
||||||
|
|
||||||
interface TripAdvisorLinkProps {
|
interface TripAdvisorLinkProps {
|
||||||
@@ -32,7 +32,7 @@ export default async function TripAdvisorLink({
|
|||||||
|
|
||||||
const hasTripAdvisorIframeSrc = !!reviews.widgetScriptEmbedUrlIframe
|
const hasTripAdvisorIframeSrc = !!reviews.widgetScriptEmbedUrlIframe
|
||||||
const tripAdvisorHref = hasTripAdvisorIframeSrc
|
const tripAdvisorHref = hasTripAdvisorIframeSrc
|
||||||
? await appendSlugToPathname("reviews")
|
? `?s=${SidepeekSlugs.tripAdvisor}`
|
||||||
: null
|
: null
|
||||||
|
|
||||||
if (!tripAdvisorHref) {
|
if (!tripAdvisorHref) {
|
||||||
|
|||||||
@@ -0,0 +1,87 @@
|
|||||||
|
import { notFound } from "next/navigation"
|
||||||
|
|
||||||
|
import Image from "@/components/Image"
|
||||||
|
import SidePeek from "@/components/TempDesignSystem/SidePeek"
|
||||||
|
import { getIntl } from "@/i18n"
|
||||||
|
import { getLang } from "@/i18n/serverContext"
|
||||||
|
|
||||||
|
import styles from "./tripAdvisor.module.css"
|
||||||
|
|
||||||
|
import { SidepeekSlugs } from "@/types/components/hotelPage/hotelPage"
|
||||||
|
import type { HotelRatings } from "@/types/hotel"
|
||||||
|
|
||||||
|
type TripAdvisorSidePeekProps = {
|
||||||
|
hotelName: string
|
||||||
|
hotelRatings: HotelRatings
|
||||||
|
showNordicEcoLabel?: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
export default async function TripAdvisorSidePeek({
|
||||||
|
hotelName,
|
||||||
|
hotelRatings,
|
||||||
|
showNordicEcoLabel,
|
||||||
|
}: TripAdvisorSidePeekProps) {
|
||||||
|
const intl = await getIntl()
|
||||||
|
const lang = await getLang()
|
||||||
|
|
||||||
|
const tripAdvisorData = hotelRatings?.tripAdvisor
|
||||||
|
if (!tripAdvisorData?.reviews.widgetScriptEmbedUrlIframe) {
|
||||||
|
notFound()
|
||||||
|
}
|
||||||
|
|
||||||
|
const awardsLogos = tripAdvisorData.awards
|
||||||
|
.map((award) => ({
|
||||||
|
imageUrl: award.images.small,
|
||||||
|
altText: award.displayName,
|
||||||
|
}))
|
||||||
|
.filter((award) => !!award.imageUrl)
|
||||||
|
|
||||||
|
const hotelHasAwards = showNordicEcoLabel || awardsLogos.length > 0
|
||||||
|
|
||||||
|
return (
|
||||||
|
<SidePeek contentKey={SidepeekSlugs.tripAdvisor} title={hotelName}>
|
||||||
|
<section className={styles.container}>
|
||||||
|
{hotelHasAwards ? (
|
||||||
|
<div className={styles.awards}>
|
||||||
|
{showNordicEcoLabel ? (
|
||||||
|
<Image
|
||||||
|
src={`/_static/img/icons/swan-eco/swan_eco_dark_${lang}.png`}
|
||||||
|
alt={intl.formatMessage({
|
||||||
|
defaultMessage: "Nordic Swan Ecolabel",
|
||||||
|
})}
|
||||||
|
className={styles.logo}
|
||||||
|
height={100}
|
||||||
|
width={100}
|
||||||
|
/>
|
||||||
|
) : null}
|
||||||
|
{awardsLogos?.map((award) => (
|
||||||
|
<Image
|
||||||
|
src={award.imageUrl}
|
||||||
|
alt={award.altText}
|
||||||
|
className={styles.logo}
|
||||||
|
width={100}
|
||||||
|
height={100}
|
||||||
|
key={award.imageUrl}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
<main className={styles.main}>
|
||||||
|
<iframe
|
||||||
|
className={styles.iframe}
|
||||||
|
src={tripAdvisorData.reviews.widgetScriptEmbedUrlIframe}
|
||||||
|
loading="lazy"
|
||||||
|
title={intl.formatMessage(
|
||||||
|
{
|
||||||
|
defaultMessage: "Ratings and reviews for {hotelName}",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
hotelName: hotelName,
|
||||||
|
}
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</main>
|
||||||
|
</section>
|
||||||
|
</SidePeek>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
.container {
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.awards {
|
||||||
|
border-radius: var(--Corner-radius-lg);
|
||||||
|
background: var(--Surface-Primary-Default);
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
padding: var(--Space-x2) var(--Space-x15);
|
||||||
|
justify-content: space-evenly;
|
||||||
|
align-items: center;
|
||||||
|
align-self: stretch;
|
||||||
|
margin-bottom: var(--Space-x3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.main {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.iframe {
|
||||||
|
width: 100%;
|
||||||
|
border-width: 0;
|
||||||
|
border-radius: var(--Corner-radius-lg);
|
||||||
|
|
||||||
|
/* Adjustments for devices with tiny screen height */
|
||||||
|
min-height: max(50dvh, 300px);
|
||||||
|
padding-bottom: var(--Space-x4);
|
||||||
|
margin-bottom: calc(0% - var(--Space-x4));
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo {
|
||||||
|
width: 100%;
|
||||||
|
max-width: 120px;
|
||||||
|
height: 100px;
|
||||||
|
object-fit: contain;
|
||||||
|
}
|
||||||
@@ -29,6 +29,7 @@ import AmenitiesSidePeek from "./SidePeeks/Amenities"
|
|||||||
import MeetingsAndConferencesSidePeek from "./SidePeeks/MeetingsAndConferences"
|
import MeetingsAndConferencesSidePeek from "./SidePeeks/MeetingsAndConferences"
|
||||||
import RestaurantBarSidePeek from "./SidePeeks/RestaurantBar"
|
import RestaurantBarSidePeek from "./SidePeeks/RestaurantBar"
|
||||||
import RoomSidePeek from "./SidePeeks/Room"
|
import RoomSidePeek from "./SidePeeks/Room"
|
||||||
|
import TripAdvisorSidePeek from "./SidePeeks/Tripadvisor"
|
||||||
import WellnessAndExerciseSidePeek from "./SidePeeks/WellnessAndExercise"
|
import WellnessAndExerciseSidePeek from "./SidePeeks/WellnessAndExercise"
|
||||||
import AmenitiesList from "./AmenitiesList"
|
import AmenitiesList from "./AmenitiesList"
|
||||||
import DialogshiftWidget from "./DialogshiftWidget"
|
import DialogshiftWidget from "./DialogshiftWidget"
|
||||||
@@ -222,6 +223,11 @@ export default async function HotelPage({ hotelId }: HotelPageProps) {
|
|||||||
</aside>
|
</aside>
|
||||||
<MobileMapToggle />
|
<MobileMapToggle />
|
||||||
<SidePeeks hotelId={hotelId}>
|
<SidePeeks hotelId={hotelId}>
|
||||||
|
<TripAdvisorSidePeek
|
||||||
|
hotelName={hotel.name}
|
||||||
|
hotelRatings={hotel.ratings}
|
||||||
|
showNordicEcoLabel={hotel.hotelFacts?.ecoLabels.nordicEcoLabel}
|
||||||
|
/>
|
||||||
<AmenitiesSidePeek
|
<AmenitiesSidePeek
|
||||||
amenitiesList={detailedFacilities}
|
amenitiesList={detailedFacilities}
|
||||||
parking={{
|
parking={{
|
||||||
|
|||||||
@@ -1,121 +0,0 @@
|
|||||||
import { notFound } from "next/navigation"
|
|
||||||
import { Suspense } from "react"
|
|
||||||
|
|
||||||
import { Typography } from "@scandic-hotels/design-system/Typography"
|
|
||||||
|
|
||||||
import Breadcrumbs from "@/components/Breadcrumbs"
|
|
||||||
import Image from "@/components/Image"
|
|
||||||
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 = await 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 (
|
|
||||||
<>
|
|
||||||
<section className={styles.reviewsSubpage}>
|
|
||||||
<Suspense
|
|
||||||
fallback={
|
|
||||||
<BreadcrumbsSkeleton
|
|
||||||
size="contentWidth"
|
|
||||||
color="Surface/Secondary/Default"
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<Breadcrumbs
|
|
||||||
subpageTitle={intl.formatMessage({
|
|
||||||
defaultMessage: "Reviews",
|
|
||||||
})}
|
|
||||||
size="contentWidth"
|
|
||||||
color="Surface/Secondary/Default"
|
|
||||||
/>
|
|
||||||
</Suspense>
|
|
||||||
<header className={styles.header}>
|
|
||||||
<Typography variant="Title/md">
|
|
||||||
<h1 className={styles.heading}>{hotel.name}</h1>
|
|
||||||
</Typography>
|
|
||||||
<Typography variant="Title/Subtitle/md">
|
|
||||||
<p className={styles.subheading}>
|
|
||||||
{intl.formatMessage({
|
|
||||||
defaultMessage: "Ratings and reviews",
|
|
||||||
})}
|
|
||||||
</p>
|
|
||||||
</Typography>
|
|
||||||
</header>
|
|
||||||
|
|
||||||
<div className={styles.contentContainer}>
|
|
||||||
<aside className={styles.sidebar}>
|
|
||||||
<Typography variant="Title/xs">
|
|
||||||
<h2 className={styles.sidebarHeading}>
|
|
||||||
{intl.formatMessage({
|
|
||||||
defaultMessage: "Awards and certifications",
|
|
||||||
})}
|
|
||||||
</h2>
|
|
||||||
</Typography>
|
|
||||||
<div className={styles.sidebarContent}>
|
|
||||||
{showNordicEcoLabel ? (
|
|
||||||
<Image
|
|
||||||
src={`/_static/img/icons/swan-eco/swan_eco_dark_${lang}.png`}
|
|
||||||
alt={intl.formatMessage({
|
|
||||||
defaultMessage: "Nordic Swan Ecolabel",
|
|
||||||
})}
|
|
||||||
className={styles.logo}
|
|
||||||
height={100}
|
|
||||||
width={100}
|
|
||||||
/>
|
|
||||||
) : null}
|
|
||||||
{awardsLogos?.map((award) => (
|
|
||||||
<Image
|
|
||||||
src={award.imageUrl}
|
|
||||||
alt={award.altText}
|
|
||||||
className={styles.logo}
|
|
||||||
width={100}
|
|
||||||
height={100}
|
|
||||||
key={award.imageUrl}
|
|
||||||
/>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
</aside>
|
|
||||||
<main className={styles.mainContent}>
|
|
||||||
<iframe
|
|
||||||
className={styles.iframe}
|
|
||||||
src={tripAdvisorData.reviews.widgetScriptEmbedUrlIframe}
|
|
||||||
loading="lazy"
|
|
||||||
title={intl.formatMessage(
|
|
||||||
{
|
|
||||||
defaultMessage: "Ratings and reviews for {hotelName}",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
hotelName: hotel.name,
|
|
||||||
}
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
</main>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
</>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,84 +0,0 @@
|
|||||||
.reviewsSubpage {
|
|
||||||
padding-bottom: var(--Space-x9);
|
|
||||||
color: var(--Text-Default);
|
|
||||||
}
|
|
||||||
|
|
||||||
.header {
|
|
||||||
width: var(--max-width-content);
|
|
||||||
margin: 0 auto;
|
|
||||||
display: grid;
|
|
||||||
gap: var(--Space-x3);
|
|
||||||
padding: var(--Space-x4) 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.heading,
|
|
||||||
.sidebarHeading {
|
|
||||||
color: var(--Text-Heading);
|
|
||||||
}
|
|
||||||
|
|
||||||
.contentContainer {
|
|
||||||
display: grid;
|
|
||||||
gap: var(--Space-x3);
|
|
||||||
width: var(--max-width-content);
|
|
||||||
margin: 0 auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sidebar {
|
|
||||||
display: grid;
|
|
||||||
gap: var(--Space-x3);
|
|
||||||
align-content: start;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sidebarContent {
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
gap: var(--Space-x7);
|
|
||||||
padding: var(--Space-x5) var(--Space-x15);
|
|
||||||
background-color: var(--Background-Secondary);
|
|
||||||
border-radius: var(--Corner-radius-lg);
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.iframe {
|
|
||||||
width: 100%;
|
|
||||||
height: 50dvh;
|
|
||||||
border-width: 0;
|
|
||||||
border-radius: var(--Corner-radius-lg);
|
|
||||||
}
|
|
||||||
|
|
||||||
.logo {
|
|
||||||
width: 100%;
|
|
||||||
max-width: 120px;
|
|
||||||
height: 100px;
|
|
||||||
object-fit: contain;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media screen and (min-width: 768px) {
|
|
||||||
.iframe {
|
|
||||||
height: 1150px; /* Maximum(ish) content height on desktop without the need of scrolling */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media screen and (max-width: 1366px) {
|
|
||||||
.subheading,
|
|
||||||
.sidebarHeading {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media screen and (min-width: 1367px) {
|
|
||||||
.contentContainer {
|
|
||||||
grid-template-columns: var(--max-width-text-block) 1fr;
|
|
||||||
grid-template-areas: "main sidebar";
|
|
||||||
gap: var(--Space-x9);
|
|
||||||
}
|
|
||||||
|
|
||||||
.mainContent {
|
|
||||||
grid-area: main;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sidebar {
|
|
||||||
grid-area: sidebar;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -8,7 +8,6 @@ import AccessibilitySubpage from "./AccessibilitySubpage"
|
|||||||
import MeetingsSubpage from "./MeetingsSubpage"
|
import MeetingsSubpage from "./MeetingsSubpage"
|
||||||
import ParkingSubpage from "./ParkingSubpage"
|
import ParkingSubpage from "./ParkingSubpage"
|
||||||
import RestaurantSubpage from "./RestaurantSubpage"
|
import RestaurantSubpage from "./RestaurantSubpage"
|
||||||
import ReviewsSubpage from "./ReviewsSubpage"
|
|
||||||
import { verifySubpageShouldExist } from "./utils"
|
import { verifySubpageShouldExist } from "./utils"
|
||||||
import WellnessSubpage from "./WellnessSubpage"
|
import WellnessSubpage from "./WellnessSubpage"
|
||||||
|
|
||||||
@@ -71,8 +70,6 @@ export default async function HotelSubpage({
|
|||||||
additionalData={additionalData}
|
additionalData={additionalData}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
case "reviews":
|
|
||||||
return <ReviewsSubpage hotel={hotel} />
|
|
||||||
default:
|
default:
|
||||||
notFound()
|
notFound()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ export enum SidepeekSlugs {
|
|||||||
restaurant = "restaurants",
|
restaurant = "restaurants",
|
||||||
meetings = "meetings",
|
meetings = "meetings",
|
||||||
wellness = "wellness",
|
wellness = "wellness",
|
||||||
|
tripAdvisor = "tripAdvisor",
|
||||||
}
|
}
|
||||||
|
|
||||||
export type HotelHashValue =
|
export type HotelHashValue =
|
||||||
|
|||||||
Reference in New Issue
Block a user