diff --git a/apps/scandic-web/components/ContentType/HotelPage/IntroSection/TripAdvisorLink/index.tsx b/apps/scandic-web/components/ContentType/HotelPage/IntroSection/TripAdvisorLink/index.tsx deleted file mode 100644 index f8ce872f4..000000000 --- a/apps/scandic-web/components/ContentType/HotelPage/IntroSection/TripAdvisorLink/index.tsx +++ /dev/null @@ -1,60 +0,0 @@ -import TripadvisorIcon from "@scandic-hotels/design-system/Icons/TripadvisorIcon" -import Link from "@scandic-hotels/design-system/Link" - -import { getIntl } from "@/i18n" - -import styles from "./tripAdvisorLink.module.css" - -import type { HotelTripAdvisor } from "@scandic-hotels/trpc/types/hotel" - -import { SidepeekSlugs } from "@/types/components/hotelPage/hotelPage" - -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 - ? `?s=${SidepeekSlugs.tripAdvisor}` - : 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 deleted file mode 100644 index d96f63339..000000000 --- a/apps/scandic-web/components/ContentType/HotelPage/IntroSection/TripAdvisorLink/tripAdvisorLink.module.css +++ /dev/null @@ -1,6 +0,0 @@ -.tripAdvisorText { - display: flex; - gap: var(--Space-x05); - align-items: center; - color: var(--Text-Secondary); -} diff --git a/apps/scandic-web/components/ContentType/HotelPage/IntroSection/TripAdvisorSection/index.tsx b/apps/scandic-web/components/ContentType/HotelPage/IntroSection/TripAdvisorSection/index.tsx new file mode 100644 index 000000000..01c0a4e64 --- /dev/null +++ b/apps/scandic-web/components/ContentType/HotelPage/IntroSection/TripAdvisorSection/index.tsx @@ -0,0 +1,70 @@ +import ButtonLink from "@scandic-hotels/design-system/ButtonLink" +import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon" +import { TripAdvisorChip } from "@scandic-hotels/design-system/TripAdvisorChip" + +import { getIntl } from "@/i18n" + +import styles from "./tripAdvisorSection.module.css" + +import type { HotelTripAdvisor } from "@scandic-hotels/trpc/types/hotel" + +import { SidepeekSlugs } from "@/types/components/hotelPage/hotelPage" + +interface TripAdvisorSectionProps { + tripAdvisor: NonNullable +} + +export default async function TripAdvisorSection({ + tripAdvisor, +}: TripAdvisorSectionProps) { + const intl = await getIntl() + const { rating, numberOfReviews, reviews } = tripAdvisor + const hasTripAdvisorData = !!(rating && numberOfReviews) + + if (!hasTripAdvisorData) { + return null + } + + const formattedTripAdvisorText = intl.formatMessage( + { + defaultMessage: "{count} reviews", + }, + { count: numberOfReviews } + ) + + const hasTripAdvisorIframeSrc = !!reviews.widgetScriptEmbedUrlIframe + const tripAdvisorHref = hasTripAdvisorIframeSrc + ? `?s=${SidepeekSlugs.tripAdvisor}` + : null + + if (!tripAdvisorHref) { + return ( + + ) + } + + return ( +
+ + + {formattedTripAdvisorText} + + +
+ ) +} diff --git a/apps/scandic-web/components/ContentType/HotelPage/IntroSection/TripAdvisorSection/tripAdvisorSection.module.css b/apps/scandic-web/components/ContentType/HotelPage/IntroSection/TripAdvisorSection/tripAdvisorSection.module.css new file mode 100644 index 000000000..a5f88480a --- /dev/null +++ b/apps/scandic-web/components/ContentType/HotelPage/IntroSection/TripAdvisorSection/tripAdvisorSection.module.css @@ -0,0 +1,4 @@ +.tripAdvisorSection { + display: flex; + gap: var(--Space-x1); +} diff --git a/apps/scandic-web/components/ContentType/HotelPage/IntroSection/index.tsx b/apps/scandic-web/components/ContentType/HotelPage/IntroSection/index.tsx index 54ca8b9e2..80a38ea70 100644 --- a/apps/scandic-web/components/ContentType/HotelPage/IntroSection/index.tsx +++ b/apps/scandic-web/components/ContentType/HotelPage/IntroSection/index.tsx @@ -1,12 +1,17 @@ +import { cx } from "class-variance-authority" + import { getSingleDecimal } from "@scandic-hotels/common/utils/numberFormatting" import ButtonLink from "@scandic-hotels/design-system/ButtonLink" import { Divider } from "@scandic-hotels/design-system/Divider" import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon" +import Link from "@scandic-hotels/design-system/Link" import { Typography } from "@scandic-hotels/design-system/Typography" +import { Country } from "@scandic-hotels/trpc/types/country" +import LocalCallCharges from "@/components/LocalCallCharges" import { getIntl } from "@/i18n" -import TripAdvisorLink from "./TripAdvisorLink" +import TripAdvisorSection from "./TripAdvisorSection" import styles from "./introSection.module.css" @@ -37,7 +42,7 @@ export default async function IntroSection({ phoneNumber, }: IntroSectionProps) { const intl = await getIntl() - const { streetAddress, city } = address + const { streetAddress, city, country } = address const { distanceToCentre } = location const formattedDistanceText = intl.formatMessage( { @@ -48,6 +53,8 @@ export default async function IntroSection({ const formattedLocationText = `${streetAddress}, ${city} (${formattedDistanceText})` + const showLocalCharges = country === Country.Finland + return (
@@ -63,7 +70,11 @@ export default async function IntroSection({

{hotelName}

-
+
@@ -71,16 +82,35 @@ export default async function IntroSection({

{formattedLocationText}

- + + {!showLocalCharges && ( + + )}
- - + +
- {tripAdvisor ? : null} + + {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 1c5ee88ef..b63ff3ae4 100644 --- a/apps/scandic-web/components/ContentType/HotelPage/IntroSection/introSection.module.css +++ b/apps/scandic-web/components/ContentType/HotelPage/IntroSection/introSection.module.css @@ -5,6 +5,14 @@ max-width: var(--hotel-page-intro-section-width); } +.localCharges::before { + content: "("; +} + +.localCharges::after { + content: ")"; +} + .mainContent { display: grid; gap: var(--Space-x15); @@ -31,20 +39,13 @@ gap: var(--Space-x2); } -.adressPhoneNumber { +.addressPhoneNumber { font-style: normal; display: grid; gap: var(--Space-x15); align-items: center; } -.phoneNumber { - color: var(--Text-Interactive-Default); - display: flex; - gap: var(--Space-x05); - align-items: center; -} - .address { color: var(--Text-Secondary); gap: var(--Space-x05); @@ -58,14 +59,40 @@ height: 100%; } +.divider { + display: none; +} + +.phoneWrapper { + display: flex; + flex-direction: column; + gap: var(--Space-x15); +} + @media screen and (min-width: 767px) { - .adressPhoneNumber { + .addressPhoneNumber { display: flex; flex-direction: row; gap: var(--Space-x2); } + .addressPhoneNumber.stacked { + display: grid; + gap: var(--Space-x15); + align-items: center; + } + .address { align-items: center; } + + .phoneWrapper { + flex-direction: row; + gap: var(--Space-x1); + align-items: center; + } + + .divider { + display: block; + } } diff --git a/apps/scandic-web/components/LocalCallCharges/index.tsx b/apps/scandic-web/components/LocalCallCharges/index.tsx index ad8027750..ef96c3a94 100644 --- a/apps/scandic-web/components/LocalCallCharges/index.tsx +++ b/apps/scandic-web/components/LocalCallCharges/index.tsx @@ -5,15 +5,17 @@ import { getIntl } from "@/i18n" interface LocalCallChargesProps { country: string + className?: string } export default async function LocalCallCharges({ country, + className, }: LocalCallChargesProps) { const intl = await getIntl() return country === Country.Finland ? ( -

+

{intl.formatMessage({ defaultMessage: "Price 0,16 €/min + local call charges", })} diff --git a/packages/design-system/lib/components/HotelCard/HotelCardDialogImage/index.tsx b/packages/design-system/lib/components/HotelCard/HotelCardDialogImage/index.tsx index 2350313b5..acaee3bb0 100644 --- a/packages/design-system/lib/components/HotelCard/HotelCardDialogImage/index.tsx +++ b/packages/design-system/lib/components/HotelCard/HotelCardDialogImage/index.tsx @@ -39,7 +39,7 @@ export function HotelCardDialogImage({ {rating?.tripAdvisor && ( )}

diff --git a/packages/design-system/lib/components/TripAdvisorChip/TripdAdvisorChip.stories.tsx b/packages/design-system/lib/components/TripAdvisorChip/TripdAdvisorChip.stories.tsx index bebf96515..37639db4b 100644 --- a/packages/design-system/lib/components/TripAdvisorChip/TripdAdvisorChip.stories.tsx +++ b/packages/design-system/lib/components/TripAdvisorChip/TripdAdvisorChip.stories.tsx @@ -7,36 +7,57 @@ const meta: Meta = { component: TripAdvisorChip, argTypes: { rating: { - control: { - type: 'number', - min: 0, - max: 5, - step: 0.1, - }, + control: { type: 'number', min: 0, max: 5, step: 0.1 }, }, - variant: { - control: { - type: 'select', - }, + size: { + control: { type: 'select' }, options: ['default', 'small'], }, + color: { + control: { type: 'select' }, + options: ['default', 'subtle'], + }, + wrapper: { + control: { type: 'boolean' }, + }, }, } export default meta - type Story = StoryObj -export const PrimaryDefault: Story = { +export const Default: Story = { args: { rating: 4.5, - variant: 'default', + size: 'default', + color: 'default', + wrapper: false, + }, +} + +export const WithWrapper: Story = { + args: { + rating: 4.5, + size: 'default', + color: 'default', + wrapper: true, }, } export const Small: Story = { args: { rating: 4.5, - variant: 'small', + size: 'small', + color: 'default', + wrapper: true, + }, +} + +export const Subtle: Story = { + args: { + rating: 4.5, + size: 'default', + color: 'subtle', + wrapper: false, }, } diff --git a/packages/design-system/lib/components/TripAdvisorChip/index.tsx b/packages/design-system/lib/components/TripAdvisorChip/index.tsx index 4eea72bfb..4a5b8b716 100644 --- a/packages/design-system/lib/components/TripAdvisorChip/index.tsx +++ b/packages/design-system/lib/components/TripAdvisorChip/index.tsx @@ -5,42 +5,57 @@ import { Typography } from '../Typography' const container = cva(styles.container, { variants: { - variant: { + size: { default: null, small: styles.containerSmall, }, }, defaultVariants: { - variant: 'default', + size: 'default', }, }) const chip = cva(styles.tripAdvisor, { variants: { - variant: { + size: { default: null, small: styles.tripAdvisorSmall, }, + color: { + default: null, + subtle: styles.tripAdvisorSubtle, + }, }, defaultVariants: { - variant: 'default', + size: 'default', + color: 'default', }, }) type TripAdvisorProps = { rating: number -} & VariantProps + wrapper?: boolean +} & VariantProps -export function TripAdvisorChip({ rating, variant }: TripAdvisorProps) { - return ( - // Wrapping the chip in a transparent container with some padding to increase the touch target -
-
- - -

{rating}

-
-
+export function TripAdvisorChip({ + rating, + wrapper = true, + size, + color, +}: TripAdvisorProps) { + const content = ( +
+ + +

{rating}

+
) + + return wrapper ? ( + // Wrapping the chip in a transparent container with some padding to increase the touch target +
{content}
+ ) : ( + content + ) } diff --git a/packages/design-system/lib/components/TripAdvisorChip/tripAdvisorChip.module.css b/packages/design-system/lib/components/TripAdvisorChip/tripAdvisorChip.module.css index e02f7b609..489849bce 100644 --- a/packages/design-system/lib/components/TripAdvisorChip/tripAdvisorChip.module.css +++ b/packages/design-system/lib/components/TripAdvisorChip/tripAdvisorChip.module.css @@ -6,14 +6,18 @@ } .containerSmall { + position: absolute; + left: 0; + top: 0; padding: var(--Space-x05); } .tripAdvisor { - display: flex; + display: inline-flex; align-items: center; gap: var(--Space-x05); background-color: var(--Base-Surface-Primary-light-Normal); + color: var(--Text-Interactive-Default); padding: var(--Space-x05) var(--Space-x1); border-radius: var(--Corner-radius-sm); } @@ -22,3 +26,7 @@ padding: 0 var(--Space-x05) 0 3px; border-radius: 2px; } + +.tripAdvisorSubtle { + background-color: var(--Surface-Secondary-Subtle, #e3d9d1); +}