Merged in SW-3270-move-interactive-map-to-design-system-or-booking-flow (pull request #2681)

SW-3270 move interactive map to design system or booking flow

* wip

* wip

* merge

* wip

* add support for locales in design-system

* add story for HotelCard

* setup alias

* .

* remove tracking from design-system for hotelcard

* pass isUserLoggedIn

* export design-system-new-deprecated.css from design-system

* Add HotelMarkerByType to Storybook

* Add interactive map to Storybook

* fix reactintl in vitest

* rename env variables

* .

* fix background colors

* add storybook stories for <Link />

* merge

* fix tracking for when clicking 'See rooms' in InteractiveMap

* Merge branch 'master' of bitbucket.org:scandic-swap/web into SW-3270-move-interactive-map-to-design-system-or-booking-flow

* remove deprecated comment


Approved-by: Anton Gunnarsson
This commit is contained in:
Joakim Jäderberg
2025-08-25 11:26:16 +00:00
parent 4f8c51298f
commit c54c1ec540
139 changed files with 2511 additions and 1557 deletions

View File

@@ -0,0 +1,76 @@
import type { Meta, StoryObj } from '@storybook/react-vite'
import { fn } from 'storybook/test'
import { BookingCodeChip } from './index'
const meta = {
title: 'Components/BookingCodeChip',
component: BookingCodeChip,
parameters: {
layout: 'centered',
},
} satisfies Meta<typeof BookingCodeChip>
export default meta
type Story = StoryObj<typeof BookingCodeChip>
export const Default: Story = {
args: {},
render: () => <BookingCodeChip bookingCode="ABC123" withText />,
}
export const WithoutText: Story = {
args: {},
render: () => <BookingCodeChip bookingCode="ABC123" withText={false} />,
}
export const FilledIcon: Story = {
args: {},
render: () => <BookingCodeChip bookingCode="ABC123" filledIcon />,
}
export const Unavailable: Story = {
args: {},
render: () => <BookingCodeChip bookingCode="ABC123" isUnavailable />,
}
export const AlignCenter: Story = {
args: {},
render: () => <BookingCodeChip bookingCode="ABC123" alignCenter />,
}
export const WithCloseButton: Story = {
args: {},
render: () => (
<BookingCodeChip bookingCode="ABC123" withCloseButton onClose={fn} />
),
}
export const CampaignBreakfastIncluded: Story = {
args: {},
render: () => (
<BookingCodeChip isCampaign bookingCode="SUMMER25" isBreakfastIncluded />
),
}
export const CampaignBreakfastExcluded: Story = {
args: {},
render: () => (
<BookingCodeChip
isCampaign
bookingCode="SUMMER25"
isBreakfastIncluded={false}
/>
),
}
export const CampaignFilledIcon: Story = {
args: {},
render: () => (
<BookingCodeChip
isCampaign
bookingCode="SUMMER25"
isBreakfastIncluded
filledIcon
/>
),
}

View File

@@ -0,0 +1,21 @@
.bookingCodeChip {
display: flex;
gap: var(--Space-x05);
}
.unavailable {
text-decoration: line-through;
}
.center {
justify-content: center;
}
.removeButton {
color: currentColor;
background-color: transparent;
border-width: 0;
cursor: pointer;
padding: var(--Space-x05);
margin: calc(-1 * var(--Space-x05));
}

View File

@@ -0,0 +1,123 @@
import { Button as ButtonRAC } from 'react-aria-components'
import { useIntl } from 'react-intl'
import IconChip from '@scandic-hotels/design-system/IconChip'
import DiscountIcon from '@scandic-hotels/design-system/Icons/DiscountIcon'
import FilledDiscountIcon from '@scandic-hotels/design-system/Icons/FilledDiscountIcon'
import { MaterialIcon } from '@scandic-hotels/design-system/Icons/MaterialIcon'
import { Typography } from '@scandic-hotels/design-system/Typography'
import styles from './bookingCodeChip.module.css'
type BaseBookingCodeChipProps = {
alignCenter?: boolean
bookingCode?: string | null
isBreakfastIncluded?: boolean
isCampaign?: boolean
isUnavailable?: boolean
withText?: boolean
filledIcon?: boolean
}
type BookingCodeChipWithoutCloseButtonProps = BaseBookingCodeChipProps & {
withCloseButton?: false
}
type BookingCodeChipWithCloseButtonProps = BaseBookingCodeChipProps & {
withCloseButton: true
onClose: () => void
}
type BookingCodeChipProps =
| BookingCodeChipWithoutCloseButtonProps
| BookingCodeChipWithCloseButtonProps
export function BookingCodeChip({
alignCenter,
bookingCode,
isBreakfastIncluded,
isCampaign,
isUnavailable,
withText = true,
filledIcon = false,
...props
}: BookingCodeChipProps) {
const intl = useIntl()
if (isCampaign) {
return (
<IconChip
color="green"
icon={
filledIcon ? (
<FilledDiscountIcon color="Icon/Feedback/Success" />
) : (
<DiscountIcon color="Icon/Feedback/Success" />
)
}
className={alignCenter ? styles.center : undefined}
>
<p className={styles.bookingCodeChip}>
<Typography variant="Body/Supporting text (caption)/smBold">
<strong>
{intl.formatMessage({ defaultMessage: 'Campaign' })}
</strong>
</Typography>
<Typography variant="Body/Supporting text (caption)/smRegular">
<span>
{isBreakfastIncluded
? // eslint-disable-next-line formatjs/no-literal-string-in-jsx
`${bookingCode ?? ''} ${intl.formatMessage({
defaultMessage: 'Breakfast included',
})}`
: // eslint-disable-next-line formatjs/no-literal-string-in-jsx
`${bookingCode ?? ''} ${intl.formatMessage({
defaultMessage: 'Breakfast excluded',
})}`}
</span>
</Typography>
</p>
</IconChip>
)
}
if (!bookingCode) {
return null
}
return (
<IconChip
color="blue"
icon={
filledIcon ? (
<FilledDiscountIcon fill="Icon/Feedback/Information" />
) : (
<DiscountIcon color="Icon/Feedback/Information" />
)
}
className={alignCenter ? styles.center : undefined}
>
<p
className={`${styles.bookingCodeChip} ${isUnavailable ? styles.unavailable : ''}`}
>
{withText && (
<Typography variant="Body/Supporting text (caption)/smBold">
<strong>
{intl.formatMessage({
defaultMessage: 'Booking code',
})}
</strong>
</Typography>
)}
<Typography variant="Body/Supporting text (caption)/smRegular">
<span>{bookingCode}</span>
</Typography>
</p>
{props.withCloseButton && (
<>
<ButtonRAC className={styles.removeButton} onPress={props.onClose}>
<MaterialIcon icon="close" size={16} color="CurrentColor" />
</ButtonRAC>
</>
)}
</IconChip>
)
}