fix: align price formatting

This commit is contained in:
Christel Westerberg
2025-01-02 10:54:19 +01:00
parent 4f58784a22
commit 139accb8ed
26 changed files with 198 additions and 193 deletions

View File

@@ -8,6 +8,7 @@ import Button from "@/components/TempDesignSystem/Button"
import Body from "@/components/TempDesignSystem/Text/Body"
import Subtitle from "@/components/TempDesignSystem/Text/Subtitle"
import useLang from "@/hooks/useLang"
import { formatPrice } from "@/utils/numberFormatting"
import styles from "./paymentDetails.module.css"
@@ -25,10 +26,7 @@ export default function PaymentDetails({
</Subtitle>
<div className={styles.payment}>
<Body color="uiTextHighContrast">
{intl.formatNumber(booking.totalPrice, {
currency: booking.currencyCode,
style: "currency",
})}{" "}
{formatPrice(intl, booking.totalPrice, booking.currencyCode)}{" "}
{intl.formatMessage({ id: "has been paid" })}
</Body>
<Body color="uiTextHighContrast">

View File

@@ -9,6 +9,7 @@ import Link from "@/components/TempDesignSystem/Link"
import Body from "@/components/TempDesignSystem/Text/Body"
import Caption from "@/components/TempDesignSystem/Text/Caption"
import Subtitle from "@/components/TempDesignSystem/Text/Subtitle"
import { formatPrice } from "@/utils/numberFormatting"
import styles from "./receipt.module.css"
@@ -44,18 +45,12 @@ export default function Receipt({
<s>N/A</s>
</Body>
<Body color="red">
{intl.formatNumber(booking.roomPrice, {
currency: booking.currencyCode,
style: "currency",
})}
{formatPrice(intl, booking.roomPrice, booking.currencyCode)}
</Body>
</div>
) : (
<Body color="uiTextHighContrast">
{intl.formatNumber(booking.roomPrice, {
currency: booking.currencyCode,
style: "currency",
})}
{formatPrice(intl, booking.roomPrice, booking.currencyCode)}
</Body>
)}
<Caption color="uiTextMediumContrast">
@@ -83,10 +78,7 @@ export default function Receipt({
<div className={styles.entry}>
<Body color="uiTextHighContrast">{room.bedType.description}</Body>
<Body color="uiTextHighContrast">
{intl.formatNumber(0, {
currency: booking.currencyCode,
style: "currency",
})}
{formatPrice(intl, 0, booking.currencyCode)}
</Body>
</div>
<div className={styles.entry}>
@@ -97,10 +89,11 @@ export default function Receipt({
{breakfastPkgSelected ? (
<Body color="uiTextHighContrast">
{intl.formatNumber(breakfastPkgSelected.totalPrice, {
currency: breakfastPkgSelected.currency,
style: "currency",
})}
{formatPrice(
intl,
breakfastPkgSelected.totalPrice,
breakfastPkgSelected.currency
)}
</Body>
) : null}
</div>
@@ -112,10 +105,7 @@ export default function Receipt({
{intl.formatMessage({ id: "Total price" })}
</Body>
<Body textTransform="bold">
{intl.formatNumber(booking.totalPrice, {
currency: booking.currencyCode,
style: "currency",
})}
{formatPrice(intl, booking.totalPrice, booking.currencyCode)}
</Body>
</div>
<div className={styles.entry}>

View File

@@ -10,6 +10,7 @@ import { useEnterDetailsStore } from "@/stores/enter-details"
import { Highlight } from "@/components/TempDesignSystem/Form/ChoiceCard/_Card"
import RadioCard from "@/components/TempDesignSystem/Form/ChoiceCard/Radio"
import Body from "@/components/TempDesignSystem/Text/Body"
import { formatPrice } from "@/utils/numberFormatting"
import { breakfastFormSchema } from "./schema"
@@ -91,7 +92,11 @@ export default function Breakfast({ packages }: BreakfastProps) {
? intl.formatMessage<React.ReactNode>(
{ id: "breakfast.price.free" },
{
amount: pkg.localPrice.price,
amount: formatPrice(
intl,
parseInt(pkg.localPrice.price),
pkg.localPrice.currency
),
currency: pkg.localPrice.currency,
free: (str) => <Highlight>{str}</Highlight>,
strikethrough: (str) => <s>{str}</s>,
@@ -100,8 +105,11 @@ export default function Breakfast({ packages }: BreakfastProps) {
: intl.formatMessage(
{ id: "breakfast.price" },
{
amount: pkg.localPrice.price,
currency: pkg.localPrice.currency,
amount: formatPrice(
intl,
parseInt(pkg.localPrice.price),
pkg.localPrice.currency
),
}
)
}
@@ -114,13 +122,7 @@ export default function Breakfast({ packages }: BreakfastProps) {
))}
<RadioCard
name="breakfast"
subtitle={intl.formatMessage(
{ id: "{amount} {currency}" },
{
amount: "0",
currency: packages[0].localPrice.currency,
}
)}
subtitle={formatPrice(intl, 0, packages[0].localPrice.currency)}
text={intl.formatMessage({
id: "You can always change your mind later and add breakfast at the hotel.",
})}

View File

@@ -11,6 +11,7 @@ import Link from "@/components/TempDesignSystem/Link"
import Caption from "@/components/TempDesignSystem/Text/Caption"
import Footnote from "@/components/TempDesignSystem/Text/Footnote"
import useLang from "@/hooks/useLang"
import { formatPrice } from "@/utils/numberFormatting"
import styles from "./joinScandicFriendsCard.module.css"
@@ -31,11 +32,14 @@ export default function JoinScandicFriendsCard({
const saveOnJoiningLabel = intl.formatMessage(
{
id: "Only pay {amount} {currency}",
id: "Only pay {amount}",
},
{
amount: intl.formatNumber(memberPrice?.price ?? 0),
currency: memberPrice?.currency ?? "SEK",
amount: formatPrice(
intl,
memberPrice?.price ?? 0,
memberPrice?.currency ?? "SEK"
),
}
)

View File

@@ -9,6 +9,7 @@ import Button from "@/components/TempDesignSystem/Button"
import Body from "@/components/TempDesignSystem/Text/Body"
import Subtitle from "@/components/TempDesignSystem/Text/Subtitle"
import Title from "@/components/TempDesignSystem/Text/Title"
import { formatPrice } from "@/utils/numberFormatting"
import Modal from "../../Modal"
@@ -47,10 +48,11 @@ export default function MemberPriceModal({
})}
</Body>
<Subtitle type="two" color="red">
{intl.formatNumber(memberPrice.pricePerStay, {
currency: memberPrice.currency,
style: "currency",
})}
{formatPrice(
intl,
memberPrice.pricePerStay,
memberPrice.currency
)}
</Subtitle>
</span>
)}

View File

@@ -2,7 +2,7 @@ import Image from "@/components/Image"
import Caption from "@/components/TempDesignSystem/Text/Caption"
import Title from "@/components/TempDesignSystem/Text/Title"
import { getIntl } from "@/i18n"
import getSingleDecimal from "@/utils/numberFormatting"
import { getSingleDecimal } from "@/utils/numberFormatting"
import ToggleSidePeek from "./ToggleSidePeek"

View File

@@ -5,6 +5,7 @@ import { InfoCircleIcon } from "@/components/Icons"
import Button from "@/components/TempDesignSystem/Button"
import Body from "@/components/TempDesignSystem/Text/Body"
import Title from "@/components/TempDesignSystem/Text/Title"
import { formatPrice } from "@/utils/numberFormatting"
import styles from "./priceChangeDialog.module.css"
@@ -51,10 +52,10 @@ export default function PriceChangeDialog({
})}
<br />
<span className={styles.oldPrice}>
{intl.formatNumber(oldPrice, { style: "currency", currency })}
{formatPrice(intl, oldPrice, currency)}
</span>{" "}
<strong className={styles.newPrice}>
{intl.formatNumber(newPrice, { style: "currency", currency })}
{formatPrice(intl, newPrice, currency)}
</strong>
</Body>
</header>

View File

@@ -9,6 +9,7 @@ import { formId } from "@/components/HotelReservation/EnterDetails/Payment/Payme
import Button from "@/components/TempDesignSystem/Button"
import Caption from "@/components/TempDesignSystem/Text/Caption"
import Subtitle from "@/components/TempDesignSystem/Text/Subtitle"
import { formatPrice } from "@/utils/numberFormatting"
import styles from "./bottomSheet.module.css"
@@ -56,12 +57,10 @@ export default function SummaryBottomSheet({ children }: PropsWithChildren) {
>
<Caption>{intl.formatMessage({ id: "Total price" })}:</Caption>
<Subtitle>
{intl.formatMessage(
{ id: "{amount} {currency}" },
{
amount: intl.formatNumber(totalPrice.local.price),
currency: totalPrice.local.currency,
}
{formatPrice(
intl,
totalPrice.local.price,
totalPrice.local.currency
)}
</Subtitle>
<Caption color="baseTextHighContrast" type="underline">

View File

@@ -9,6 +9,7 @@ import Body from "@/components/TempDesignSystem/Text/Body"
import Caption from "@/components/TempDesignSystem/Text/Caption"
import useLang from "@/hooks/useLang"
import { getNights } from "@/utils/dateFormatting"
import { formatPrice } from "@/utils/numberFormatting"
import styles from "./priceDetailsTable.module.css"
@@ -47,13 +48,9 @@ export function storeSelector(state: DetailsState) {
bedType: state.bedType,
booking: state.booking,
breakfast: state.breakfast,
join: state.guest.join,
membershipNo: state.guest.membershipNo,
packages: state.packages,
roomRate: state.roomRate,
roomPrice: state.roomPrice,
toggleSummaryOpen: state.actions.toggleSummaryOpen,
togglePriceDetailsModalOpen: state.actions.togglePriceDetailsModalOpen,
totalPrice: state.totalPrice,
vat: state.vat,
}
@@ -65,20 +62,8 @@ export default function PriceDetailsTable({
const intl = useIntl()
const lang = useLang()
const {
bedType,
booking,
breakfast,
join,
membershipNo,
packages,
roomPrice,
roomRate,
toggleSummaryOpen,
togglePriceDetailsModalOpen,
totalPrice,
vat,
} = useEnterDetailsStore(storeSelector)
const { bedType, booking, breakfast, roomPrice, totalPrice, vat } =
useEnterDetailsStore(storeSelector)
// TODO: Update for Multiroom later
const { adults, children } = booking.rooms[0]
@@ -98,10 +83,11 @@ export default function PriceDetailsTable({
<Row
key={night.format("YYMMDD")}
label={dt(night).locale(lang).format("ddd, D MMM YYYY")}
value={intl.formatNumber(roomPrice.perNight.local.price, {
currency: roomPrice.perNight.local.currency,
style: "currency",
})}
value={formatPrice(
intl,
roomPrice.perNight.local.price,
roomPrice.perNight.local.currency
)}
/>
)
})}
@@ -110,10 +96,7 @@ export default function PriceDetailsTable({
<TableSection>
<Row
label={bedType.description}
value={intl.formatNumber(0, {
currency: roomPrice.perStay.local.currency,
style: "currency",
})}
value={formatPrice(intl, 0, roomPrice.perStay.local.currency)}
/>
</TableSection>
) : null}
@@ -125,12 +108,10 @@ export default function PriceDetailsTable({
{ id: "booking.adults.breakfasts" },
{ totalAdults: adults, totalBreakfasts: nights.length }
)}
value={intl.formatNumber(
value={formatPrice(
intl,
parseInt(breakfast.localPrice.totalPrice),
{
currency: breakfast.localPrice.currency,
style: "currency",
}
breakfast.localPrice.currency
)}
/>
{children?.length ? (
@@ -142,10 +123,7 @@ export default function PriceDetailsTable({
totalBreakfasts: nights.length,
}
)}
value={intl.formatNumber(0, {
currency: breakfast.localPrice.currency,
style: "currency",
})}
value={formatPrice(intl, 0, breakfast.localPrice.currency)}
/>
) : null}
</TableSection>
@@ -154,17 +132,11 @@ export default function PriceDetailsTable({
<TableSectionHeader title={intl.formatMessage({ id: "Total" })} />
<Row
label={intl.formatMessage({ id: "booking.vat.excl" })}
value={intl.formatNumber(priceExclVat, {
currency: totalPrice.local.currency,
style: "currency",
})}
value={formatPrice(intl, priceExclVat, totalPrice.local.currency)}
/>
<Row
label={intl.formatMessage({ id: "booking.vat" }, { vat })}
value={intl.formatNumber(vatAmount, {
currency: totalPrice.local.currency,
style: "currency",
})}
value={formatPrice(intl, vatAmount, totalPrice.local.currency)}
/>
<tr className={styles.row}>
<td>
@@ -174,10 +146,11 @@ export default function PriceDetailsTable({
</td>
<td className={styles.price}>
<Body textTransform="bold">
{intl.formatNumber(totalPrice.local.price, {
currency: totalPrice.local.currency,
style: "currency",
})}
{formatPrice(
intl,
totalPrice.local.price,
totalPrice.local.currency
)}
</Body>
</td>
</tr>

View File

@@ -18,7 +18,7 @@ import Body from "@/components/TempDesignSystem/Text/Body"
import Caption from "@/components/TempDesignSystem/Text/Caption"
import Subtitle from "@/components/TempDesignSystem/Text/Subtitle"
import useLang from "@/hooks/useLang"
import { getNights } from "@/utils/dateFormatting"
import { formatPrice } from "@/utils/numberFormatting"
import Modal from "../../Modal"
import PriceDetailsTable from "../PriceDetailsTable"
@@ -148,10 +148,11 @@ export default function SummaryUI({
<div className={styles.entry}>
<Body color="uiTextHighContrast">{roomType}</Body>
<Body color={showMemberPrice ? "red" : "uiTextHighContrast"}>
{intl.formatNumber(roomPrice.perStay.local.price, {
currency: roomPrice.perStay.local.currency,
style: "currency",
})}
{formatPrice(
intl,
roomPrice.perStay.local.price,
roomPrice.perStay.local.currency
)}
</Body>
</div>
<Caption color="uiTextMediumContrast">
@@ -196,10 +197,11 @@ export default function SummaryUI({
</div>
<Body color="uiTextHighContrast">
{intl.formatNumber(parseInt(roomPackage.localPrice.price), {
currency: roomPackage.localPrice.currency,
style: "currency",
})}
{formatPrice(
intl,
parseInt(roomPackage.localPrice.price),
roomPackage.localPrice.currency
)}
</Body>
</div>
))
@@ -209,10 +211,7 @@ export default function SummaryUI({
<Body color="uiTextHighContrast">{bedType.description}</Body>
<Body color="uiTextHighContrast">
{intl.formatNumber(0, {
currency: roomPrice.perStay.local.currency,
style: "currency",
})}
{formatPrice(intl, 0, roomPrice.perStay.local.currency)}
</Body>
</div>
) : null}
@@ -227,10 +226,7 @@ export default function SummaryUI({
</Caption>
</div>
<Body color="uiTextHighContrast">
{intl.formatNumber(0, {
currency: roomPrice.perStay.local.currency,
style: "currency",
})}
{formatPrice(intl, 0, roomPrice.perStay.local.currency)}
</Body>
</div>
) : null}
@@ -242,10 +238,7 @@ export default function SummaryUI({
</Body>
</div>
<Body color="uiTextHighContrast">
{intl.formatNumber(0, {
currency: roomPrice.perStay.local.currency,
style: "currency",
})}
{formatPrice(intl, 0, roomPrice.perStay.local.currency)}
</Body>
</div>
) : null}
@@ -255,10 +248,7 @@ export default function SummaryUI({
{intl.formatMessage({ id: "No breakfast" })}
</Body>
<Body color="uiTextHighContrast">
{intl.formatNumber(0, {
currency: roomPrice.perStay.local.currency,
style: "currency",
})}
{formatPrice(intl, 0, roomPrice.perStay.local.currency)}
</Body>
</div>
) : null}
@@ -275,10 +265,11 @@ export default function SummaryUI({
)}
</Caption>
<Body color="uiTextHighContrast">
{intl.formatNumber(parseInt(breakfast.localPrice.totalPrice), {
currency: breakfast.localPrice.currency,
style: "currency",
})}
{formatPrice(
intl,
parseInt(breakfast.localPrice.totalPrice),
breakfast.localPrice.currency
)}
</Body>
</div>
{children?.length ? (
@@ -290,10 +281,7 @@ export default function SummaryUI({
)}
</Caption>
<Body color="uiTextHighContrast">
{intl.formatNumber(0, {
currency: breakfast.localPrice.currency,
style: "currency",
})}
{formatPrice(intl, 0, breakfast.localPrice.currency)}
</Body>
</div>
) : null}
@@ -331,18 +319,20 @@ export default function SummaryUI({
</div>
<div>
<Body textTransform="bold">
{intl.formatNumber(totalPrice.local.price, {
currency: totalPrice.local.currency,
style: "currency",
})}
{formatPrice(
intl,
totalPrice.local.price,
totalPrice.local.currency
)}
</Body>
{totalPrice.requested && (
<Caption color="uiTextMediumContrast">
{intl.formatMessage({ id: "Approx." })}{" "}
{intl.formatNumber(totalPrice.requested.price, {
currency: totalPrice.requested.currency,
style: "currency",
})}
{formatPrice(
intl,
totalPrice.requested.price,
totalPrice.requested.currency
)}
</Caption>
)}
</div>

View File

@@ -15,7 +15,7 @@ import Link from "@/components/TempDesignSystem/Link"
import Body from "@/components/TempDesignSystem/Text/Body"
import Caption from "@/components/TempDesignSystem/Text/Caption"
import Subtitle from "@/components/TempDesignSystem/Text/Subtitle"
import getSingleDecimal from "@/utils/numberFormatting"
import { getSingleDecimal } from "@/utils/numberFormatting"
import ReadMore from "../ReadMore"
import TripAdvisorChip from "../TripAdvisorChip"

View File

@@ -10,7 +10,7 @@ import Body from "@/components/TempDesignSystem/Text/Body"
import Caption from "@/components/TempDesignSystem/Text/Caption"
import Title from "@/components/TempDesignSystem/Text/Title"
import { getIntl } from "@/i18n"
import getSingleDecimal from "@/utils/numberFormatting"
import { getSingleDecimal } from "@/utils/numberFormatting"
import ReadMore from "../../ReadMore"
import TripAdvisorChip from "../../TripAdvisorChip"

View File

@@ -10,6 +10,7 @@ import Body from "@/components/TempDesignSystem/Text/Body"
import Caption from "@/components/TempDesignSystem/Text/Caption"
import Footnote from "@/components/TempDesignSystem/Text/Footnote"
import Subtitle from "@/components/TempDesignSystem/Text/Subtitle"
import { formatPrice } from "@/utils/numberFormatting"
import styles from "./rateSummary.module.css"
@@ -48,9 +49,6 @@ export default function RateSummary({
(pkg) => pkg.code === RoomPackageCodeEnum.PET_ROOM
)
const petRoomPrice = petRoomPackage?.localPrice.totalPrice ?? null
const petRoomCurrency = petRoomPackage?.localPrice.currency ?? null
const checkInDate = new Date(roomsAvailability.checkInDate)
const checkOutDate = new Date(roomsAvailability.checkOutDate)
const nights = dt(checkOutDate).diff(dt(checkInDate), "days")
@@ -106,22 +104,33 @@ export default function RateSummary({
color={isUserLoggedIn ? "red" : "uiTextHighContrast"}
textAlign="right"
>
{priceToShow?.localPrice.pricePerStay}{" "}
{priceToShow?.localPrice.currency}
{formatPrice(
intl,
priceToShow.localPrice.pricePerStay,
priceToShow.localPrice.currency
)}
</Subtitle>
<Body color="uiTextMediumContrast">
{intl.formatMessage({ id: "Approx." })}{" "}
{priceToShow?.requestedPrice?.pricePerStay}{" "}
{priceToShow?.requestedPrice?.currency}
</Body>
{priceToShow?.requestedPrice ? (
<Body color="uiTextMediumContrast">
{intl.formatMessage({ id: "Approx." })}{" "}
{formatPrice(
intl,
priceToShow.requestedPrice.pricePerStay,
priceToShow.requestedPrice.currency
)}
</Body>
) : null}
</div>
<div className={styles.summaryPriceTextMobile}>
<Caption color="uiTextHighContrast">
{intl.formatMessage({ id: "Total price" })}
</Caption>
<Subtitle color={isUserLoggedIn ? "red" : "uiTextHighContrast"}>
{priceToShow?.localPrice.pricePerStay}{" "}
{priceToShow?.localPrice.currency}
{formatPrice(
intl,
priceToShow.localPrice.pricePerStay,
priceToShow.localPrice.currency
)}
</Subtitle>
<Footnote
color="uiTextMediumContrast"
@@ -130,14 +139,19 @@ export default function RateSummary({
{summaryPriceTex}
</Footnote>
</div>
{isPetRoomSelected && (
{isPetRoomSelected && petRoomPackage?.localPrice && (
<div className={styles.petInfo}>
<Body
color="uiTextHighContrast"
textTransform="bold"
textAlign="right"
>
+ {petRoomPrice} {petRoomCurrency}
+{" "}
{formatPrice(
intl,
parseInt(petRoomPackage.localPrice.totalPrice),
petRoomPackage.localPrice.currency
)}
</Body>
<Body color="uiTextMediumContrast" textAlign="right">
{intl.formatMessage({ id: "Pet charge" })}

View File

@@ -3,6 +3,7 @@ import { useIntl } from "react-intl"
import Caption from "@/components/TempDesignSystem/Text/Caption"
import Title from "@/components/TempDesignSystem/Text/Title"
import { formatPrice } from "@/utils/numberFormatting"
import styles from "./selectionCard.module.css"
@@ -29,15 +30,17 @@ export default function SelectionCard({
<div>
<Caption color="burgundy" className={styles.price}>
{/* TODO: Handle currency and this whole line of text in a better way through intl */}
{price} {currency}/{intl.formatMessage({ id: "night" })}
</Caption>
<Caption color="burgundy" className={styles.membersPrice}>
{/* TODO: Handle currency and this whole line of text in a better way through intl */}
{intl.formatMessage({ id: "Members" })} {membersPrice} {currency}/
{formatPrice(intl, price, currency)}/
{intl.formatMessage({ id: "night" })}
</Caption>
{membersPrice && (
<Caption color="burgundy" className={styles.membersPrice}>
{intl.formatMessage({ id: "Members" })}{" "}
{formatPrice(intl, membersPrice, currency)}/
{intl.formatMessage({ id: "night" })}
</Caption>
)}
</div>
</div>
)

View File

@@ -4,6 +4,7 @@ import { useIntl } from "react-intl"
import Caption from "@/components/TempDesignSystem/Text/Caption"
import Footnote from "@/components/TempDesignSystem/Text/Footnote"
import { formatPrice } from "@/utils/numberFormatting"
import styles from "./signupPromo.module.css"
@@ -18,7 +19,7 @@ export default function SignupPromoDesktop({
return null
}
const { amount, currency } = memberPrice
const price = intl.formatNumber(amount, { currency, style: "currency" })
const price = formatPrice(intl, amount, currency)
return memberPrice ? (
<div className={styles.memberDiscountBannerDesktop}>