feat(SW-706): make eslint rule 'formatjs/no-literal-string-in-jsx' pass

This commit is contained in:
Michael Zetterberg
2025-02-07 06:51:36 +01:00
parent e22fc1f3c8
commit 440e1f92df
393 changed files with 4839 additions and 1554 deletions

View File

@@ -17,11 +17,12 @@ export default function BedTypeInfo({ hasMultipleBedTypes }: BedTypeInfoProps) {
)
const availabilityText = intl.formatMessage({
id: "Your selected bed type will be provided based on availability",
defaultMessage:
"Your selected bed type will be provided based on availability",
})
const extraBedText = intl.formatMessage({
id: "Extra bed will be provided additionally",
defaultMessage: "Extra bed will be provided additionally",
})
const combinedStr = `${availabilityText}. ${extraBedText}`

View File

@@ -72,7 +72,8 @@ export default function Breakfast() {
{hasChildrenInRoom ? (
<Body>
{intl.formatMessage({
id: "Children's breakfast is always free as part of the adult's breakfast.",
defaultMessage:
"Children's breakfast is always free as part of the adult's breakfast.",
})}
</Body>
) : null}
@@ -83,22 +84,29 @@ export default function Breakfast() {
name="breakfast"
value={pkg.code}
Icon={BreakfastBuffetIcon}
title={intl.formatMessage({ id: "Breakfast buffet" })}
title={intl.formatMessage({
defaultMessage: "Breakfast buffet",
})}
subtitle={
pkg.code === BreakfastPackageEnum.FREE_MEMBER_BREAKFAST
? intl.formatMessage({ id: "Included" })
? intl.formatMessage({
defaultMessage: "Included",
})
: `+ ${formatPrice(intl, pkg.localPrice.price, pkg.localPrice.currency ?? "")}`
}
subtitleSecondary={intl.formatMessage({ id: "Per adult/night" })}
subtitleSecondary={intl.formatMessage({
defaultMessage: "Per adult/night",
})}
description={
hasChildrenInRoom
? intl.formatMessage({
id: "Free for kids aged 12 and under.",
defaultMessage: "Free for kids aged 12 and under.",
})
: undefined
}
descriptionSecondary={intl.formatMessage({
id: "Includes vegan, gluten-free, and other allergy-friendly options.",
defaultMessage:
"Includes vegan, gluten-free, and other allergy-friendly options.",
})}
/>
))}
@@ -106,15 +114,19 @@ export default function Breakfast() {
name="breakfast"
value="false"
Icon={NoBreakfastBuffetIcon}
title={intl.formatMessage({ id: "No breakfast" })}
title={intl.formatMessage({
defaultMessage: "No breakfast",
})}
subtitle={`+ ${formatPrice(intl, totalPriceForNoBreakfast, packages?.[0].localPrice.currency ?? "")}`}
descriptionSecondary={
hasChildrenInRoom
? intl.formatMessage({
id: "Breakfast can be added after booking for an extra cost for adults and kids ages 4 and up.",
defaultMessage:
"Breakfast can be added after booking for an extra cost for adults and kids ages 4 and up.",
})
: intl.formatMessage({
id: "Breakfast can be added after booking for an additional fee.",
defaultMessage:
"Breakfast can be added after booking for an additional fee.",
})
}
/>

View File

@@ -44,7 +44,7 @@ export default function ConfirmBooking({
<Typography variant="Body/Paragraph/mdBold">
<p>
{intl.formatMessage({
id: "Guarantee room for late arrival",
defaultMessage: "Guarantee room for late arrival",
})}
</p>
</Typography>
@@ -57,27 +57,33 @@ export default function ConfirmBooking({
onPress={() => setModalOpen(true)}
>
<MaterialIcon icon="info" size={20} color="CurrentColor" />
{intl.formatMessage({ id: "How does it work" })}
{intl.formatMessage({
defaultMessage: "How does it work",
})}
</Button>
<Modal isOpen={isModalOpen} onToggle={() => setModalOpen(false)}>
<div className={styles.modalContainer}>
<Typography variant="Title/smRegular">
<h3>
{intl.formatMessage({ id: "Guarantee for late arrival" })}
{intl.formatMessage({
defaultMessage: "Guarantee for late arrival",
})}
</h3>
</Typography>
<Typography variant="Body/Lead text">
<p className={styles.modalText}>
{intl.formatMessage({
id: "When guaranteeing your booking with a credit card, we will hold the booking until 07:00 the day after check-in.",
defaultMessage:
"When guaranteeing your booking with a credit card, we will hold the booking until 07:00 the day after check-in.",
})}
</p>
</Typography>
<Typography variant="Body/Supporting text (caption)/smRegular">
<p className={styles.modalText}>
{intl.formatMessage({
id: "In case of a no-show, your credit card will be charged for the first night.",
defaultMessage:
"In case of a no-show, your credit card will be charged for the first night.",
})}
</p>
</Typography>
@@ -88,7 +94,9 @@ export default function ConfirmBooking({
onPress={() => setModalOpen(false)}
className={styles.closeButton}
>
{intl.formatMessage({ id: "Close" })}
{intl.formatMessage({
defaultMessage: "Close",
})}
</Button>
</div>
</Modal>
@@ -97,7 +105,8 @@ export default function ConfirmBooking({
<Typography variant="Body/Supporting text (caption)/smRegular">
<p>
{intl.formatMessage({
id: "I may arrive later than 18:00 and want to guarantee my booking with a credit card.",
defaultMessage:
"I may arrive later than 18:00 and want to guarantee my booking with a credit card.",
})}
</p>
</Typography>
@@ -108,13 +117,19 @@ export default function ConfirmBooking({
<>
{savedCreditCards?.length ? (
<Typography variant="Title/Overline/sm">
<h4>{intl.formatMessage({ id: "OTHER" })}</h4>
<h4>
{intl.formatMessage({
defaultMessage: "OTHER",
})}
</h4>
</Typography>
) : null}
<PaymentOption
name="paymentMethod"
value={PaymentMethodEnum.card}
label={intl.formatMessage({ id: "Credit card" })}
label={intl.formatMessage({
defaultMessage: "Credit card",
})}
/>
</>
)}
@@ -134,7 +149,8 @@ export function ConfirmBookingRedemption() {
<Typography variant="Body/Supporting text (caption)/smRegular">
<p>
{intl.formatMessage({
id: "When you confirm the booking the room will be guaranteed for late arrival. If you fail to arrive without cancelling in advance or if you cancel after 18:00 local time, you will be charged for one reward night.",
defaultMessage:
"When you confirm the booking the room will be guaranteed for late arrival. If you fail to arrive without cancelling in advance or if you cancel after 18:00 local time, you will be charged for one reward night.",
})}
</p>
</Typography>

View File

@@ -25,14 +25,26 @@ export default function JoinScandicFriendsCard({
}
const list = [
{ title: intl.formatMessage({ id: "Earn bonus nights & points" }) },
{ title: intl.formatMessage({ id: "Get member benefits & offers" }) },
{ title: intl.formatMessage({ id: "Join at no cost" }) },
{
title: intl.formatMessage({
defaultMessage: "Earn bonus nights & points",
}),
},
{
title: intl.formatMessage({
defaultMessage: "Get member benefits & offers",
}),
},
{
title: intl.formatMessage({
defaultMessage: "Join at no cost",
}),
},
]
const saveOnJoiningLabel = intl.formatMessage(
{
id: "Pay the member price of {amount} for Room {roomNr}",
defaultMessage: "Pay the member price of {amount} for Room {roomNr}",
},
{
amount: formatPrice(
@@ -53,7 +65,8 @@ export default function JoinScandicFriendsCard({
</Caption>
<Caption color="uiTextHighContrast">
{intl.formatMessage({
id: "I promise to join Scandic Friends before checking in",
defaultMessage:
"I promise to join Scandic Friends before checking in",
})}
</Caption>
</div>

View File

@@ -75,42 +75,56 @@ export default function Details() {
type="label"
className={styles.fullWidth}
>
{intl.formatMessage({ id: "Guest information" })}
{intl.formatMessage({
defaultMessage: "Guest information",
})}
</Footnote>
<Input
label={intl.formatMessage({ id: "First name" })}
label={intl.formatMessage({
defaultMessage: "First name",
})}
maxLength={30}
name="firstName"
registerOptions={{ required: true }}
/>
<Input
label={intl.formatMessage({ id: "Last name" })}
label={intl.formatMessage({
defaultMessage: "Last name",
})}
maxLength={30}
name="lastName"
registerOptions={{ required: true }}
/>
<CountrySelect
className={styles.fullWidth}
label={intl.formatMessage({ id: "Country" })}
label={intl.formatMessage({
defaultMessage: "Country",
})}
name="countryCode"
registerOptions={{ required: true }}
/>
<Input
className={styles.fullWidth}
label={intl.formatMessage({ id: "Email address" })}
label={intl.formatMessage({
defaultMessage: "Email address",
})}
name="email"
registerOptions={{ required: true }}
/>
<Phone
className={styles.fullWidth}
label={intl.formatMessage({ id: "Phone number" })}
label={intl.formatMessage({
defaultMessage: "Phone number",
})}
name="phoneNumber"
registerOptions={{ required: true }}
/>
{guestIsGoingToJoin ? null : (
<Input
className={styles.fullWidth}
label={intl.formatMessage({ id: "Membership no" })}
label={intl.formatMessage({
defaultMessage: "Membership no",
})}
name="membershipNo"
type="tel"
/>
@@ -131,9 +145,13 @@ export default function Details() {
type="submit"
>
{isPaymentNext
? intl.formatMessage({ id: "Continue" })
? intl.formatMessage({
defaultMessage: "Continue",
})
: intl.formatMessage(
{ id: "Continue to room {nextRoomNumber}" },
{
defaultMessage: "Continue to room {nextRoomNumber}",
},
{ nextRoomNumber: roomNr + 1 }
)}
</Button>

View File

@@ -32,14 +32,26 @@ export default function JoinScandicFriendsCard({
}
const list = [
{ title: intl.formatMessage({ id: "Friendly room rates" }) },
{ title: intl.formatMessage({ id: "Earn & spend points" }) },
{ title: intl.formatMessage({ id: "Join for free" }) },
{
title: intl.formatMessage({
defaultMessage: "Friendly room rates",
}),
},
{
title: intl.formatMessage({
defaultMessage: "Earn & spend points",
}),
},
{
title: intl.formatMessage({
defaultMessage: "Join for free",
}),
},
]
const saveOnJoiningLabel = intl.formatMessage(
{
id: "Get the member price: {amount}",
defaultMessage: "Get the member price: {amount}",
},
{
amount: formatPrice(
@@ -62,20 +74,27 @@ export default function JoinScandicFriendsCard({
textTransform="uppercase"
color="uiTextHighContrast"
>
{intl.formatMessage({ id: "Join Scandic Friends" })}
{intl.formatMessage({
defaultMessage: "Join Scandic Friends",
})}
</Caption>
</div>
</Checkbox>
<Footnote color="uiTextHighContrast" className={styles.login}>
{intl.formatMessage({ id: "Already a friend?" })}{" "}
{/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}
{`${intl.formatMessage({
defaultMessage: "Already a friend?",
})} `}
<LoginButton
color="burgundy"
position="enter details"
trackingId="join-scandic-friends-enter-details"
variant="breadcrumb"
>
{intl.formatMessage({ id: "Log in" })}
{intl.formatMessage({
defaultMessage: "Log in",
})}
</LoginButton>
</Footnote>
@@ -99,7 +118,8 @@ export default function JoinScandicFriendsCard({
<Footnote color="uiTextPlaceholder">
{intl.formatMessage(
{
id: "By signing up you accept the Scandic Friends <termsAndConditionsLink>Terms and Conditions</termsAndConditionsLink>. Your membership is valid until further notice, and you can terminate your membership at any time by sending an email to Scandic's customer service",
defaultMessage:
"By signing up you accept the Scandic Friends <termsAndConditionsLink>Terms and Conditions</termsAndConditionsLink>. Your membership is valid until further notice, and you can terminate your membership at any time by sending an email to Scandic's customer service",
},
{
termsAndConditionsLink: (str) => (

View File

@@ -42,7 +42,7 @@ export default function MemberPriceModal({
<MagicWandIcon width="265px" />
<Title as="h3" level="h1" textTransform="regular">
{intl.formatMessage({
id: "Member price activated",
defaultMessage: "Member price activated",
})}
</Title>
@@ -50,7 +50,7 @@ export default function MemberPriceModal({
<span className={styles.newPrice}>
<Body>
{intl.formatMessage({
id: "The new price is",
defaultMessage: "The new price is",
})}
</Body>
<Subtitle type="two" color="red">
@@ -64,7 +64,9 @@ export default function MemberPriceModal({
)}
</div>
<Button intent="primary" theme="base" onClick={() => setIsOpen(false)}>
{intl.formatMessage({ id: "OK" })}
{intl.formatMessage({
defaultMessage: "OK",
})}
</Button>
</div>
</Modal>

View File

@@ -27,14 +27,18 @@ export default function Signup({ name }: { name: string }) {
<div className={styles.additionalFormData}>
<Input
name="zipCode"
label={intl.formatMessage({ id: "Zip code" })}
label={intl.formatMessage({
defaultMessage: "Zip code",
})}
registerOptions={{ required: true }}
/>
<div className={styles.dateField}>
<header>
<Caption type="bold">
<span className={styles.required}>
{intl.formatMessage({ id: "Birth date" })}
{intl.formatMessage({
defaultMessage: "Birth date",
})}
</span>
</Caption>
</header>
@@ -43,7 +47,9 @@ export default function Signup({ name }: { name: string }) {
</div>
) : (
<Input
label={intl.formatMessage({ id: "Membership no" })}
label={intl.formatMessage({
defaultMessage: "Membership no",
})}
name="membershipNo"
type="tel"
/>

View File

@@ -93,17 +93,23 @@ export default function Details({ user }: DetailsProps) {
type="label"
className={styles.fullWidth}
>
{intl.formatMessage({ id: "Guest information" })}
{intl.formatMessage({
defaultMessage: "Guest information",
})}
</Footnote>
<Input
label={intl.formatMessage({ id: "First name" })}
label={intl.formatMessage({
defaultMessage: "First name",
})}
maxLength={30}
name="firstName"
readOnly={!!user}
registerOptions={{ required: true }}
/>
<Input
label={intl.formatMessage({ id: "Last name" })}
label={intl.formatMessage({
defaultMessage: "Last name",
})}
maxLength={30}
name="lastName"
readOnly={!!user}
@@ -111,21 +117,27 @@ export default function Details({ user }: DetailsProps) {
/>
<CountrySelect
className={styles.fullWidth}
label={intl.formatMessage({ id: "Country" })}
label={intl.formatMessage({
defaultMessage: "Country",
})}
name="countryCode"
readOnly={!!user}
registerOptions={{ required: true }}
/>
<Input
className={styles.fullWidth}
label={intl.formatMessage({ id: "Email address" })}
label={intl.formatMessage({
defaultMessage: "Email address",
})}
name="email"
readOnly={!!user}
registerOptions={{ required: true }}
/>
<Phone
className={styles.fullWidth}
label={intl.formatMessage({ id: "Phone number" })}
label={intl.formatMessage({
defaultMessage: "Phone number",
})}
name="phoneNumber"
readOnly={!!user}
registerOptions={{ required: true }}
@@ -151,9 +163,13 @@ export default function Details({ user }: DetailsProps) {
type="submit"
>
{isPaymentNext
? intl.formatMessage({ id: "Continue" })
? intl.formatMessage({
defaultMessage: "Continue",
})
: intl.formatMessage(
{ id: "Continue to room {nextRoomNumber}" },
{
defaultMessage: "Continue to room {nextRoomNumber}",
},
{ nextRoomNumber: roomNr + 1 }
)}
</Button>

View File

@@ -27,7 +27,9 @@ export default function SpecialRequests() {
className={styles.header}
textAlign="left"
>
{intl.formatMessage({ id: "Special requests" })}
{intl.formatMessage({
defaultMessage: "Special requests",
})}
</Footnote>
<MaterialIcon icon="keyboard_arrow_down" className={styles.chevron} />
<Divider className={styles.divider} color="subtle" />
@@ -74,7 +76,8 @@ export default function SpecialRequests() {
/> */}
<TextArea
label={intl.formatMessage({
id: "Is there anything else you would like us to know before your arrival?",
defaultMessage:
"Is there anything else you would like us to know before your arrival?",
})}
name="specialRequest.comment"
/>

View File

@@ -29,7 +29,9 @@ export default function ToggleSidePeek({
wrapping
className={styles.toggle}
>
{intl.formatMessage({ id: "See hotel details" })}
{intl.formatMessage({
defaultMessage: "See hotel details",
})}
<MaterialIcon icon="chevron_right" size={14} color="Icon/Inverted" />
</Button>
)

View File

@@ -35,10 +35,13 @@ export default async function HotelHeader({
</Title>
<div className={styles.address}>
<Caption color="white">{addressStr}</Caption>
{/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}
<Caption color="white"></Caption>
<Caption color="white">
{intl.formatMessage(
{ id: "{number} km to city center" },
{
defaultMessage: "{number} km to city center",
},
{
number: getSingleDecimal(
hotel.location.distanceToCentre / 1000

View File

@@ -13,7 +13,9 @@ export default function GuaranteeDetails() {
<details>
<Caption color="burgundy" type="bold" asChild>
<summary className={styles.summary}>
{intl.formatMessage({ id: "How it works" })}
{intl.formatMessage({
defaultMessage: "How it works",
})}
<MaterialIcon
icon="keyboard_arrow_down"
color="Icon/Interactive/Default"
@@ -24,29 +26,35 @@ export default function GuaranteeDetails() {
<section className={styles.content}>
<Body>
{intl.formatMessage({
id: "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.",
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: "What you have to do to guarantee booking:",
defaultMessage: "What you have to do to guarantee booking:",
})}
</Body>
<ol>
<Body asChild>
<li>{intl.formatMessage({ id: "Complete the booking" })}</li>
<li>
{intl.formatMessage({
defaultMessage: "Complete the booking",
})}
</li>
</Body>
<Body asChild>
<li>
{intl.formatMessage({
id: "Provide a payment card in the next step",
defaultMessage: "Provide a payment card in the next step",
})}
</li>
</Body>
</ol>
<Body>
{intl.formatMessage({
id: "Please note that this is mandatory, and that your card will only be charged in the event of a no-show.",
defaultMessage:
"Please note that this is mandatory, and that your card will only be charged in the event of a no-show.",
})}
</Body>
</section>

View File

@@ -34,8 +34,12 @@ export default function MixedRatePaymentBreakdown({
currency,
}: MixedRatePaymentBreakdownProps) {
const intl = useIntl()
const payNowTitle = intl.formatMessage({ id: "Pay now" })
const payAtCheckInTitle = intl.formatMessage({ id: "Pay at check-in" })
const payNowTitle = intl.formatMessage({
defaultMessage: "Pay now",
})
const payAtCheckInTitle = intl.formatMessage({
defaultMessage: "Pay at check-in",
})
const initialState: PaymentBreakdownState = {
roomsWithPrepaidRate: [],
@@ -114,11 +118,15 @@ function PaymentCard({
textTransform="uppercase"
className={styles.cardTitle}
>
{/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}
{title}{" "}
<span>
/{" "}
{/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}
{"/ "}
{intl.formatMessage(
{ id: "Room {roomIndex}" },
{
defaultMessage: "Room {roomIndex}",
},
{
roomIndex: roomIndexes.map((idx) => idx + 1).join(" & "),
}

View File

@@ -2,7 +2,10 @@ import { useIntl } from "react-intl"
import { Typography } from "@scandic-hotels/design-system/Typography"
import { PAYMENT_METHOD_TITLES ,type PaymentMethodEnum } from "@/constants/booking"
import {
PAYMENT_METHOD_TITLES,
type PaymentMethodEnum,
} from "@/constants/booking"
import PaymentOption from "../PaymentOption"
@@ -20,7 +23,11 @@ export default function MySavedCards({ savedCreditCards }: MySavedCardsProps) {
return (
<section className={styles.section}>
<Typography variant="Title/Overline/sm">
<h4>{intl.formatMessage({ id: "MY SAVED CARDS" })}</h4>
<h4>
{intl.formatMessage({
defaultMessage: "MY SAVED CARDS",
})}
</h4>
</Typography>
<div className={styles.paymentOptionContainer}>
{savedCreditCards?.map((savedCreditCard) => (

View File

@@ -34,11 +34,12 @@ function useBookingErrorAlert() {
switch (errorCode) {
case BookingErrorCodeEnum.TransactionCancelled:
return intl.formatMessage({
id: "You have now cancelled your payment.",
defaultMessage: "You have now cancelled your payment.",
})
default:
return intl.formatMessage({
id: "We had an issue processing your booking. Please try again. No charges have been made.",
defaultMessage:
"We had an issue processing your booking. Please try again. No charges have been made.",
})
}
}

View File

@@ -20,12 +20,15 @@ export default function TimeoutSpinner() {
<div className={styles.container}>
<LoadingSpinner />
<Subtitle className={styles.heading}>
{intl.formatMessage({ id: "Taking longer than usual" })}
{intl.formatMessage({
defaultMessage: "Taking longer than usual",
})}
</Subtitle>
<Body textAlign="center" className={styles.messageContainer}>
{intl.formatMessage(
{
id: "We are still confirming your booking. This is usually a matter of minutes and we do apologise for the wait. Please check your inbox for a booking confirmation email and if you still haven't received it by end of day, please contact our <link>customer support</link>.",
defaultMessage:
"We are still confirming your booking. This is usually a matter of minutes and we do apologise for the wait. Please check your inbox for a booking confirmation email and if you still haven't received it by end of day, please contact our <link>customer support</link>.",
},
{
link: (text) => (

View File

@@ -433,13 +433,13 @@ export default function PaymentClient({
}
const paymentGuarantee = intl.formatMessage({
id: "Payment Guarantee",
defaultMessage: "Payment Guarantee",
})
const payment = intl.formatMessage({
id: "Payment",
defaultMessage: "Payment",
})
const confirm = intl.formatMessage({
id: "Confirm booking",
defaultMessage: "Confirm booking",
})
return (
@@ -472,7 +472,8 @@ export default function PaymentClient({
<section className={styles.section}>
<Body>
{intl.formatMessage({
id: "To secure your reservation, we kindly ask you to provide your payment card details. Rest assured, no charges will be made at this time.",
defaultMessage:
"To secure your reservation, we kindly ask you to provide your payment card details. Rest assured, no charges will be made at this time.",
})}
</Body>
<GuaranteeDetails />
@@ -482,7 +483,8 @@ export default function PaymentClient({
{hasMixedRates ? (
<Body>
{intl.formatMessage({
id: "As your booking includes rooms with different terms, we will be charging part of the booking now and the remainder will be collected by the reception at check-in.",
defaultMessage:
"As your booking includes rooms with different terms, we will be charging part of the booking now and the remainder will be collected by the reception at check-in.",
})}
</Body>
) : null}
@@ -496,14 +498,18 @@ export default function PaymentClient({
<section className={styles.section}>
{savedCreditCards?.length ? (
<Body color="uiTextHighContrast" textTransform="bold">
{intl.formatMessage({ id: "OTHER PAYMENT METHODS" })}
{intl.formatMessage({
defaultMessage: "OTHER PAYMENT METHODS",
})}
</Body>
) : null}
<div className={styles.paymentOptionContainer}>
<PaymentOption
name="paymentMethod"
value={PaymentMethodEnum.card}
label={intl.formatMessage({ id: "Credit card" })}
label={intl.formatMessage({
defaultMessage: "Credit card",
})}
/>
{!hasMixedRates &&
availablePaymentOptions.map((paymentMethod) => (
@@ -542,7 +548,9 @@ export default function PaymentClient({
!methods.formState.isValid || methods.formState.isSubmitting
}
>
{intl.formatMessage({ id: "Complete booking" })}
{intl.formatMessage({
defaultMessage: "Complete booking",
})}
</Button>
</div>
</form>

View File

@@ -39,7 +39,10 @@ export default function PaymentOption({
<Body>{label}</Body>
</div>
{cardNumber ? (
<Caption color="uiTextMediumContrast"> {cardNumber}</Caption>
<>
{/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}
<Caption color="uiTextMediumContrast"> {cardNumber}</Caption>
</>
) : (
<Image
className={styles.paymentOptionIcon}

View File

@@ -21,7 +21,8 @@ export default function TermsAndConditions() {
<Caption>
{intl.formatMessage(
{
id: "By paying with any of the payment methods available, I accept the terms for this booking and the general <termsAndConditionsLink>Terms & Conditions</termsAndConditionsLink>, and understand that Scandic will process my personal data for this booking in accordance with <privacyPolicyLink>Scandic's Privacy policy</privacyPolicyLink>. I also accept that Scandic require a valid credit card during my visit in case anything is left unpaid.",
defaultMessage:
"By paying with any of the payment methods available, I accept the terms for this booking and the general <termsAndConditionsLink>Terms & Conditions</termsAndConditionsLink>, and understand that Scandic will process my personal data for this booking in accordance with <privacyPolicyLink>Scandic's Privacy policy</privacyPolicyLink>. I also accept that Scandic require a valid credit card during my visit in case anything is left unpaid.",
},
{
termsAndConditionsLink: (str) => (
@@ -54,14 +55,15 @@ export default function TermsAndConditions() {
<Checkbox name="termsAndConditions">
<Caption>
{intl.formatMessage({
id: "I accept the terms and conditions",
defaultMessage: "I accept the terms and conditions",
})}
</Caption>
</Checkbox>
<Checkbox name="smsConfirmation">
<Caption>
{intl.formatMessage({
id: "I would like to get my booking confirmation via sms",
defaultMessage:
"I would like to get my booking confirmation via sms",
})}
</Caption>
</Checkbox>

View File

@@ -50,7 +50,9 @@ export default function PriceChangeSummary({
wrapping
onClick={() => toggleOpen((isOpen) => !isOpen)}
>
{intl.formatMessage({ id: "See price details" })}
{intl.formatMessage({
defaultMessage: "See price details",
})}
<MaterialIcon icon="chevron_right" size={20} color="CurrentColor" />
</Button>
<ModalOverlay isOpen={isOpen} onOpenChange={toggleOpen}>
@@ -60,7 +62,9 @@ export default function PriceChangeSummary({
<div className={styles.content}>
<header className={styles.header}>
<Subtitle>
{intl.formatMessage({ id: "Price details" })}
{intl.formatMessage({
defaultMessage: "Price details",
})}
</Subtitle>
<Button
onPress={close}
@@ -82,15 +86,21 @@ export default function PriceChangeSummary({
<Body textTransform="bold">
{rooms.length > 1
? intl.formatMessage(
{ id: "Room {roomIndex}" },
{
defaultMessage: "Room {roomIndex}",
},
{ roomIndex: roomNumber }
)
: intl.formatMessage({ id: "Room" })}
: intl.formatMessage({
defaultMessage: "Room",
})}
</Body>
<Body>{room.roomType}</Body>
<div className={styles.priceRow}>
<Caption color="uiTextMediumContrast">
{intl.formatMessage({ id: "Room charge" })}
{intl.formatMessage({
defaultMessage: "Room charge",
})}
</Caption>
{newPrice ? (
<div className={styles.updatedPrice}>
@@ -126,7 +136,7 @@ export default function PriceChangeSummary({
<div className={styles.priceRow}>
<Caption color="uiTextMediumContrast">
{intl.formatMessage({
id: "Breakfast charge",
defaultMessage: "Breakfast charge",
})}
</Caption>
<Caption color="uiTextMediumContrast">
@@ -164,10 +174,16 @@ export default function PriceChangeSummary({
})}
</div>
<div className={styles.rowContainer}>
<Body>{intl.formatMessage({ id: "Total" })}</Body>
<Body>
{intl.formatMessage({
defaultMessage: "Total",
})}
</Body>
<div className={styles.priceRow}>
<Body textTransform="bold">
{intl.formatMessage({ id: "Price including VAT" })}
{intl.formatMessage({
defaultMessage: "Price including VAT",
})}
</Body>
<Body textTransform="bold">
{formatPrice(
@@ -181,10 +197,14 @@ export default function PriceChangeSummary({
</section>
<footer className={styles.footer}>
<Button intent="secondary" onClick={onCancel}>
{intl.formatMessage({ id: "Back to select room" })}
{intl.formatMessage({
defaultMessage: "Back to select room",
})}
</Button>
<Button onClick={onAccept}>
{intl.formatMessage({ id: "Continue with new price" })}
{intl.formatMessage({
defaultMessage: "Continue with new price",
})}
</Button>
</footer>
</div>

View File

@@ -42,7 +42,9 @@ export default function PriceChangeDialog({
onAccept,
}: PriceChangeDialogProps) {
const intl = useIntl()
const title = intl.formatMessage({ id: "Price change" })
const title = intl.formatMessage({
defaultMessage: "Price change",
})
const rooms = useEnterDetailsStore((state) => state.rooms)
const { newTotalPrice, roomPrices } = rooms.reduce<PriceDetailsState>(
@@ -66,6 +68,25 @@ export default function PriceChangeDialog({
{ newTotalPrice: 0, roomPrices: [] }
)
const roomSelectionMsg = intl.formatMessage(
{
defaultMessage: "{totalRooms, plural, one {room} other {rooms}}",
},
{
totalRooms: rooms.length,
}
)
const newRoomSelectionMsg = intl.formatMessage(
{
defaultMessage:
"{totalRooms, plural, one {a new room} other {new rooms}}",
},
{
totalRooms: rooms.length,
}
)
return (
<ModalOverlay
className={styles.overlay}
@@ -93,14 +114,21 @@ export default function PriceChangeDialog({
<Body textAlign="center">
{intl.formatMessage(
{
id: "Prices have increased since you selected your {totalRooms, plural, one {room} other {rooms}}.{br} To continue your booking, accept the updated price,{br} or go back to select {totalRooms, plural, one {a new room} other {new rooms}}.",
defaultMessage:
"Prices have increased since you selected your {roomSelection}.{linebreak} To continue your booking, accept the updated price,{linebreak} or go back to select {newRoomSelection}.",
},
{ totalRooms: rooms.length, br: <br /> }
{
roomSelection: roomSelectionMsg,
newRoomSelection: newRoomSelectionMsg,
linebreak: <br />,
}
)}
</Body>
<div>
<Subtitle textAlign="center" color="burgundy">
{intl.formatMessage({ id: "New total" })}
{intl.formatMessage({
defaultMessage: "New total",
})}
</Subtitle>
<div className={styles.prices}>
<Caption striked>
@@ -121,10 +149,14 @@ export default function PriceChangeDialog({
</header>
<footer className={styles.footer}>
<Button intent="secondary" onClick={onCancel}>
{intl.formatMessage({ id: "Back to select room" })}
{intl.formatMessage({
defaultMessage: "Back to select room",
})}
</Button>
<Button onClick={onAccept}>
{intl.formatMessage({ id: "Continue with new price" })}
{intl.formatMessage({
defaultMessage: "Continue with new price",
})}
</Button>
</footer>
</Dialog>

View File

@@ -46,7 +46,9 @@ export default function Multiroom() {
<Header>
<Title level="h2" as="h4">
{intl.formatMessage(
{ id: "Room {roomIndex}" },
{
defaultMessage: "Room {roomIndex}",
},
{
roomIndex: roomNr,
}
@@ -58,8 +60,12 @@ export default function Multiroom() {
{room.bedTypes ? (
<Section
header={intl.formatMessage({ id: "Select bed" })}
label={intl.formatMessage({ id: "Request bedtype" })}
header={intl.formatMessage({
defaultMessage: "Select bed",
})}
label={intl.formatMessage({
defaultMessage: "Request bedtype",
})}
step={StepEnum.selectBed}
disabled={!arePreviousRoomsValid}
>
@@ -69,9 +75,11 @@ export default function Multiroom() {
{showBreakfastStep ? (
<Section
header={intl.formatMessage({ id: "Food options" })}
header={intl.formatMessage({
defaultMessage: "Food options",
})}
label={intl.formatMessage({
id: "Select breakfast options",
defaultMessage: "Select breakfast options",
})}
step={StepEnum.breakfast}
disabled={isBreakfastDisabled}
@@ -81,9 +89,13 @@ export default function Multiroom() {
) : null}
<Section
header={intl.formatMessage({ id: "Details" })}
header={intl.formatMessage({
defaultMessage: "Details",
})}
step={StepEnum.details}
label={intl.formatMessage({ id: "Enter your details" })}
label={intl.formatMessage({
defaultMessage: "Enter your details",
})}
disabled={isDetailsDisabled}
>
<Details />

View File

@@ -31,7 +31,9 @@ export default function RoomOne({ user }: { user: SafeUser }) {
<Header>
<Title level="h2" as="h4">
{intl.formatMessage(
{ id: "Room {roomIndex}" },
{
defaultMessage: "Room {roomIndex}",
},
{
roomIndex: 1,
}
@@ -44,8 +46,12 @@ export default function RoomOne({ user }: { user: SafeUser }) {
{room.bedTypes ? (
<Section
header={intl.formatMessage({ id: "Select bed" })}
label={intl.formatMessage({ id: "Request bedtype" })}
header={intl.formatMessage({
defaultMessage: "Select bed",
})}
label={intl.formatMessage({
defaultMessage: "Request bedtype",
})}
step={StepEnum.selectBed}
>
<BedType />
@@ -54,9 +60,11 @@ export default function RoomOne({ user }: { user: SafeUser }) {
{showBreakfastStep ? (
<Section
header={intl.formatMessage({ id: "Food options" })}
header={intl.formatMessage({
defaultMessage: "Food options",
})}
label={intl.formatMessage({
id: "Select breakfast options",
defaultMessage: "Select breakfast options",
})}
step={StepEnum.breakfast}
disabled={!steps[StepEnum.selectBed].isValid}
@@ -66,9 +74,13 @@ export default function RoomOne({ user }: { user: SafeUser }) {
) : null}
<Section
header={intl.formatMessage({ id: "Details" })}
header={intl.formatMessage({
defaultMessage: "Details",
})}
step={StepEnum.details}
label={intl.formatMessage({ id: "Enter your details" })}
label={intl.formatMessage({
defaultMessage: "Enter your details",
})}
disabled={
!(
steps[StepEnum.selectBed].isValid &&

View File

@@ -26,8 +26,12 @@ export default function Section({
const [title, setTitle] = useState(label)
const noBreakfastTitle = intl.formatMessage({ id: "No breakfast" })
const breakfastTitle = intl.formatMessage({ id: "Breakfast buffet" })
const noBreakfastTitle = intl.formatMessage({
defaultMessage: "No breakfast",
})
const breakfastTitle = intl.formatMessage({
defaultMessage: "Breakfast buffet",
})
useEffect(() => {
if (step === StepEnum.selectBed && bedType) {

View File

@@ -31,7 +31,11 @@ export default function ToggleSidePeek({
intent={intent}
wrapping
>
{title ? title : intl.formatMessage({ id: "See room details" })}
{title
? title
: intl.formatMessage({
defaultMessage: "See room details",
})}
<MaterialIcon icon="chevron_right" size={14} color="CurrentColor" />
</Button>
)

View File

@@ -51,7 +51,11 @@ export default function SelectedRoom() {
type="label"
color="uiTextHighContrast"
>
<h2>{intl.formatMessage({ id: "Your room" })}</h2>
<h2>
{intl.formatMessage({
defaultMessage: "Your room",
})}
</h2>
</Footnote>
<Subtitle
type="two"
@@ -59,7 +63,9 @@ export default function SelectedRoom() {
color="uiTextHighContrast"
>
{intl.formatMessage(
{ id: "{roomType} <rate>{rateDescription}</rate>" },
{
defaultMessage: "{roomType} <rate>{rateDescription}</rate>",
},
{
roomType: room.roomType,
rateDescription: room.cancellationText,
@@ -78,7 +84,9 @@ export default function SelectedRoom() {
>
<MaterialIcon icon="edit_square" color="CurrentColor" />
<Caption color="burgundy" type="bold">
{intl.formatMessage({ id: "Change room" })}
{intl.formatMessage({
defaultMessage: "Change room",
})}
</Caption>
</Button>
</div>

View File

@@ -55,7 +55,11 @@ export default function SummaryBottomSheet({ children }: PropsWithChildren) {
onClick={toggleSummaryOpen}
className={styles.priceDetailsButton}
>
<Caption>{intl.formatMessage({ id: "Total price" })}</Caption>
<Caption>
{intl.formatMessage({
defaultMessage: "Total price",
})}
</Caption>
<Subtitle>
{formatPrice(
intl,
@@ -66,7 +70,9 @@ export default function SummaryBottomSheet({ children }: PropsWithChildren) {
)}
</Subtitle>
<Caption color="baseTextHighContrast" type="underline">
{intl.formatMessage({ id: "See details" })}
{intl.formatMessage({
defaultMessage: "See details",
})}
</Caption>
</button>
<Button
@@ -77,7 +83,9 @@ export default function SummaryBottomSheet({ children }: PropsWithChildren) {
disabled={isSubmittingDisabled}
form={formId}
>
{intl.formatMessage({ id: "Complete booking" })}
{intl.formatMessage({
defaultMessage: "Complete booking",
})}
</Button>
</div>
</div>

View File

@@ -99,7 +99,9 @@ export default function PriceDetailsTable({
const diff = dt(toDate).diff(fromDate, "days")
const nights = intl.formatMessage(
{ id: "{totalNights, plural, one {# night} other {# nights}}" },
{
defaultMessage: "{totalNights, plural, one {# night} other {# nights}}",
},
{ totalNights: diff }
)
const vatPercentage = vat / 100
@@ -152,7 +154,14 @@ export default function PriceDetailsTable({
<tr>
<th colSpan={2}>
<Body textTransform="bold">
{intl.formatMessage({ id: "Room" })} {idx + 1}
{intl.formatMessage({
defaultMessage: "Room",
})}
{
/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */
" "
}
{idx + 1}
</Body>
</th>
</tr>
@@ -162,7 +171,7 @@ export default function PriceDetailsTable({
<>
<Row
label={intl.formatMessage({
id: "Average price per night",
defaultMessage: "Average price per night",
})}
value={formatPrice(
intl,
@@ -191,7 +200,9 @@ export default function PriceDetailsTable({
) : null}
<Row
bold
label={intl.formatMessage({ id: "Room charge" })}
label={intl.formatMessage({
defaultMessage: "Room charge",
})}
value={formatPrice(
intl,
price.localPrice.pricePerStay,
@@ -203,7 +214,9 @@ export default function PriceDetailsTable({
{voucherPrice && (
<Row
bold
label={intl.formatMessage({ id: "Room charge" })}
label={intl.formatMessage({
defaultMessage: "Room charge",
})}
value={formatPrice(
intl,
voucherPrice.numberOfVouchers,
@@ -214,7 +227,9 @@ export default function PriceDetailsTable({
{chequePrice && (
<Row
bold
label={intl.formatMessage({ id: "Room charge" })}
label={intl.formatMessage({
defaultMessage: "Room charge",
})}
value={formatPrice(
intl,
chequePrice.localPrice.numberOfCheques,
@@ -227,7 +242,9 @@ export default function PriceDetailsTable({
{redemptionPrice && (
<Row
bold
label={intl.formatMessage({ id: "Room charge" })}
label={intl.formatMessage({
defaultMessage: "Room charge",
})}
value={formatPrice(
intl,
redemptionPrice.localPrice.pointsPerStay,
@@ -244,7 +261,8 @@ export default function PriceDetailsTable({
<Row
label={intl.formatMessage(
{
id: "Breakfast ({totalAdults, plural, one {# adult} other {# adults}}) x {totalBreakfasts}",
defaultMessage:
"Breakfast ({totalAdults, plural, one {# adult} other {# adults}}) x {totalBreakfasts}",
},
{ totalAdults: room.adults, totalBreakfasts: diff }
)}
@@ -258,7 +276,8 @@ export default function PriceDetailsTable({
<Row
label={intl.formatMessage(
{
id: "Breakfast ({totalChildren, plural, one {# child} other {# children}}) x {totalBreakfasts}",
defaultMessage:
"Breakfast ({totalChildren, plural, one {# child} other {# children}}) x {totalBreakfasts}",
},
{
totalChildren: room.childrenInRoom.length,
@@ -275,7 +294,7 @@ export default function PriceDetailsTable({
<Row
bold
label={intl.formatMessage({
id: "Breakfast charge",
defaultMessage: "Breakfast charge",
})}
value={formatPrice(
intl,
@@ -289,15 +308,26 @@ export default function PriceDetailsTable({
)
})}
<TableSection>
<TableSectionHeader title={intl.formatMessage({ id: "Total" })} />
<TableSectionHeader
title={intl.formatMessage({
defaultMessage: "Total",
})}
/>
{!noVatCurrencies.includes(totalPrice.local.currency) ? (
<>
<Row
label={intl.formatMessage({ id: "Price excluding VAT" })}
label={intl.formatMessage({
defaultMessage: "Price excluding VAT",
})}
value={formatPrice(intl, priceExclVat, totalPrice.local.currency)}
/>
<Row
label={intl.formatMessage({ id: "VAT {vat}%" }, { vat })}
label={intl.formatMessage(
{
defaultMessage: "VAT {vat}%",
},
{ vat }
)}
value={formatPrice(intl, vatAmount, totalPrice.local.currency)}
/>
</>
@@ -305,7 +335,9 @@ export default function PriceDetailsTable({
<tr className={styles.row}>
<td>
<Body textTransform="bold">
{intl.formatMessage({ id: "Price including VAT" })}
{intl.formatMessage({
defaultMessage: "Price including VAT",
})}
</Body>
</td>
<td className={styles.price}>
@@ -343,7 +375,9 @@ export default function PriceDetailsTable({
icon={<DiscountIcon color="Icon/Feedback/Information" />}
>
{intl.formatMessage(
{ id: "<strong>Booking code</strong>: {value}" },
{
defaultMessage: "<strong>Booking code</strong>: {value}",
},
{
value: bookingCode,
strong: (text) => (

View File

@@ -51,7 +51,9 @@ export default function SummaryUI({
const diff = dt(booking.toDate).diff(booking.fromDate, "days")
const nights = intl.formatMessage(
{ id: "{totalNights, plural, one {# night} other {# nights}}" },
{
defaultMessage: "{totalNights, plural, one {# night} other {# nights}}",
},
{ totalNights: diff }
)
@@ -97,7 +99,9 @@ export default function SummaryUI({
<section className={styles.summary}>
<header className={styles.header}>
<Subtitle className={styles.title} type="two">
{intl.formatMessage({ id: "Booking summary" })}
{intl.formatMessage({
defaultMessage: "Booking summary",
})}
</Subtitle>
<Body className={styles.date} color="baseTextMediumContrast">
{dt(booking.fromDate).locale(lang).format("ddd, D MMM")}
@@ -106,6 +110,7 @@ export default function SummaryUI({
color="Icon/Interactive/Secondary"
size={15}
/>
{/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}
{dt(booking.toDate).locale(lang).format("ddd, D MMM")} ({nights})
</Body>
<Button
@@ -156,7 +161,10 @@ export default function SummaryUI({
const showMemberPrice = !!(isOrWillBecomeMember && memberPrice)
const adultsMsg = intl.formatMessage(
{ id: "{totalAdults, plural, one {# adult} other {# adults}}" },
{
defaultMessage:
"{totalAdults, plural, one {# adult} other {# adults}}",
},
{ totalAdults: adults }
)
@@ -164,7 +172,8 @@ export default function SummaryUI({
if (childrenInRoom?.length) {
const childrenMsg = intl.formatMessage(
{
id: "{totalChildren, plural, one {# child} other {# children}}",
defaultMessage:
"{totalChildren, plural, one {# child} other {# children}}",
},
{ totalChildren: childrenInRoom.length }
)
@@ -185,7 +194,9 @@ export default function SummaryUI({
{rooms.length > 1 ? (
<Body textTransform="bold">
{intl.formatMessage(
{ id: "Room {roomIndex}" },
{
defaultMessage: "Room {roomIndex}",
},
{
roomIndex: roomNumber,
}
@@ -223,7 +234,9 @@ export default function SummaryUI({
typography="Body/Supporting text (caption)/smBold"
wrapping={false}
>
{intl.formatMessage({ id: "Rate details" })}
{intl.formatMessage({
defaultMessage: "Rate details",
})}
<MaterialIcon
icon="chevron_right"
size={20}
@@ -296,12 +309,16 @@ export default function SummaryUI({
<div>
<Body color="uiTextHighContrast">
{intl.formatMessage(
{ id: "Crib (child) × {count}" },
{
defaultMessage: "Crib (child) × {count}",
},
{ count: childBedCrib }
)}
</Body>
<Caption color="uiTextMediumContrast">
{intl.formatMessage({ id: "Based on availability" })}
{intl.formatMessage({
defaultMessage: "Based on availability",
})}
</Caption>
</div>
<Body color="uiTextHighContrast">
@@ -318,7 +335,9 @@ export default function SummaryUI({
<div>
<Body color="uiTextHighContrast">
{intl.formatMessage(
{ id: "Extra bed (child) × {count}" },
{
defaultMessage: "Extra bed (child) × {count}",
},
{
count: childBedExtraBed,
}
@@ -337,13 +356,17 @@ export default function SummaryUI({
{room.breakfastIncluded ? (
<div className={styles.entry}>
<Body color="uiTextHighContrast">
{intl.formatMessage({ id: "Breakfast included" })}
{intl.formatMessage({
defaultMessage: "Breakfast included",
})}
</Body>
</div>
) : room.breakfast === false ? (
<div className={styles.entry}>
<Body color="uiTextHighContrast">
{intl.formatMessage({ id: "No breakfast" })}
{intl.formatMessage({
defaultMessage: "No breakfast",
})}
</Body>
<Body color="uiTextHighContrast">
{formatPrice(
@@ -357,13 +380,16 @@ export default function SummaryUI({
{room.breakfast ? (
<div>
<Body color="uiTextHighContrast">
{intl.formatMessage({ id: "Breakfast buffet" })}
{intl.formatMessage({
defaultMessage: "Breakfast buffet",
})}
</Body>
<div className={styles.entry}>
<Caption color="uiTextMediumContrast">
{intl.formatMessage(
{
id: "{totalAdults, plural, one {# adult} other {# adults}}",
defaultMessage:
"{totalAdults, plural, one {# adult} other {# adults}}",
},
{ totalAdults: adults }
)}
@@ -381,7 +407,8 @@ export default function SummaryUI({
<Caption color="uiTextMediumContrast">
{intl.formatMessage(
{
id: "{totalChildren, plural, one {# child} other {# children}}",
defaultMessage:
"{totalChildren, plural, one {# child} other {# children}}",
},
{ totalChildren: childrenInRoom.length }
)}
@@ -407,7 +434,9 @@ export default function SummaryUI({
<div>
<Body>
{intl.formatMessage(
{ id: "<b>Total price</b> (incl VAT)" },
{
defaultMessage: "<b>Total price</b> (incl VAT)",
},
{ b: (str) => <b>{str}</b> }
)}
</Body>
@@ -445,7 +474,9 @@ export default function SummaryUI({
{totalPrice.requested && !isSpecialRate && !isSameCurrency && (
<Caption color="uiTextMediumContrast">
{intl.formatMessage(
{ id: "Approx. {value}" },
{
defaultMessage: "Approx. {value}",
},
{
value: formatPrice(
intl,
@@ -465,7 +496,9 @@ export default function SummaryUI({
icon={<DiscountIcon color="Icon/Feedback/Information" />}
>
{intl.formatMessage(
{ id: "<strong>Booking code</strong>: {value}" },
{
defaultMessage: "<strong>Booking code</strong>: {value}",
},
{
value: booking.bookingCode,
strong: (text) => (