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,7 +8,7 @@ import Caption from "@/components/TempDesignSystem/Text/Caption"
import Subtitle from "@/components/TempDesignSystem/Text/Subtitle" import Subtitle from "@/components/TempDesignSystem/Text/Subtitle"
import Title from "@/components/TempDesignSystem/Text/Title" import Title from "@/components/TempDesignSystem/Text/Title"
import { getIntl } from "@/i18n" import { getIntl } from "@/i18n"
import getSingleDecimal from "@/utils/numberFormatting" import { getSingleDecimal } from "@/utils/numberFormatting"
import { getTypeSpecificInformation } from "./utils" import { getTypeSpecificInformation } from "./utils"

View File

@@ -8,7 +8,7 @@ import Preamble from "@/components/TempDesignSystem/Text/Preamble"
import Title from "@/components/TempDesignSystem/Text/Title" import Title from "@/components/TempDesignSystem/Text/Title"
import { getIntl } from "@/i18n" import { getIntl } from "@/i18n"
import { getLang } from "@/i18n/serverContext" import { getLang } from "@/i18n/serverContext"
import getSingleDecimal from "@/utils/numberFormatting" import { getSingleDecimal } from "@/utils/numberFormatting"
import styles from "./introSection.module.css" import styles from "./introSection.module.css"

View File

@@ -1,5 +1,6 @@
import Body from "@/components/TempDesignSystem/Text/Body" import Body from "@/components/TempDesignSystem/Text/Body"
import { getIntl } from "@/i18n" import { getIntl } from "@/i18n"
import { formatPrice } from "@/utils/numberFormatting"
import styles from "./parkingPrices.module.css" import styles from "./parkingPrices.module.css"
@@ -42,9 +43,11 @@ export default async function ParkingPrices({
{getPeriod(parking.period)} {getPeriod(parking.period)}
</Body> </Body>
<Body color="uiTextHighContrast"> <Body color="uiTextHighContrast">
{freeParking {parking.amount
? intl.formatMessage({ id: "Free parking" }) ? freeParking
: `${parking.amount} ${currency}`} ? intl.formatMessage({ id: "Free parking" })
: formatPrice(intl, parking.amount, currency)
: "N/A"}
</Body> </Body>
</div> </div>
{parking.startTime && {parking.startTime &&

View File

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

View File

@@ -9,6 +9,7 @@ import Link from "@/components/TempDesignSystem/Link"
import Body from "@/components/TempDesignSystem/Text/Body" import Body from "@/components/TempDesignSystem/Text/Body"
import Caption from "@/components/TempDesignSystem/Text/Caption" import Caption from "@/components/TempDesignSystem/Text/Caption"
import Subtitle from "@/components/TempDesignSystem/Text/Subtitle" import Subtitle from "@/components/TempDesignSystem/Text/Subtitle"
import { formatPrice } from "@/utils/numberFormatting"
import styles from "./receipt.module.css" import styles from "./receipt.module.css"
@@ -44,18 +45,12 @@ export default function Receipt({
<s>N/A</s> <s>N/A</s>
</Body> </Body>
<Body color="red"> <Body color="red">
{intl.formatNumber(booking.roomPrice, { {formatPrice(intl, booking.roomPrice, booking.currencyCode)}
currency: booking.currencyCode,
style: "currency",
})}
</Body> </Body>
</div> </div>
) : ( ) : (
<Body color="uiTextHighContrast"> <Body color="uiTextHighContrast">
{intl.formatNumber(booking.roomPrice, { {formatPrice(intl, booking.roomPrice, booking.currencyCode)}
currency: booking.currencyCode,
style: "currency",
})}
</Body> </Body>
)} )}
<Caption color="uiTextMediumContrast"> <Caption color="uiTextMediumContrast">
@@ -83,10 +78,7 @@ export default function Receipt({
<div className={styles.entry}> <div className={styles.entry}>
<Body color="uiTextHighContrast">{room.bedType.description}</Body> <Body color="uiTextHighContrast">{room.bedType.description}</Body>
<Body color="uiTextHighContrast"> <Body color="uiTextHighContrast">
{intl.formatNumber(0, { {formatPrice(intl, 0, booking.currencyCode)}
currency: booking.currencyCode,
style: "currency",
})}
</Body> </Body>
</div> </div>
<div className={styles.entry}> <div className={styles.entry}>
@@ -97,10 +89,11 @@ export default function Receipt({
{breakfastPkgSelected ? ( {breakfastPkgSelected ? (
<Body color="uiTextHighContrast"> <Body color="uiTextHighContrast">
{intl.formatNumber(breakfastPkgSelected.totalPrice, { {formatPrice(
currency: breakfastPkgSelected.currency, intl,
style: "currency", breakfastPkgSelected.totalPrice,
})} breakfastPkgSelected.currency
)}
</Body> </Body>
) : null} ) : null}
</div> </div>
@@ -112,10 +105,7 @@ export default function Receipt({
{intl.formatMessage({ id: "Total price" })} {intl.formatMessage({ id: "Total price" })}
</Body> </Body>
<Body textTransform="bold"> <Body textTransform="bold">
{intl.formatNumber(booking.totalPrice, { {formatPrice(intl, booking.totalPrice, booking.currencyCode)}
currency: booking.currencyCode,
style: "currency",
})}
</Body> </Body>
</div> </div>
<div className={styles.entry}> <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 { Highlight } from "@/components/TempDesignSystem/Form/ChoiceCard/_Card"
import RadioCard from "@/components/TempDesignSystem/Form/ChoiceCard/Radio" import RadioCard from "@/components/TempDesignSystem/Form/ChoiceCard/Radio"
import Body from "@/components/TempDesignSystem/Text/Body" import Body from "@/components/TempDesignSystem/Text/Body"
import { formatPrice } from "@/utils/numberFormatting"
import { breakfastFormSchema } from "./schema" import { breakfastFormSchema } from "./schema"
@@ -91,7 +92,11 @@ export default function Breakfast({ packages }: BreakfastProps) {
? intl.formatMessage<React.ReactNode>( ? intl.formatMessage<React.ReactNode>(
{ id: "breakfast.price.free" }, { id: "breakfast.price.free" },
{ {
amount: pkg.localPrice.price, amount: formatPrice(
intl,
parseInt(pkg.localPrice.price),
pkg.localPrice.currency
),
currency: pkg.localPrice.currency, currency: pkg.localPrice.currency,
free: (str) => <Highlight>{str}</Highlight>, free: (str) => <Highlight>{str}</Highlight>,
strikethrough: (str) => <s>{str}</s>, strikethrough: (str) => <s>{str}</s>,
@@ -100,8 +105,11 @@ export default function Breakfast({ packages }: BreakfastProps) {
: intl.formatMessage( : intl.formatMessage(
{ id: "breakfast.price" }, { id: "breakfast.price" },
{ {
amount: pkg.localPrice.price, amount: formatPrice(
currency: pkg.localPrice.currency, intl,
parseInt(pkg.localPrice.price),
pkg.localPrice.currency
),
} }
) )
} }
@@ -114,13 +122,7 @@ export default function Breakfast({ packages }: BreakfastProps) {
))} ))}
<RadioCard <RadioCard
name="breakfast" name="breakfast"
subtitle={intl.formatMessage( subtitle={formatPrice(intl, 0, packages[0].localPrice.currency)}
{ id: "{amount} {currency}" },
{
amount: "0",
currency: packages[0].localPrice.currency,
}
)}
text={intl.formatMessage({ text={intl.formatMessage({
id: "You can always change your mind later and add breakfast at the hotel.", 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 Caption from "@/components/TempDesignSystem/Text/Caption"
import Footnote from "@/components/TempDesignSystem/Text/Footnote" import Footnote from "@/components/TempDesignSystem/Text/Footnote"
import useLang from "@/hooks/useLang" import useLang from "@/hooks/useLang"
import { formatPrice } from "@/utils/numberFormatting"
import styles from "./joinScandicFriendsCard.module.css" import styles from "./joinScandicFriendsCard.module.css"
@@ -31,11 +32,14 @@ export default function JoinScandicFriendsCard({
const saveOnJoiningLabel = intl.formatMessage( const saveOnJoiningLabel = intl.formatMessage(
{ {
id: "Only pay {amount} {currency}", id: "Only pay {amount}",
}, },
{ {
amount: intl.formatNumber(memberPrice?.price ?? 0), amount: formatPrice(
currency: memberPrice?.currency ?? "SEK", 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 Body from "@/components/TempDesignSystem/Text/Body"
import Subtitle from "@/components/TempDesignSystem/Text/Subtitle" import Subtitle from "@/components/TempDesignSystem/Text/Subtitle"
import Title from "@/components/TempDesignSystem/Text/Title" import Title from "@/components/TempDesignSystem/Text/Title"
import { formatPrice } from "@/utils/numberFormatting"
import Modal from "../../Modal" import Modal from "../../Modal"
@@ -47,10 +48,11 @@ export default function MemberPriceModal({
})} })}
</Body> </Body>
<Subtitle type="two" color="red"> <Subtitle type="two" color="red">
{intl.formatNumber(memberPrice.pricePerStay, { {formatPrice(
currency: memberPrice.currency, intl,
style: "currency", memberPrice.pricePerStay,
})} memberPrice.currency
)}
</Subtitle> </Subtitle>
</span> </span>
)} )}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -3,11 +3,13 @@ import {
AdvancedMarkerAnchorPoint, AdvancedMarkerAnchorPoint,
} from "@vis.gl/react-google-maps" } from "@vis.gl/react-google-maps"
import { useCallback, useState } from "react" import { useCallback, useState } from "react"
import { useIntl } from "react-intl"
import { useHotelsMapStore } from "@/stores/hotels-map" import { useHotelsMapStore } from "@/stores/hotels-map"
import HotelCardDialog from "@/components/HotelReservation/HotelCardDialog" import HotelCardDialog from "@/components/HotelReservation/HotelCardDialog"
import Body from "@/components/TempDesignSystem/Text/Body" import Body from "@/components/TempDesignSystem/Text/Body"
import { formatPrice } from "@/utils/numberFormatting"
import HotelMarker from "../../Markers/HotelMarker" import HotelMarker from "../../Markers/HotelMarker"
@@ -16,6 +18,7 @@ import styles from "./hotelListingMapContent.module.css"
import type { HotelListingMapContentProps } from "@/types/components/hotelReservation/selectHotel/map" import type { HotelListingMapContentProps } from "@/types/components/hotelReservation/selectHotel/map"
function HotelListingMapContent({ hotelPins }: HotelListingMapContentProps) { function HotelListingMapContent({ hotelPins }: HotelListingMapContentProps) {
const intl = useIntl()
const [hoveredHotelPin, setHoveredHotelPin] = useState<string | null>(null) const [hoveredHotelPin, setHoveredHotelPin] = useState<string | null>(null)
const { activeHotelPin, setActiveHotelPin, setActiveHotelCard } = const { activeHotelPin, setActiveHotelPin, setActiveHotelCard } =
useHotelsMapStore() useHotelsMapStore()
@@ -55,6 +58,7 @@ function HotelListingMapContent({ hotelPins }: HotelListingMapContentProps) {
{hotelPins.map((pin) => { {hotelPins.map((pin) => {
const isActiveOrHovered = const isActiveOrHovered =
activeHotelPin === pin.name || hoveredHotelPin === pin.name activeHotelPin === pin.name || hoveredHotelPin === pin.name
const hotelPrice = pin.memberPrice ?? pin.publicPrice
return ( return (
<AdvancedMarker <AdvancedMarker
key={pin.name} key={pin.name}
@@ -93,7 +97,10 @@ function HotelListingMapContent({ hotelPins }: HotelListingMapContentProps) {
color={isActiveOrHovered ? "white" : "baseTextHighContrast"} color={isActiveOrHovered ? "white" : "baseTextHighContrast"}
> >
<span> <span>
{pin.memberPrice} {pin.currency} {/* TODO: Handle when no price is available */}
{hotelPrice
? formatPrice(intl, hotelPrice, pin.currency)
: "N/A"}
</span> </span>
</Body> </Body>
</span> </span>

View File

@@ -288,7 +288,7 @@
"Number of parking spots": "Antal parkeringspladser: {number}", "Number of parking spots": "Antal parkeringspladser: {number}",
"OTHER PAYMENT METHODS": "ANDRE BETALINGSMETODER", "OTHER PAYMENT METHODS": "ANDRE BETALINGSMETODER",
"On your journey": "På din rejse", "On your journey": "På din rejse",
"Only pay {amount} {currency}": "Betal kun {amount} {currency}", "Only pay {amount}": "Betal kun {amount}",
"Open": "Åben", "Open": "Åben",
"Open gift(s)": "Åbne {amount, plural, one {gave} other {gaver}}", "Open gift(s)": "Åbne {amount, plural, one {gave} other {gaver}}",
"Open image gallery": "Åbn billedgalleri", "Open image gallery": "Åbn billedgalleri",
@@ -512,8 +512,8 @@
"booking.vat": "Moms {vat}%", "booking.vat": "Moms {vat}%",
"booking.vat.excl": "Pris ekskl. moms", "booking.vat.excl": "Pris ekskl. moms",
"booking.vat.incl": "Pris inkl. moms", "booking.vat.incl": "Pris inkl. moms",
"breakfast.price": "{amount} {currency}/nat per voksen", "breakfast.price": "{amount}/nat per voksen",
"breakfast.price.free": "<strikethrough>{amount} {currency}</strikethrough> <free>0 {currency}</free>/nat per voksen", "breakfast.price.free": "<strikethrough>{amount}</strikethrough> <free>0 {currency}</free>/nat per voksen",
"by": "inden", "by": "inden",
"characters": "tegn", "characters": "tegn",
"filters.nohotel.heading": "Ingen rum matchede dine filtre.", "filters.nohotel.heading": "Ingen rum matchede dine filtre.",
@@ -546,7 +546,6 @@
"to": "til", "to": "til",
"uppercase letter": "stort bogstav", "uppercase letter": "stort bogstav",
"{amount} out of {total}": "{amount} ud af {total}", "{amount} out of {total}": "{amount} ud af {total}",
"{amount} {currency}": "{amount} {currency}",
"{card} ending with {cardno}": "{card} slutter med {cardno}", "{card} ending with {cardno}": "{card} slutter med {cardno}",
"{difference}{amount} {currency}": "{difference}{amount} {currency}" "{difference}{amount} {currency}": "{difference}{amount} {currency}"
} }

View File

@@ -287,7 +287,7 @@
"Number of parking spots": "Anzahl der Parkplätze: {number}", "Number of parking spots": "Anzahl der Parkplätze: {number}",
"OTHER PAYMENT METHODS": "ANDERE BEZAHLMETHODE", "OTHER PAYMENT METHODS": "ANDERE BEZAHLMETHODE",
"On your journey": "Auf deiner Reise", "On your journey": "Auf deiner Reise",
"Only pay {amount} {currency}": "Nur bezahlen {amount} {currency}", "Only pay {amount}": "Nur bezahlen {amount}",
"Open": "Offen", "Open": "Offen",
"Open gift(s)": "{amount, plural, one {Geschenk} other {Geschenke}} öffnen", "Open gift(s)": "{amount, plural, one {Geschenk} other {Geschenke}} öffnen",
"Open image gallery": "Bildergalerie öffnen", "Open image gallery": "Bildergalerie öffnen",
@@ -511,8 +511,8 @@
"booking.vat": "MwSt. {vat}%", "booking.vat": "MwSt. {vat}%",
"booking.vat.excl": "Preis ohne MwSt.", "booking.vat.excl": "Preis ohne MwSt.",
"booking.vat.incl": "Preis inkl. MwSt.", "booking.vat.incl": "Preis inkl. MwSt.",
"breakfast.price": "{amount} {currency}/Nacht pro Erwachsenem", "breakfast.price": "{amount}/Nacht pro Erwachsenem",
"breakfast.price.free": "<strikethrough>{amount} {currency}</strikethrough> <free>0 {currency}</free>/Nacht pro Erwachsenem", "breakfast.price.free": "<strikethrough>{amount}</strikethrough> <free>0 {currency}</free>/Nacht pro Erwachsenem",
"by": "bis", "by": "bis",
"characters": "figuren", "characters": "figuren",
"filters.nohotel.heading": "Kein Zimmer entspricht Ihren Filtern.", "filters.nohotel.heading": "Kein Zimmer entspricht Ihren Filtern.",
@@ -545,7 +545,6 @@
"to": "zu", "to": "zu",
"uppercase letter": "großbuchstabe", "uppercase letter": "großbuchstabe",
"{amount} out of {total}": "{amount} von {total}", "{amount} out of {total}": "{amount} von {total}",
"{amount} {currency}": "{amount} {currency}",
"{card} ending with {cardno}": "{card} endet mit {cardno}", "{card} ending with {cardno}": "{card} endet mit {cardno}",
"{difference}{amount} {currency}": "{difference}{amount} {currency}" "{difference}{amount} {currency}": "{difference}{amount} {currency}"
} }

View File

@@ -309,7 +309,7 @@
"Number of parking spots": "Number of parking spots: {number}", "Number of parking spots": "Number of parking spots: {number}",
"OTHER PAYMENT METHODS": "OTHER PAYMENT METHODS", "OTHER PAYMENT METHODS": "OTHER PAYMENT METHODS",
"On your journey": "On your journey", "On your journey": "On your journey",
"Only pay {amount} {currency}": "Only pay {amount} {currency}", "Only pay {amount}": "Only pay {amount}",
"Open": "Open", "Open": "Open",
"Open gift(s)": "Open {amount, plural, one {gift} other {gifts}}", "Open gift(s)": "Open {amount, plural, one {gift} other {gifts}}",
"Open image gallery": "Open image gallery", "Open image gallery": "Open image gallery",
@@ -555,8 +555,8 @@
"booking.vat": "VAT {vat}%", "booking.vat": "VAT {vat}%",
"booking.vat.excl": "Price excluding VAT", "booking.vat.excl": "Price excluding VAT",
"booking.vat.incl": "Price including VAT", "booking.vat.incl": "Price including VAT",
"breakfast.price": "{amount} {currency}/night per adult", "breakfast.price": "{amount}/night per adult",
"breakfast.price.free": "<strikethrough>{amount} {currency}</strikethrough> <free>0 {currency}</free>/night per adult", "breakfast.price.free": "<strikethrough>{amount}</strikethrough> <free>0 {currency}</free>/night per adult",
"by": "by", "by": "by",
"characters": "characters", "characters": "characters",
"filters.nohotel.heading": "No hotels match your filters", "filters.nohotel.heading": "No hotels match your filters",
@@ -592,7 +592,6 @@
"to": "to", "to": "to",
"uppercase letter": "uppercase letter", "uppercase letter": "uppercase letter",
"{amount} out of {total}": "{amount} out of {total}", "{amount} out of {total}": "{amount} out of {total}",
"{amount} {currency}": "{amount} {currency}",
"{card} ending with {cardno}": "{card} ending with {cardno}", "{card} ending with {cardno}": "{card} ending with {cardno}",
"{difference}{amount} {currency}": "{difference}{amount} {currency}" "{difference}{amount} {currency}": "{difference}{amount} {currency}"
} }

View File

@@ -288,7 +288,7 @@
"Number of parking spots": "Pysäköintipaikkojen määrä: {number}", "Number of parking spots": "Pysäköintipaikkojen määrä: {number}",
"OTHER PAYMENT METHODS": "MUISE KORT", "OTHER PAYMENT METHODS": "MUISE KORT",
"On your journey": "Matkallasi", "On your journey": "Matkallasi",
"Only pay {amount} {currency}": "Vain maksaa {amount} {currency}", "Only pay {amount}": "Vain maksaa {amount}",
"Open": "Avata", "Open": "Avata",
"Open gift(s)": "{amount, plural, one {Avoin lahja} other {Avoimet lahjat}}", "Open gift(s)": "{amount, plural, one {Avoin lahja} other {Avoimet lahjat}}",
"Open image gallery": "Avaa kuvagalleria", "Open image gallery": "Avaa kuvagalleria",
@@ -510,8 +510,8 @@
"booking.vat": "ALV {vat}%", "booking.vat": "ALV {vat}%",
"booking.vat.excl": "ALV ei sisälly hintaan", "booking.vat.excl": "ALV ei sisälly hintaan",
"booking.vat.incl": "ALV sisältyy hintaan", "booking.vat.incl": "ALV sisältyy hintaan",
"breakfast.price": "{amount} {currency}/yötä aikuista kohti", "breakfast.price": "{amount}/yötä aikuista kohti",
"breakfast.price.free": "<strikethrough>{amount} {currency}</strikethrough> <free>0 {currency}</free>/yötä aikuista kohti", "breakfast.price.free": "<strikethrough>{amount}</strikethrough> <free>0 {currency}</free>/yötä aikuista kohti",
"by": "mennessä", "by": "mennessä",
"characters": "hahmoja", "characters": "hahmoja",
"filters.nohotel.heading": "Yksikään huone ei vastannut suodattimiasi", "filters.nohotel.heading": "Yksikään huone ei vastannut suodattimiasi",
@@ -544,7 +544,6 @@
"to": "to", "to": "to",
"uppercase letter": "iso kirjain", "uppercase letter": "iso kirjain",
"{amount} out of {total}": "{amount}/{total}", "{amount} out of {total}": "{amount}/{total}",
"{amount} {currency}": "{amount} {currency}",
"{card} ending with {cardno}": "{card} päättyen {cardno}", "{card} ending with {cardno}": "{card} päättyen {cardno}",
"{difference}{amount} {currency}": "{difference}{amount} {currency}" "{difference}{amount} {currency}": "{difference}{amount} {currency}"
} }

View File

@@ -287,7 +287,7 @@
"Number of parking spots": "Antall parkeringsplasser: {number}", "Number of parking spots": "Antall parkeringsplasser: {number}",
"OTHER PAYMENT METHODS": "ANDRE BETALINGSMETODER", "OTHER PAYMENT METHODS": "ANDRE BETALINGSMETODER",
"On your journey": "På reisen din", "On your journey": "På reisen din",
"Only pay {amount} {currency}": "Bare betal {amount} {currency}", "Only pay {amount}": "Bare betal {amount}",
"Open": "Åpen", "Open": "Åpen",
"Open gift(s)": "{amount, plural, one {Åpen gave} other {Åpnen gaver}}", "Open gift(s)": "{amount, plural, one {Åpen gave} other {Åpnen gaver}}",
"Open image gallery": "Åpne bildegalleri", "Open image gallery": "Åpne bildegalleri",
@@ -510,8 +510,8 @@
"booking.vat": "mva {vat}%", "booking.vat": "mva {vat}%",
"booking.vat.excl": "Pris exkludert mva", "booking.vat.excl": "Pris exkludert mva",
"booking.vat.incl": "Pris inkludert mva", "booking.vat.incl": "Pris inkludert mva",
"breakfast.price": "{amount} {currency}/natt per voksen", "breakfast.price": "{amount}/natt per voksen",
"breakfast.price.free": "<strikethrough>{amount} {currency}</strikethrough> <free>0 {currency}</free>/natt per voksen", "breakfast.price.free": "<strikethrough>{amount}</strikethrough> <free>0 {currency}</free>/natt per voksen",
"by": "innen", "by": "innen",
"characters": "tegn", "characters": "tegn",
"filters.nohotel.heading": "Ingen rom samsvarte med filtrene dine", "filters.nohotel.heading": "Ingen rom samsvarte med filtrene dine",
@@ -544,7 +544,6 @@
"to": "til", "to": "til",
"uppercase letter": "stor bokstav", "uppercase letter": "stor bokstav",
"{amount} out of {total}": "{amount} av {total}", "{amount} out of {total}": "{amount} av {total}",
"{amount} {currency}": "{amount} {currency}",
"{card} ending with {cardno}": "{card} slutter med {cardno}", "{card} ending with {cardno}": "{card} slutter med {cardno}",
"{difference}{amount} {currency}": "{difference}{amount} {currency}" "{difference}{amount} {currency}": "{difference}{amount} {currency}"
} }

View File

@@ -287,7 +287,7 @@
"Number of parking spots": "Antal parkeringsplatser: {number}", "Number of parking spots": "Antal parkeringsplatser: {number}",
"OTHER PAYMENT METHODS": "ANDRE BETALINGSMETODER", "OTHER PAYMENT METHODS": "ANDRE BETALINGSMETODER",
"On your journey": "På din resa", "On your journey": "På din resa",
"Only pay {amount} {currency}": "Betala endast {amount} {currency}", "Only pay {amount}": "Betala endast {amount}",
"Open": "Öppna", "Open": "Öppna",
"Open gift(s)": "Öppna {amount, plural, one {gåva} other {gåvor}}", "Open gift(s)": "Öppna {amount, plural, one {gåva} other {gåvor}}",
"Open image gallery": "Öppna bildgalleri", "Open image gallery": "Öppna bildgalleri",
@@ -510,8 +510,8 @@
"booking.vat": "Moms {vat}%", "booking.vat": "Moms {vat}%",
"booking.vat.excl": "Pris exkl. VAT", "booking.vat.excl": "Pris exkl. VAT",
"booking.vat.incl": "Pris inkl. VAT", "booking.vat.incl": "Pris inkl. VAT",
"breakfast.price": "{amount} {currency}/natt per vuxen", "breakfast.price": "{amount}/natt per vuxen",
"breakfast.price.free": "<strikethrough>{amount} {currency}</strikethrough> <free>0 {currency}</free>/natt per vuxen", "breakfast.price.free": "<strikethrough>{amount}</strikethrough> <free>0 {currency}</free>/natt per vuxen",
"by": "innan", "by": "innan",
"characters": "tecken", "characters": "tecken",
"filters.nohotel.heading": "Inga rum matchade dina filter", "filters.nohotel.heading": "Inga rum matchade dina filter",
@@ -546,7 +546,6 @@
"types": "typer", "types": "typer",
"uppercase letter": "stor bokstav", "uppercase letter": "stor bokstav",
"{amount} out of {total}": "{amount} av {total}", "{amount} out of {total}": "{amount} av {total}",
"{amount} {currency}": "{amount} {currency}",
"{card} ending with {cardno}": "{card} som slutar på {cardno}", "{card} ending with {cardno}": "{card} som slutar på {cardno}",
"{difference}{amount} {currency}": "{difference}{amount} {currency}" "{difference}{amount} {currency}": "{difference}{amount} {currency}"
} }

View File

@@ -1,8 +1,32 @@
import type { IntlShape } from "react-intl"
/** /**
* Function to parse number with single decimal if any * Function to parse number with single decimal if any
* @param n * @param n
* @returns number in float type with single digit decimal if any * @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)) 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,
})
}