172 lines
5.0 KiB
TypeScript
172 lines
5.0 KiB
TypeScript
"use client"
|
|
|
|
import { useIntl } from "react-intl"
|
|
|
|
import { dt } from "@/lib/dt"
|
|
import { useEnterDetailsStore } from "@/stores/enter-details"
|
|
|
|
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"
|
|
|
|
import { type PriceDetailsTableProps } from "@/types/components/hotelReservation/enterDetails/priceDetailsTable"
|
|
import type { DetailsState } from "@/types/stores/enter-details"
|
|
|
|
function Row({ label, value }: { label: string; value: string }) {
|
|
return (
|
|
<tr className={styles.row}>
|
|
<td>
|
|
<Caption>{label}</Caption>
|
|
</td>
|
|
<td className={styles.price}>
|
|
<Caption>{value}</Caption>
|
|
</td>
|
|
</tr>
|
|
)
|
|
}
|
|
|
|
function TableSection({ children }: React.PropsWithChildren) {
|
|
return <tbody className={styles.tableSection}>{children}</tbody>
|
|
}
|
|
|
|
function TableSectionHeader({ title }: { title: string }) {
|
|
return (
|
|
<tr>
|
|
<th colSpan={2}>
|
|
<Body>{title}</Body>
|
|
</th>
|
|
</tr>
|
|
)
|
|
}
|
|
|
|
export function storeSelector(state: DetailsState) {
|
|
return {
|
|
bedType: state.bedType,
|
|
booking: state.booking,
|
|
breakfast: state.breakfast,
|
|
packages: state.packages,
|
|
roomRate: state.roomRate,
|
|
roomPrice: state.roomPrice,
|
|
totalPrice: state.totalPrice,
|
|
vat: state.vat,
|
|
}
|
|
}
|
|
|
|
export default function PriceDetailsTable({
|
|
roomType,
|
|
}: PriceDetailsTableProps) {
|
|
const intl = useIntl()
|
|
const lang = useLang()
|
|
|
|
const { bedType, booking, breakfast, roomPrice, totalPrice, vat } =
|
|
useEnterDetailsStore(storeSelector)
|
|
|
|
// TODO: Update for Multiroom later
|
|
const { adults, children } = booking.rooms[0]
|
|
const nights = getNights(booking.fromDate, booking.toDate)
|
|
|
|
const vatPercentage = vat / 100
|
|
const vatAmount = totalPrice.local.price * vatPercentage
|
|
|
|
const priceExclVat = totalPrice.local.price - vatAmount
|
|
|
|
return (
|
|
<table className={styles.priceDetailsTable}>
|
|
<TableSection>
|
|
<TableSectionHeader title={roomType} />
|
|
{nights.map((night) => {
|
|
return (
|
|
<Row
|
|
key={night.format("YYMMDD")}
|
|
label={dt(night).locale(lang).format("ddd, D MMM YYYY")}
|
|
value={formatPrice(
|
|
intl,
|
|
roomPrice.perNight.local.price,
|
|
roomPrice.perNight.local.currency
|
|
)}
|
|
/>
|
|
)
|
|
})}
|
|
</TableSection>
|
|
{bedType ? (
|
|
<TableSection>
|
|
<Row
|
|
label={bedType.description}
|
|
value={formatPrice(intl, 0, roomPrice.perStay.local.currency)}
|
|
/>
|
|
</TableSection>
|
|
) : null}
|
|
{breakfast ? (
|
|
<TableSection>
|
|
<TableSectionHeader title={intl.formatMessage({ id: "Breakfast" })} />
|
|
<Row
|
|
label={`${intl.formatMessage(
|
|
{
|
|
id: "{totalAdults, plural, one {# voksen} other {# voksne}}",
|
|
},
|
|
{ totalAdults: adults }
|
|
)}, ${intl.formatMessage(
|
|
{
|
|
id: "{totalBreakfasts, plural, one {# morgenmad} other {# morgenmad}}",
|
|
},
|
|
{ totalBreakfasts: nights.length }
|
|
)}`}
|
|
value={formatPrice(
|
|
intl,
|
|
parseInt(breakfast.localPrice.totalPrice),
|
|
breakfast.localPrice.currency
|
|
)}
|
|
/>
|
|
{children?.length ? (
|
|
<Row
|
|
label={`${intl.formatMessage(
|
|
{
|
|
id: "{totalChildren, plural, one {# child} other {# children}}",
|
|
},
|
|
{ totalChildren: children.length }
|
|
)}, ${intl.formatMessage(
|
|
{
|
|
id: "{totalBreakfasts, plural, one {# breakfast} other {# breakfasts}}",
|
|
},
|
|
{ totalBreakfasts: nights.length }
|
|
)}`}
|
|
value={formatPrice(intl, 0, breakfast.localPrice.currency)}
|
|
/>
|
|
) : null}
|
|
</TableSection>
|
|
) : null}
|
|
<TableSection>
|
|
<TableSectionHeader title={intl.formatMessage({ id: "Total" })} />
|
|
<Row
|
|
label={intl.formatMessage({ id: "Price excluding VAT" })}
|
|
value={formatPrice(intl, priceExclVat, totalPrice.local.currency)}
|
|
/>
|
|
<Row
|
|
label={intl.formatMessage({ id: "VAT {vat}%" }, { vat })}
|
|
value={formatPrice(intl, vatAmount, totalPrice.local.currency)}
|
|
/>
|
|
<tr className={styles.row}>
|
|
<td>
|
|
<Body textTransform="bold">
|
|
{intl.formatMessage({ id: "Price including VAT" })}
|
|
</Body>
|
|
</td>
|
|
<td className={styles.price}>
|
|
<Body textTransform="bold">
|
|
{formatPrice(
|
|
intl,
|
|
totalPrice.local.price,
|
|
totalPrice.local.currency
|
|
)}
|
|
</Body>
|
|
</td>
|
|
</tr>
|
|
</TableSection>
|
|
</table>
|
|
)
|
|
}
|