From 139accb8ed6e5e2dbd6247d00843c3ae216d5ec3 Mon Sep 17 00:00:00 2001 From: Christel Westerberg Date: Thu, 2 Jan 2025 10:54:19 +0100 Subject: [PATCH] fix: align price formatting --- .../HotelListing/HotelListingItem/index.tsx | 2 +- .../HotelPage/IntroSection/index.tsx | 2 +- .../Parking/ParkingPrices/index.tsx | 9 ++- .../PaymentDetails/index.tsx | 6 +- .../BookingConfirmation/Receipt/index.tsx | 30 +++----- .../EnterDetails/Breakfast/index.tsx | 22 +++--- .../Details/JoinScandicFriendsCard/index.tsx | 10 ++- .../Details/MemberPriceModal/index.tsx | 10 +-- .../EnterDetails/Header/index.tsx | 2 +- .../EnterDetails/PriceChangeDialog/index.tsx | 5 +- .../Summary/Mobile/BottomSheet/index.tsx | 11 ++- .../Summary/PriceDetailsTable/index.tsx | 67 ++++++----------- .../EnterDetails/Summary/UI/index.tsx | 72 ++++++++----------- .../HotelReservation/HotelCard/index.tsx | 2 +- .../SelectRate/HotelInfoCard/index.tsx | 2 +- .../RoomSelection/RateSummary/index.tsx | 42 +++++++---- .../SelectRate/SelectionCard/index.tsx | 17 +++-- .../HotelReservation/SignupPromo/Desktop.tsx | 3 +- .../HotelListingMapContent/index.tsx | 9 ++- i18n/dictionaries/da.json | 7 +- i18n/dictionaries/de.json | 7 +- i18n/dictionaries/en.json | 7 +- i18n/dictionaries/fi.json | 7 +- i18n/dictionaries/no.json | 7 +- i18n/dictionaries/sv.json | 7 +- utils/numberFormatting.ts | 26 ++++++- 26 files changed, 198 insertions(+), 193 deletions(-) diff --git a/components/Blocks/HotelListing/HotelListingItem/index.tsx b/components/Blocks/HotelListing/HotelListingItem/index.tsx index fea0d1a1b..cd26d13b7 100644 --- a/components/Blocks/HotelListing/HotelListingItem/index.tsx +++ b/components/Blocks/HotelListing/HotelListingItem/index.tsx @@ -8,7 +8,7 @@ import Caption from "@/components/TempDesignSystem/Text/Caption" import Subtitle from "@/components/TempDesignSystem/Text/Subtitle" import Title from "@/components/TempDesignSystem/Text/Title" import { getIntl } from "@/i18n" -import getSingleDecimal from "@/utils/numberFormatting" +import { getSingleDecimal } from "@/utils/numberFormatting" import { getTypeSpecificInformation } from "./utils" diff --git a/components/ContentType/HotelPage/IntroSection/index.tsx b/components/ContentType/HotelPage/IntroSection/index.tsx index 79f29adbd..b14866ea8 100644 --- a/components/ContentType/HotelPage/IntroSection/index.tsx +++ b/components/ContentType/HotelPage/IntroSection/index.tsx @@ -8,7 +8,7 @@ import Preamble from "@/components/TempDesignSystem/Text/Preamble" import Title from "@/components/TempDesignSystem/Text/Title" import { getIntl } from "@/i18n" import { getLang } from "@/i18n/serverContext" -import getSingleDecimal from "@/utils/numberFormatting" +import { getSingleDecimal } from "@/utils/numberFormatting" import styles from "./introSection.module.css" diff --git a/components/ContentType/HotelPage/SidePeeks/Amenities/AccordionAmenities/Parking/ParkingPrices/index.tsx b/components/ContentType/HotelPage/SidePeeks/Amenities/AccordionAmenities/Parking/ParkingPrices/index.tsx index 3ca2bb527..c62d5e6a1 100644 --- a/components/ContentType/HotelPage/SidePeeks/Amenities/AccordionAmenities/Parking/ParkingPrices/index.tsx +++ b/components/ContentType/HotelPage/SidePeeks/Amenities/AccordionAmenities/Parking/ParkingPrices/index.tsx @@ -1,5 +1,6 @@ import Body from "@/components/TempDesignSystem/Text/Body" import { getIntl } from "@/i18n" +import { formatPrice } from "@/utils/numberFormatting" import styles from "./parkingPrices.module.css" @@ -42,9 +43,11 @@ export default async function ParkingPrices({ {getPeriod(parking.period)} - {freeParking - ? intl.formatMessage({ id: "Free parking" }) - : `${parking.amount} ${currency}`} + {parking.amount + ? freeParking + ? intl.formatMessage({ id: "Free parking" }) + : formatPrice(intl, parking.amount, currency) + : "N/A"} {parking.startTime && diff --git a/components/HotelReservation/BookingConfirmation/PaymentDetails/index.tsx b/components/HotelReservation/BookingConfirmation/PaymentDetails/index.tsx index 500c7ed74..9dc818b6f 100644 --- a/components/HotelReservation/BookingConfirmation/PaymentDetails/index.tsx +++ b/components/HotelReservation/BookingConfirmation/PaymentDetails/index.tsx @@ -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({
- {intl.formatNumber(booking.totalPrice, { - currency: booking.currencyCode, - style: "currency", - })}{" "} + {formatPrice(intl, booking.totalPrice, booking.currencyCode)}{" "} {intl.formatMessage({ id: "has been paid" })} diff --git a/components/HotelReservation/BookingConfirmation/Receipt/index.tsx b/components/HotelReservation/BookingConfirmation/Receipt/index.tsx index d2a6bc4fa..546b1bb80 100644 --- a/components/HotelReservation/BookingConfirmation/Receipt/index.tsx +++ b/components/HotelReservation/BookingConfirmation/Receipt/index.tsx @@ -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({ N/A - {intl.formatNumber(booking.roomPrice, { - currency: booking.currencyCode, - style: "currency", - })} + {formatPrice(intl, booking.roomPrice, booking.currencyCode)}
) : ( - {intl.formatNumber(booking.roomPrice, { - currency: booking.currencyCode, - style: "currency", - })} + {formatPrice(intl, booking.roomPrice, booking.currencyCode)} )} @@ -83,10 +78,7 @@ export default function Receipt({
{room.bedType.description} - {intl.formatNumber(0, { - currency: booking.currencyCode, - style: "currency", - })} + {formatPrice(intl, 0, booking.currencyCode)}
@@ -97,10 +89,11 @@ export default function Receipt({ {breakfastPkgSelected ? ( - {intl.formatNumber(breakfastPkgSelected.totalPrice, { - currency: breakfastPkgSelected.currency, - style: "currency", - })} + {formatPrice( + intl, + breakfastPkgSelected.totalPrice, + breakfastPkgSelected.currency + )} ) : null}
@@ -112,10 +105,7 @@ export default function Receipt({ {intl.formatMessage({ id: "Total price" })} - {intl.formatNumber(booking.totalPrice, { - currency: booking.currencyCode, - style: "currency", - })} + {formatPrice(intl, booking.totalPrice, booking.currencyCode)}
diff --git a/components/HotelReservation/EnterDetails/Breakfast/index.tsx b/components/HotelReservation/EnterDetails/Breakfast/index.tsx index f413b841d..bd69ad5f6 100644 --- a/components/HotelReservation/EnterDetails/Breakfast/index.tsx +++ b/components/HotelReservation/EnterDetails/Breakfast/index.tsx @@ -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( { id: "breakfast.price.free" }, { - amount: pkg.localPrice.price, + amount: formatPrice( + intl, + parseInt(pkg.localPrice.price), + pkg.localPrice.currency + ), currency: pkg.localPrice.currency, free: (str) => {str}, strikethrough: (str) => {str}, @@ -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) { ))} - {intl.formatNumber(memberPrice.pricePerStay, { - currency: memberPrice.currency, - style: "currency", - })} + {formatPrice( + intl, + memberPrice.pricePerStay, + memberPrice.currency + )} )} diff --git a/components/HotelReservation/EnterDetails/Header/index.tsx b/components/HotelReservation/EnterDetails/Header/index.tsx index e1fbb96dd..beeb1174e 100644 --- a/components/HotelReservation/EnterDetails/Header/index.tsx +++ b/components/HotelReservation/EnterDetails/Header/index.tsx @@ -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" diff --git a/components/HotelReservation/EnterDetails/PriceChangeDialog/index.tsx b/components/HotelReservation/EnterDetails/PriceChangeDialog/index.tsx index 3bc61bd06..0751a6fcb 100644 --- a/components/HotelReservation/EnterDetails/PriceChangeDialog/index.tsx +++ b/components/HotelReservation/EnterDetails/PriceChangeDialog/index.tsx @@ -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({ })}
- {intl.formatNumber(oldPrice, { style: "currency", currency })} + {formatPrice(intl, oldPrice, currency)} {" "} - {intl.formatNumber(newPrice, { style: "currency", currency })} + {formatPrice(intl, newPrice, currency)} diff --git a/components/HotelReservation/EnterDetails/Summary/Mobile/BottomSheet/index.tsx b/components/HotelReservation/EnterDetails/Summary/Mobile/BottomSheet/index.tsx index 579e55e53..4114ba830 100644 --- a/components/HotelReservation/EnterDetails/Summary/Mobile/BottomSheet/index.tsx +++ b/components/HotelReservation/EnterDetails/Summary/Mobile/BottomSheet/index.tsx @@ -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) { > {intl.formatMessage({ id: "Total price" })}: - {intl.formatMessage( - { id: "{amount} {currency}" }, - { - amount: intl.formatNumber(totalPrice.local.price), - currency: totalPrice.local.currency, - } + {formatPrice( + intl, + totalPrice.local.price, + totalPrice.local.currency )} diff --git a/components/HotelReservation/EnterDetails/Summary/PriceDetailsTable/index.tsx b/components/HotelReservation/EnterDetails/Summary/PriceDetailsTable/index.tsx index 5a924f7bb..6344c3ed9 100644 --- a/components/HotelReservation/EnterDetails/Summary/PriceDetailsTable/index.tsx +++ b/components/HotelReservation/EnterDetails/Summary/PriceDetailsTable/index.tsx @@ -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({ ) })} @@ -110,10 +96,7 @@ export default function PriceDetailsTable({ ) : 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} @@ -154,17 +132,11 @@ export default function PriceDetailsTable({ @@ -174,10 +146,11 @@ export default function PriceDetailsTable({ - {intl.formatNumber(totalPrice.local.price, { - currency: totalPrice.local.currency, - style: "currency", - })} + {formatPrice( + intl, + totalPrice.local.price, + totalPrice.local.currency + )} diff --git a/components/HotelReservation/EnterDetails/Summary/UI/index.tsx b/components/HotelReservation/EnterDetails/Summary/UI/index.tsx index 43984bea1..d61563fdd 100644 --- a/components/HotelReservation/EnterDetails/Summary/UI/index.tsx +++ b/components/HotelReservation/EnterDetails/Summary/UI/index.tsx @@ -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({
{roomType} - {intl.formatNumber(roomPrice.perStay.local.price, { - currency: roomPrice.perStay.local.currency, - style: "currency", - })} + {formatPrice( + intl, + roomPrice.perStay.local.price, + roomPrice.perStay.local.currency + )}
@@ -196,10 +197,11 @@ export default function SummaryUI({
- {intl.formatNumber(parseInt(roomPackage.localPrice.price), { - currency: roomPackage.localPrice.currency, - style: "currency", - })} + {formatPrice( + intl, + parseInt(roomPackage.localPrice.price), + roomPackage.localPrice.currency + )} )) @@ -209,10 +211,7 @@ export default function SummaryUI({ {bedType.description} - {intl.formatNumber(0, { - currency: roomPrice.perStay.local.currency, - style: "currency", - })} + {formatPrice(intl, 0, roomPrice.perStay.local.currency)} ) : null} @@ -227,10 +226,7 @@ export default function SummaryUI({ - {intl.formatNumber(0, { - currency: roomPrice.perStay.local.currency, - style: "currency", - })} + {formatPrice(intl, 0, roomPrice.perStay.local.currency)} ) : null} @@ -242,10 +238,7 @@ export default function SummaryUI({ - {intl.formatNumber(0, { - currency: roomPrice.perStay.local.currency, - style: "currency", - })} + {formatPrice(intl, 0, roomPrice.perStay.local.currency)} ) : null} @@ -255,10 +248,7 @@ export default function SummaryUI({ {intl.formatMessage({ id: "No breakfast" })} - {intl.formatNumber(0, { - currency: roomPrice.perStay.local.currency, - style: "currency", - })} + {formatPrice(intl, 0, roomPrice.perStay.local.currency)} ) : null} @@ -275,10 +265,11 @@ export default function SummaryUI({ )} - {intl.formatNumber(parseInt(breakfast.localPrice.totalPrice), { - currency: breakfast.localPrice.currency, - style: "currency", - })} + {formatPrice( + intl, + parseInt(breakfast.localPrice.totalPrice), + breakfast.localPrice.currency + )} {children?.length ? ( @@ -290,10 +281,7 @@ export default function SummaryUI({ )} - {intl.formatNumber(0, { - currency: breakfast.localPrice.currency, - style: "currency", - })} + {formatPrice(intl, 0, breakfast.localPrice.currency)} ) : null} @@ -331,18 +319,20 @@ export default function SummaryUI({
- {intl.formatNumber(totalPrice.local.price, { - currency: totalPrice.local.currency, - style: "currency", - })} + {formatPrice( + intl, + totalPrice.local.price, + totalPrice.local.currency + )} {totalPrice.requested && ( {intl.formatMessage({ id: "Approx." })}{" "} - {intl.formatNumber(totalPrice.requested.price, { - currency: totalPrice.requested.currency, - style: "currency", - })} + {formatPrice( + intl, + totalPrice.requested.price, + totalPrice.requested.currency + )} )}
diff --git a/components/HotelReservation/HotelCard/index.tsx b/components/HotelReservation/HotelCard/index.tsx index 03406d824..99ce75f42 100644 --- a/components/HotelReservation/HotelCard/index.tsx +++ b/components/HotelReservation/HotelCard/index.tsx @@ -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" diff --git a/components/HotelReservation/SelectRate/HotelInfoCard/index.tsx b/components/HotelReservation/SelectRate/HotelInfoCard/index.tsx index 369d4184b..72bd42b25 100644 --- a/components/HotelReservation/SelectRate/HotelInfoCard/index.tsx +++ b/components/HotelReservation/SelectRate/HotelInfoCard/index.tsx @@ -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" diff --git a/components/HotelReservation/SelectRate/RoomSelection/RateSummary/index.tsx b/components/HotelReservation/SelectRate/RoomSelection/RateSummary/index.tsx index 34e78e572..109bbcd76 100644 --- a/components/HotelReservation/SelectRate/RoomSelection/RateSummary/index.tsx +++ b/components/HotelReservation/SelectRate/RoomSelection/RateSummary/index.tsx @@ -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 + )} - - {intl.formatMessage({ id: "Approx." })}{" "} - {priceToShow?.requestedPrice?.pricePerStay}{" "} - {priceToShow?.requestedPrice?.currency} - + {priceToShow?.requestedPrice ? ( + + {intl.formatMessage({ id: "Approx." })}{" "} + {formatPrice( + intl, + priceToShow.requestedPrice.pricePerStay, + priceToShow.requestedPrice.currency + )} + + ) : null}
{intl.formatMessage({ id: "Total price" })} - {priceToShow?.localPrice.pricePerStay}{" "} - {priceToShow?.localPrice.currency} + {formatPrice( + intl, + priceToShow.localPrice.pricePerStay, + priceToShow.localPrice.currency + )}
- {isPetRoomSelected && ( + {isPetRoomSelected && petRoomPackage?.localPrice && (
- + {petRoomPrice} {petRoomCurrency} + +{" "} + {formatPrice( + intl, + parseInt(petRoomPackage.localPrice.totalPrice), + petRoomPackage.localPrice.currency + )} {intl.formatMessage({ id: "Pet charge" })} diff --git a/components/HotelReservation/SelectRate/SelectionCard/index.tsx b/components/HotelReservation/SelectRate/SelectionCard/index.tsx index 496b936da..00385c91c 100644 --- a/components/HotelReservation/SelectRate/SelectionCard/index.tsx +++ b/components/HotelReservation/SelectRate/SelectionCard/index.tsx @@ -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({
- {/* TODO: Handle currency and this whole line of text in a better way through intl */} - {price} {currency}/{intl.formatMessage({ id: "night" })} - - - - {/* 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" })} + + {membersPrice && ( + + {intl.formatMessage({ id: "Members" })}{" "} + {formatPrice(intl, membersPrice, currency)}/ + {intl.formatMessage({ id: "night" })} + + )}
) diff --git a/components/HotelReservation/SignupPromo/Desktop.tsx b/components/HotelReservation/SignupPromo/Desktop.tsx index 0c78e9fcf..b96dfd189 100644 --- a/components/HotelReservation/SignupPromo/Desktop.tsx +++ b/components/HotelReservation/SignupPromo/Desktop.tsx @@ -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 ? (
diff --git a/components/Maps/InteractiveMap/HotelListingMapContent/index.tsx b/components/Maps/InteractiveMap/HotelListingMapContent/index.tsx index 672414fe1..4c069c7b9 100644 --- a/components/Maps/InteractiveMap/HotelListingMapContent/index.tsx +++ b/components/Maps/InteractiveMap/HotelListingMapContent/index.tsx @@ -3,11 +3,13 @@ import { AdvancedMarkerAnchorPoint, } from "@vis.gl/react-google-maps" import { useCallback, useState } from "react" +import { useIntl } from "react-intl" import { useHotelsMapStore } from "@/stores/hotels-map" import HotelCardDialog from "@/components/HotelReservation/HotelCardDialog" import Body from "@/components/TempDesignSystem/Text/Body" +import { formatPrice } from "@/utils/numberFormatting" import HotelMarker from "../../Markers/HotelMarker" @@ -16,6 +18,7 @@ import styles from "./hotelListingMapContent.module.css" import type { HotelListingMapContentProps } from "@/types/components/hotelReservation/selectHotel/map" function HotelListingMapContent({ hotelPins }: HotelListingMapContentProps) { + const intl = useIntl() const [hoveredHotelPin, setHoveredHotelPin] = useState(null) const { activeHotelPin, setActiveHotelPin, setActiveHotelCard } = useHotelsMapStore() @@ -55,6 +58,7 @@ function HotelListingMapContent({ hotelPins }: HotelListingMapContentProps) { {hotelPins.map((pin) => { const isActiveOrHovered = activeHotelPin === pin.name || hoveredHotelPin === pin.name + const hotelPrice = pin.memberPrice ?? pin.publicPrice return ( - {pin.memberPrice} {pin.currency} + {/* TODO: Handle when no price is available */} + {hotelPrice + ? formatPrice(intl, hotelPrice, pin.currency) + : "N/A"} diff --git a/i18n/dictionaries/da.json b/i18n/dictionaries/da.json index 6d0e0ddd4..7051fac39 100644 --- a/i18n/dictionaries/da.json +++ b/i18n/dictionaries/da.json @@ -288,7 +288,7 @@ "Number of parking spots": "Antal parkeringspladser: {number}", "OTHER PAYMENT METHODS": "ANDRE BETALINGSMETODER", "On your journey": "På din rejse", - "Only pay {amount} {currency}": "Betal kun {amount} {currency}", + "Only pay {amount}": "Betal kun {amount}", "Open": "Åben", "Open gift(s)": "Åbne {amount, plural, one {gave} other {gaver}}", "Open image gallery": "Åbn billedgalleri", @@ -512,8 +512,8 @@ "booking.vat": "Moms {vat}%", "booking.vat.excl": "Pris ekskl. moms", "booking.vat.incl": "Pris inkl. moms", - "breakfast.price": "{amount} {currency}/nat per voksen", - "breakfast.price.free": "{amount} {currency} 0 {currency}/nat per voksen", + "breakfast.price": "{amount}/nat per voksen", + "breakfast.price.free": "{amount} 0 {currency}/nat per voksen", "by": "inden", "characters": "tegn", "filters.nohotel.heading": "Ingen rum matchede dine filtre.", @@ -546,7 +546,6 @@ "to": "til", "uppercase letter": "stort bogstav", "{amount} out of {total}": "{amount} ud af {total}", - "{amount} {currency}": "{amount} {currency}", "{card} ending with {cardno}": "{card} slutter med {cardno}", "{difference}{amount} {currency}": "{difference}{amount} {currency}" } diff --git a/i18n/dictionaries/de.json b/i18n/dictionaries/de.json index f88424df9..7954874e0 100644 --- a/i18n/dictionaries/de.json +++ b/i18n/dictionaries/de.json @@ -287,7 +287,7 @@ "Number of parking spots": "Anzahl der Parkplätze: {number}", "OTHER PAYMENT METHODS": "ANDERE BEZAHLMETHODE", "On your journey": "Auf deiner Reise", - "Only pay {amount} {currency}": "Nur bezahlen {amount} {currency}", + "Only pay {amount}": "Nur bezahlen {amount}", "Open": "Offen", "Open gift(s)": "{amount, plural, one {Geschenk} other {Geschenke}} öffnen", "Open image gallery": "Bildergalerie öffnen", @@ -511,8 +511,8 @@ "booking.vat": "MwSt. {vat}%", "booking.vat.excl": "Preis ohne MwSt.", "booking.vat.incl": "Preis inkl. MwSt.", - "breakfast.price": "{amount} {currency}/Nacht pro Erwachsenem", - "breakfast.price.free": "{amount} {currency} 0 {currency}/Nacht pro Erwachsenem", + "breakfast.price": "{amount}/Nacht pro Erwachsenem", + "breakfast.price.free": "{amount} 0 {currency}/Nacht pro Erwachsenem", "by": "bis", "characters": "figuren", "filters.nohotel.heading": "Kein Zimmer entspricht Ihren Filtern.", @@ -545,7 +545,6 @@ "to": "zu", "uppercase letter": "großbuchstabe", "{amount} out of {total}": "{amount} von {total}", - "{amount} {currency}": "{amount} {currency}", "{card} ending with {cardno}": "{card} endet mit {cardno}", "{difference}{amount} {currency}": "{difference}{amount} {currency}" } diff --git a/i18n/dictionaries/en.json b/i18n/dictionaries/en.json index 92ca1629a..771290e0a 100644 --- a/i18n/dictionaries/en.json +++ b/i18n/dictionaries/en.json @@ -309,7 +309,7 @@ "Number of parking spots": "Number of parking spots: {number}", "OTHER PAYMENT METHODS": "OTHER PAYMENT METHODS", "On your journey": "On your journey", - "Only pay {amount} {currency}": "Only pay {amount} {currency}", + "Only pay {amount}": "Only pay {amount}", "Open": "Open", "Open gift(s)": "Open {amount, plural, one {gift} other {gifts}}", "Open image gallery": "Open image gallery", @@ -555,8 +555,8 @@ "booking.vat": "VAT {vat}%", "booking.vat.excl": "Price excluding VAT", "booking.vat.incl": "Price including VAT", - "breakfast.price": "{amount} {currency}/night per adult", - "breakfast.price.free": "{amount} {currency} 0 {currency}/night per adult", + "breakfast.price": "{amount}/night per adult", + "breakfast.price.free": "{amount} 0 {currency}/night per adult", "by": "by", "characters": "characters", "filters.nohotel.heading": "No hotels match your filters", @@ -592,7 +592,6 @@ "to": "to", "uppercase letter": "uppercase letter", "{amount} out of {total}": "{amount} out of {total}", - "{amount} {currency}": "{amount} {currency}", "{card} ending with {cardno}": "{card} ending with {cardno}", "{difference}{amount} {currency}": "{difference}{amount} {currency}" } diff --git a/i18n/dictionaries/fi.json b/i18n/dictionaries/fi.json index 9eefaa923..4b242c84e 100644 --- a/i18n/dictionaries/fi.json +++ b/i18n/dictionaries/fi.json @@ -288,7 +288,7 @@ "Number of parking spots": "Pysäköintipaikkojen määrä: {number}", "OTHER PAYMENT METHODS": "MUISE KORT", "On your journey": "Matkallasi", - "Only pay {amount} {currency}": "Vain maksaa {amount} {currency}", + "Only pay {amount}": "Vain maksaa {amount}", "Open": "Avata", "Open gift(s)": "{amount, plural, one {Avoin lahja} other {Avoimet lahjat}}", "Open image gallery": "Avaa kuvagalleria", @@ -510,8 +510,8 @@ "booking.vat": "ALV {vat}%", "booking.vat.excl": "ALV ei sisälly hintaan", "booking.vat.incl": "ALV sisältyy hintaan", - "breakfast.price": "{amount} {currency}/yötä aikuista kohti", - "breakfast.price.free": "{amount} {currency} 0 {currency}/yötä aikuista kohti", + "breakfast.price": "{amount}/yötä aikuista kohti", + "breakfast.price.free": "{amount} 0 {currency}/yötä aikuista kohti", "by": "mennessä", "characters": "hahmoja", "filters.nohotel.heading": "Yksikään huone ei vastannut suodattimiasi", @@ -544,7 +544,6 @@ "to": "to", "uppercase letter": "iso kirjain", "{amount} out of {total}": "{amount}/{total}", - "{amount} {currency}": "{amount} {currency}", "{card} ending with {cardno}": "{card} päättyen {cardno}", "{difference}{amount} {currency}": "{difference}{amount} {currency}" } diff --git a/i18n/dictionaries/no.json b/i18n/dictionaries/no.json index 07eda4ef4..3fa2f494f 100644 --- a/i18n/dictionaries/no.json +++ b/i18n/dictionaries/no.json @@ -287,7 +287,7 @@ "Number of parking spots": "Antall parkeringsplasser: {number}", "OTHER PAYMENT METHODS": "ANDRE BETALINGSMETODER", "On your journey": "På reisen din", - "Only pay {amount} {currency}": "Bare betal {amount} {currency}", + "Only pay {amount}": "Bare betal {amount}", "Open": "Åpen", "Open gift(s)": "{amount, plural, one {Åpen gave} other {Åpnen gaver}}", "Open image gallery": "Åpne bildegalleri", @@ -510,8 +510,8 @@ "booking.vat": "mva {vat}%", "booking.vat.excl": "Pris exkludert mva", "booking.vat.incl": "Pris inkludert mva", - "breakfast.price": "{amount} {currency}/natt per voksen", - "breakfast.price.free": "{amount} {currency} 0 {currency}/natt per voksen", + "breakfast.price": "{amount}/natt per voksen", + "breakfast.price.free": "{amount} 0 {currency}/natt per voksen", "by": "innen", "characters": "tegn", "filters.nohotel.heading": "Ingen rom samsvarte med filtrene dine", @@ -544,7 +544,6 @@ "to": "til", "uppercase letter": "stor bokstav", "{amount} out of {total}": "{amount} av {total}", - "{amount} {currency}": "{amount} {currency}", "{card} ending with {cardno}": "{card} slutter med {cardno}", "{difference}{amount} {currency}": "{difference}{amount} {currency}" } diff --git a/i18n/dictionaries/sv.json b/i18n/dictionaries/sv.json index 85050becf..1fae7caf6 100644 --- a/i18n/dictionaries/sv.json +++ b/i18n/dictionaries/sv.json @@ -287,7 +287,7 @@ "Number of parking spots": "Antal parkeringsplatser: {number}", "OTHER PAYMENT METHODS": "ANDRE BETALINGSMETODER", "On your journey": "På din resa", - "Only pay {amount} {currency}": "Betala endast {amount} {currency}", + "Only pay {amount}": "Betala endast {amount}", "Open": "Öppna", "Open gift(s)": "Öppna {amount, plural, one {gåva} other {gåvor}}", "Open image gallery": "Öppna bildgalleri", @@ -510,8 +510,8 @@ "booking.vat": "Moms {vat}%", "booking.vat.excl": "Pris exkl. VAT", "booking.vat.incl": "Pris inkl. VAT", - "breakfast.price": "{amount} {currency}/natt per vuxen", - "breakfast.price.free": "{amount} {currency} 0 {currency}/natt per vuxen", + "breakfast.price": "{amount}/natt per vuxen", + "breakfast.price.free": "{amount} 0 {currency}/natt per vuxen", "by": "innan", "characters": "tecken", "filters.nohotel.heading": "Inga rum matchade dina filter", @@ -546,7 +546,6 @@ "types": "typer", "uppercase letter": "stor bokstav", "{amount} out of {total}": "{amount} av {total}", - "{amount} {currency}": "{amount} {currency}", "{card} ending with {cardno}": "{card} som slutar på {cardno}", "{difference}{amount} {currency}": "{difference}{amount} {currency}" } diff --git a/utils/numberFormatting.ts b/utils/numberFormatting.ts index cd3cd1fa4..664067cc8 100644 --- a/utils/numberFormatting.ts +++ b/utils/numberFormatting.ts @@ -1,8 +1,32 @@ +import type { IntlShape } from "react-intl" + /** * Function to parse number with single decimal if any * @param n * @returns number in float type with single digit decimal if any */ -export default function getSingleDecimal(n: Number | string) { +export function getSingleDecimal(n: Number | string) { return parseFloat(Number(n).toFixed(1)) } + +/** + * Function to parse number for i18n format for prices with currency + * @param intl - react-intl object + * @param price - number to be formatted + * @param currency - currency code + * @returns localized and formatted number in string type with currency + */ +export function formatPrice( + intl: IntlShape, + price: number, + currency?: string | null +) { + if (!currency) { + return intl.formatNumber(price) + } + return intl.formatNumber(price, { + style: "currency", + currency, + minimumFractionDigits: 0, + }) +}