Merged in feat/BOOK-529-update-GLA-design-mystay (pull request #3230)

Feat/BOOK-529 update GLA design mystay

* feat(BOOK-529): update gla design on my stay

* feat(BOOK-529): open gla modal if error

* feat(BOOK-529): add inline accordion to storybook

* feat(529): move errormessage below message

* feat(529): update infomodal

* feat(BOOK-529): update infomodal

* feat(BOOK-529): hide guarantee info for adding ancillaries if prepaid

* feat(BOOK-529): update width on info dialog

* feat(BOOK-529): fix alignment

* feat(BOOK-529): check if member price

* feat(BOOK-529): refactor msg

* feat(BOOK-529): refactor terms and conditions to own component

* feat(BOOK-529): clean up confirmation step


Approved-by: Christel Westerberg
This commit is contained in:
Bianca Widstam
2025-11-28 14:27:25 +00:00
parent 22dd2f60fe
commit 46fa42750f
39 changed files with 681 additions and 485 deletions

View File

@@ -1,22 +0,0 @@
.content {
display: flex;
flex-direction: column;
gap: var(--Space-x1);
padding-top: var(--Space-x2);
}
.content ol {
margin: 0;
}
.summary {
list-style: none;
display: flex;
align-items: center;
gap: var(--Space-x05);
}
.summary::-webkit-details-marker,
.summary::marker {
display: none;
}

View File

@@ -1,68 +0,0 @@
import { useIntl } from "react-intl"
import Body from "@scandic-hotels/design-system/Body"
import Caption from "@scandic-hotels/design-system/Caption"
import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon"
import styles from "./guaranteeDetails.module.css"
export default function GuaranteeDetails() {
const intl = useIntl()
return (
<details>
<Caption color="burgundy" type="bold" asChild>
<summary className={styles.summary}>
{intl.formatMessage({
id: "common.howItWorks",
defaultMessage: "How it works",
})}
<MaterialIcon
icon="keyboard_arrow_down"
color="Icon/Interactive/Default"
size={16}
/>
</summary>
</Caption>
<section className={styles.content}>
<Body>
{intl.formatMessage({
id: "enterDetails.payment.guaranteeInfoDescription",
defaultMessage:
"When guaranteeing your booking, we will hold the booking until 07:00 until the day after check-in. This will provide you as a guest with added flexibility for check-in times.",
})}
</Body>
<Body>
{intl.formatMessage({
id: "enterDetails.payment.guaranteeInfoWhatToDo",
defaultMessage: "What you have to do to guarantee booking:",
})}
</Body>
<ol>
<Body asChild>
<li>
{intl.formatMessage({
id: "enterDetails.payment.guaranteeInfoCompleteBooking",
defaultMessage: "Complete the booking",
})}
</li>
</Body>
<Body asChild>
<li>
{intl.formatMessage({
id: "enterDetails.payment.guaranteeInfoProvideCard",
defaultMessage: "Provide a payment card in the next step",
})}
</li>
</Body>
</ol>
<Body>
{intl.formatMessage({
id: "enterDetails.payment.guaranteeInfoMandatoryNote",
defaultMessage:
"Please note that this is mandatory, and that your card will only be charged in the event of a no-show.",
})}
</Body>
</section>
</details>
)
}

View File

@@ -12,7 +12,7 @@ const meta: Meta<typeof Accordion> = {
argTypes: {
type: {
control: 'select',
options: ['card', 'sidepeek'],
options: ['card', 'sidepeek', 'inline'],
},
},
}
@@ -137,3 +137,22 @@ export const WithSubtitle: Story = {
</Accordion>
),
}
export const Inline: Story = {
args: {
type: 'inline',
},
render: () => (
<Accordion type="inline">
<AccordionItem title="Read more about our rooms">
<Typography variant="Body/Paragraph/mdRegular">
<p>
All rooms feature comfortable beds, modern amenities, and
complimentary Wi-Fi. Check-in is available from 3 PM and check-out
is at 12 PM.
</p>
</Typography>
</AccordionItem>
</Accordion>
),
}

View File

@@ -18,6 +18,19 @@
}
}
&.inline {
list-style: none;
padding: var(--Space-x15);
background-color: var(--Surface-Primary-Default);
.content {
padding: var(--Space-x1) 0 0 0;
}
.summary:hover {
background-color: transparent;
}
}
.summary:hover {
background-color: var(--Surface-Primary-Hover);
}

View File

@@ -93,6 +93,10 @@ export default function AccordionItem({
<Typography variant="Title/Subtitle/md">
<p className={styles.title}>{title}</p>
</Typography>
) : type === 'inline' ? (
<Typography variant="Body/Supporting text (caption)/smBold">
<p className={styles.title}>{title}</p>
</Typography>
) : (
<div className={styles.title}>
{subtitle || showAsSubtitle ? (

View File

@@ -7,6 +7,7 @@ export const accordionItemVariants = cva(styles.accordionItem, {
type: {
card: styles.card,
sidepeek: styles.sidepeek,
inline: styles.inline,
},
},
defaultVariants: {

View File

@@ -7,6 +7,7 @@ export const accordionVariants = cva(styles.accordion, {
type: {
card: styles.card,
sidepeek: styles.sidepeek,
inline: styles.inline,
},
},
defaultVariants: {

View File

@@ -12,11 +12,13 @@ export type PaymentOptionProps = {
value: PaymentMethodEnum
label: string
cardNumber?: string
hideRadioButton?: boolean
}
export function PaymentOption({
value,
label,
cardNumber,
hideRadioButton = false,
}: PaymentOptionProps) {
return (
<Radio
@@ -28,10 +30,12 @@ export function PaymentOption({
{({ isSelected }) => (
<>
<div className={styles.titleContainer}>
<span
className={cx(styles.radio, { [styles.selected]: isSelected })}
aria-hidden
/>
{!hideRadioButton && (
<span
className={cx(styles.radio, { [styles.selected]: isSelected })}
aria-hidden
/>
)}
<Typography variant="Body/Paragraph/mdRegular">
<Label>{label}</Label>
</Typography>

View File

@@ -31,12 +31,19 @@ export function SelectPaymentMethod({
formName,
}: SelectPaymentMethodProps) {
const intl = useIntl()
const hasSavedCards = paymentMethods.length > 0
if (!hasSavedCards) {
return null
}
const mySavedCardsLabel = paymentMethods.length
? intl.formatMessage({
id: 'payment.mySavedCards',
defaultMessage: 'My saved cards',
})
: undefined
const otherCardLabel = paymentMethods.length
? intl.formatMessage({
id: 'common.other',
@@ -44,8 +51,6 @@ export function SelectPaymentMethod({
})
: undefined
const hasSavedCards = paymentMethods.length > 0
return (
<section className={styles.section}>
<PaymentOptionsGroup
@@ -63,32 +68,27 @@ export function SelectPaymentMethod({
defaultMessage: 'Card options',
})}
</Label>
{hasSavedCards ? (
<>
<Typography variant="Title/Overline/sm">
<span>{mySavedCardsLabel}</span>
</Typography>
{paymentMethods?.map((paymentMethods) => {
const label =
PAYMENT_METHOD_TITLES[paymentMethods.cardType] ||
paymentMethods.alias ||
paymentMethods.cardType
return (
<PaymentOption
key={paymentMethods.id}
value={paymentMethods.id as PaymentMethodEnum}
label={label}
cardNumber={paymentMethods.truncatedNumber}
/>
)
})}
<Typography variant="Title/Overline/sm">
<span>{otherCardLabel}</span>
</Typography>
</>
) : null}
<Typography variant="Title/Overline/sm">
<span>{mySavedCardsLabel}</span>
</Typography>
{paymentMethods?.map((paymentMethods) => {
const label =
PAYMENT_METHOD_TITLES[paymentMethods.cardType] ||
paymentMethods.alias ||
paymentMethods.cardType
return (
<PaymentOption
key={paymentMethods.id}
value={paymentMethods.id as PaymentMethodEnum}
label={label}
cardNumber={paymentMethods.truncatedNumber}
/>
)
})}
<Typography variant="Title/Overline/sm">
<span>{otherCardLabel}</span>
</Typography>
<PaymentOption
value={PAYMENT_METHOD_TITLES.card as PaymentMethodEnum}
label={intl.formatMessage({

View File

@@ -276,7 +276,7 @@
font-style: normal;
font-weight: 400;
font-display: block;
src: url(/_static/shared/fonts/material-symbols/rounded-1b8067b7.woff2)
src: url(/_static/shared/fonts/material-symbols/rounded-3e9207ba.woff2)
format('woff2');
}