Merged in fix/BOOK-529-my-stay-guarantee (pull request #3282)

fix(BOOK-529): add card icon to payment cards, show scrollbar, add missing text

* fix(BOOK-529): add card icon to payment cards, show scrollbar, add missing text

* fix(BOOK-529): refactor savdecard

* fix(BOOK-529): fix lokaliseid

* fix(BOOK-529): paymentmethods


Approved-by: Joakim Jäderberg
This commit is contained in:
Bianca Widstam
2025-12-03 13:04:02 +00:00
parent 6730575f7a
commit 7db225a3ee
9 changed files with 74 additions and 38 deletions

View File

@@ -20,6 +20,14 @@
padding: var(--Space-x2);
}
.refundPolicy {
color: var(--Text-Secondary);
}
.pointsAvailable {
text-align: end;
}
.paymentInfo {
display: flex;
gap: var(--Space-x1);

View File

@@ -2,7 +2,6 @@ import { useWatch } from "react-hook-form"
import { useIntl } from "react-intl"
import { PaymentMethodEnum } from "@scandic-hotels/common/constants/paymentMethod"
import { dt } from "@scandic-hotels/common/dt"
import AccordionItem from "@scandic-hotels/design-system/Accordion/AccordionItem"
import { Alert } from "@scandic-hotels/design-system/Alert"
import { Divider } from "@scandic-hotels/design-system/Divider"
@@ -15,7 +14,6 @@ import { Typography } from "@scandic-hotels/design-system/Typography"
import { useAddAncillaryStore } from "@/stores/my-stay/add-ancillary-flow"
import TermsAndConditions from "@/components/HotelReservation/MyStay/TermsAndConditions"
import useLang from "@/hooks/useLang"
import { trackUpdatePaymentMethod } from "@/utils/tracking"
import Summary from "../Summary"
@@ -30,19 +28,15 @@ export default function ConfirmationStep({
error,
}: ConfirmationStepProps) {
const intl = useIntl()
const lang = useLang()
const { checkInDate, guaranteeInfo, selectedAncillary, booking } =
useAddAncillaryStore((state) => ({
const { guaranteeInfo, selectedAncillary, booking } = useAddAncillaryStore(
(state) => ({
checkInDate: state.booking.checkInDate,
guaranteeInfo: state.booking.guaranteeInfo,
selectedAncillary: state.selectedAncillary,
booking: state.booking,
}))
const refundableDate = dt(checkInDate)
.subtract(1, "day")
.locale(lang)
.format("23:59, dddd, D MMMM YYYY")
})
)
const mustBeGuaranteed = !guaranteeInfo && booking.isGuaranteeable
const quantityWithCard = useWatch({ name: "quantityWithCard" })
@@ -99,7 +93,7 @@ export default function ConfirmationStep({
</Typography>
</div>
<Typography variant="Body/Paragraph/mdRegular">
<p>
<p className={styles.pointsAvailable}>
{intl.formatMessage(
{
id: "addAncillary.confirmationStep.pointsAvailable",
@@ -112,7 +106,7 @@ export default function ConfirmationStep({
</div>
</>
)}
{!!quantityWithCard && (
{!!quantityWithCard ? (
<>
<Typography variant="Title/Subtitle/md">
<h2>
@@ -123,15 +117,12 @@ export default function ConfirmationStep({
</h2>
</Typography>
<Typography variant="Body/Paragraph/mdRegular">
<p>
{intl.formatMessage(
{
id: "addAncillary.confirmationStep.refundPolicy",
defaultMessage:
"All ancillaries are fully refundable until {date}. Time selection and special requests are also modifiable.",
},
{ date: refundableDate }
)}
<p className={styles.refundPolicy}>
{intl.formatMessage({
id: "addAncillary.confirmationStep.refundPolicyNightBefore",
defaultMessage:
"All extras can be cancelled until 23:59 the night before arrival. Time selection and special requests can also be modified.",
})}
</p>
</Typography>
<div className={styles.guarantee}>
@@ -171,6 +162,7 @@ export default function ConfirmationStep({
<PaymentOptionsGroup name="paymentMethod">
<PaymentOption
value={PaymentMethodEnum.card}
type={PaymentMethodEnum.card}
cardNumber={guaranteeInfo.maskedCard.slice(-4)}
label={intl.formatMessage({
id: "common.card",
@@ -209,7 +201,7 @@ export default function ConfirmationStep({
</Typography>
</AccordionItem>
)}
{savedCreditCards && <Divider />}
{!!savedCreditCards?.length && <Divider />}
<SelectPaymentMethod
paymentMethods={(savedCreditCards ?? []).map((card) => ({
...card,
@@ -224,6 +216,16 @@ export default function ConfirmationStep({
)}
</div>
</>
) : (
<Typography variant="Body/Paragraph/mdRegular">
<p className={styles.refundPolicy}>
{intl.formatMessage({
id: "addAncillary.confirmationStep.refundPolicyNightBefore",
defaultMessage:
"All extras can be cancelled until 23:59 the night before arrival. Time selection and special requests can also be modified.",
})}
</p>
</Typography>
)}
<TermsAndConditions />
<Summary isConfirmation />

View File

@@ -5,10 +5,6 @@
overflow-y: auto;
}
.form::-webkit-scrollbar {
display: none;
}
.modalScrollable {
display: flex;
flex-direction: column;

View File

@@ -110,6 +110,18 @@ export function calculateTotalPrice(rooms: Room[], currency: CurrencyEnum) {
}
}
break
case PriceTypeEnum.money:
{
if (room.totalPoints) {
total.local.additionalPrice =
(total.local.additionalPrice || 0) + room.totalPoints
}
if (!total.local.additionalPriceCurrency) {
total.local.additionalPriceCurrency = CurrencyEnum.POINTS
}
}
break
}
return total

View File

@@ -64,8 +64,9 @@ export function ConfirmBookingPaymentOptions({
{savedCreditCards.map((savedCreditCard) => (
<PaymentOption
type={savedCreditCard.cardType as PaymentMethodEnum}
key={savedCreditCard.id}
value={savedCreditCard.id as PaymentMethodEnum}
value={savedCreditCard.id}
label={
PAYMENT_METHOD_TITLES[
savedCreditCard.cardType as PaymentMethodEnum
@@ -86,6 +87,7 @@ export function ConfirmBookingPaymentOptions({
</>
) : null}
<PaymentOption
type={PaymentMethodEnum.card}
value={PaymentMethodEnum.card}
label={intl.formatMessage({
id: "common.creditCard",
@@ -96,6 +98,7 @@ export function ConfirmBookingPaymentOptions({
{!hasMixedRates
? availablePaymentOptions.map((paymentMethod) => (
<PaymentOption
type={paymentMethod}
key={paymentMethod}
value={paymentMethod}
label={PAYMENT_METHOD_TITLES[paymentMethod]}

View File

@@ -9,14 +9,16 @@ import { PaymentMethodIcon } from '../../Payment/PaymentMethodIcon'
import { Typography } from '../../Typography'
export type PaymentOptionProps = {
value: PaymentMethodEnum
value: string
label: string
type: PaymentMethodEnum
cardNumber?: string
hideRadioButton?: boolean
}
export function PaymentOption({
value,
label,
type,
cardNumber,
hideRadioButton = false,
}: PaymentOptionProps) {
@@ -40,16 +42,15 @@ export function PaymentOption({
<Label>{label}</Label>
</Typography>
</div>
{cardNumber ? (
<>
<div className={styles.cardContainer}>
{cardNumber && (
<Typography variant={'Body/Supporting text (caption)/smRegular'}>
{/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}
<span> {cardNumber}</span>
</Typography>
</>
) : (
<PaymentMethodIcon paymentMethod={value} alt={label} />
)}
)}
<PaymentMethodIcon paymentMethod={type} alt={label} />
</div>
</>
)}
</Radio>

View File

@@ -22,15 +22,21 @@ export const Default: Story = {
onChange: fn(),
children: (
<>
<PaymentOption label="Visa" value={PaymentMethodEnum.visa} />
<PaymentOption
label="Visa"
value={PaymentMethodEnum.visa}
type={PaymentMethodEnum.visa}
/>
<PaymentOption
label="American Express"
value={PaymentMethodEnum.americanExpress}
type={PaymentMethodEnum.americanExpress}
/>
<PaymentOption
label="MasterCard"
value={PaymentMethodEnum.masterCard}
cardNumber="1234"
type={PaymentMethodEnum.masterCard}
/>
</>
),

View File

@@ -11,6 +11,12 @@
cursor: pointer;
}
.cardContainer {
display: flex;
gap: var(--Space-x15);
align-items: center;
}
.paymentOption.focused {
outline: 2px solid var(--UI-Input-Controls-Border-Focus);
outline-offset: 2px;

View File

@@ -9,7 +9,7 @@ import styles from './selectPaymentMethod.module.css'
import {
PAYMENT_METHOD_TITLES,
type PaymentMethodEnum,
PaymentMethodEnum,
} from '@scandic-hotels/common/constants/paymentMethod'
type PaymentMethod = {
@@ -79,8 +79,9 @@ export function SelectPaymentMethod({
return (
<PaymentOption
type={paymentMethods.cardType}
key={paymentMethods.id}
value={paymentMethods.id as PaymentMethodEnum}
value={paymentMethods.id}
label={label}
cardNumber={paymentMethods.truncatedNumber}
/>
@@ -90,7 +91,8 @@ export function SelectPaymentMethod({
<span>{otherCardLabel}</span>
</Typography>
<PaymentOption
value={PAYMENT_METHOD_TITLES.card as PaymentMethodEnum}
value={PaymentMethodEnum.card}
type={PaymentMethodEnum.card}
label={intl.formatMessage({
id: 'common.creditCard',
defaultMessage: 'Credit card',