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

@@ -26,7 +26,11 @@ export default function AddToCalendar({
createEvent(event, (error, value) => {
if (error) {
console.error("ICS Error:", error)
toast.error(intl.formatMessage({ id: "Failed to add to calendar" }))
toast.error(
intl.formatMessage({
defaultMessage: "Failed to add to calendar",
})
)
return
}
@@ -42,7 +46,11 @@ export default function AddToCalendar({
})
} catch (error) {
console.error("Download error:", error)
toast.error(intl.formatMessage({ id: "Failed to add to calendar" }))
toast.error(
intl.formatMessage({
defaultMessage: "Failed to add to calendar",
})
)
}
}

View File

@@ -26,10 +26,11 @@ export default function Alerts({ booking }: BookingConfirmationAlertsProps) {
<Alert
type={AlertTypeEnum.Info}
heading={intl.formatMessage({
id: "Failed to verify membership",
defaultMessage: "Failed to verify membership",
})}
text={intl.formatMessage({
id: "The first or last name doesn't match the membership number you provided. Your booking(s) is confirmed but to get the membership attached you'll need to present your existing membership number upon check-in. If you have booked with a member discount, you'll either need to present your existing membership number upon check-in, become a member or pay the price difference at the hotel. Signing up is preferably done online before the stay, or we can assist upon arrival.",
defaultMessage:
"The first or last name doesn't match the membership number you provided. Your booking(s) is confirmed but to get the membership attached you'll need to present your existing membership number upon check-in. If you have booked with a member discount, you'll either need to present your existing membership number upon check-in, become a member or pay the price difference at the hotel. Signing up is preferably done online before the stay, or we can assist upon arrival.",
})}
/>
)}
@@ -38,10 +39,11 @@ export default function Alerts({ booking }: BookingConfirmationAlertsProps) {
<Alert
type={AlertTypeEnum.Info}
heading={intl.formatMessage({
id: "Failed to verify membership",
defaultMessage: "Failed to verify membership",
})}
text={intl.formatMessage({
id: "Your booking(s) is confirmed but we could not verify your membership. If you have booked with a member discount, you'll either need to present your existing membership number upon check-in, become a member or pay the price difference at the hotel. Signing up is preferably done online before the stay.",
defaultMessage:
"Your booking(s) is confirmed but we could not verify your membership. If you have booked with a member discount, you'll either need to present your existing membership number upon check-in, become a member or pay the price difference at the hotel. Signing up is preferably done online before the stay.",
})}
/>
)}

View File

@@ -15,7 +15,9 @@ export default function AddToCalendarButton({
return (
<Button intent="text" size="small" theme="base" wrapping onPress={onPress}>
<MaterialIcon icon="calendar_add_on" color="CurrentColor" />
{intl.formatMessage({ id: "Add to calendar" })}
{intl.formatMessage({
defaultMessage: "Add to calendar",
})}
</Button>
)
}

View File

@@ -26,7 +26,9 @@ export default function DownloadInvoice({ mainRef }: DownloadInvoiceProps) {
wrapping
>
<MaterialIcon icon="download" color="CurrentColor" />
{intl.formatMessage({ id: "Download invoice" })}
{intl.formatMessage({
defaultMessage: "Download invoice",
})}
</Button>
)
}

View File

@@ -22,7 +22,9 @@ export default function ManageBooking({ bookingUrl }: ManageBookingProps) {
>
<Link color="none" href={bookingUrl} weight="bold">
<MaterialIcon icon="edit_square" color="CurrentColor" />
{intl.formatMessage({ id: "Manage booking" })}
{intl.formatMessage({
defaultMessage: "Manage booking",
})}
</Link>
</Button>
)

View File

@@ -32,7 +32,8 @@ export default function Header({
const text = intl.formatMessage(
{
id: "Thank you for booking with us! We look forward to welcoming you and hope you have a pleasant stay. If you have any questions or need to make changes to your reservation, please <emailLink>contact us.</emailLink>",
defaultMessage:
"Thank you for booking with us! We look forward to welcoming you and hope you have a pleasant stay. If you have any questions or need to make changes to your reservation, please <emailLink>contact us.</emailLink>",
},
{
emailLink: (str) => (
@@ -68,7 +69,9 @@ export default function Header({
<header className={styles.header}>
<hgroup className={styles.hgroup}>
<Title as="h2" color="red" textTransform="uppercase" type="h2">
{intl.formatMessage({ id: "Booking confirmation" })}
{intl.formatMessage({
defaultMessage: "Booking confirmation",
})}
</Title>
<Title as="h2" color="burgundy" textTransform="uppercase" type="h1">
{hotel.name}
@@ -76,7 +79,9 @@ export default function Header({
</hgroup>
<Subtitle color="uiTextHighContrast" type="two">
{intl.formatMessage(
{ id: "Booking number {value}" },
{
defaultMessage: "Booking number {value}",
},
{
value: booking.confirmationNumber,
}

View File

@@ -18,13 +18,17 @@ export default function HotelDetails({
<div className={styles.container}>
<div className={styles.details}>
<Subtitle color="uiTextHighContrast" type="two">
{intl.formatMessage({ id: "Hotel details" })}
{intl.formatMessage({
defaultMessage: "Hotel details",
})}
</Subtitle>
<div className={styles.hotel}>
<Body color="uiTextHighContrast">{hotel.name}</Body>
<Body color="uiTextHighContrast">
{intl.formatMessage(
{ id: "{streetAddress}, {zipCode} {city}" },
{
defaultMessage: "{streetAddress}, {zipCode} {city}",
},
{
streetAddress: hotel.address.streetAddress,
zipCode: hotel.address.zipCode,

View File

@@ -24,13 +24,17 @@ export default function PaymentDetails() {
return (
<div className={styles.details}>
<Subtitle color="uiTextHighContrast" type="two">
{intl.formatMessage({ id: "Payment details" })}
{intl.formatMessage({
defaultMessage: "Payment details",
})}
</Subtitle>
<div className={styles.payment}>
{hasAllRoomsLoaded ? (
<Body color="uiTextHighContrast">
{intl.formatMessage(
{ id: "Total cost: {amount}" },
{
defaultMessage: "Total cost: {amount}",
},
{
amount: formattedTotalCost,
}

View File

@@ -117,7 +117,9 @@ export default function PriceDetailsModal() {
const diff = dt(checkOutDate).diff(checkInDate, "days")
const nights = intl.formatMessage(
{ id: "{totalNights, plural, one {# night} other {# nights}}" },
{
defaultMessage: "{totalNights, plural, one {# night} other {# nights}}",
},
{ totalNights: diff }
)
@@ -126,11 +128,15 @@ export default function PriceDetailsModal() {
${dt(toDate).locale(lang).format("ddd, D MMM")} (${nights})`
return (
<Modal
title={intl.formatMessage({ id: "Price details" })}
title={intl.formatMessage({
defaultMessage: "Price details",
})}
trigger={
<Button intent="text">
<Caption color="burgundy">
{intl.formatMessage({ id: "Price details" })}
{intl.formatMessage({
defaultMessage: "Price details",
})}
</Caption>
<MaterialIcon icon="chevron_right" color="CurrentColor" size={20} />
</Button>
@@ -144,7 +150,9 @@ export default function PriceDetailsModal() {
{rooms.length > 1 && (
<TableSectionHeader
title={intl.formatMessage(
{ id: "Room {roomIndex}" },
{
defaultMessage: "Room {roomIndex}",
},
{ roomIndex: idx + 1 }
)}
bold
@@ -172,7 +180,9 @@ export default function PriceDetailsModal() {
) : null}
<Row
bold
label={intl.formatMessage({ id: "Room charge" })}
label={intl.formatMessage({
defaultMessage: "Room charge",
})}
value={room.formattedRoomCost}
/>
</TableSection>
@@ -182,7 +192,8 @@ export default function PriceDetailsModal() {
<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 }
)}
@@ -196,7 +207,8 @@ export default function PriceDetailsModal() {
<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.childrenAges.length,
@@ -209,7 +221,7 @@ export default function PriceDetailsModal() {
<Row
bold
label={intl.formatMessage({
id: "Breakfast charge",
defaultMessage: "Breakfast charge",
})}
value={formatPrice(
intl,
@@ -223,15 +235,26 @@ export default function PriceDetailsModal() {
) : null
})}
<TableSection>
<TableSectionHeader title={intl.formatMessage({ id: "Total" })} />
<TableSectionHeader
title={intl.formatMessage({
defaultMessage: "Total",
})}
/>
{isVatCurrency ? (
<>
<Row
label={intl.formatMessage({ id: "Price excluding VAT" })}
label={intl.formatMessage({
defaultMessage: "Price excluding VAT",
})}
value={formatPrice(intl, bookingTotal.priceExVat, currencyCode)}
/>
<Row
label={intl.formatMessage({ id: "VAT {vat}%" }, { vat })}
label={intl.formatMessage(
{
defaultMessage: "VAT {vat}%",
},
{ vat }
)}
value={formatPrice(intl, bookingTotal.vatAmount, currencyCode)}
/>
</>
@@ -239,7 +262,11 @@ export default function PriceDetailsModal() {
<tr className={styles.row}>
<td>
<Typography variant="Body/Paragraph/mdBold">
<span>{intl.formatMessage({ id: "Price including VAT" })}</span>
<span>
{intl.formatMessage({
defaultMessage: "Price including VAT",
})}
</span>
</Typography>
</td>
<td className={styles.price}>
@@ -257,7 +284,10 @@ export default function PriceDetailsModal() {
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

@@ -25,20 +25,30 @@ export default function Promos({
return (
<div className={styles.promos}>
<Promo
buttonText={intl.formatMessage({ id: "View and buy add-ons" })}
buttonText={intl.formatMessage({
defaultMessage: "View and buy add-ons",
})}
href={`${myBookingUrl}?bookingId=${confirmationNumber}&lastName=${lastName}`}
text={intl.formatMessage({
id: "Discover the little extra touches to make your upcoming stay even more unforgettable.",
defaultMessage:
"Discover the little extra touches to make your upcoming stay even more unforgettable.",
})}
title={intl.formatMessage({
defaultMessage: "Spice things up",
})}
title={intl.formatMessage({ id: "Spice things up" })}
/>
<Promo
buttonText={intl.formatMessage({ id: "Book another stay" })}
buttonText={intl.formatMessage({
defaultMessage: "Book another stay",
})}
href={`${homeUrl}?hotel=${hotelId}`}
text={intl.formatMessage({
id: "Get inspired and start dreaming beyond your next trip. Explore more Scandic destinations.",
defaultMessage:
"Get inspired and start dreaming beyond your next trip. Explore more Scandic destinations.",
})}
title={intl.formatMessage({
defaultMessage: "Book your next stay",
})}
title={intl.formatMessage({ id: "Book your next stay" })}
/>
</div>
)

View File

@@ -66,7 +66,10 @@ export default function ReceiptRoom({
<Typography variant="Body/Paragraph/mdRegular">
<p className={styles.uiTextMediumContrast}>
{intl.formatMessage(
{ id: "{totalAdults, plural, one {# adult} other {# adults}}" },
{
defaultMessage:
"{totalAdults, plural, one {# adult} other {# adults}}",
},
{
totalAdults: room.adults,
}
@@ -88,7 +91,9 @@ export default function ReceiptRoom({
textDecoration="underline"
variant="icon"
>
{intl.formatMessage({ id: "Reservation policy" })}
{intl.formatMessage({
defaultMessage: "Reservation policy",
})}
<MaterialIcon icon="info" color="CurrentColor" />
</Link>
</Button>
@@ -101,8 +106,12 @@ export default function ReceiptRoom({
subtitle={
room.rateDefinition.cancellationRule ===
CancellationRuleEnum.CancellableBefore6PM
? intl.formatMessage({ id: "Pay later" })
: intl.formatMessage({ id: "Pay now" })
? intl.formatMessage({
defaultMessage: "Pay later",
})
: intl.formatMessage({
defaultMessage: "Pay now",
})
}
>
<div className={styles.terms}>
@@ -161,14 +170,18 @@ export default function ReceiptRoom({
<Typography variant="Body/Paragraph/mdRegular">
<p className={styles.uiTextHighContrast}>
{intl.formatMessage(
{ id: "Crib (child) × {count}" },
{
defaultMessage: "Crib (child) × {count}",
},
{ count: childBedCrib.quantity }
)}
</p>
</Typography>
<Typography variant="Body/Supporting text (caption)/smRegular">
<p className={styles.uiTextHighContrast}>
{intl.formatMessage({ id: "Based on availability" })}
{intl.formatMessage({
defaultMessage: "Based on availability",
})}
</p>
</Typography>
</div>
@@ -185,7 +198,9 @@ export default function ReceiptRoom({
<Typography variant="Body/Paragraph/mdRegular">
<p className={styles.uiTextHighContrast}>
{intl.formatMessage(
{ id: "Extra bed (child) × {count}" },
{
defaultMessage: "Extra bed (child) × {count}",
},
{
count: childBedExtraBed.quantity,
}
@@ -203,12 +218,18 @@ export default function ReceiptRoom({
{room.breakfast || breakfastIncluded ? (
<div className={styles.entry}>
<Typography variant="Body/Paragraph/mdRegular">
<p>{intl.formatMessage({ id: "Breakfast buffet" })}</p>
<p>
{intl.formatMessage({
defaultMessage: "Breakfast buffet",
})}
</p>
</Typography>
{breakfastIncluded ? (
<Typography variant="Body/Paragraph/mdRegular">
<p className={styles.red}>
{intl.formatMessage({ id: "Included" })}
{intl.formatMessage({
defaultMessage: "Included",
})}
</p>
</Typography>
) : null}

View File

@@ -30,7 +30,11 @@ export default function TotalPrice() {
<div className={styles.price}>
<div className={styles.entry}>
<Typography variant="Body/Paragraph/mdBold">
<p>{intl.formatMessage({ id: "Total price" })}</p>
<p>
{intl.formatMessage({
defaultMessage: "Total price",
})}
</p>
</Typography>
{hasAllRoomsLoaded ? (
<Typography variant="Body/Paragraph/mdBold">

View File

@@ -19,7 +19,9 @@ export default function Receipt() {
return (
<section className={styles.receipt}>
<Subtitle type="two">
{intl.formatMessage({ id: "Booking summary" })}
{intl.formatMessage({
defaultMessage: "Booking summary",
})}
</Subtitle>
{rooms.map((room, idx) => (
@@ -27,7 +29,9 @@ export default function Receipt() {
{rooms.length > 1 ? (
<Body color="uiTextHighContrast" textTransform={"bold"}>
{intl.formatMessage(
{ id: "Room {roomIndex}" },
{
defaultMessage: "Room {roomIndex}",
},
{ roomIndex: idx + 1 }
)}
</Body>

View File

@@ -13,10 +13,16 @@ export default function Retry({ handleRefetch }: RetryProps) {
const intl = useIntl()
return (
<div className={styles.retry}>
<Body>{intl.formatMessage({ id: "Something went wrong!" })}</Body>
<Body>
{intl.formatMessage({
defaultMessage: "Something went wrong!",
})}
</Body>
<Button size={"small"} onPress={handleRefetch}>
{intl.formatMessage({ id: "Try again" })}
{intl.formatMessage({
defaultMessage: "Try again",
})}
</Button>
</div>
)

View File

@@ -50,7 +50,9 @@ export default function Room({
size={20}
/>
<Caption>
{intl.formatMessage({ id: "Membership benefits applied" })}
{intl.formatMessage({
defaultMessage: "Membership benefits applied",
})}
</Caption>
</>
) : null}
@@ -65,10 +67,15 @@ export default function Room({
<Typography variant="Body/Supporting text (caption)/smRegular">
<p>
<strong>
{intl.formatMessage({ id: "Booking guaranteed." })}
</strong>{" "}
{intl.formatMessage({
defaultMessage: "Booking guaranteed.",
})}
</strong>
{/* eslint-disable formatjs/no-literal-string-in-jsx */}{" "}
{/* eslint-enable formatjs/no-literal-string-in-jsx */}
{intl.formatMessage({
id: "Your room will remain available for check-in even after 18:00.",
defaultMessage:
"Your room will remain available for check-in even after 18:00.",
})}
</p>
</Typography>
@@ -92,7 +99,9 @@ export default function Room({
{roomName}
</Subtitle>
<Link color="burgundy" href="" variant="icon">
{intl.formatMessage({ id: "View room details" })}
{intl.formatMessage({
defaultMessage: "View room details",
})}
<MaterialIcon
icon="chevron_right"
size={20}
@@ -103,11 +112,15 @@ export default function Room({
<ul className={styles.details}>
<li className={styles.listItem}>
<Body color="uiTextPlaceholder">
{intl.formatMessage({ id: "Check-in" })}
{intl.formatMessage({
defaultMessage: "Check-in",
})}
</Body>
<Body color="uiTextHighContrast">
{intl.formatMessage(
{ id: "{checkInDate} from {checkInTime}" },
{
defaultMessage: "{checkInDate} from {checkInTime}",
},
{
checkInDate: fromDate.format("ddd, D MMM"),
checkInTime: checkInTime,
@@ -117,11 +130,15 @@ export default function Room({
</li>
<li className={styles.listItem}>
<Body color="uiTextPlaceholder">
{intl.formatMessage({ id: "Check-out" })}
{intl.formatMessage({
defaultMessage: "Check-out",
})}
</Body>
<Body color="uiTextHighContrast">
{intl.formatMessage(
{ id: "{checkOutDate} from {checkOutTime}" },
{
defaultMessage: "{checkOutDate} from {checkOutTime}",
},
{
checkOutDate: toDate.format("ddd, D MMM"),
checkOutTime: checkOutTime,
@@ -131,7 +148,9 @@ export default function Room({
</li>
<li className={styles.listItem}>
<Body color="uiTextPlaceholder">
{intl.formatMessage({ id: "Cancellation policy" })}
{intl.formatMessage({
defaultMessage: "Cancellation policy",
})}
</Body>
<Body color="uiTextHighContrast">
{booking.rateDefinition.cancellationText}
@@ -140,11 +159,15 @@ export default function Room({
{isFlexBooking || isChangeBooking ? (
<li className={styles.listItem}>
<Body color="uiTextPlaceholder">
{intl.formatMessage({ id: "Rebooking" })}
{intl.formatMessage({
defaultMessage: "Rebooking",
})}
</Body>
<Body color="uiTextHighContrast">
{intl.formatMessage(
{ id: "Until {time}, {date}" },
{
defaultMessage: "Until {time}, {date}",
},
{ time: "18:00", date: fromDate.format("dddd D MMM") }
)}
</Body>
@@ -153,13 +176,17 @@ export default function Room({
</ul>
<div className={styles.guest}>
<Body color="uiTextPlaceholder">
{intl.formatMessage({ id: "Main guest" })}
{intl.formatMessage({
defaultMessage: "Main guest",
})}
</Body>
<Body color="uiTextHighContrast">{guestName}</Body>
{booking.guest.membershipNumber ? (
<Body color="uiTextHighContrast">
{intl.formatMessage(
{ id: "Friend no. {value}" },
{
defaultMessage: "Friend no. {value}",
},
{
value: booking.guest.membershipNumber,
}

View File

@@ -22,7 +22,12 @@ export default async function Rooms({
<div className={styles.room}>
{linkedReservations.length ? (
<Subtitle color="mainGrey60" type="two">
{intl.formatMessage({ id: "Room {roomIndex}" }, { roomIndex: 1 })}
{intl.formatMessage(
{
defaultMessage: "Room {roomIndex}",
},
{ roomIndex: 1 }
)}
</Subtitle>
) : null}
<Room
@@ -38,7 +43,9 @@ export default async function Rooms({
<div className={styles.room} key={reservation.confirmationNumber}>
<Subtitle color="mainGrey60" type="two">
{intl.formatMessage(
{ id: "Room {roomIndex}" },
{
defaultMessage: "Room {roomIndex}",
},
{ roomIndex: idx + 2 }
)}
</Subtitle>

View File

@@ -27,7 +27,9 @@ export default function Contact({ hotel }: ContactProps) {
<ul className={styles.contactInfo}>
<li>
<Body textTransform="bold">
{intl.formatMessage({ id: "Address" })}
{intl.formatMessage({
defaultMessage: "Address",
})}
</Body>
<Body>
{addressStr}
@@ -37,19 +39,25 @@ export default function Contact({ hotel }: ContactProps) {
</li>
<li>
<Body textTransform="bold">
{intl.formatMessage({ id: "Driving directions" })}
{intl.formatMessage({
defaultMessage: "Driving directions",
})}
</Body>
<Link
href={`https://www.google.com/maps/dir/?api=1&destination=${hotel.location.latitude},${hotel.location.longitude}`}
>
<span className={styles.link}>
{intl.formatMessage({ id: "Google Maps" })}
{intl.formatMessage({
defaultMessage: "Google Maps",
})}
</span>
</Link>
</li>
<li>
<Body textTransform="bold">
{intl.formatMessage({ id: "Contact us" })}
{intl.formatMessage({
defaultMessage: "Contact us",
})}
</Body>
<Link href={`tel:${hotel.contactInformation.phoneNumber}`}>
<span className={styles.link}>
@@ -61,7 +69,9 @@ export default function Contact({ hotel }: ContactProps) {
{(hotel.socialMedia.facebook || hotel.socialMedia.instagram) && (
<>
<Body textTransform="bold">
{intl.formatMessage({ id: "Follow us" })}
{intl.formatMessage({
defaultMessage: "Follow us",
})}
</Body>
<div className={styles.soMeIcons}>
{hotel.socialMedia.instagram && (
@@ -80,7 +90,9 @@ export default function Contact({ hotel }: ContactProps) {
</li>
<li>
<Body textTransform="bold">
{intl.formatMessage({ id: "Email" })}
{intl.formatMessage({
defaultMessage: "Email",
})}
</Body>
<Link href={`mailto:${hotel.contactInformation.email}`}>
<span className={styles.link}>
@@ -96,12 +108,18 @@ export default function Contact({ hotel }: ContactProps) {
<Image
height={38}
width={38}
alt={intl.formatMessage({ id: "Nordic Swan Ecolabel" })}
alt={intl.formatMessage({
defaultMessage: "Nordic Swan Ecolabel",
})}
src={`/_static/img/icons/swan-eco/swan_eco_dark_${lang}.png`}
/>
</div>
<div className={styles.ecoLabelText}>
<span>{intl.formatMessage({ id: "Nordic Swan Ecolabel" })}</span>
<span>
{intl.formatMessage({
defaultMessage: "Nordic Swan Ecolabel",
})}
</span>
<span>
{hotel.hotelFacts.ecoLabels.svanenEcoLabelCertificateNumber}
</span>

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) => (

View File

@@ -50,24 +50,29 @@ export default function AdditionalInfoForm({
<div>
<Title level="h2" as="h3">
{intl.formatMessage({
id: "One last step",
defaultMessage: "One last step",
})}
</Title>
<Body>
{intl.formatMessage({
id: "We need some more details to confirm your identity.",
defaultMessage:
"We need some more details to confirm your identity.",
})}
</Body>
</div>
<div className={styles.inputs}>
<Input
label={intl.formatMessage({ id: "First name" })}
label={intl.formatMessage({
defaultMessage: "First name",
})}
name="firstName"
placeholder="Anna"
registerOptions={{ required: true }}
/>
<Input
label={intl.formatMessage({ id: "Email" })}
label={intl.formatMessage({
defaultMessage: "Email",
})}
name="email"
placeholder="anna@scandichotels.com"
registerOptions={{ required: true }}
@@ -80,7 +85,9 @@ export default function AdditionalInfoForm({
theme="base"
disabled={form.formState.isSubmitting}
>
{intl.formatMessage({ id: "Confirm" })}
{intl.formatMessage({
defaultMessage: "Confirm",
})}
</Button>
</div>
</form>

View File

@@ -50,7 +50,7 @@ export default function FindMyBooking() {
console.error("Failed to create ref id", error)
toast.error(
intl.formatMessage({
id: "Failed to submit form, please try again later.",
defaultMessage: "Failed to submit form, please try again later.",
})
)
},
@@ -68,35 +68,46 @@ export default function FindMyBooking() {
<form onSubmit={form.handleSubmit(onSubmit)} className={styles.form}>
<div>
<Title level="h2" as="h3">
{intl.formatMessage({ id: "Find your stay" })}
{intl.formatMessage({
defaultMessage: "Find your stay",
})}
</Title>
<Body>
{intl.formatMessage({
id: "View and manage your stay made on Scandic's website",
defaultMessage:
"View and manage your stay made on Scandic's website",
})}
</Body>
</div>
<div className={[styles.inputs, styles.grid].join(" ")}>
<Input
label={intl.formatMessage({ id: "Booking number" })}
label={intl.formatMessage({
defaultMessage: "Booking number",
})}
name="confirmationNumber"
placeholder="XXXXXX"
registerOptions={{ required: true }}
/>
<Input
label={intl.formatMessage({ id: "First name" })}
label={intl.formatMessage({
defaultMessage: "First name",
})}
name="firstName"
placeholder="Anna"
registerOptions={{ required: true }}
/>
<Input
label={intl.formatMessage({ id: "Last name" })}
label={intl.formatMessage({
defaultMessage: "Last name",
})}
name="lastName"
placeholder="Andersson"
registerOptions={{ required: true }}
/>
<Input
label={intl.formatMessage({ id: "Email" })}
label={intl.formatMessage({
defaultMessage: "Email",
})}
name="email"
placeholder="anna@scandichotels.com"
registerOptions={{ required: true }}
@@ -105,11 +116,16 @@ export default function FindMyBooking() {
<div className={styles.buttons}>
<div className={styles.footnote}>
<Caption type="bold">
{intl.formatMessage({ id: "Can't find your stay?" })}
{intl.formatMessage({
defaultMessage: "Can't find your stay?",
})}
</Caption>
<Caption>
{intl.formatMessage(
{ id: "Please contact <link>customer service</link>." },
{
defaultMessage:
"Please contact <link>customer service</link>.",
},
{
link: (str) => (
<Link
@@ -132,7 +148,9 @@ export default function FindMyBooking() {
theme="base"
disabled={form.formState.isSubmitting || update.isPending}
>
{intl.formatMessage({ id: "Find" })}
{intl.formatMessage({
defaultMessage: "Find",
})}
</Button>
</div>
</form>

View File

@@ -17,14 +17,16 @@ export default function HotelChequeCard({
return (
<div className={styles.chequeCard}>
<div className={styles.chequeRow}>
<Caption>{intl.formatMessage({ id: "From" })}</Caption>
<Caption>
{intl.formatMessage({
defaultMessage: "From",
})}
</Caption>
<div className={styles.cheque}>
<Subtitle type="two" color="uiTextHighContrast">
{productTypeCheque.localPrice.numberOfCheques}
</Subtitle>
<Caption color="uiTextHighContrast" className={styles.currency}>
{CurrencyEnum.CC}
</Caption>
<Caption color="uiTextHighContrast">{CurrencyEnum.CC}</Caption>
{productTypeCheque.localPrice.additionalPricePerStay && (
<>
{"+"}
@@ -41,15 +43,18 @@ export default function HotelChequeCard({
{productTypeCheque.requestedPrice ? (
<div className={styles.chequeRow}>
<Caption color="uiTextMediumContrast">
{intl.formatMessage({ id: "Approx." })}
{intl.formatMessage({
defaultMessage: "Approx.",
})}
</Caption>
<Caption color={"uiTextMediumContrast"}>
{productTypeCheque.requestedPrice.numberOfCheques} {CurrencyEnum.CC}
{productTypeCheque.requestedPrice.additionalPricePerStay
? " + "
? // eslint-disable-next-line formatjs/no-literal-string-in-jsx
" + "
: ""}
{productTypeCheque.requestedPrice.additionalPricePerStay}{" "}
{productTypeCheque.requestedPrice.currency}
{/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}
{`${productTypeCheque.requestedPrice.additionalPricePerStay} ${productTypeCheque.requestedPrice.currency}`}
</Caption>
</div>
) : null}

View File

@@ -20,11 +20,13 @@ export default function HotelPointsRow({
{pointsPerStay}
</Subtitle>
<Caption color="uiTextHighContrast">
{intl.formatMessage({ id: "Points" })}
{intl.formatMessage({
defaultMessage: "Points",
})}
</Caption>
{additionalPricePerStay ? (
<>
+
{"+"}
<Subtitle type="two" color="uiTextHighContrast">
{additionalPricePerStay}
</Subtitle>

View File

@@ -26,7 +26,9 @@ export default function HotelPriceCard({
<div className={styles.priceRow}>
<dt>
<Caption color="red">
{intl.formatMessage({ id: "Member price" })}
{intl.formatMessage({
defaultMessage: "Member price",
})}
</Caption>
</dt>
</div>
@@ -34,7 +36,9 @@ export default function HotelPriceCard({
<div className={styles.priceRow}>
<dt>
<Caption color="uiTextHighContrast">
{intl.formatMessage({ id: "Standard price" })}
{intl.formatMessage({
defaultMessage: "Standard price",
})}
</Caption>
</dt>
</div>
@@ -45,7 +49,9 @@ export default function HotelPriceCard({
type="bold"
color={isMemberPrice ? "red" : "uiTextHighContrast"}
>
{intl.formatMessage({ id: "From" })}
{intl.formatMessage({
defaultMessage: "From",
})}
</Caption>
</dt>
<dd>
@@ -61,8 +67,12 @@ export default function HotelPriceCard({
textTransform="bold"
>
{productTypePrices.localPrice.currency}
{/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}
<span className={styles.perNight}>
/{intl.formatMessage({ id: "night" })}
/
{intl.formatMessage({
defaultMessage: "night",
})}
</span>
</Body>
</div>
@@ -72,12 +82,15 @@ export default function HotelPriceCard({
<div className={styles.priceRow}>
<dt>
<Caption color="uiTextMediumContrast">
{intl.formatMessage({ id: "Approx." })}
{intl.formatMessage({
defaultMessage: "Approx.",
})}
</Caption>
</dt>
<dd>
<Caption color={"uiTextMediumContrast"}>
{productTypePrices.requestedPrice.pricePerNight}{" "}
{/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}
{`${productTypePrices.requestedPrice.pricePerNight} `}
{productTypePrices.requestedPrice.currency}
</Caption>
</dd>
@@ -92,12 +105,15 @@ export default function HotelPriceCard({
<div className={styles.priceRow}>
<dt>
<Caption color="uiTextMediumContrast">
{intl.formatMessage({ id: "Total" })}
{intl.formatMessage({
defaultMessage: "Total",
})}
</Caption>
</dt>
<dd>
<Caption color={"uiTextMediumContrast"}>
{productTypePrices.localPrice.pricePerStay}{" "}
{/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}
{`${productTypePrices.localPrice.pricePerStay} `}
{productTypePrices.localPrice.currency}
</Caption>
</dd>

View File

@@ -17,7 +17,11 @@ export default function HotelVoucherCard({
return (
<div className={styles.voucherCard}>
<div className={styles.voucherRow}>
<Caption>{intl.formatMessage({ id: "From" })}</Caption>
<Caption>
{intl.formatMessage({
defaultMessage: "From",
})}
</Caption>
<div className={styles.voucher}>
<Subtitle type="two" color="uiTextHighContrast">
{productTypeVoucher.numberOfVouchers}

View File

@@ -16,7 +16,8 @@ export default function NoPriceAvailableCard() {
</div>
<Caption color="uiTextHighContrast">
{intl.formatMessage({
id: "There are no rooms available that match your request.",
defaultMessage:
"There are no rooms available that match your request.",
})}
</Caption>
</div>

View File

@@ -88,7 +88,9 @@ function HotelCard({
const hasInsufficientPoints = !price?.redemptions?.some(
(r) => r.hasEnoughPoints
)
const notEnoughPointsLabel = intl.formatMessage({ id: "Not enough points" })
const notEnoughPointsLabel = intl.formatMessage({
defaultMessage: "Not enough points",
})
return (
<article
@@ -129,7 +131,7 @@ function HotelCard({
href={selectHotelMap(lang)}
keepSearchParams
aria-label={intl.formatMessage({
id: "See on map",
defaultMessage: "See on map",
})}
>
<Typography variant="Body/Supporting text (caption)/smRegular">
@@ -144,7 +146,9 @@ function HotelCard({
</div>
<Caption color="uiTextPlaceholder">
{intl.formatMessage(
{ id: "{number} km to city center" },
{
defaultMessage: "{number} km to city center",
},
{
number: getSingleDecimal(
hotel.location.distanceToCentre / 1000
@@ -173,7 +177,9 @@ function HotelCard({
})}
</div>
<ReadMore
label={intl.formatMessage({ id: "See hotel details" })}
label={intl.formatMessage({
defaultMessage: "See hotel details",
})}
hotelId={hotel.operaId}
hotel={hotel}
showCTA={true}
@@ -192,7 +198,10 @@ function HotelCard({
icon={<DiscountIcon color="Icon/Feedback/Information" />}
>
{intl.formatMessage(
{ id: "<strong>Booking code</strong>: {value}" },
{
defaultMessage:
"<strong>Booking code</strong>: {value}",
},
{
value: bookingCode,
strong: (text) => (
@@ -227,7 +236,9 @@ function HotelCard({
{price?.redemptions?.length ? (
<div className={styles.pointsCard}>
<Caption>
{intl.formatMessage({ id: "Available rates" })}
{intl.formatMessage({
defaultMessage: "Available rates",
})}
</Caption>
{price.redemptions.map((redemption) => (
<HotelPointsRow
@@ -272,7 +283,9 @@ function HotelCard({
color="none"
keepSearchParams
>
{intl.formatMessage({ id: "See rooms" })}
{intl.formatMessage({
defaultMessage: "See rooms",
})}
</Link>
</Button>
)}

View File

@@ -93,11 +93,15 @@ export default function ListingHotelCardDialog({
<div className={styles.pricesContainer}>
{redemptionPrice ? (
<Caption color="uiTextHighContrast">
{intl.formatMessage({ id: "Available rates" })}
{intl.formatMessage({
defaultMessage: "Available rates",
})}
</Caption>
) : (
<Caption color="uiTextHighContrast">
{intl.formatMessage({ id: "Per night from" })}
{intl.formatMessage({
defaultMessage: "Per night from",
})}
</Caption>
)}
<div className={styles.listingPrices}>
@@ -106,13 +110,16 @@ export default function ListingHotelCardDialog({
<Subtitle type="two">
{publicPrice} {currency}
</Subtitle>
{/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}
{memberPrice && <Caption>/</Caption>}
</>
)}
{memberPrice && (
<Subtitle type="two" color="red" className={styles.memberPrice}>
{intl.formatMessage(
{ id: "{price} {currency}" },
{
defaultMessage: "{price} {currency}",
},
{
price: memberPrice,
currency,
@@ -131,7 +138,9 @@ export default function ListingHotelCardDialog({
color="none"
keepSearchParams
>
{intl.formatMessage({ id: "See rooms" })}
{intl.formatMessage({
defaultMessage: "See rooms",
})}
</Link>
</Button>
</div>

View File

@@ -92,24 +92,36 @@ export default function StandaloneHotelCardDialog({
<div className={styles.priceCard}>
{redemptionPrice ? (
<Caption>
{intl.formatMessage({ id: "Available rates" })}
{intl.formatMessage({
defaultMessage: "Available rates",
})}
</Caption>
) : (
<Caption type="bold">
{intl.formatMessage({ id: "From" })}
{intl.formatMessage({
defaultMessage: "From",
})}
</Caption>
)}
{publicPrice && !isUserLoggedIn && (
<Subtitle type="two">
{intl.formatMessage(
{ id: "{price} {currency}" },
{
defaultMessage: "{price} {currency}",
},
{
price: publicPrice,
currency,
}
)}
<Body asChild>
<span>/{intl.formatMessage({ id: "night" })}</span>
{/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}
<span>
/
{intl.formatMessage({
defaultMessage: "night",
})}
</span>
</Body>
</Subtitle>
)}
@@ -120,14 +132,22 @@ export default function StandaloneHotelCardDialog({
className={styles.memberPrice}
>
{intl.formatMessage(
{ id: "{price} {currency}" },
{
defaultMessage: "{price} {currency}",
},
{
price: memberPrice,
currency,
}
)}
<Body asChild color="red">
<span>/{intl.formatMessage({ id: "night" })}</span>
{/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}
<span>
/
{intl.formatMessage({
defaultMessage: "night",
})}
</span>
</Body>
</Subtitle>
)}
@@ -146,7 +166,9 @@ export default function StandaloneHotelCardDialog({
color="none"
keepSearchParams
>
{intl.formatMessage({ id: "See rooms" })}
{intl.formatMessage({
defaultMessage: "See rooms",
})}
</Link>
</Button>
</>

View File

@@ -23,7 +23,9 @@ export default function HotelCardDialogListing({
(hotel) => hotel.availability.productType?.redemptions?.length
)
const currencyValue = isRedemption
? intl.formatMessage({ id: "Points" })
? intl.formatMessage({
defaultMessage: "Points",
})
: undefined
const hotelsPinData = hotels ? getHotelPins(hotels, currencyValue) : []
const activeCardRef = useRef<HTMLDivElement | null>(null)

View File

@@ -151,9 +151,12 @@ export default function HotelCardListing({
{!hotels?.length && activeFilters ? (
<Alert
type={AlertTypeEnum.Info}
heading={intl.formatMessage({ id: "No hotels match your filters" })}
heading={intl.formatMessage({
defaultMessage: "No hotels match your filters",
})}
text={intl.formatMessage({
id: "It looks like no hotels match your filters. Try adjusting your search to find the perfect stay.",
defaultMessage:
"It looks like no hotels match your filters. Try adjusting your search to find the perfect stay.",
})}
/>
) : null}

View File

@@ -50,14 +50,18 @@ export function getSortedHotels({
if (bookingCode) {
const bookingCodeRateHotels = availableHotels.filter(
(hotel) =>
(hotel.availability.productType?.public?.rateType !== RateTypeEnum.Regular &&
hotel.availability.productType?.member?.rateType !== RateTypeEnum.Regular) &&
hotel.availability.productType?.public?.rateType !==
RateTypeEnum.Regular &&
hotel.availability.productType?.member?.rateType !==
RateTypeEnum.Regular &&
!!hotel.availability.productType
)
const regularRateHotels = availableHotels.filter(
(hotel) =>
hotel.availability.productType?.public?.rateType === RateTypeEnum.Regular ||
hotel?.availability.productType?.member?.rateType === RateTypeEnum.Regular
hotel.availability.productType?.public?.rateType ===
RateTypeEnum.Regular ||
hotel?.availability.productType?.member?.rateType ===
RateTypeEnum.Regular
)
return bookingCodeRateHotels

View File

@@ -43,8 +43,12 @@ export default function ActionButtons({
const intl = useIntl()
const isConfirmStep = currentStep === AncillaryStepEnum.confirmation
const confirmLabel = intl.formatMessage({ id: "Confirm" })
const continueLabel = intl.formatMessage({ id: "Continue" })
const confirmLabel = intl.formatMessage({
defaultMessage: "Confirm",
})
const continueLabel = intl.formatMessage({
defaultMessage: "Continue",
})
const quantityWithCard = useWatch<AncillaryQuantityFormData>({
name: "quantityWithCard",
})
@@ -87,7 +91,9 @@ export default function ActionButtons({
onPress={togglePriceDetails}
className={styles.priceButton}
>
{intl.formatMessage({ id: "Price details" })}
{intl.formatMessage({
defaultMessage: "Price details",
})}
{isPriceDetailsOpen ? (
<MaterialIcon
icon="keyboard_arrow_up"
@@ -112,7 +118,9 @@ export default function ActionButtons({
color="Primary"
onPress={prevStep}
>
{intl.formatMessage({ id: "Back" })}
{intl.formatMessage({
defaultMessage: "Back",
})}
</Button>
{isConfirmStep && (
<Button

View File

@@ -22,7 +22,8 @@ export default function PriceRow({
<h2>{title}</h2>
</Typography>
<Typography variant="Body/Paragraph/mdBold">
<p>{`X${quantity}`}</p>
{/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}
<p>{`×${quantity}`}</p>
</Typography>
</div>
<div className={styles.column}>

View File

@@ -35,7 +35,11 @@ export default function PriceSummary({
return (
<div className={styles.container}>
<Typography variant="Body/Paragraph/mdBold">
<h2>{intl.formatMessage({ id: "Summary" })}</h2>
<h2>
{intl.formatMessage({
defaultMessage: "Summary",
})}
</h2>
</Typography>
<Divider color="subtle" />
@@ -45,7 +49,9 @@ export default function PriceSummary({
<PriceRow
title={item.title}
quantity={item.quantityWithCard}
label={intl.formatMessage({ id: "Price including VAT" })}
label={intl.formatMessage({
defaultMessage: "Price including VAT",
})}
value={formatPrice(intl, item.totalPrice, item.currency)}
/>
)}
@@ -53,8 +59,12 @@ export default function PriceSummary({
<PriceRow
title={item.title}
quantity={item.quantityWithPoints}
label={intl.formatMessage({ id: "Points" })}
value={`${item.points} ${intl.formatMessage({ id: "points" })}`}
label={intl.formatMessage({
defaultMessage: "Points",
})}
value={`${item.points} ${intl.formatMessage({
defaultMessage: "points",
})}`}
/>
)}
<Divider color="subtle" />
@@ -65,19 +75,29 @@ export default function PriceSummary({
<Typography variant="Body/Paragraph/mdBold">
<p>
{hasTotalPrice
? intl.formatMessage({ id: "Total price including VAT" })
: intl.formatMessage({ id: "Total points" })}
? intl.formatMessage({
defaultMessage: "Total price including VAT",
})
: intl.formatMessage({
defaultMessage: "Total points",
})}
</p>
</Typography>
<div className={styles.totalPrice}>
{(hasTotalPoints || hasTotalPrice) && (
<Typography variant="Body/Paragraph/mdBold">
<p>
{hasTotalPrice &&
formatPrice(intl, totalPrice, items[0]?.currency)}
{hasTotalPoints && hasTotalPrice && " + "}
{hasTotalPoints &&
`${totalPoints} ${intl.formatMessage({ id: "points" })}`}
{hasTotalPrice
? formatPrice(intl, totalPrice, items[0]?.currency)
: null}
{/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}
{hasTotalPoints && hasTotalPrice ? " + " : null}
{hasTotalPoints
? // eslint-disable-next-line formatjs/no-literal-string-in-jsx
`${totalPoints} ${intl.formatMessage({
defaultMessage: "points",
})}`
: null}
</p>
</Typography>
)}

View File

@@ -74,7 +74,9 @@ export default function PriceDetails({
const items = [
{
title: `${selectedAncillary.title} / ${intl.formatMessage({ id: "Adult" })}`,
title: `${selectedAncillary.title} / ${intl.formatMessage({
defaultMessage: "Adult",
})}`,
totalPrice: breakfastData.priceAdult,
currency: breakfastData.currency,
quantityWithCard: breakfastData.nrOfAdults * breakfastData.nrOfNights,
@@ -83,7 +85,9 @@ export default function PriceDetails({
if (breakfastData.nrOfPayingChildren > 0) {
items.push({
title: `${selectedAncillary.title} / ${intl.formatMessage({ id: "Children" })} 4-12`,
title: `${selectedAncillary.title} / ${intl.formatMessage({
defaultMessage: "Children",
})} 4-12`,
totalPrice: breakfastData.priceChild,
currency: breakfastData.currency,
quantityWithCard:
@@ -93,7 +97,12 @@ export default function PriceDetails({
if (breakfastData.nrOfFreeChildren > 0) {
items.push({
title: `${selectedAncillary.title} / ${intl.formatMessage({ id: "Children under {age}" }, { age: 4 })}`,
title: `${selectedAncillary.title} / ${intl.formatMessage(
{
defaultMessage: "Children under {age}",
},
{ age: 4 }
)}`,
totalPrice: 0,
currency: breakfastData.currency,
quantityWithCard:
@@ -122,12 +131,19 @@ export default function PriceDetails({
<div className={styles.totalPrice}>
<div className={styles.totalPriceInclVAT}>
<Typography variant="Body/Paragraph/mdBold">
<p>{intl.formatMessage({ id: "Total" })}</p>
<p>
{intl.formatMessage({
defaultMessage: "Total",
})}
</p>
</Typography>
{totalPrice && (
<Typography variant="Body/Paragraph/mdRegular">
<p className={styles.vatText}>
({intl.formatMessage({ id: "Incl. VAT" })})
{/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}
{`(${intl.formatMessage({
defaultMessage: "Incl. VAT",
})})`}
</p>
</Typography>
)}
@@ -154,7 +170,14 @@ export default function PriceDetails({
</div>
<Typography variant="Body/Paragraph/mdBold">
<p>
{totalPoints} {intl.formatMessage({ id: "points" })}
{totalPoints}
{
/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */
" "
}
{intl.formatMessage({
defaultMessage: "points",
})}
</p>
</Typography>
</div>

View File

@@ -54,7 +54,8 @@ export default function ConfirmationStep({
<p>
{intl.formatMessage(
{
id: "All ancillaries are fully refundable until {date}. Time selection and special requests are also modifiable.",
defaultMessage:
"All ancillaries are fully refundable until {date}. Time selection and special requests are also modifiable.",
},
{ date: refundableDate }
)}
@@ -65,7 +66,7 @@ export default function ConfirmationStep({
<Typography variant="Title/Subtitle/md">
<h2>
{intl.formatMessage({
id: "Points to be deducted now",
defaultMessage: "Points to be deducted now",
})}
</h2>
</Typography>
@@ -75,7 +76,9 @@ export default function ConfirmationStep({
<Typography variant="Title/Overline/sm">
<h2>
{intl.formatMessage(
{ id: "{amount} points" },
{
defaultMessage: "{amount} points",
},
{ amount: totalPoints }
)}
</h2>
@@ -84,7 +87,9 @@ export default function ConfirmationStep({
<Typography variant="Body/Paragraph/mdRegular">
<p>
{intl.formatMessage(
{ id: "{amount} points available" },
{
defaultMessage: "{amount} points available",
},
{ amount: currentPoints }
)}
</p>
@@ -98,7 +103,7 @@ export default function ConfirmationStep({
<Typography variant="Title/Subtitle/md">
<h2>
{intl.formatMessage({
id: "Reserve with Card",
defaultMessage: "Reserve with Card",
})}
</h2>
</Typography>
@@ -106,7 +111,8 @@ export default function ConfirmationStep({
<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.",
defaultMessage:
"Payment will be made on check-in. The card will be only used to guarantee the ancillary in case of no-show.",
})}
</p>
</Typography>
@@ -115,14 +121,17 @@ export default function ConfirmationStep({
name="paymentMethod"
value={PaymentMethodEnum.card}
cardNumber={guaranteeInfo.maskedCard.slice(-4)}
label={intl.formatMessage({ id: "Credit card" })}
label={intl.formatMessage({
defaultMessage: "Credit card",
})}
/>
) : (
<>
<Alert
type={AlertTypeEnum.Info}
text={intl.formatMessage({
id: "By adding a card you also guarantee your room booking for late arrival.",
defaultMessage:
"By adding a card you also guarantee your room booking for late arrival.",
})}
/>
{savedCreditCards?.length && (
@@ -131,13 +140,19 @@ export default function ConfirmationStep({
<>
{savedCreditCards?.length && (
<Typography variant="Title/Overline/sm">
<h4>{intl.formatMessage({ id: "OTHER" })}</h4>
<h4>
{intl.formatMessage({
defaultMessage: "OTHER",
})}
</h4>
</Typography>
)}
<PaymentOption
name="paymentMethod"
value={PaymentMethodEnum.card}
label={intl.formatMessage({ id: "Credit card" })}
label={intl.formatMessage({
defaultMessage: "Credit card",
})}
/>
</>
</>
@@ -150,7 +165,8 @@ export default function ConfirmationStep({
<p>
{intl.formatMessage(
{
id: "Yes, I accept the general <termsAndConditionsLink>Terms & Conditions</termsAndConditionsLink>, and understand that Scandic will process my personal data in accordance with <privacyPolicyLink>Scandic's Privacy policy</privacyPolicyLink>. There you can learn more about what data we process, your rights and where to turn if you have questions.",
defaultMessage:
"Yes, I accept the general <termsAndConditionsLink>Terms & Conditions</termsAndConditionsLink>, and understand that Scandic will process my personal data in accordance with <privacyPolicyLink>Scandic's Privacy policy</privacyPolicyLink>. There you can learn more about what data we process, your rights and where to turn if you have questions.",
},
{
termsAndConditionsLink: (str) => (
@@ -185,7 +201,7 @@ export default function ConfirmationStep({
<Typography variant="Body/Supporting text (caption)/smRegular">
<span>
{intl.formatMessage({
id: "I accept the terms and conditions",
defaultMessage: "I accept the terms and conditions",
})}
</span>
</Typography>

View File

@@ -17,7 +17,9 @@ export default function DeliveryMethodStep() {
<div className={styles.selectContainer}>
<div className={styles.select}>
<Subtitle type="two">
{intl.formatMessage({ id: "Delivered at:" })}
{intl.formatMessage({
defaultMessage: "Delivered at:",
})}
</Subtitle>
<Select
name="deliveryTime"
@@ -28,18 +30,21 @@ export default function DeliveryMethodStep() {
/>
<Body>
{intl.formatMessage({
id: "All add-ons are delivered at the same time. Changes to delivery times will affect earlier add-ons.",
defaultMessage:
"All add-ons are delivered at the same time. Changes to delivery times will affect earlier add-ons.",
})}
</Body>
</div>
<div className={styles.select}>
<Input
label={intl.formatMessage({ id: "Other Requests" })}
label={intl.formatMessage({
defaultMessage: "Other Requests",
})}
name="optionalText"
/>
<Caption>
{intl.formatMessage({
id: "Optional",
defaultMessage: "Optional",
})}
</Caption>
</div>

View File

@@ -34,7 +34,9 @@ export default function SelectAncillaryStep() {
<p>
{categoryName
? categoryName
: intl.formatMessage({ id: "Other" })}
: intl.formatMessage({
defaultMessage: "Other",
})}
</p>
</Typography>
</button>

View File

@@ -51,21 +51,33 @@ export default function SelectQuantityStep({ user }: SelectQuantityStepProps) {
const insufficientPoints = currentPoints < pointsCost || currentPoints === 0
const pointsLabel = insufficientPoints
? intl.formatMessage({ id: "Insufficient points" })
: intl.formatMessage({ id: "Select quantity" })
? intl.formatMessage({
defaultMessage: "Insufficient points",
})
: intl.formatMessage({
defaultMessage: "Select quantity",
})
return (
<div className={styles.selectContainer}>
{selectedAncillary?.points && user && (
<div className={styles.select}>
<Typography variant="Title/Subtitle/md">
<h2>{intl.formatMessage({ id: "Pay with points" })}</h2>
<h2>
{intl.formatMessage({
defaultMessage: "Pay with points",
})}
</h2>
</Typography>
<div className={styles.totalPointsContainer}>
<div className={styles.totalPoints}>
<MaterialIcon icon="diamond" />
<Typography variant="Title/Overline/sm">
<h2>{intl.formatMessage({ id: "Total points" })}</h2>
<h2>
{intl.formatMessage({
defaultMessage: "Total points",
})}
</h2>
</Typography>
</div>
<Typography variant="Body/Paragraph/mdRegular">
@@ -83,11 +95,21 @@ export default function SelectQuantityStep({ user }: SelectQuantityStepProps) {
)}
<div className={styles.select}>
<Typography variant="Title/Subtitle/md">
<h2> {intl.formatMessage({ id: "Pay with Card" })}</h2>
<h2>
{
/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */
" "
}
{intl.formatMessage({
defaultMessage: "Pay with Card",
})}
</h2>
</Typography>
<Select
name="quantityWithCard"
label={intl.formatMessage({ id: "Select quantity" })}
label={intl.formatMessage({
defaultMessage: "Select quantity",
})}
items={cardQuantityOptions}
isNestedInModal
/>
@@ -107,7 +129,7 @@ function BreakfastInfo() {
if (!breakfastData) {
return intl.formatMessage({
id: "Can not show breakfast prices.",
defaultMessage: "Can not show breakfast prices.",
})
}
@@ -116,7 +138,8 @@ function BreakfastInfo() {
<Alert
type={AlertTypeEnum.Info}
text={intl.formatMessage({
id: "Breakfast can only be added for the entire duration of the stay and for all guests.",
defaultMessage:
"Breakfast can only be added for the entire duration of the stay and for all guests.",
})}
/>
{(breakfastData.nrOfPayingChildren > 0 ||
@@ -126,10 +149,14 @@ function BreakfastInfo() {
<MaterialIcon icon="check_circle" className={styles.icon} />
<div>
<dt>
{`${breakfastData.nrOfAdults} X ${intl.formatMessage({ id: "Adults" })}`}
{/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}
{`${breakfastData.nrOfAdults} × ${intl.formatMessage({
defaultMessage: "Adults",
})}`}
</dt>
<dd>
<Body>
{/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}
{`${breakfastData.priceAdult} ${breakfastData.currency}`}
</Body>
</dd>
@@ -141,10 +168,14 @@ function BreakfastInfo() {
<MaterialIcon icon="check_circle" className={styles.icon} />
<div>
<dt>
{`${breakfastData.nrOfPayingChildren} X ${intl.formatMessage({ id: "ages" })} 4-12`}
{/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}
{`${breakfastData.nrOfPayingChildren} × ${intl.formatMessage({
defaultMessage: "ages",
})} 4-12`}
</dt>
<dd>
<Body>
{/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}
{`${breakfastData.priceChild} ${breakfastData.currency}`}
</Body>
</dd>
@@ -157,10 +188,17 @@ function BreakfastInfo() {
<MaterialIcon icon="check_circle" className={styles.icon} />
<div>
<dt>
{`${breakfastData.nrOfFreeChildren} X ${intl.formatMessage({ id: "under" })} 4`}
{/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}
{`${breakfastData.nrOfFreeChildren} × ${intl.formatMessage({
defaultMessage: "under",
})} 4`}
</dt>
<dd>
<Body>{intl.formatMessage({ id: "Free" })}</Body>
<Body>
{intl.formatMessage({
defaultMessage: "Free",
})}
</Body>
</dd>
</div>
</div>

View File

@@ -110,7 +110,8 @@ export default function AddAncillaryFlowModal({
const ancillaryErrorMessage = intl.formatMessage(
{
id: "Something went wrong. {ancillary} could not be added to your booking!",
defaultMessage:
"Something went wrong. {ancillary} could not be added to your booking!",
},
{ ancillary: selectedAncillary?.title }
)
@@ -170,7 +171,9 @@ export default function AddAncillaryFlowModal({
)
toast.success(
intl.formatMessage(
{ id: "{ancillary} added to your booking!" },
{
defaultMessage: "{ancillary} added to your booking!",
},
{ ancillary: selectedAncillary?.title }
)
)
@@ -261,7 +264,11 @@ export default function AddAncillaryFlowModal({
: []
if (isBreakfast && !breakfastData) {
toast.error(intl.formatMessage({ id: "Something went wrong!" }))
toast.error(
intl.formatMessage({
defaultMessage: "Something went wrong!",
})
)
return
}
const shouldSkipGuarantee =
@@ -329,7 +336,9 @@ export default function AddAncillaryFlowModal({
const modalTitle =
currentStep === AncillaryStepEnum.selectAncillary
? intl.formatMessage({ id: "Upgrade your stay" })
? intl.formatMessage({
defaultMessage: "Upgrade your stay",
})
: selectedAncillary?.title
return (
<Modal isOpen={true} onToggle={closeModal} title={modalTitle}>
@@ -375,7 +384,9 @@ export default function AddAncillaryFlowModal({
<Typography variant="Body/Paragraph/mdBold">
<p>
{intl.formatMessage(
{ id: "{value} points" },
{
defaultMessage: "{value} points",
},
{
value: selectedAncillary.points,
}
@@ -431,7 +442,7 @@ function BreakfastPriceList() {
if (!breakfastData) {
return intl.formatMessage({
id: "Can not show breakfast prices.",
defaultMessage: "Can not show breakfast prices.",
})
}
@@ -439,7 +450,12 @@ function BreakfastPriceList() {
<div>
<div className={styles.breakfastPriceList}>
<Typography variant="Body/Paragraph/mdBold">
<span>{`${breakfastData.priceAdult} ${breakfastData.currency} / ${intl.formatMessage({ id: "Adult" })}`}</span>
{/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}
<span>{`${breakfastData.priceAdult} ${breakfastData.currency} / ${intl.formatMessage(
{
defaultMessage: "Adult",
}
)}`}</span>
</Typography>
{breakfastData.nrOfPayingChildren > 0 && (
@@ -449,7 +465,12 @@ function BreakfastPriceList() {
</div>
<Typography variant="Body/Paragraph/mdBold">
<span>{`${breakfastData.priceChild} ${breakfastData.currency} / ${intl.formatMessage({ id: "Years" })} 4-12`}</span>
{/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}
<span>{`${breakfastData.priceChild} ${breakfastData.currency} / ${intl.formatMessage(
{
defaultMessage: "Years",
}
)} 4-12`}</span>
</Typography>
</>
)}
@@ -461,7 +482,15 @@ function BreakfastPriceList() {
</div>
<Typography variant="Body/Paragraph/mdBold">
<span>{`${intl.formatMessage({ id: "Free" })} / ${intl.formatMessage({ id: "Under {age} years" }, { age: 4 })}`}</span>
{/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}
<span>{`${intl.formatMessage({
defaultMessage: "Free",
})} / ${intl.formatMessage(
{
defaultMessage: "Under {age} years",
},
{ age: 4 }
)}`}</span>
</Typography>
</>
)}

View File

@@ -27,16 +27,24 @@ export default function RemoveButton({
return (
<Dialog
bodyText={intl.formatMessage({
id: "Are you sure you want to remove this product?",
defaultMessage: "Are you sure you want to remove this product?",
})}
proceedText={intl.formatMessage({
defaultMessage: "Remove",
})}
proceedText={intl.formatMessage({ id: "Remove" })}
proceedIsPending={removePackage.isPending}
cancelButtonText={intl.formatMessage({ id: "Cancel" })}
titleText={`${intl.formatMessage({ id: "Remove" })} ${title}`}
cancelButtonText={intl.formatMessage({
defaultMessage: "Cancel",
})}
titleText={`${intl.formatMessage({
defaultMessage: "Remove",
})} ${title}`}
trigger={
<Button intent="text" size="small" variant="icon" theme="base">
<MaterialIcon icon="delete" color="CurrentColor" />
{intl.formatMessage({ id: "Remove" })}
{intl.formatMessage({
defaultMessage: "Remove",
})}
</Button>
}
proceedOnClick={(close) => {
@@ -56,7 +64,11 @@ export default function RemoveButton({
onSuccess()
},
onError: () => {
toast.error(intl.formatMessage({ id: "Something went wrong!" }))
toast.error(
intl.formatMessage({
defaultMessage: "Something went wrong!",
})
)
},
}
)

View File

@@ -42,12 +42,18 @@ export function AddedAncillaries({
return (
<div className={styles.container}>
<div className={styles.header}>
<Subtitle>{intl.formatMessage({ id: "My Add-on's" })}</Subtitle>
<Subtitle>
{intl.formatMessage({
defaultMessage: "My Add-on's",
})}
</Subtitle>
{booking.ancillary?.deliveryTime && (
<div className={styles.deliveryTime}>
<Body color="baseTextHighContrast" textTransform="bold">
{intl.formatMessage({ id: "Delivered at:" })}
{intl.formatMessage({
defaultMessage: "Delivered at:",
})}
</Body>
<Body color="baseTextHighContrast" textTransform="bold">
{booking.ancillary?.deliveryTime}
@@ -59,7 +65,9 @@ export function AddedAncillaries({
{addedAncillaries.map((ancillary) => {
const ancillaryTitle =
ancillary.code === BreakfastPackageEnum.ANCILLARY_REGULAR_BREAKFAST
? intl.formatMessage({ id: "Breakfast" })
? intl.formatMessage({
defaultMessage: "Breakfast",
})
: (ancillaries?.find(
(a) =>
a.id === ancillary.code || a.loyaltyCode === ancillary.code
@@ -82,7 +90,11 @@ export function AddedAncillaries({
<>
<div className={styles.commentMobile}>
<Body textTransform="bold">
{intl.formatMessage({ id: "Other requests" })}:
{intl.formatMessage({
defaultMessage: "Other requests",
})}
{/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}
{":"}
</Body>
<Body color="uiTextMediumContrast">
{ancillary.comment}
@@ -92,11 +104,19 @@ export function AddedAncillaries({
)}
<div className={styles.paymentMobileWrapper}>
<div className={styles.paymentMobile}>
<Body>{intl.formatMessage({ id: "Total" })}</Body>
<Body>
{intl.formatMessage({
defaultMessage: "Total",
})}
</Body>
<Body textTransform="bold">
{ancillary.currency.toLowerCase() === "points"
? `${ancillary.totalPrice} ${intl.formatMessage({ id: "Points" })}`
: `${ancillary.totalPrice} ${ancillary.currency}`}
? // eslint-disable-next-line formatjs/no-literal-string-in-jsx
`${ancillary.totalPrice} ${intl.formatMessage({
defaultMessage: "Points",
})}`
: // eslint-disable-next-line formatjs/no-literal-string-in-jsx
`${ancillary.totalPrice} ${ancillary.currency}`}
</Body>
</div>
</div>
@@ -129,14 +149,23 @@ export function AddedAncillaries({
color="Icon/Feedback/Success"
/>
<Body textTransform="bold">{ancillaryTitle}</Body>
{/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}
<Body textTransform="bold">{`X${ancillary.totalUnit}`}</Body>
</div>
<div className={styles.payment}>
<Body>{intl.formatMessage({ id: "Total" })}</Body>
<Body>
{intl.formatMessage({
defaultMessage: "Total",
})}
</Body>
<Body textTransform="bold">
{ancillary.currency.toLowerCase() === "points"
? `${ancillary.totalPrice} ${intl.formatMessage({ id: "Points" })}`
: `${ancillary.totalPrice} ${ancillary.currency}`}
? // eslint-disable-next-line formatjs/no-literal-string-in-jsx
`${ancillary.totalPrice} ${intl.formatMessage({
defaultMessage: "Points",
})}`
: // eslint-disable-next-line formatjs/no-literal-string-in-jsx
`${ancillary.totalPrice} ${ancillary.currency}`}
</Body>
</div>
</div>
@@ -148,7 +177,11 @@ export function AddedAncillaries({
{ancillary.comment && (
<>
<Body textTransform="bold">
{intl.formatMessage({ id: "Other requests" })}:
{intl.formatMessage({
defaultMessage: "Other requests",
})}
{/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}
{":"}
</Body>
<Body>{ancillary.comment}</Body>
</>

View File

@@ -17,7 +17,9 @@ export default function ViewAllAncillaries() {
size="small"
onClick={openModal}
>
{intl.formatMessage({ id: "View all" })}
{intl.formatMessage({
defaultMessage: "View all",
})}
<MaterialIcon icon="chevron_right" size={20} color="CurrentColor" />
</Button>
)

View File

@@ -113,9 +113,13 @@ export function Ancillaries({
const breakfastAncillary: SelectedAncillary | undefined = breakfastPackage
? {
description: intl.formatMessage({ id: "Buffet" }),
description: intl.formatMessage({
defaultMessage: "Buffet",
}),
id: breakfastPackage.code,
title: intl.formatMessage({ id: "Breakfast" }),
title: intl.formatMessage({
defaultMessage: "Breakfast",
}),
price: {
currency: breakfastPackage.localPrice.currency,
total: breakfastPackage.localPrice.totalPrice,
@@ -172,7 +176,9 @@ export function Ancillaries({
<>
<div className={styles.title}>
<Title as="h5">
{intl.formatMessage({ id: "Upgrade your stay" })}
{intl.formatMessage({
defaultMessage: "Upgrade your stay",
})}
</Title>
<ViewAllAncillaries />
</div>

View File

@@ -27,7 +27,9 @@ export default function BookingSummary({ hotel }: BookingSummaryProps) {
<div className={styles.bookingSummary}>
<Typography variant="Title/sm">
<h2 className={styles.title}>
{intl.formatMessage({ id: "Practical information" })}
{intl.formatMessage({
defaultMessage: "Practical information",
})}
</h2>
</Typography>
<div className={styles.bookingSummaryContent}>
@@ -46,7 +48,9 @@ export default function BookingSummary({ hotel }: BookingSummaryProps) {
`${hotel.address.zipCode} ${hotel.address.city}`,
]}
supportingText={intl.formatMessage(
{ id: "Long {long} ∙ Lat {lat}" },
{
defaultMessage: "Long {long} ∙ Lat {lat}",
},
{
lat: hotel.location.latitude,
long: hotel.location.longitude,
@@ -55,7 +59,9 @@ export default function BookingSummary({ hotel }: BookingSummaryProps) {
links={[
{
href: directionsUrl,
text: intl.formatMessage({ id: "Directions" }),
text: intl.formatMessage({
defaultMessage: "Directions",
}),
icon: (
<MaterialIcon
icon="directions"
@@ -67,7 +73,9 @@ export default function BookingSummary({ hotel }: BookingSummaryProps) {
},
{
href: `mailto:${hotel.contactInformation.email}`,
text: intl.formatMessage({ id: "Email" }),
text: intl.formatMessage({
defaultMessage: "Email",
}),
icon: (
<MaterialIcon
icon="mail"
@@ -79,7 +87,9 @@ export default function BookingSummary({ hotel }: BookingSummaryProps) {
},
{
href: hotel.contactInformation.websiteUrl,
text: intl.formatMessage({ id: "Homepage" }),
text: intl.formatMessage({
defaultMessage: "Homepage",
}),
icon: (
<MaterialIcon
icon="link"

View File

@@ -107,7 +107,7 @@ export default function GuaranteeLateArrival({
handleGuaranteeError("No confirmation number")
toast.error(
intl.formatMessage({
id: "Something went wrong!",
defaultMessage: "Something went wrong!",
})
)
}
@@ -116,39 +116,48 @@ export default function GuaranteeLateArrival({
return (
<FormProvider {...methods}>
<ModalContentWithActions
title={intl.formatMessage({ id: "Guarantee late arrival" })}
title={intl.formatMessage({
defaultMessage: "Guarantee late arrival",
})}
onClose={handleCloseModal}
content={
<>
<Caption>
{intl.formatMessage({
id: "Planning to arrive after 18.00? Secure your room by guaranteeing it with a credit card. Without the guarantee and in case of no-show, the room might be reallocated after 18:00.",
defaultMessage:
"Planning to arrive after 18.00? Secure your room by guaranteeing it with a credit card. Without the guarantee and in case of no-show, the room might be reallocated after 18:00.",
})}
</Caption>
<Caption type="bold">
{intl.formatMessage({
id: "In case of no-show you will be charged for the first night.",
defaultMessage:
"In case of no-show you will be charged for the first night.",
})}
</Caption>
{savedCreditCards?.length ? (
<>
<MySavedCards savedCreditCards={savedCreditCards} />
<Body color="uiTextHighContrast" textTransform="bold">
{intl.formatMessage({ id: "OTHER" })}
{intl.formatMessage({
defaultMessage: "OTHER",
})}
</Body>
</>
) : null}
<PaymentOption
name="paymentMethod"
value={PaymentMethodEnum.card}
label={intl.formatMessage({ id: "Credit card" })}
label={intl.formatMessage({
defaultMessage: "Credit card",
})}
/>
<div className={styles.termsAndConditions}>
<Typography variant="Body/Supporting text (caption)/smRegular">
<p>
{intl.formatMessage(
{
id: "By guaranteeing with any of the payment methods available, I accept the terms for this stay and the general <termsAndConditionsLink>Terms & Conditions</termsAndConditionsLink>, and understand Scandic will process my personal data for this stay in accordance with <privacyPolicyLink>Scandics Privacy Policy</privacyPolicyLink>. I accept Scandic requiring a valid credit card during my visit in case anything is left unpaid.",
defaultMessage:
"By guaranteeing with any of the payment methods available, I accept the terms for this stay and the general <termsAndConditionsLink>Terms & Conditions</termsAndConditionsLink>, and understand Scandic will process my personal data for this stay in accordance with <privacyPolicyLink>Scandics Privacy Policy</privacyPolicyLink>. I accept Scandic requiring a valid credit card during my visit in case anything is left unpaid.",
},
{
termsAndConditionsLink: (str) => (
@@ -179,7 +188,7 @@ export default function GuaranteeLateArrival({
<Typography variant="Body/Supporting text (caption)/smRegular">
<span>
{intl.formatMessage({
id: "I accept the terms and conditions",
defaultMessage: "I accept the terms and conditions",
})}
</span>
</Typography>
@@ -188,11 +197,14 @@ export default function GuaranteeLateArrival({
<div className={styles.guaranteeCost}>
<div className={styles.guaranteeCostText}>
<Caption type="bold">
{intl.formatMessage({ id: "Guarantee cost" })}
{intl.formatMessage({
defaultMessage: "Guarantee cost",
})}
</Caption>
<Caption color="uiTextHighContrast">
{intl.formatMessage({
id: "Your card will only be used for authorisation",
defaultMessage:
"Your card will only be used for authorisation",
})}
</Caption>
</div>
@@ -204,12 +216,16 @@ export default function GuaranteeLateArrival({
</>
}
primaryAction={{
label: intl.formatMessage({ id: "Guarantee" }),
label: intl.formatMessage({
defaultMessage: "Guarantee",
}),
onClick: methods.handleSubmit(handleGuaranteeLateArrival),
intent: "primary",
}}
secondaryAction={{
label: intl.formatMessage({ id: "Back" }),
label: intl.formatMessage({
defaultMessage: "Back",
}),
onClick: handleCloseView,
intent: "text",
}}

View File

@@ -71,7 +71,9 @@ export default function GuestDetails({
onSuccess: (data) => {
if (!data) {
toast.error(
intl.formatMessage({ id: "Failed to update guest details" })
intl.formatMessage({
defaultMessage: "Failed to update guest details",
})
)
return
@@ -86,12 +88,20 @@ export default function GuestDetails({
},
})
toast.success(intl.formatMessage({ id: "Guest details updated" }))
toast.success(
intl.formatMessage({
defaultMessage: "Guest details updated",
})
)
setIsModifyGuestDetailsOpen(false)
setCurrentStep(MODAL_STEPS.INITIAL)
},
onError: () => {
toast.error(intl.formatMessage({ id: "Failed to update guest details" }))
toast.error(
intl.formatMessage({
defaultMessage: "Failed to update guest details",
})
)
},
onSettled: () => {
setIsLoading(false)
@@ -127,7 +137,11 @@ export default function GuestDetails({
<div className={styles.userDetails}>
<div className={styles.userDetailsTitle}>
<Typography variant="Title/Overline/sm">
<p>{intl.formatMessage({ id: "Your member tier" })}</p>
<p>
{intl.formatMessage({
defaultMessage: "Your member tier",
})}
</p>
</Typography>
</div>
<div className={styles.memberLevel}>
@@ -143,7 +157,11 @@ export default function GuestDetails({
<MaterialIcon icon="diamond" color="Icon/Intense" />
<Typography variant="Title/Overline/sm">
<p>{intl.formatMessage({ id: "Total points" })}</p>
<p>
{intl.formatMessage({
defaultMessage: "Total points",
})}
</p>
</Typography>
</div>
@@ -163,7 +181,9 @@ export default function GuestDetails({
<Typography variant="Body/Paragraph/mdRegular">
<p className={styles.memberNumber}>
{intl.formatMessage(
{ id: "Member no. {nr}" },
{
defaultMessage: "Member no. {nr}",
},
{
nr: user.membership.membershipNumber,
}
@@ -203,7 +223,11 @@ export default function GuestDetails({
size={20}
/>
<Typography variant="Body/Paragraph/mdRegular">
<span>{intl.formatMessage({ id: "Modify guest details" })}</span>
<span>
{intl.formatMessage({
defaultMessage: "Modify guest details",
})}
</span>
</Typography>
</Button>
) : (
@@ -228,7 +252,11 @@ export default function GuestDetails({
size={20}
/>
<Typography variant="Body/Paragraph/mdRegular">
<span>{intl.formatMessage({ id: "Modify guest details" })}</span>
<span>
{intl.formatMessage({
defaultMessage: "Modify guest details",
})}
</span>
</Typography>
</Button>
{isModifyGuestDetailsOpen && (
@@ -239,12 +267,16 @@ export default function GuestDetails({
onToggle={setIsModifyGuestDetailsOpen}
>
<Dialog
aria-label={intl.formatMessage({ id: "Modify guest details" })}
aria-label={intl.formatMessage({
defaultMessage: "Modify guest details",
})}
>
{({ close }) => (
<FormProvider {...form}>
<ModalContentWithActions
title={intl.formatMessage({ id: "Modify guest details" })}
title={intl.formatMessage({
defaultMessage: "Modify guest details",
})}
onClose={() => setIsModifyGuestDetailsOpen(false)}
content={
booking.guest && (
@@ -256,8 +288,12 @@ export default function GuestDetails({
}
primaryAction={{
label: isFirstStep
? intl.formatMessage({ id: "Save updates" })
: intl.formatMessage({ id: "Confirm" }),
? intl.formatMessage({
defaultMessage: "Save updates",
})
: intl.formatMessage({
defaultMessage: "Confirm",
}),
onClick: isFirstStep
? () => setCurrentStep(MODAL_STEPS.CONFIRMATION)
: () => form.handleSubmit(onSubmit)(),
@@ -266,8 +302,12 @@ export default function GuestDetails({
}}
secondaryAction={{
label: isFirstStep
? intl.formatMessage({ id: "Back" })
: intl.formatMessage({ id: "Cancel" }),
? intl.formatMessage({
defaultMessage: "Back",
})
: intl.formatMessage({
defaultMessage: "Cancel",
}),
onClick: () => {
close()
setCurrentStep(MODAL_STEPS.INITIAL)

View File

@@ -12,7 +12,13 @@ export async function Header({ hotel }: Pick<BookingConfirmation, "hotel">) {
<header>
<Title as="h2" color="white" className={styles.title} textAlign="center">
<BiroScript type="two" tilted="medium">
{intl.formatMessage({ id: "My stay at" })}{" "}
{intl.formatMessage({
defaultMessage: "My stay at",
})}
{
/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */
" "
}
</BiroScript>
<span className={styles.hotelName}>{hotel.name}</span>
{hotel.cityName}

View File

@@ -31,7 +31,9 @@ export default function AddToCalendarButton({
onPress={handleAddToCalendar}
disabled={disabled}
>
{intl.formatMessage({ id: "Add to calendar" })}
{intl.formatMessage({
defaultMessage: "Add to calendar",
})}
<MaterialIcon icon="calendar_add_on" color="CurrentColor" />
</Button>
)

View File

@@ -26,7 +26,9 @@ export default function CancelStayPriceContainer({
return (
<PriceContainer
text={intl.formatMessage({ id: "Cancellation cost" })}
text={intl.formatMessage({
defaultMessage: "Cancellation cost",
})}
price={0}
currencyCode={roomDetails.currencyCode}
nightsText={stayDetails.nightsText}

View File

@@ -37,7 +37,8 @@ export function CancelStayConfirmation({
<Body color="uiTextHighContrast">
{intl.formatMessage(
{
id: "Are you sure you want to cancel your stay at {hotel} from {checkInDate} to {checkOutDate}? This can't be reversed.",
defaultMessage:
"Are you sure you want to cancel your stay at {hotel} from {checkInDate} to {checkOutDate}? This can't be reversed.",
},
{
hotel: hotel.name,
@@ -47,13 +48,17 @@ export function CancelStayConfirmation({
)}
</Body>
<Caption color="uiTextHighContrast">
{intl.formatMessage({ id: "No charges were made." })}
{intl.formatMessage({
defaultMessage: "No charges were made.",
})}
</Caption>
</div>
{multiRoom && (
<>
<Body color="uiTextHighContrast" textTransform="bold">
{intl.formatMessage({ id: "Select rooms" })}
{intl.formatMessage({
defaultMessage: "Select rooms",
})}
</Body>
<div className={styles.rooms}>
@@ -80,7 +85,9 @@ export function CancelStayConfirmation({
<div className={styles.roomInfo}>
<Caption color="uiTextHighContrast">
{intl.formatMessage(
{ id: "Room {roomIndex}" },
{
defaultMessage: "Room {roomIndex}",
},
{
roomIndex: index + 1,
}

View File

@@ -20,7 +20,8 @@ export function FinalConfirmation({ stayDetails }: FinalConfirmationProps) {
<div className={styles.modalText}>
<Body color="uiTextHighContrast">
{intl.formatMessage({
id: "Are you sure you want to continue with the cancellation?",
defaultMessage:
"Are you sure you want to continue with the cancellation?",
})}
</Body>
</div>

View File

@@ -51,7 +51,7 @@ export default function useCancelStay({
if (!bookedRoom.confirmationNumber) {
toast.error(
intl.formatMessage({
id: "Something went wrong. Please try again later.",
defaultMessage: "Something went wrong. Please try again later.",
})
)
return
@@ -136,7 +136,8 @@ export default function useCancelStay({
toast.success(
intl.formatMessage(
{
id: "Your stay was cancelled. Cancellation cost: 0 {currency}. We're sorry to see that the plans didn't work out",
defaultMessage:
"Your stay was cancelled. Cancellation cost: 0 {currency}. We're sorry to see that the plans didn't work out",
},
{ currency: bookedRoom.currencyCode }
)
@@ -145,14 +146,15 @@ export default function useCancelStay({
// Some rooms cancelled, some failed
toast.warning(
intl.formatMessage({
id: "Some rooms were cancelled successfully, but we encountered issues with others. Please contact customer service for assistance.",
defaultMessage:
"Some rooms were cancelled successfully, but we encountered issues with others. Please contact customer service for assistance.",
})
)
} else {
// No rooms cancelled successfully
toast.error(
intl.formatMessage({
id: "Something went wrong. Please try again later.",
defaultMessage: "Something went wrong. Please try again later.",
})
)
}
@@ -162,7 +164,7 @@ export default function useCancelStay({
console.error("Error in handleCancelStay:", error)
toast.error(
intl.formatMessage({
id: "Something went wrong. Please try again later.",
defaultMessage: "Something went wrong. Please try again later.",
})
)
} finally {

View File

@@ -59,15 +59,27 @@ export default function CancelStay({ hotel }: CancelStayProps) {
function getModalCopy() {
if (isFirstStep) {
return {
title: intl.formatMessage({ id: "Cancel stay" }),
primaryLabel: intl.formatMessage({ id: "Cancel stay" }),
secondaryLabel: intl.formatMessage({ id: "Back" }),
title: intl.formatMessage({
defaultMessage: "Cancel stay",
}),
primaryLabel: intl.formatMessage({
defaultMessage: "Cancel stay",
}),
secondaryLabel: intl.formatMessage({
defaultMessage: "Back",
}),
}
} else {
return {
title: intl.formatMessage({ id: "Confirm cancellation" }),
primaryLabel: intl.formatMessage({ id: "Confirm cancellation" }),
secondaryLabel: intl.formatMessage({ id: "Don't cancel" }),
title: intl.formatMessage({
defaultMessage: "Confirm cancellation",
}),
primaryLabel: intl.formatMessage({
defaultMessage: "Confirm cancellation",
}),
secondaryLabel: intl.formatMessage({
defaultMessage: "Don't cancel",
}),
}
}
}
@@ -84,10 +96,11 @@ export default function CancelStay({ hotel }: CancelStayProps) {
<Alert
type={AlertTypeEnum.Info}
heading={intl.formatMessage({
id: "Contact the person who booked the stay",
defaultMessage: "Contact the person who booked the stay",
})}
text={intl.formatMessage({
id: "As this is a multiroom stay, the cancellation has to be done by the person who made the booking. Please call 08-517 517 00 to talk to our customer service if you would need further assistance.",
defaultMessage:
"As this is a multiroom stay, the cancellation has to be done by the person who made the booking. Please call 08-517 517 00 to talk to our customer service if you would need further assistance.",
})}
/>
)

View File

@@ -62,15 +62,22 @@ export function formatStayDetails({
.diff(dt(checkInDate).startOf("day"), "days")
const nightsText = intl.formatMessage(
{ id: "{totalNights, plural, one {# night} other {# nights}}" },
{
defaultMessage: "{totalNights, plural, one {# night} other {# nights}}",
},
{ totalNights: diff }
)
const adultsText = intl.formatMessage(
{ id: "{totalAdults, plural, one {# adult} other {# adults}}" },
{
defaultMessage: "{totalAdults, plural, one {# adult} other {# adults}}",
},
{ totalAdults: totalAdults }
)
const childrenText = intl.formatMessage(
{ id: "{totalChildren, plural, one {# child} other {# children}}" },
{
defaultMessage:
"{totalChildren, plural, one {# child} other {# children}}",
},
{ totalChildren: totalChildren }
)
@@ -138,11 +145,16 @@ export const useCheckedRoomsCounts = (
const { totalAdults, totalChildren } = calculateTotals(matchedRooms)
const adultsText = intl.formatMessage(
{ id: "{totalAdults, plural, one {# adult} other {# adults}}" },
{
defaultMessage: "{totalAdults, plural, one {# adult} other {# adults}}",
},
{ totalAdults: totalAdults }
)
const childrenText = intl.formatMessage(
{ id: "{totalChildren, plural, one {# child} other {# children}}" },
{
defaultMessage:
"{totalChildren, plural, one {# child} other {# children}}",
},
{ totalChildren: totalChildren }
)

View File

@@ -55,7 +55,9 @@ export default function Confirmation({
.diff(dt(newCheckIn).startOf("day"), "days")
const nightsText = intl.formatMessage(
{ id: "{totalNights, plural, one {# night} other {# nights}}" },
{
defaultMessage: "{totalNights, plural, one {# night} other {# nights}}",
},
{ totalNights: diff }
)
@@ -69,7 +71,9 @@ export default function Confirmation({
type="bold"
textTransform="uppercase"
>
{intl.formatMessage({ id: "Old dates" })}
{intl.formatMessage({
defaultMessage: "Old dates",
})}
</Caption>
<Body color="uiTextMediumContrast">
{oldPrice} {currencyCode}
@@ -82,7 +86,9 @@ export default function Confirmation({
type="bold"
textTransform="uppercase"
>
{intl.formatMessage({ id: "Check-in" })}
{intl.formatMessage({
defaultMessage: "Check-in",
})}
</Caption>
<Body color="uiTextMediumContrast">{originalCheckIn}</Body>
</div>
@@ -92,7 +98,9 @@ export default function Confirmation({
type="bold"
textTransform="uppercase"
>
{intl.formatMessage({ id: "Check-out" })}
{intl.formatMessage({
defaultMessage: "Check-out",
})}
</Caption>
<Body color="uiTextMediumContrast">{originalCheckOut}</Body>
</div>
@@ -104,7 +112,9 @@ export default function Confirmation({
<div className={styles.dateGroup}>
<div className={styles.dateHeader}>
<Caption color="red" type="bold" textTransform="uppercase">
{intl.formatMessage({ id: "New dates" })}
{intl.formatMessage({
defaultMessage: "New dates",
})}
</Caption>
<Body color="red">
{newPrice} {currencyCode}
@@ -117,7 +127,9 @@ export default function Confirmation({
type="bold"
textTransform="uppercase"
>
{intl.formatMessage({ id: "Check-in" })}
{intl.formatMessage({
defaultMessage: "Check-in",
})}
</Caption>
<Body color="uiTextMediumContrast">{newCheckIn}</Body>
</div>
@@ -127,7 +139,9 @@ export default function Confirmation({
type="bold"
textTransform="uppercase"
>
{intl.formatMessage({ id: "Check-out" })}
{intl.formatMessage({
defaultMessage: "Check-out",
})}
</Caption>
<Body color="uiTextMediumContrast">{newCheckOut}</Body>
</div>
@@ -136,7 +150,9 @@ export default function Confirmation({
</div>
<PriceContainer
text={intl.formatMessage({ id: "To be paid" })}
text={intl.formatMessage({
defaultMessage: "To be paid",
})}
price={newPrice}
currencyCode={currencyCode}
nightsText={nightsText}

View File

@@ -131,25 +131,31 @@ export default function NewDates({
{noAvailability && (
<Alert
type={AlertTypeEnum.Info}
heading={intl.formatMessage({ id: "No availability" })}
heading={intl.formatMessage({
defaultMessage: "No availability",
})}
text={intl.formatMessage({
id: "No single rooms are available on these dates",
defaultMessage: "No single rooms are available on these dates",
})}
/>
)}
{error && (
<Alert
type={AlertTypeEnum.Alarm}
heading={intl.formatMessage({ id: "Error" })}
heading={intl.formatMessage({
defaultMessage: "Error",
})}
text={intl.formatMessage({
id: "Something went wrong!",
defaultMessage: "Something went wrong!",
})}
/>
)}
<div className={styles.container}>
<div className={styles.checkInDate}>
<Caption color="uiTextHighContrast" type="bold">
{intl.formatMessage({ id: "Check-in" })}
{intl.formatMessage({
defaultMessage: "Check-in",
})}
</Caption>
<CalendarButton
@@ -161,7 +167,9 @@ export default function NewDates({
</div>
<div className={styles.checkOutDate}>
<Caption color="uiTextHighContrast" type="bold">
{intl.formatMessage({ id: "Check-out" })}
{intl.formatMessage({
defaultMessage: "Check-out",
})}
</Caption>
<CalendarButton

View File

@@ -40,7 +40,11 @@ export default function useModifyStay({
onMutate: () => setIsLoading(true),
onSuccess: (updatedBooking) => {
if (!updatedBooking) {
toast.error(intl.formatMessage({ id: "Failed to update your stay" }))
toast.error(
intl.formatMessage({
defaultMessage: "Failed to update your stay",
})
)
return
}
// Update room details with server response data
@@ -50,11 +54,19 @@ export default function useModifyStay({
checkOutDate: updatedBooking.checkOutDate,
})
toast.success(intl.formatMessage({ id: "Your stay was updated" }))
toast.success(
intl.formatMessage({
defaultMessage: "Your stay was updated",
})
)
handleCloseModal()
},
onError: () => {
toast.error(intl.formatMessage({ id: "Failed to update your stay" }))
toast.error(
intl.formatMessage({
defaultMessage: "Failed to update your stay",
})
)
},
onSettled: () => {
setIsLoading(false)
@@ -65,7 +77,11 @@ export default function useModifyStay({
const formValues = getFormValues()
if (!formValues.checkInDate || !formValues.checkOutDate) {
toast.error(intl.formatMessage({ id: "Please select dates" }))
toast.error(
intl.formatMessage({
defaultMessage: "Please select dates",
})
)
return { success: false }
}
@@ -146,7 +162,7 @@ export default function useModifyStay({
console.error("Error modifying stay:", error)
toast.error(
intl.formatMessage({
id: "Failed to update your stay. Please try again later.",
defaultMessage: "Failed to update your stay. Please try again later.",
})
)
setIsLoading(false)

View File

@@ -98,10 +98,11 @@ export default function ModifyStay({ isLoggedIn }: ModifyStayProps) {
<Alert
type={AlertTypeEnum.Info}
heading={intl.formatMessage({
id: "Contact customer service",
defaultMessage: "Contact customer service",
})}
text={intl.formatMessage({
id: "As this is a multiroom stay, any dates changes are applicable to all rooms. Please contact customer service to update the dates.",
defaultMessage:
"As this is a multiroom stay, any dates changes are applicable to all rooms. Please contact customer service to update the dates.",
})}
/>
)
@@ -111,10 +112,11 @@ export default function ModifyStay({ isLoggedIn }: ModifyStayProps) {
<Alert
type={AlertTypeEnum.Info}
heading={intl.formatMessage({
id: "Contact customer service",
defaultMessage: "Contact customer service",
})}
text={intl.formatMessage({
id: "Please contact customer service to update the dates.",
defaultMessage:
"Please contact customer service to update the dates.",
})}
/>
)
@@ -142,10 +144,11 @@ export default function ModifyStay({ isLoggedIn }: ModifyStayProps) {
<Alert
type={AlertTypeEnum.Info}
heading={intl.formatMessage({
id: "Contact the person who booked the stay",
defaultMessage: "Contact the person who booked the stay",
})}
text={intl.formatMessage({
id: "As this is a multiroom stay, any dates changes are applicable to all rooms. Please ask the person who booked the stay to contact customer service.",
defaultMessage:
"As this is a multiroom stay, any dates changes are applicable to all rooms. Please ask the person who booked the stay to contact customer service.",
})}
/>
)
@@ -156,8 +159,12 @@ export default function ModifyStay({ isLoggedIn }: ModifyStayProps) {
<ModalContentWithActions
title={
isFirstStep
? intl.formatMessage({ id: "New dates for the stay" })
: intl.formatMessage({ id: "Confirm date change" })
? intl.formatMessage({
defaultMessage: "New dates for the stay",
})
: intl.formatMessage({
defaultMessage: "Confirm date change",
})
}
content={getModalContent()}
onClose={handleCloseModal}
@@ -165,8 +172,12 @@ export default function ModifyStay({ isLoggedIn }: ModifyStayProps) {
mainRoom && !multiRoom && canChangeDate
? {
label: isFirstStep
? intl.formatMessage({ id: "Check availability" })
: intl.formatMessage({ id: "Confirm" }),
? intl.formatMessage({
defaultMessage: "Check availability",
})
: intl.formatMessage({
defaultMessage: "Confirm",
}),
onClick: isFirstStep ? onCheckAvailability : handleModifyStay,
intent: isFirstStep ? "secondary" : "primary",
isLoading: isLoading,
@@ -176,8 +187,12 @@ export default function ModifyStay({ isLoggedIn }: ModifyStayProps) {
}
secondaryAction={{
label: isFirstStep
? intl.formatMessage({ id: "Back" })
: intl.formatMessage({ id: "Cancel" }),
? intl.formatMessage({
defaultMessage: "Back",
})
: intl.formatMessage({
defaultMessage: "Cancel",
}),
onClick: isFirstStep ? handleCloseView : handleCloseModal,
intent: "text",
}}

View File

@@ -29,7 +29,9 @@ export default function PriceContainer({
{text}
</Caption>
<Caption color="uiTextHighContrast">
{/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}
{nightsText}, {adultsText}
{/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}
{totalChildren > 0 ? `, ${childrenText}` : ""}
</Caption>
</div>

View File

@@ -139,7 +139,9 @@ export default function ActionPanel({ hotel }: ActionPanelProps) {
className={styles.button}
disabled={!isDateModifyable}
>
{intl.formatMessage({ id: "Modify dates" })}
{intl.formatMessage({
defaultMessage: "Modify dates",
})}
<MaterialIcon icon="calendar_month" color="CurrentColor" />
</Button>
@@ -150,7 +152,9 @@ export default function ActionPanel({ hotel }: ActionPanelProps) {
className={styles.button}
disabled={!isGuaranteeable}
>
{intl.formatMessage({ id: "Guarantee late arrival" })}
{intl.formatMessage({
defaultMessage: "Guarantee late arrival",
})}
<MaterialIcon icon="credit_card" color="CurrentColor" />
</Button>
@@ -173,13 +177,19 @@ export default function ActionPanel({ hotel }: ActionPanelProps) {
className={styles.actionLink}
onClick={handleDownloadInvoice}
>
{intl.formatMessage({ id: "Download invoice" })}
{intl.formatMessage({
defaultMessage: "Download invoice",
})}
<MaterialIcon icon="download" color="CurrentColor" />
</Link>
) : (
<div className={styles.disabledLink}>
<Typography variant="Body/Paragraph/mdBold">
<p>{intl.formatMessage({ id: "Download invoice" })}</p>
<p>
{intl.formatMessage({
defaultMessage: "Download invoice",
})}
</p>
</Typography>
<MaterialIcon icon="download" color="CurrentColor" />
@@ -193,14 +203,18 @@ export default function ActionPanel({ hotel }: ActionPanelProps) {
className={styles.button}
disabled={!isCancelable}
>
{intl.formatMessage({ id: "Cancel stay" })}
{intl.formatMessage({
defaultMessage: "Cancel stay",
})}
<MaterialIcon icon="cancel" color="CurrentColor" />
</Button>
</div>
<div className={styles.info}>
<div>
<span className={styles.tag}>
{intl.formatMessage({ id: "Reference number" })}
{intl.formatMessage({
defaultMessage: "Reference number",
})}
</span>
<Subtitle color="burgundy" textAlign="right">
{confirmationNumber}
@@ -229,7 +243,9 @@ export default function ActionPanel({ hotel }: ActionPanelProps) {
onClick={handleCustomerSupport}
>
<Caption color="burgundy">
{intl.formatMessage({ id: "Customer support" })}
{intl.formatMessage({
defaultMessage: "Customer support",
})}
</Caption>
<MaterialIcon icon="chevron_right" size={20} color="CurrentColor" />
</Link>

View File

@@ -77,7 +77,9 @@ export default function ManageStay({
disabled={allRoomsCancelled}
className={styles.manageStayButton}
>
{intl.formatMessage({ id: "Manage stay" })}
{intl.formatMessage({
defaultMessage: "Manage stay",
})}
<MaterialIcon
icon="keyboard_arrow_down"
color={

View File

@@ -38,13 +38,17 @@ export default function ModifyContact({
<div className={styles.container}>
<div className={`${styles.row} ${styles.gridEqual}`}>
<Input
label={intl.formatMessage({ id: "First name" })}
label={intl.formatMessage({
defaultMessage: "First name",
})}
maxLength={30}
name="firstName"
disabled={!!guest.firstName}
/>
<Input
label={intl.formatMessage({ id: "Last name" })}
label={intl.formatMessage({
defaultMessage: "Last name",
})}
maxLength={30}
name="lastName"
disabled={!!guest.lastName}
@@ -52,13 +56,17 @@ export default function ModifyContact({
</div>
<div className={styles.row}>
<CountrySelect
label={intl.formatMessage({ id: "Country" })}
label={intl.formatMessage({
defaultMessage: "Country",
})}
name="countryCode"
/>
</div>
<div className={styles.row}>
<Input
label={intl.formatMessage({ id: "Email" })}
label={intl.formatMessage({
defaultMessage: "Email",
})}
name="email"
type="email"
registerOptions={{ required: true }}
@@ -66,7 +74,9 @@ export default function ModifyContact({
</div>
<div className={styles.row}>
<Phone
label={intl.formatMessage({ id: "Phone number" })}
label={intl.formatMessage({
defaultMessage: "Phone number",
})}
name="phoneNumber"
registerOptions={{ required: true }}
/>
@@ -76,7 +86,8 @@ export default function ModifyContact({
<>
<Body color="uiTextHighContrast">
{intl.formatMessage({
id: "Are you sure you want to change your guest details?",
defaultMessage:
"Are you sure you want to change your guest details?",
})}
</Body>
<div className={styles.container}>

View File

@@ -135,7 +135,9 @@ export default function MultiRoom({
const fromDate = dt(checkInDate).locale(lang)
const adultsMsg = intl.formatMessage(
{ id: "{adults, plural, one {# adult} other {# adults}}" },
{
defaultMessage: "{adults, plural, one {# adult} other {# adults}}",
},
{
adults: adults,
}
@@ -143,7 +145,7 @@ export default function MultiRoom({
const childrenMsg = intl.formatMessage(
{
id: "{children, plural, one {# child} other {# children}}",
defaultMessage: "{children, plural, one {# child} other {# children}}",
},
{
children: childrenAges.length,
@@ -171,16 +173,25 @@ export default function MultiRoom({
}
>
<Typography variant="Body/Supporting text (caption)/smBold">
<span>{intl.formatMessage({ id: "Cancelled" })}</span>
<span>
{intl.formatMessage({
defaultMessage: "Cancelled",
})}
</span>
</Typography>
</IconChip>
) : (
<div className={styles.chip}>
<Typography variant="Tag/sm">
<span>
{intl.formatMessage({ id: "Room" }) +
" " +
(index !== undefined ? index + 2 : 1)}
{intl.formatMessage(
{
defaultMessage: "Room {roomIndex}",
},
{
roomIndex: index !== undefined ? index + 2 : 1,
}
)}
</span>
</Typography>
</div>
@@ -188,9 +199,21 @@ export default function MultiRoom({
<div className={styles.reference}>
<Typography variant="Body/Supporting text (caption)/smBold">
{isCancelled ? (
<span>{intl.formatMessage({ id: "Cancellation no" })}:</span>
<span>
{intl.formatMessage({
defaultMessage: "Cancellation no",
})}
{/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}
{":"}
</span>
) : (
<span>{intl.formatMessage({ id: "Reference" })}:</span>
<span>
{intl.formatMessage({
defaultMessage: "Reference",
})}
{/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}
{":"}
</span>
)}
</Typography>
<Typography variant="Body/Supporting text (caption)/smRegular">
@@ -250,7 +273,11 @@ export default function MultiRoom({
<div className={styles.details}>
<div className={styles.row}>
<Typography variant="Body/Paragraph/mdBold">
<p>{intl.formatMessage({ id: "Guests" })}</p>
<p>
{intl.formatMessage({
defaultMessage: "Guests",
})}
</p>
</Typography>
<Typography variant="Body/Paragraph/mdRegular">
<p>
@@ -260,7 +287,11 @@ export default function MultiRoom({
</div>
<div className={styles.row}>
<Typography variant="Body/Paragraph/mdBold">
<p>{intl.formatMessage({ id: "Terms" })}</p>
<p>
{intl.formatMessage({
defaultMessage: "Terms",
})}
</p>
</Typography>
<Typography variant="Body/Paragraph/mdRegular">
<p>{rateDefinition.cancellationText}</p>
@@ -269,10 +300,15 @@ export default function MultiRoom({
{hasModifiableRate(rateDefinition.cancellationRule) && (
<div className={styles.row}>
<Typography variant="Body/Paragraph/mdBold">
<p>{intl.formatMessage({ id: "Modify By" })}</p>
<p>
{intl.formatMessage({
defaultMessage: "Modify By",
})}
</p>
</Typography>
<Typography variant="Body/Paragraph/mdRegular">
{/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}
<p color="uiTextHighContrast">
18:00, {fromDate.format("dddd D MMM")}
</p>
@@ -281,7 +317,11 @@ export default function MultiRoom({
)}
<div className={styles.row}>
<Typography variant="Body/Paragraph/mdBold">
<p>{intl.formatMessage({ id: "Breakfast" })}</p>
<p>
{intl.formatMessage({
defaultMessage: "Breakfast",
})}
</p>
</Typography>
<Typography variant="Body/Paragraph/mdRegular">
@@ -291,15 +331,23 @@ export default function MultiRoom({
code: pkg.code,
})) ?? []
)
? intl.formatMessage({ id: "Included" })
: intl.formatMessage({ id: "Not included" })}
? intl.formatMessage({
defaultMessage: "Included",
})
: intl.formatMessage({
defaultMessage: "Not included",
})}
</p>
</Typography>
</div>
<Divider color="subtle" />
<div className={styles.row}>
<Typography variant="Body/Lead text">
<p>{intl.formatMessage({ id: "Room total" })}</p>
<p>
{intl.formatMessage({
defaultMessage: "Room total",
})}
</p>
</Typography>
{priceType === "points" ? (
<Points points={roomPoints} variant="Body/Paragraph/mdBold" />
@@ -307,7 +355,9 @@ export default function MultiRoom({
<Typography variant="Body/Paragraph/mdBold">
<p>
{intl.formatMessage(
{ id: "{count} voucher" },
{
defaultMessage: "{count} voucher",
},
{ count: vouchers }
)}
</p>

View File

@@ -24,7 +24,14 @@ export default function Points({
return (
<Typography variant={variant}>
<p>
{intl.formatNumber(points)} {intl.formatMessage({ id: "Points" })}
{intl.formatNumber(points)}
{
/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */
" "
}
{intl.formatMessage({
defaultMessage: "Points",
})}
</p>
</Typography>
)

View File

@@ -130,7 +130,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
@@ -145,6 +147,31 @@ export default function PriceDetailsTable({
return (
<table className={styles.priceDetailsTable}>
{rooms.map((room, idx) => {
const totalAdultsMsg = intl.formatMessage(
{
defaultMessage:
"{totalAdults, plural, one {# adult} other {# adults}}",
},
{
totalAdults: room.adults,
}
)
const totalChildrenMsg = intl.formatMessage(
{
defaultMessage:
"{totalChildren, plural, one {# child} other {# children}}",
},
{
totalChildren: room.childrenInRoom.length,
}
)
const guestsCountMsg = [totalAdultsMsg]
if (room.childrenInRoom.length) {
guestsCountMsg.push(totalChildrenMsg)
}
return (
<Fragment key={idx}>
<TableSection>
@@ -154,7 +181,9 @@ export default function PriceDetailsTable({
<Typography variant="Body/Paragraph/mdBold">
<span>
{intl.formatMessage(
{ id: "Room {roomIndex}" },
{
defaultMessage: "Room {roomIndex}",
},
{ roomIndex: idx + 1 }
)}
</span>
@@ -164,7 +193,9 @@ export default function PriceDetailsTable({
)}
<TableSectionHeader title={room.roomName} subtitle={duration} />
<Row
label={intl.formatMessage({ id: "Average price per night" })}
label={intl.formatMessage({
defaultMessage: "Average price per night",
})}
value={formatPrice(
intl,
room.roomPrice.perNight.local.price,
@@ -186,7 +217,9 @@ export default function PriceDetailsTable({
: null}
<Row
bold
label={intl.formatMessage({ id: "Room charge" })}
label={intl.formatMessage({
defaultMessage: "Room charge",
})}
value={formatPrice(
intl,
room.roomPrice.perStay.local.price,
@@ -199,11 +232,11 @@ export default function PriceDetailsTable({
<Row
label={intl.formatMessage(
{
id: "Breakfast ({totalAdults, plural, one {# adult} other {# adults}}{totalChildren, plural, =0 {} one {, # child} other {, # children}}) x {totalBreakfasts}",
defaultMessage:
"Breakfast ({guestsCount}) x {totalBreakfasts}",
},
{
totalAdults: room.adults,
totalChildren: room.childrenInRoom.length,
guestsCount: guestsCountMsg.join(", "),
totalBreakfasts: diff,
}
)}
@@ -216,7 +249,7 @@ export default function PriceDetailsTable({
<Row
bold
label={intl.formatMessage({
id: "Breakfast charge",
defaultMessage: "Breakfast charge",
})}
value={formatPrice(
intl,
@@ -230,19 +263,32 @@ export default function PriceDetailsTable({
)
})}
<TableSection>
<TableSectionHeader title={intl.formatMessage({ id: "Total" })} />
<TableSectionHeader
title={intl.formatMessage({
defaultMessage: "Total",
})}
/>
<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)}
/>
<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}>

View File

@@ -24,7 +24,11 @@ export default async function Footer({ booking, room }: FooterProps) {
<div>
<div>
<Typography variant="Body/Supporting text (caption)/smRegular">
<dt>{intl.formatMessage({ id: "Reference number" })}</dt>
<dt>
{intl.formatMessage({
defaultMessage: "Reference number",
})}
</dt>
</Typography>
<Typography variant="Body/Supporting text (caption)/smRegular">
<dd>{booking.confirmationNumber}</dd>
@@ -33,7 +37,11 @@ export default async function Footer({ booking, room }: FooterProps) {
<div>
<Typography variant="Body/Supporting text (caption)/smRegular">
<dt>{intl.formatMessage({ id: "Room" })}</dt>
<dt>
{intl.formatMessage({
defaultMessage: "Room",
})}
</dt>
</Typography>
<Typography variant="Body/Supporting text (caption)/smRegular">
<dd>{room?.name}</dd>
@@ -42,7 +50,11 @@ export default async function Footer({ booking, room }: FooterProps) {
<div>
<Typography variant="Body/Supporting text (caption)/smRegular">
<dt>{intl.formatMessage({ id: "Rate" })}</dt>
<dt>
{intl.formatMessage({
defaultMessage: "Rate",
})}
</dt>
</Typography>
<Typography variant="Body/Supporting text (caption)/smRegular">
<dd>{booking.rateDefinition.title}</dd>
@@ -51,7 +63,11 @@ export default async function Footer({ booking, room }: FooterProps) {
<div>
<Typography variant="Body/Supporting text (caption)/smRegular">
<dt>{intl.formatMessage({ id: "Check-in" })}</dt>
<dt>
{intl.formatMessage({
defaultMessage: "Check-in",
})}
</dt>
</Typography>
<Typography variant="Body/Supporting text (caption)/smRegular">
<dd>
@@ -62,7 +78,11 @@ export default async function Footer({ booking, room }: FooterProps) {
<div>
<Typography variant="Body/Supporting text (caption)/smRegular">
<dt>{intl.formatMessage({ id: "Check-out" })}</dt>
<dt>
{intl.formatMessage({
defaultMessage: "Check-out",
})}
</dt>
</Typography>
<Typography variant="Body/Supporting text (caption)/smRegular">
<dd>
@@ -75,7 +95,11 @@ export default async function Footer({ booking, room }: FooterProps) {
<div className={styles.rightColumn}>
<div>
<Typography variant="Body/Supporting text (caption)/smRegular">
<dt>{intl.formatMessage({ id: "Number of nights" })}</dt>
<dt>
{intl.formatMessage({
defaultMessage: "Number of nights",
})}
</dt>
</Typography>
<Typography variant="Body/Supporting text (caption)/smRegular">
<dd>
@@ -86,12 +110,19 @@ export default async function Footer({ booking, room }: FooterProps) {
<div>
<Typography variant="Body/Supporting text (caption)/smRegular">
<dt>{intl.formatMessage({ id: "Number of guests" })}</dt>
<dt>
{intl.formatMessage({
defaultMessage: "Number of guests",
})}
</dt>
</Typography>
<Typography variant="Body/Supporting text (caption)/smRegular">
<dd>
{intl.formatMessage(
{ id: "{adults, plural, one {# adult} other {# adults}}" },
{
defaultMessage:
"{adults, plural, one {# adult} other {# adults}}",
},
{ adults: booking.adults }
)}
{booking.childrenAges.length > 0 && (
@@ -99,7 +130,8 @@ export default async function Footer({ booking, room }: FooterProps) {
{", "}
{intl.formatMessage(
{
id: "{children, plural, one {# child} other {# children}}",
defaultMessage:
"{children, plural, one {# child} other {# children}}",
},
{ children: booking.childrenAges.length }
)}
@@ -111,7 +143,11 @@ export default async function Footer({ booking, room }: FooterProps) {
<div>
<Typography variant="Body/Supporting text (caption)/smRegular">
<dt>{intl.formatMessage({ id: "Bed type" })}</dt>
<dt>
{intl.formatMessage({
defaultMessage: "Bed type",
})}
</dt>
</Typography>
<Typography variant="Body/Supporting text (caption)/smRegular">
<dd>{room?.bedType.mainBed.description}</dd>
@@ -121,23 +157,39 @@ export default async function Footer({ booking, room }: FooterProps) {
{petRoomPackage && (
<div>
<Typography variant="Body/Supporting text (caption)/smRegular">
<dt>{intl.formatMessage({ id: "Room classification" })}</dt>
<dt>
{intl.formatMessage({
defaultMessage: "Room classification",
})}
</dt>
</Typography>
<Typography variant="Body/Supporting text (caption)/smRegular">
<dd>{intl.formatMessage({ id: "Pet-friendly" })}</dd>
<dd>
{intl.formatMessage({
defaultMessage: "Pet-friendly",
})}
</dd>
</Typography>
</div>
)}
<div>
<Typography variant="Body/Supporting text (caption)/smRegular">
<dt>{intl.formatMessage({ id: "Breakfast" })}</dt>
<dt>
{intl.formatMessage({
defaultMessage: "Breakfast",
})}
</dt>
</Typography>
<Typography variant="Body/Supporting text (caption)/smRegular">
<dd>
{booking.rateDefinition.breakfastIncluded
? intl.formatMessage({ id: "Included" })
: intl.formatMessage({ id: "Not included" })}
? intl.formatMessage({
defaultMessage: "Included",
})
: intl.formatMessage({
defaultMessage: "Not included",
})}
</dd>
</Typography>
</div>

View File

@@ -40,7 +40,9 @@ export default async function Specification({
: ""
const breakfastPointsString =
breakfastTotalPriceInPoints > 0
? `${breakfastTotalPriceInPoints} ${intl.formatMessage({ id: "Points" })}`
? `${breakfastTotalPriceInPoints} ${intl.formatMessage({
defaultMessage: "Points",
})}`
: ""
const breakfastPlusString =
breakfastMoneyString && breakfastPointsString ? " + " : ""
@@ -59,23 +61,36 @@ export default async function Specification({
{/****** The room ********/}
<Typography variant="Body/Supporting text (caption)/smBold">
<span>
{intl.formatMessage({ id: "Accommodation" })}
{intl.formatMessage({
defaultMessage: "Accommodation",
})}
{!booking.rateDefinition.mustBeGuaranteed && (
<>
{" - "}
{intl.formatMessage({ id: "Room is prepaid" })}
{intl.formatMessage({
defaultMessage: "Room is prepaid",
})}
</>
)}
</span>
</Typography>
<dl className={styles.dl}>
<Typography variant="Body/Supporting text (caption)/smRegular">
<dt>{intl.formatMessage({ id: "Price including VAT" })}</dt>
<dt>
{intl.formatMessage({
defaultMessage: "Price including VAT",
})}
</dt>
</Typography>
<Typography variant="Body/Supporting text (caption)/smRegular">
<dd>
{!booking.rateDefinition.mustBeGuaranteed &&
`(${intl.formatMessage({ id: "PREPAID" })}) `}
{!booking.rateDefinition.mustBeGuaranteed
? // eslint-disable-next-line formatjs/no-literal-string-in-jsx
`(${intl.formatMessage({
defaultMessage: "PREPAID",
})}) `
: null}
{/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}
{`${booking.roomPrice} ${currency}`}
</dd>
</Typography>
@@ -84,10 +99,13 @@ export default async function Specification({
<>
<Typography variant="Body/Supporting text (caption)/smRegular">
<dt>
{intl.formatMessage({ id: "Pet room charge including VAT" })}
{intl.formatMessage({
defaultMessage: "Pet room charge including VAT",
})}
</dt>
</Typography>
<Typography variant="Body/Supporting text (caption)/smRegular">
{/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}
<dd>{`${petRoomPackage.totalPrice} ${petRoomPackage.currency}`}</dd>
</Typography>
</>
@@ -95,24 +113,32 @@ export default async function Specification({
<Typography variant="Body/Supporting text (caption)/smRegular">
<dt className={styles.tertiary}>
{intl.formatMessage({ id: "Price excluding VAT" })}
{intl.formatMessage({
defaultMessage: "Price excluding VAT",
})}
</dt>
</Typography>
<Typography variant="Body/Supporting text (caption)/smRegular">
<dd
className={styles.tertiary}
>{`${roomPriceExclVat.toFixed(2)} ${currency}`}</dd>
<dd className={styles.tertiary}>
{/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}
{`${roomPriceExclVat.toFixed(2)} ${currency}`}
</dd>
</Typography>
<Typography variant="Body/Supporting text (caption)/smRegular">
<dt className={styles.tertiary}>
{intl.formatMessage({ id: "VAT" })} {booking.vatPercentage} %
{intl.formatMessage({
defaultMessage: "VAT",
})}
{/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}
{` ${booking.vatPercentage} %`}
</dt>
</Typography>
<Typography variant="Body/Supporting text (caption)/smRegular">
<dd
className={styles.tertiary}
>{`${roomPriceVat.toFixed(2)} ${currency}`}</dd>
<dd className={styles.tertiary}>
{/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}
{`${roomPriceVat.toFixed(2)} ${currency}`}
</dd>
</Typography>
</dl>
</div>
@@ -131,11 +157,17 @@ export default async function Specification({
aa.id === ancillary.code ||
aa.loyaltyCode === ancillary.code
)
)[0]?.title ?? intl.formatMessage({ id: "Unknown item" })}
)[0]?.title ??
intl.formatMessage({
defaultMessage: "Unknown item",
})}
</span>
</Typography>
<Typography variant="Body/Supporting text (caption)/smBold">
<span>{`x ${ancillary.unit}`}</span>
<span>
{/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}
{`× ${ancillary.unit}`}
</span>
</Typography>
</div>
@@ -143,12 +175,19 @@ export default async function Specification({
<Typography variant="Body/Supporting text (caption)/smRegular">
<dt>
{ancillary.currency !== CurrencyEnum.POINTS
? intl.formatMessage({ id: "Price including VAT" })
: intl.formatMessage({ id: "Price" })}
? intl.formatMessage({
defaultMessage: "Price including VAT",
})
: intl.formatMessage({
defaultMessage: "Price",
})}
</dt>
</Typography>
<Typography variant="Body/Supporting text (caption)/smRegular">
<dd>{`${ancillary.totalPrice} ${ancillary.currency}`}</dd>
<dd>
{/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}
{`${ancillary.totalPrice} ${ancillary.currency}`}
</dd>
</Typography>
</dl>
</div>
@@ -162,10 +201,15 @@ export default async function Specification({
<div>
<div className={styles.quantifyingHeader}>
<Typography variant="Body/Supporting text (caption)/smBold">
<span>{intl.formatMessage({ id: "Breakfast" })}</span>
<span>
{intl.formatMessage({
defaultMessage: "Breakfast",
})}
</span>
</Typography>
<Typography variant="Body/Supporting text (caption)/smBold">
<span>{`x ${breakfastCount}`}</span>
{/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}
<span>{`× ${breakfastCount}`}</span>
</Typography>
</div>
@@ -173,12 +217,19 @@ export default async function Specification({
<Typography variant="Body/Supporting text (caption)/smRegular">
<dt>
{breakfastTotalPriceInMoney > 0
? intl.formatMessage({ id: "Price including VAT" })
: intl.formatMessage({ id: "Price" })}
? intl.formatMessage({
defaultMessage: "Price including VAT",
})
: intl.formatMessage({
defaultMessage: "Price",
})}
</dt>
</Typography>
<Typography variant="Body/Supporting text (caption)/smRegular">
<dd>{`${breakfastMoneyString}${breakfastPlusString}${breakfastPointsString}`}</dd>
<dd>
{/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}
{`${breakfastMoneyString}${breakfastPlusString}${breakfastPointsString}`}
</dd>
</Typography>
</dl>
</div>

View File

@@ -22,7 +22,9 @@ export default async function Total({ booking, currency }: TotalProps) {
totalPriceInMoney > 0 ? `${totalPriceInMoney} ${currency}` : ""
const pointsString =
totalPriceInPoints > 0
? `${totalPriceInPoints} ${intl.formatMessage({ id: "Points" })}`
? `${totalPriceInPoints} ${intl.formatMessage({
defaultMessage: "Points",
})}`
: ""
const plusString = moneyString && pointsString ? " + " : ""
@@ -33,11 +35,14 @@ export default async function Total({ booking, currency }: TotalProps) {
<Typography>
<div>
<span className={styles.title}>
{intl.formatMessage({ id: "Preliminary receipt" })}
{intl.formatMessage({
defaultMessage: "Preliminary receipt",
})}
</span>
<span className={styles.titleSubtext}>
{intl.formatMessage({
id: "Final VAT breakdown will be provided at check-out.",
defaultMessage:
"Final VAT breakdown will be provided at check-out.",
})}
</span>
</div>
@@ -46,9 +51,14 @@ export default async function Total({ booking, currency }: TotalProps) {
<Divider color="subtle" />
<dl className={styles.dl}>
<Typography>
<dt>{intl.formatMessage({ id: "Total including VAT" })}</dt>
<dt>
{intl.formatMessage({
defaultMessage: "Total including VAT",
})}
</dt>
</Typography>
<Typography>
{/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}
<dd>{`${moneyString}${plusString}${pointsString}`}</dd>
</Typography>
@@ -56,13 +66,16 @@ export default async function Total({ booking, currency }: TotalProps) {
<>
<Typography>
<dt className={styles.tertiary}>
{intl.formatMessage({ id: "Total excluding VAT" })}
{intl.formatMessage({
defaultMessage: "Total excluding VAT",
})}
</dt>
</Typography>
<Typography>
<dd
className={styles.tertiary}
>{`${totalPriceInMoneyExclVat} ${currency}`}</dd>
<dd className={styles.tertiary}>
{/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}
{`${totalPriceInMoneyExclVat} ${currency}`}
</dd>
</Typography>
</>
)}
@@ -71,11 +84,16 @@ export default async function Total({ booking, currency }: TotalProps) {
<>
<Typography>
<dt className={styles.tertiary}>
{intl.formatMessage({ id: "VAT" })}
{intl.formatMessage({
defaultMessage: "VAT",
})}
</dt>
</Typography>
<Typography>
<dd className={styles.tertiary}>{`${totalVat} ${currency}`}</dd>
<dd className={styles.tertiary}>
{/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}
{`${totalVat} ${currency}`}
</dd>
</Typography>
</>
)}

View File

@@ -72,6 +72,7 @@ export async function Receipt({ refId }: { refId: string }) {
</Typography>
<Typography variant="Body/Supporting text (caption)/smRegular">
<div>
{/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}
{`${hotel.address.streetAddress}, ${hotel.address.zipCode} ${hotel.address.city}`}
</div>
</Typography>
@@ -88,11 +89,15 @@ export async function Receipt({ refId }: { refId: string }) {
</div>
<div className={styles.rightColumn}>
<Typography variant="Body/Supporting text (caption)/smRegular">
{/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}
<div>{`${booking.guest.firstName} ${booking.guest.lastName}`}</div>
</Typography>
{booking.guest.membershipNumber && (
<Typography variant="Body/Supporting text (caption)/smRegular">
<div>{`${intl.formatMessage({ id: "Member" })} ${booking.guest.membershipNumber}`}</div>
{/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}
<div>{`${intl.formatMessage({
defaultMessage: "Member",
})} ${booking.guest.membershipNumber}`}</div>
</Typography>
)}
<Typography variant="Body/Supporting text (caption)/smRegular">
@@ -142,14 +147,15 @@ export async function Receipt({ refId }: { refId: string }) {
<Typography variant="Title/md">
<h1>
{intl.formatMessage({
id: "You need to be logged in to view your booking",
defaultMessage: "You need to be logged in to view your booking",
})}
</h1>
</Typography>
<Typography variant="Body/Lead text">
<p>
{intl.formatMessage({
id: "And you need to be logged in with the same member account that made the booking.",
defaultMessage:
"And you need to be logged in with the same member account that made the booking.",
})}
</p>
</Typography>

View File

@@ -120,7 +120,9 @@ export function ReferenceCard({
const allRoomsCancelled = allRooms.every((room) => room.isCancelled)
const adultsMsg = intl.formatMessage(
{ id: "{adults, plural, one {# adult} other {# adults}}" },
{
defaultMessage: "{adults, plural, one {# adult} other {# adults}}",
},
{
adults: adults,
}
@@ -128,7 +130,7 @@ export function ReferenceCard({
const childrenMsg = intl.formatMessage(
{
id: "{children, plural, one {# child} other {# children}}",
defaultMessage: "{children, plural, one {# child} other {# children}}",
},
{
children: children,
@@ -136,16 +138,22 @@ export function ReferenceCard({
)
const cancelledRoomsMsg = intl.formatMessage(
{ id: "{rooms, plural, one {# room} other {# rooms}}" },
{
defaultMessage: "{rooms, plural, one {# room} other {# rooms}}",
},
{
rooms: cancelledRooms,
}
)
const roomCancelledRoomsMsg = intl.formatMessage({ id: "Room cancelled" })
const roomCancelledRoomsMsg = intl.formatMessage({
defaultMessage: "Room cancelled",
})
const roomsMsg = intl.formatMessage(
{ id: "{rooms, plural, one {# room} other {# rooms}}" },
{
defaultMessage: "{rooms, plural, one {# room} other {# rooms}}",
},
{
rooms: allRooms.filter((room) => !room.isCancelled).length,
}
@@ -163,15 +171,21 @@ export function ReferenceCard({
<>
<div className={styles.referenceRow}>
<Subtitle color="uiTextHighContrast" className={styles.titleMobile}>
{intl.formatMessage({ id: "Reference" })}
{intl.formatMessage({
defaultMessage: "Reference",
})}
</Subtitle>
<Subtitle
color="uiTextHighContrast"
className={styles.titleDesktop}
>
{isCancelled && !isMultiRoom
? intl.formatMessage({ id: "Cancellation number" })
: intl.formatMessage({ id: "Reference number" })}
? intl.formatMessage({
defaultMessage: "Cancellation number",
})
: intl.formatMessage({
defaultMessage: "Reference number",
})}
</Subtitle>
<Subtitle color="uiTextHighContrast">
{isCancelled && !isMultiRoom
@@ -187,7 +201,11 @@ export function ReferenceCard({
{!allRoomsCancelled && (
<div className={styles.referenceRow}>
<Typography variant="Title/Overline/sm">
<p>{intl.formatMessage({ id: "Guests" })}</p>
<p>
{intl.formatMessage({
defaultMessage: "Guests",
})}
</p>
</Typography>
<Typography variant="Body/Paragraph/mdBold">
<p>
@@ -205,12 +223,19 @@ export function ReferenceCard({
{allRooms.some((room) => room.isCancelled) && (
<div className={styles.referenceRow}>
<Typography variant="Title/Overline/sm">
<p>{intl.formatMessage({ id: "Cancellation" })}</p>
<p>
{intl.formatMessage({
defaultMessage: "Cancellation",
})}
</p>
</Typography>
<Typography variant="Body/Paragraph/mdBold">
<p className={styles.cancelledRooms}>
{isMultiRoom
? `${cancelledRoomsMsg} ${intl.formatMessage({ id: "cancelled" })}`
? // eslint-disable-next-line formatjs/no-literal-string-in-jsx
`${cancelledRoomsMsg} ${intl.formatMessage({
defaultMessage: "cancelled",
})}`
: roomCancelledRoomsMsg}
</p>
</Typography>
@@ -220,21 +245,39 @@ export function ReferenceCard({
<>
<div className={styles.referenceRow}>
<Typography variant="Title/Overline/sm">
<p>{intl.formatMessage({ id: "Check-in" })}</p>
<p>
{intl.formatMessage({
defaultMessage: "Check-in",
})}
</p>
</Typography>
<Typography variant="Body/Paragraph/mdBold">
<p>
{`${dt(checkInDate).locale(lang).format("dddd, D MMMM")} ${intl.formatMessage({ id: "from" })} ${hotel.hotelFacts.checkin.checkInTime}`}
{/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}
{`${dt(checkInDate).locale(lang).format("dddd, D MMMM")} ${intl.formatMessage(
{
defaultMessage: "from",
}
)} ${hotel.hotelFacts.checkin.checkInTime}`}
</p>
</Typography>
</div>
<div className={styles.referenceRow}>
<Typography variant="Title/Overline/sm">
<p>{intl.formatMessage({ id: "Check-out" })}</p>
<p>
{intl.formatMessage({
defaultMessage: "Check-out",
})}
</p>
</Typography>
<Typography variant="Body/Paragraph/mdBold">
<p>
{`${dt(checkOutDate).locale(lang).format("dddd, D MMMM")} ${intl.formatMessage({ id: "until" })} ${hotel.hotelFacts.checkin.checkOutTime}`}
{/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}
{`${dt(checkOutDate).locale(lang).format("dddd, D MMMM")} ${intl.formatMessage(
{
defaultMessage: "until",
}
)} ${hotel.hotelFacts.checkin.checkOutTime}`}
</p>
</Typography>
</div>
@@ -252,10 +295,15 @@ export function ReferenceCard({
<Typography variant="Body/Supporting text (caption)/smRegular">
<p className={styles.guaranteedText}>
<strong>
{intl.formatMessage({ id: "Booking guaranteed." })}
</strong>{" "}
{intl.formatMessage({
defaultMessage: "Booking guaranteed.",
})}
</strong>
{/* eslint-disable formatjs/no-literal-string-in-jsx */}{" "}
{/* eslint-enable formatjs/no-literal-string-in-jsx */}
{intl.formatMessage({
id: "Your stay remains available for check-in after 18:00.",
defaultMessage:
"Your stay remains available for check-in after 18:00.",
})}
</p>
</Typography>
@@ -266,14 +314,22 @@ export function ReferenceCard({
<div className={styles.referenceRow}>
<Typography variant="Title/Overline/sm">
<p>{intl.formatMessage({ id: "Total" })}</p>
<p>
{intl.formatMessage({
defaultMessage: "Total",
})}
</p>
</Typography>
<TotalPrice variant="Title/Subtitle/md" type={priceType} />
</div>
{bookingCode && (
<div className={styles.referenceRow}>
<Typography variant="Title/Overline/sm">
<p>{intl.formatMessage({ id: "Booking code" })}</p>
<p>
{intl.formatMessage({
defaultMessage: "Booking code",
})}
</p>
</Typography>
<Typography variant="Body/Supporting text (caption)/smBold">
<IconChip
@@ -281,11 +337,14 @@ export function ReferenceCard({
icon={<DiscountIcon color="Icon/Feedback/Information" />}
>
{intl.formatMessage(
{ id: "<strong>Booking code</strong>: {value}" },
{
defaultMessage: "<strong>Booking code</strong>: {value}",
},
{
value: bookingCode,
strong: (text) => (
<Typography variant="Body/Supporting text (caption)/smBold">
{/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}
<strong>{text}</strong>
</Typography>
),
@@ -304,14 +363,18 @@ export function ReferenceCard({
/>
<Button fullWidth intent="secondary" asChild size="small">
<Link href={directionsUrl} target="_blank">
{intl.formatMessage({ id: "Get directions" })}
{intl.formatMessage({
defaultMessage: "Get directions",
})}
</Link>
</Button>
</div>
{isMultiRoom && (
<Typography variant="Body/Supporting text (caption)/smBold">
<p className={styles.note}>
{intl.formatMessage({ id: "Multi-room stay" })}
{intl.formatMessage({
defaultMessage: "Multi-room stay",
})}
</p>
</Typography>
)}
@@ -323,6 +386,7 @@ export function ReferenceCard({
{rateDefinition.generalTerms.map((term) => (
<span key={term}>
{term}
{/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}
{term.endsWith(".") ? " " : ". "}
</span>
))}

Some files were not shown because too many files have changed in this diff Show More