188 lines
5.3 KiB
TypeScript
188 lines
5.3 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 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,
|
|
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,
|
|
}
|
|
}
|
|
|
|
export default function PriceDetailsTable({
|
|
roomType,
|
|
}: PriceDetailsTableProps) {
|
|
const intl = useIntl()
|
|
const lang = useLang()
|
|
|
|
const {
|
|
bedType,
|
|
booking,
|
|
breakfast,
|
|
join,
|
|
membershipNo,
|
|
packages,
|
|
roomPrice,
|
|
roomRate,
|
|
toggleSummaryOpen,
|
|
togglePriceDetailsModalOpen,
|
|
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={intl.formatNumber(roomPrice.perNight.local.price, {
|
|
currency: roomPrice.perNight.local.currency,
|
|
style: "currency",
|
|
})}
|
|
/>
|
|
)
|
|
})}
|
|
</TableSection>
|
|
{bedType ? (
|
|
<TableSection>
|
|
<Row
|
|
label={bedType.description}
|
|
value={intl.formatNumber(0, {
|
|
currency: roomPrice.perStay.local.currency,
|
|
style: "currency",
|
|
})}
|
|
/>
|
|
</TableSection>
|
|
) : null}
|
|
{breakfast ? (
|
|
<TableSection>
|
|
<TableSectionHeader title={intl.formatMessage({ id: "Breakfast" })} />
|
|
<Row
|
|
label={intl.formatMessage(
|
|
{ id: "booking.adults.breakfasts" },
|
|
{ totalAdults: adults, totalBreakfasts: nights.length }
|
|
)}
|
|
value={intl.formatNumber(
|
|
parseInt(breakfast.localPrice.totalPrice),
|
|
{
|
|
currency: breakfast.localPrice.currency,
|
|
style: "currency",
|
|
}
|
|
)}
|
|
/>
|
|
{children?.length ? (
|
|
<Row
|
|
label={intl.formatMessage(
|
|
{ id: "booking.children.breakfasts" },
|
|
{
|
|
totalChildren: children.length,
|
|
totalBreakfasts: nights.length,
|
|
}
|
|
)}
|
|
value={intl.formatNumber(0, {
|
|
currency: breakfast.localPrice.currency,
|
|
style: "currency",
|
|
})}
|
|
/>
|
|
) : null}
|
|
</TableSection>
|
|
) : null}
|
|
<TableSection>
|
|
<TableSectionHeader title={intl.formatMessage({ id: "Total" })} />
|
|
<Row
|
|
label={intl.formatMessage({ id: "booking.vat.excl" })}
|
|
value={intl.formatNumber(priceExclVat, {
|
|
currency: totalPrice.local.currency,
|
|
style: "currency",
|
|
})}
|
|
/>
|
|
<Row
|
|
label={intl.formatMessage({ id: "booking.vat" }, { vat })}
|
|
value={intl.formatNumber(vatAmount, {
|
|
currency: totalPrice.local.currency,
|
|
style: "currency",
|
|
})}
|
|
/>
|
|
<tr className={styles.row}>
|
|
<td>
|
|
<Body textTransform="bold">
|
|
{intl.formatMessage({ id: "booking.vat.incl" })}
|
|
</Body>
|
|
</td>
|
|
<td className={styles.price}>
|
|
<Body textTransform="bold">
|
|
{intl.formatNumber(totalPrice.local.price, {
|
|
currency: totalPrice.local.currency,
|
|
style: "currency",
|
|
})}
|
|
</Body>
|
|
</td>
|
|
</tr>
|
|
</TableSection>
|
|
</table>
|
|
)
|
|
}
|