fix: unite all price details modals to one and align on ui

This commit is contained in:
Simon Emanuelsson
2025-04-15 15:04:11 +02:00
committed by Michael Zetterberg
parent 8152aea649
commit 1f94c581ae
54 changed files with 1926 additions and 746 deletions

View File

@@ -1,37 +0,0 @@
.priceDetailsTable {
border-collapse: collapse;
width: 100%;
}
.price {
text-align: end;
}
.tableSection {
display: flex;
gap: var(--Spacing-x-half);
flex-direction: column;
width: 100%;
}
.tableSection:has(tr > th) {
padding-top: var(--Spacing-x2);
}
.tableSection:has(tr > th):not(:first-of-type) {
border-top: 1px solid var(--Primary-Light-On-Surface-Divider-subtle);
}
.tableSection:not(:last-child) {
padding-bottom: var(--Spacing-x2);
}
.row {
display: flex;
justify-content: space-between;
}
@media screen and (min-width: 768px) {
.priceDetailsTable {
min-width: 512px;
}
}

View File

@@ -1,10 +1,10 @@
"use client"
import { dt } from "@/lib/dt"
import { useMyStayRoomDetailsStore } from "@/stores/my-stay/myStayRoomDetailsStore"
import { useMyStayTotalPriceStore } from "@/stores/my-stay/myStayTotalPrice"
import PriceDetailsModal from "../../PriceDetailsModal"
import PriceDetailsTable from "./PriceDetailsTable"
import PriceDetailsModal from "@/components/HotelReservation/PriceDetailsModal"
import { calculateTotalPrice, mapToPrice } from "./mapToPrice"
import styles from "./priceDetails.module.css"
@@ -13,27 +13,32 @@ export default function PriceDetails() {
const linkedReservationRooms = useMyStayRoomDetailsStore(
(state) => state.linkedReservationRooms
)
const currencyCode = useMyStayTotalPriceStore((state) => state.currencyCode)
const totalPrice = useMyStayTotalPriceStore((state) => state.totalPrice)
const rooms = [bookedRoom, ...linkedReservationRooms]
.filter((room) => !room.isCancelled)
.map((room) => ({
...room,
breakfastIncluded: room.rateDefinition.breakfastIncluded,
price: mapToPrice(room),
roomType: room.roomName,
}))
const bookingCode =
rooms.find((room) => room.bookingCode)?.bookingCode ?? undefined
const totalPrice = calculateTotalPrice(rooms, bookedRoom.currencyCode)
const fromDate = dt(bookedRoom.checkInDate).format("YYYY-MM-DD")
const toDate = dt(bookedRoom.checkOutDate).format("YYYY-MM-DD")
return (
<div className={styles.priceDetailsModal}>
<PriceDetailsModal>
<PriceDetailsTable
fromDate={dt(bookedRoom.checkInDate).format("YYYY-MM-DD")}
toDate={dt(bookedRoom.checkOutDate).format("YYYY-MM-DD")}
linkedReservationRooms={linkedReservationRooms}
bookedRoom={bookedRoom}
totalPrice={{
requested: undefined,
local: {
currency: currencyCode,
price: totalPrice ?? 0,
},
}}
vat={bookedRoom.vatPercentage}
/>
</PriceDetailsModal>
<PriceDetailsModal
bookingCode={bookingCode}
fromDate={fromDate}
rooms={rooms}
toDate={toDate}
totalPrice={totalPrice}
vat={bookedRoom.vatPercentage}
/>
</div>
)
}

View File

@@ -0,0 +1,125 @@
import { dt } from "@/lib/dt"
import { sumPackages } from "@/components/HotelReservation/utils"
import { PriceTypeEnum } from "@/types/components/hotelReservation/myStay/myStay"
import type { Price } from "@/types/components/hotelReservation/price"
import { CurrencyEnum } from "@/types/enums/currency"
import type { Room } from "@/stores/my-stay/myStayRoomDetailsStore"
export function mapToPrice(room: Room) {
switch (room.priceType) {
case PriceTypeEnum.cheque:
return {
corporateCheque: {
additionalPricePerStay: room.roomPrice.perStay.local.price,
currency: room.roomPrice.perStay.local.currency,
numberOfCheques: room.cheques,
},
}
case PriceTypeEnum.money:
return {
regular: {
currency: room.currencyCode,
pricePerNight: room.roomPrice.perNight,
pricePerStay: room.roomPrice.perStay,
},
}
case PriceTypeEnum.points:
const nights = dt(room.checkOutDate)
.startOf("day")
.diff(dt(room.checkInDate).startOf("day"), "days")
return {
redemption: {
additionalPricePerStay: room.roomPrice.perStay.local.price,
currency: room.roomPrice.perStay.local.currency,
pointsPerNight: room.roomPoints / nights,
pointsPerStay: room.roomPoints,
},
}
case PriceTypeEnum.voucher:
return {
voucher: {
numberOfVouchers: room.vouchers,
},
}
default:
throw new Error(`Unknown payment method!`)
}
}
export function calculateTotalPrice(rooms: Room[], currency: CurrencyEnum) {
return rooms.reduce<Price>(
(total, room) => {
const pkgsSum = sumPackages(room.packages)
let breakfastPrice = 0
if (room.breakfast && !room.rateDefinition.breakfastIncluded) {
breakfastPrice = room.breakfast.localPrice.totalPrice
}
switch (room.priceType) {
case PriceTypeEnum.cheque:
{
total.local.currency = CurrencyEnum.CC
total.local.price = total.local.price + room.cheques
}
break
case PriceTypeEnum.money:
{
total.local.price =
total.local.price +
room.roomPrice.perStay.local.price +
pkgsSum.price +
breakfastPrice
if (!total.local.currency) {
total.local.currency = room.currencyCode
}
}
break
case PriceTypeEnum.points:
{
total.local.currency = CurrencyEnum.POINTS
total.local.price = total.local.price + room.roomPoints
}
break
case PriceTypeEnum.voucher:
total.local.currency = CurrencyEnum.Voucher
total.local.price = total.local.price + room.vouchers
break
}
switch (room.priceType) {
case PriceTypeEnum.cheque:
case PriceTypeEnum.points:
case PriceTypeEnum.voucher:
{
if (room.roomPrice.perStay.local.price || pkgsSum) {
total.local.additionalPrice =
room.roomPrice.perStay.local.price +
pkgsSum.price +
breakfastPrice
}
if (!total.local.additionalPriceCurrency) {
if (room.roomPrice.perStay.local.currency) {
total.local.additionalPriceCurrency =
room.roomPrice.perStay.local.currency
} else {
total.local.additionalPriceCurrency = currency
}
}
}
break
}
return total
},
{
local: {
currency,
price: 0,
},
requested: undefined,
}
)
}