Merged in fix/hide-payment-if-only-points (pull request #1741)

Feat(SW-1943): add new design for pay ancillaries with points

* fix: hide card and payment info if only quantity with points is selected

* feat(SW-1943): add new design for pay ancillaries with points

* feat(SW-1943): add missing translation

* feat(SW-1943): fix rebase

* feat(SW-1943): remove console log


Approved-by: Linus Flood
Approved-by: Matilda Landström
This commit is contained in:
Bianca Widstam
2025-04-10 06:18:02 +00:00
parent 8f4834a6ef
commit 77c03905e4
13 changed files with 129 additions and 47 deletions

View File

@@ -9,3 +9,17 @@
gap: var(--Space-x2);
color: var(--Text-Secondary);
}
.totalPointsContainer {
display: flex;
justify-content: space-between;
background-color: var(--Surface-Brand-Primary-2-OnSurface-Accent);
padding: var(--Space-x1) var(--Space-x15);
border-radius: var(--Corner-radius-Medium);
}
.totalPoints {
display: flex;
gap: var(--Space-x15);
align-items: center;
}

View File

@@ -1,5 +1,7 @@
import { useWatch } from "react-hook-form"
import { useIntl } from "react-intl"
import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon"
import { Typography } from "@scandic-hotels/design-system/Typography"
import { PaymentMethodEnum } from "@/constants/booking"
@@ -24,18 +26,28 @@ import { AlertTypeEnum } from "@/types/enums/alert"
export default function ConfirmationStep({
savedCreditCards,
user,
}: ConfirmationStepProps) {
const intl = useIntl()
const lang = useLang()
const { checkInDate, guaranteeInfo } = useAddAncillaryStore((state) => ({
checkInDate: state.booking.checkInDate,
guaranteeInfo: state.booking.guaranteeInfo,
}))
const { checkInDate, guaranteeInfo, selectedAncillary } =
useAddAncillaryStore((state) => ({
checkInDate: state.booking.checkInDate,
guaranteeInfo: state.booking.guaranteeInfo,
selectedAncillary: state.selectedAncillary,
}))
const refundableDate = dt(checkInDate)
.subtract(1, "day")
.locale(lang)
.format("23:59, dddd, D MMMM YYYY")
const quantityWithCard = useWatch({ name: "quantityWithCard" })
const quantityWithPoints = useWatch({ name: "quantityWithPoints" })
const currentPoints = user?.membership?.currentPoints ?? 0
const totalPoints =
quantityWithPoints && selectedAncillary?.points
? selectedAncillary.points * quantityWithPoints
: null
return (
<div className={styles.modalContent}>
<Typography variant="Body/Paragraph/mdRegular">
@@ -48,54 +60,91 @@ export default function ConfirmationStep({
)}
</p>
</Typography>
<header>
<Typography variant="Title/Subtitle/md">
<h2>
{intl.formatMessage({
id: "Reserve with Card",
})}
</h2>
</Typography>
</header>
<Typography variant="Body/Supporting text (caption)/smRegular">
<p>
{intl.formatMessage({
id: "Payment will be made on check-in. The card will be only used to guarantee the ancillary in case of no-show.",
})}
</p>
</Typography>
{guaranteeInfo ? (
<PaymentOption
name="paymentMethod"
value={PaymentMethodEnum.card}
cardNumber={guaranteeInfo.maskedCard.slice(-4)}
label={intl.formatMessage({ id: "Credit card" })}
/>
) : (
{!!quantityWithPoints && (
<>
<Alert
type={AlertTypeEnum.Info}
text={intl.formatMessage({
id: "By adding a card you also guarantee your room booking for late arrival.",
})}
/>
{savedCreditCards?.length && (
<MySavedCards savedCreditCards={savedCreditCards} />
)}
<>
{savedCreditCards?.length && (
<Typography variant="Title/Subtitle/md">
<h2>
{intl.formatMessage({
id: "Points to be deducted now",
})}
</h2>
</Typography>
<div className={styles.totalPointsContainer}>
<div className={styles.totalPoints}>
<MaterialIcon icon="diamond" />
<Typography variant="Title/Overline/sm">
<h4>{intl.formatMessage({ id: "OTHER" })}</h4>
<h2>
{intl.formatMessage(
{ id: "{amount} points" },
{ amount: totalPoints }
)}
</h2>
</Typography>
)}
</div>
<Typography variant="Body/Paragraph/mdRegular">
<p>
{intl.formatMessage(
{ id: "{amount} points available" },
{ amount: currentPoints }
)}
</p>
</Typography>
</div>
</>
)}
{!!quantityWithCard && (
<>
<header>
<Typography variant="Title/Subtitle/md">
<h2>
{intl.formatMessage({
id: "Reserve with Card",
})}
</h2>
</Typography>
</header>
<Typography variant="Body/Supporting text (caption)/smRegular">
<p>
{intl.formatMessage({
id: "Payment will be made on check-in. The card will be only used to guarantee the ancillary in case of no-show.",
})}
</p>
</Typography>
{guaranteeInfo ? (
<PaymentOption
name="paymentMethod"
value={PaymentMethodEnum.card}
cardNumber={guaranteeInfo.maskedCard.slice(-4)}
label={intl.formatMessage({ id: "Credit card" })}
/>
</>
) : (
<>
<Alert
type={AlertTypeEnum.Info}
text={intl.formatMessage({
id: "By adding a card you also guarantee your room booking for late arrival.",
})}
/>
{savedCreditCards?.length && (
<MySavedCards savedCreditCards={savedCreditCards} />
)}
<>
{savedCreditCards?.length && (
<Typography variant="Title/Overline/sm">
<h4>{intl.formatMessage({ id: "OTHER" })}</h4>
</Typography>
)}
<PaymentOption
name="paymentMethod"
value={PaymentMethodEnum.card}
label={intl.formatMessage({ id: "Credit card" })}
/>
</>
</>
)}
</>
)}
<div className={styles.termsAndConditions}>
<Typography variant="Body/Supporting text (caption)/smRegular">
<p>

View File

@@ -22,5 +22,5 @@ export default function Desktop({ user, savedCreditCards }: StepsProps) {
return <DeliveryMethodStep />
}
return <ConfirmationStep savedCreditCards={savedCreditCards} />
return <ConfirmationStep savedCreditCards={savedCreditCards} user={user} />
}

View File

@@ -23,5 +23,5 @@ export default function Mobile({ user, savedCreditCards }: StepsProps) {
</>
)
}
return <ConfirmationStep savedCreditCards={savedCreditCards} />
return <ConfirmationStep savedCreditCards={savedCreditCards} user={user} />
}

View File

@@ -264,8 +264,10 @@ export default function AddAncillaryFlowModal({
toast.error(intl.formatMessage({ id: "Something went wrong!" }))
return
}
const shouldSkipGuarantee =
booking.guaranteeInfo || (data.quantityWithCard ?? 0) <= 0
if (booking.guaranteeInfo) {
if (shouldSkipGuarantee) {
handleAncillarySubmission(data, packagesToAdd)
} else {
handleGuaranteePayment(data, packagesToAdd)

View File

@@ -631,6 +631,7 @@
"Points may take up to 10 days to be displayed.": "Det kan tage op til 10 dage at få vist point.",
"Points needed to level up": "Point nødvendige for at stige i niveau",
"Points needed to stay on level": "Point nødvendige for at holde sig på niveau",
"Points to be deducted now": "Point, der skal trækkes nu",
"Points used": "Points used",
"Practical information": "Praktisk information",
"Preliminary receipt": "Foreløbig kvittering",
@@ -978,6 +979,8 @@
"{amount, plural, one {Gift} other {Gifts}} added to your benefits": "{amount, plural, one {Gave} other {Gaver}} tilføjet til dine fordele",
"{amount} has been paid": "{amount} has been paid",
"{amount} out of {total}": "{amount} ud af {total}",
"{amount} points": "{amount} point",
"{amount} points available": "{amount} point tilgængelige",
"{amount} {amount, plural, one {hotel} other {hotels}}": "{amount} {amount, plural, one {hotel} other {hoteller}}",
"{amount}/night per adult": "{amount}/nat per voksen",
"{ancillary} added to your booking!": "{ancillary} tilføjet til din booking!",

View File

@@ -630,6 +630,7 @@
"Points may take up to 10 days to be displayed.": "Es kann bis zu 10 Tage dauern, bis Punkte angezeigt werden.",
"Points needed to level up": "Punkte, die zum Levelaufstieg benötigt werden",
"Points needed to stay on level": "Erforderliche Punkte, um auf diesem Level zu bleiben",
"Points to be deducted now": "Punkte, die jetzt abgezogen werden",
"Points used": "Points used",
"Practical information": "Praktische Informationen",
"Preliminary receipt": "Vorläufige Quittung",
@@ -976,6 +977,8 @@
"{amount, plural, one {Gift} other {Gifts}} added to your benefits": "{amount, plural, one {Geschenk zu Ihren Vorteilen hinzugefügt} other {Geschenke, die zu Ihren Vorteilen hinzugefügt werden}}",
"{amount} has been paid": "{amount} has been paid",
"{amount} out of {total}": "{amount} von {total}",
"{amount} points": "{amount} Punkte",
"{amount} points available": "{amount} Punkte verfügbar",
"{amount} {amount, plural, one {hotel} other {hotels}}": "{amount} {amount, plural, one {hotel} other {hotels}}",
"{amount}/night per adult": "{amount}/Nacht pro Erwachsenem",
"{ancillary} added to your booking!": "{ancillary} zu Ihrer Buchung hinzugefügt!",

View File

@@ -631,6 +631,7 @@
"Points may take up to 10 days to be displayed.": "Points may take up to 10 days to be displayed.",
"Points needed to level up": "Points needed to level up",
"Points needed to stay on level": "Points needed to stay on level",
"Points to be deducted now": "Points to be deducted now",
"Points used": "Points used",
"Practical information": "Practical information",
"Preliminary receipt": "Preliminary receipt",
@@ -973,6 +974,8 @@
"{amount, plural, one {Gift} other {Gifts}} added to your benefits": "{amount, plural, one {Gift} other {Gifts}} added to your benefits",
"{amount} has been paid": "{amount} has been paid",
"{amount} out of {total}": "{amount} out of {total}",
"{amount} points": "{amount} points",
"{amount} points available": "{amount} points available",
"{amount} {amount, plural, one {hotel} other {hotels}}": "{amount} {amount, plural, one {hotel} other {hotels}}",
"{amount}/night per adult": "{amount}/night per adult",
"{ancillary} added to your booking!": "{ancillary} added to your booking!",

View File

@@ -629,6 +629,7 @@
"Points may take up to 10 days to be displayed.": "Pisteiden näyttäminen voi kestää jopa 10 päivää.",
"Points needed to level up": "Tarvitset vielä",
"Points needed to stay on level": "Tällä tasolla pysymiseen tarvittavat pisteet",
"Points to be deducted now": "Nyt vähennettävät pisteet",
"Points used": "Points used",
"Practical information": "Käytännön tietoa",
"Preliminary receipt": "Alustava kuitti",
@@ -976,6 +977,8 @@
"{amount, plural, one {Gift} other {Gifts}} added to your benefits": "{amount, plural, one {Lahja} other {Lahjat}} lisätty etuusi",
"{amount} has been paid": "{amount} has been paid",
"{amount} out of {total}": "{amount}/{total}",
"{amount} points": "{amount} pistettä",
"{amount} points available": "{amount} pistettä saatavilla",
"{amount} {amount, plural, one {hotel} other {hotels}}": "{amount} {amount, plural, one {hotelli} other {hotellit}}",
"{amount}/night per adult": "{amount}/yötä aikuista kohti",
"{ancillary} added to your booking!": "{ancillary} lisätty varaukseesi!",

View File

@@ -628,6 +628,7 @@
"Points may take up to 10 days to be displayed.": "Det kan ta opptil 10 dager før poeng vises.",
"Points needed to level up": "Poeng som trengs for å komme opp i nivå",
"Points needed to stay on level": "Poeng som trengs for å holde seg på nivå",
"Points to be deducted now": "Poeng som trekkes nå",
"Points used": "Points used",
"Practical information": "Praktisk informasjon",
"Preliminary receipt": "Foreløpig kvittering",
@@ -972,6 +973,8 @@
"{amount, plural, one {Gift} other {Gifts}} added to your benefits": "{amount, plural, one {Gave} other {Gaver}} lagt til fordelene dine",
"{amount} has been paid": "{amount} has been paid",
"{amount} out of {total}": "{amount} av {total}",
"{amount} points": "{amount} poeng",
"{amount} points available": "{amount} poeng tilgjengelig",
"{amount} {amount, plural, one {hotel} other {hotels}}": "{amount} {amount, plural, one {hotell} other {hoteller}}",
"{amount}/night per adult": "{amount}/natt per voksen",
"{ancillary} added to your booking!": "{ancillary} lagt til bestillingen din!",

View File

@@ -628,6 +628,7 @@
"Points may take up to 10 days to be displayed.": "Det kan ta upp till 10 dagar innan poäng visas.",
"Points needed to level up": "Poäng som behövs för att gå upp i nivå",
"Points needed to stay on level": "Poäng som behövs för att hålla sig på nivå",
"Points to be deducted now": "Poäng som dras av nu",
"Points used": "Points used",
"Practical information": "Praktisk information",
"Preliminary receipt": "Preliminärt kvitto",
@@ -976,6 +977,8 @@
"{amount, plural, one {Gift} other {Gifts}} added to your benefits": "{amount, plural, one {Gåva} other {Gåvor}} läggs till dina förmåner",
"{amount} has been paid": "{amount} has been paid",
"{amount} out of {total}": "{amount} av {total}",
"{amount} points": "{amount} poäng",
"{amount} points available": "{amount} poäng tillgängliga",
"{amount} {amount, plural, one {hotel} other {hotels}}": "{amount} {amount, plural, one {hotell} other {hotell}}",
"{amount}/night per adult": "{amount}/natt per vuxen",
"{ancillary} added to your booking!": "{ancillary} har lagts till i din bokning!",

View File

@@ -60,6 +60,7 @@ export interface SelectQuantityStepProps {
export interface ConfirmationStepProps {
savedCreditCards: CreditCard[] | null
user: User | null
}
export interface StepsProps {

View File

@@ -185,7 +185,6 @@ export function trackAddAncillary(
productName: ancillary?.title,
productUnits: quantityWithCard,
productPrice: ancillary?.price,
productPoints: ancillary?.points,
productCategory: ancillary?.categoryName,
})
}
@@ -196,7 +195,6 @@ export function trackAddAncillary(
productId: ancillary?.loyaltyCode,
productName: ancillary?.title,
productUnits: quantityWithPoints,
productPrice: ancillary?.price,
productPoints: ancillary?.points,
productCategory: ancillary?.categoryName,
})