diff --git a/apps/scandic-web/__mocks__/hotelReservation/index.ts b/apps/scandic-web/__mocks__/hotelReservation/index.ts
index 44249401d..b86ddb470 100644
--- a/apps/scandic-web/__mocks__/hotelReservation/index.ts
+++ b/apps/scandic-web/__mocks__/hotelReservation/index.ts
@@ -1,8 +1,8 @@
import { BedTypeEnum } from "@/constants/booking"
import { ChildBedMapEnum } from "@/types/components/bookingWidget/enums"
+import type { BreakfastPackage } from "@/types/components/hotelReservation/breakfast"
import type { BedTypeSelection } from "@/types/components/hotelReservation/enterDetails/bedType"
-import type { BreakfastPackage } from "@/types/components/hotelReservation/enterDetails/breakfast"
import type {
DetailsSchema,
RoomPrice,
diff --git a/apps/scandic-web/components/HotelReservation/BookingConfirmation/PaymentDetails/index.tsx b/apps/scandic-web/components/HotelReservation/BookingConfirmation/PaymentDetails/index.tsx
index ff355a487..2210613bf 100644
--- a/apps/scandic-web/components/HotelReservation/BookingConfirmation/PaymentDetails/index.tsx
+++ b/apps/scandic-web/components/HotelReservation/BookingConfirmation/PaymentDetails/index.tsx
@@ -4,9 +4,7 @@ import { useIntl } from "react-intl"
import { useBookingConfirmationStore } from "@/stores/booking-confirmation"
-import { CreditCardAddIcon } from "@/components/Icons"
import SkeletonShimmer from "@/components/SkeletonShimmer"
-import Button from "@/components/TempDesignSystem/Button"
import Body from "@/components/TempDesignSystem/Text/Body"
import Subtitle from "@/components/TempDesignSystem/Text/Subtitle"
import { formatPrice } from "@/utils/numberFormatting"
@@ -16,10 +14,11 @@ import styles from "./paymentDetails.module.css"
export default function PaymentDetails() {
const intl = useIntl()
- const rooms = useBookingConfirmationStore((state) => state.rooms)
- const currencyCode = useBookingConfirmationStore(
- (state) => state.currencyCode
- )
+ const { rooms, currencyCode } = useBookingConfirmationStore((state) => ({
+ rooms: state.rooms,
+ currencyCode: state.currencyCode,
+ }))
+
const hasAllRoomsLoaded = rooms.every((room) => room)
const grandTotal = rooms.reduce((acc, room) => {
const reservationTotalPrice = room?.totalPrice || 0
@@ -45,17 +44,6 @@ export default function PaymentDetails() {
)}
-
)
}
diff --git a/apps/scandic-web/components/HotelReservation/BookingConfirmation/PriceDetailsModal/index.tsx b/apps/scandic-web/components/HotelReservation/BookingConfirmation/PriceDetailsModal/index.tsx
new file mode 100644
index 000000000..85dbbf475
--- /dev/null
+++ b/apps/scandic-web/components/HotelReservation/BookingConfirmation/PriceDetailsModal/index.tsx
@@ -0,0 +1,233 @@
+"use client"
+import React from "react"
+import { useIntl } from "react-intl"
+
+import { dt } from "@/lib/dt"
+import { useBookingConfirmationStore } from "@/stores/booking-confirmation"
+
+import { PriceTagIcon } from "@/components/Icons"
+import ChevronRightSmallIcon from "@/components/Icons/ChevronRightSmall"
+import Modal from "@/components/Modal"
+import Button from "@/components/TempDesignSystem/Button"
+import Body from "@/components/TempDesignSystem/Text/Body"
+import Caption from "@/components/TempDesignSystem/Text/Caption"
+import useLang from "@/hooks/useLang"
+import { formatPrice } from "@/utils/numberFormatting"
+
+import styles from "./priceDetailsModal.module.css"
+
+function Row({
+ label,
+ value,
+ bold,
+}: {
+ label: string
+ value: string
+ bold?: boolean
+}) {
+ return (
+
@@ -99,23 +108,71 @@ export default function ReceiptRoom({
+ {room.roomFeatures
+ ? room.roomFeatures.map((feature) => (
+
+
+ {feature.description}
+
+
+
+ {formatPrice(intl, feature.totalPrice, feature.currency)}
+
+
+ ))
+ : null}
{room.bedDescription}
{formatPrice(intl, 0, currencyCode)}
+ {childBedCrib ? (
+
+
+
+ {intl.formatMessage(
+ { id: "Crib (child) × {count}" },
+ { count: childBedCrib.quantity }
+ )}
+
+
+ {intl.formatMessage({ id: "Based on availability" })}
+
+
+
+ {formatPrice(intl, 0, currencyCode)}
+
+
+ ) : null}
+ {childBedExtraBed ? (
+
+
+
+ {intl.formatMessage(
+ { id: "Extra bed (child) × {count}" },
+ {
+ count: childBedExtraBed.quantity,
+ }
+ )}
+
+
+
+ {formatPrice(intl, 0, currencyCode)}
+
+
+ ) : null}
{intl.formatMessage({ id: "Breakfast buffet" })}
{(room.rateDefinition.breakfastIncluded ?? room.breakfastIncluded) ? (
{intl.formatMessage({ id: "Included" })}
) : null}
- {room.selectedBreakfast ? (
+ {room.breakfast ? (
{formatPrice(
intl,
- room.selectedBreakfast.totalPrice,
- room.selectedBreakfast.currency
+ room.breakfast.totalPrice * room.adults,
+ room.breakfast.currency
)}
) : null}
diff --git a/apps/scandic-web/components/HotelReservation/BookingConfirmation/Receipt/TotalPrice/index.tsx b/apps/scandic-web/components/HotelReservation/BookingConfirmation/Receipt/TotalPrice/index.tsx
index 806e35870..59f614d94 100644
--- a/apps/scandic-web/components/HotelReservation/BookingConfirmation/Receipt/TotalPrice/index.tsx
+++ b/apps/scandic-web/components/HotelReservation/BookingConfirmation/Receipt/TotalPrice/index.tsx
@@ -4,21 +4,22 @@ import { useIntl } from "react-intl"
import { useBookingConfirmationStore } from "@/stores/booking-confirmation"
-import { ChevronRightSmallIcon } from "@/components/Icons"
import SkeletonShimmer from "@/components/SkeletonShimmer"
-import Button from "@/components/TempDesignSystem/Button"
import Divider from "@/components/TempDesignSystem/Divider"
import Body from "@/components/TempDesignSystem/Text/Body"
import { formatPrice } from "@/utils/numberFormatting"
+import PriceDetailsModal from "../../PriceDetailsModal"
+
import styles from "./totalPrice.module.css"
export default function TotalPrice() {
const intl = useIntl()
- const rooms = useBookingConfirmationStore((state) => state.rooms)
- const currencyCode = useBookingConfirmationStore(
- (state) => state.currencyCode
- )
+ const { rooms, currencyCode } = useBookingConfirmationStore((state) => ({
+ rooms: state.rooms,
+ currencyCode: state.currencyCode,
+ }))
+
const hasAllRoomsLoaded = rooms.every((room) => room)
const grandTotal = rooms.reduce((acc, room) => {
const reservationTotalPrice = room?.totalPrice || 0
@@ -42,19 +43,7 @@ export default function TotalPrice() {
)}
{hasAllRoomsLoaded ? (
-
-
-
+
) : (
diff --git a/apps/scandic-web/components/HotelReservation/BookingConfirmation/index.tsx b/apps/scandic-web/components/HotelReservation/BookingConfirmation/index.tsx
index c892c0453..340a6c821 100644
--- a/apps/scandic-web/components/HotelReservation/BookingConfirmation/index.tsx
+++ b/apps/scandic-web/components/HotelReservation/BookingConfirmation/index.tsx
@@ -114,12 +114,16 @@ export default async function BookingConfirmation({
return (
diff --git a/apps/scandic-web/components/HotelReservation/BookingConfirmation/utils.ts b/apps/scandic-web/components/HotelReservation/BookingConfirmation/utils.ts
index 436f9ce59..8b3826610 100644
--- a/apps/scandic-web/components/HotelReservation/BookingConfirmation/utils.ts
+++ b/apps/scandic-web/components/HotelReservation/BookingConfirmation/utils.ts
@@ -6,24 +6,29 @@ export function mapRoomState(
booking: BookingConfirmationSchema,
room: BookingConfirmationRoom
) {
- const selectedBreakfast = booking.packages.find(
+ const breakfast = booking.packages.find(
(pkg) => pkg.code === BreakfastPackageEnum.REGULAR_BREAKFAST
)
const breakfastIncluded = booking.packages.some(
(pkg) => pkg.code === BreakfastPackageEnum.FREE_MEMBER_BREAKFAST
)
+
return {
adults: booking.adults,
bedDescription: room.bedType.description,
+ breakfast,
breakfastIncluded,
children: booking.childrenAges.length,
+ childBedPreferences: booking.childBedPreferences,
confirmationNumber: booking.confirmationNumber,
fromDate: booking.checkInDate,
name: room.name,
rateDefinition: booking.rateDefinition,
+ roomFeatures: booking.packages.filter((p) => p.type === "RoomFeature"),
roomPrice: booking.roomPrice,
- selectedBreakfast,
toDate: booking.checkOutDate,
totalPrice: booking.totalPrice,
+ totalPriceExVat: booking.totalPriceExVat,
+ vatAmount: booking.vatAmount,
}
}
diff --git a/apps/scandic-web/components/HotelReservation/EnterDetails/Breakfast/index.tsx b/apps/scandic-web/components/HotelReservation/EnterDetails/Breakfast/index.tsx
index 4ae2d914c..712aac448 100644
--- a/apps/scandic-web/components/HotelReservation/EnterDetails/Breakfast/index.tsx
+++ b/apps/scandic-web/components/HotelReservation/EnterDetails/Breakfast/index.tsx
@@ -15,7 +15,7 @@ import { breakfastFormSchema } from "./schema"
import styles from "./breakfast.module.css"
-import type { BreakfastFormSchema } from "@/types/components/hotelReservation/enterDetails/breakfast"
+import type { BreakfastFormSchema } from "@/types/components/hotelReservation/breakfast"
import { BreakfastPackageEnum } from "@/types/enums/breakfast"
export default function Breakfast() {
diff --git a/apps/scandic-web/components/HotelReservation/PriceDetailsModal/PriceDetailsTable/index.tsx b/apps/scandic-web/components/HotelReservation/PriceDetailsModal/PriceDetailsTable/index.tsx
index 7882d029f..bfc5d7024 100644
--- a/apps/scandic-web/components/HotelReservation/PriceDetailsModal/PriceDetailsTable/index.tsx
+++ b/apps/scandic-web/components/HotelReservation/PriceDetailsModal/PriceDetailsTable/index.tsx
@@ -1,6 +1,6 @@
"use client"
-import React from "react"
+import { Fragment } from "react"
import { useIntl } from "react-intl"
import { dt } from "@/lib/dt"
@@ -13,8 +13,8 @@ import { formatPrice } from "@/utils/numberFormatting"
import styles from "./priceDetailsTable.module.css"
+import type { BreakfastPackage } from "@/types/components/hotelReservation/breakfast"
import type { BedTypeSchema } from "@/types/components/hotelReservation/enterDetails/bedType"
-import type { BreakfastPackage } from "@/types/components/hotelReservation/enterDetails/breakfast"
import type { RoomPrice } from "@/types/components/hotelReservation/enterDetails/details"
import type { Price } from "@/types/components/hotelReservation/price"
import type { Child } from "@/types/components/hotelReservation/selectRate/selectRate"
@@ -106,7 +106,7 @@ export default function PriceDetailsTable({
return (
{rooms.map((room, idx) => (
-
+
{rooms.length > 1 && (
@@ -134,8 +134,8 @@ export default function PriceDetailsTable({
label={feature.description}
value={formatPrice(
intl,
- 0,
- room.roomPrice.perStay.local.currency
+ parseInt(feature.localPrice.price),
+ feature.localPrice.currency
)}
/>
))
@@ -209,7 +209,7 @@ export default function PriceDetailsTable({
/>
) : null}
-
+
))}
diff --git a/apps/scandic-web/components/HotelReservation/PriceDetailsModal/index.tsx b/apps/scandic-web/components/HotelReservation/PriceDetailsModal/index.tsx
index 1b4019810..d99817f35 100644
--- a/apps/scandic-web/components/HotelReservation/PriceDetailsModal/index.tsx
+++ b/apps/scandic-web/components/HotelReservation/PriceDetailsModal/index.tsx
@@ -8,8 +8,8 @@ import Caption from "@/components/TempDesignSystem/Text/Caption"
import PriceDetailsTable from "./PriceDetailsTable"
+import type { BreakfastPackage } from "@/types/components/hotelReservation/breakfast"
import type { BedTypeSchema } from "@/types/components/hotelReservation/enterDetails/bedType"
-import type { BreakfastPackage } from "@/types/components/hotelReservation/enterDetails/breakfast"
import type { RoomPrice } from "@/types/components/hotelReservation/enterDetails/details"
import type { Price } from "@/types/components/hotelReservation/price"
import type { Child } from "@/types/components/hotelReservation/selectRate/selectRate"
diff --git a/apps/scandic-web/providers/BookingConfirmationProvider.tsx b/apps/scandic-web/providers/BookingConfirmationProvider.tsx
index 4aa89e382..ced2145ca 100644
--- a/apps/scandic-web/providers/BookingConfirmationProvider.tsx
+++ b/apps/scandic-web/providers/BookingConfirmationProvider.tsx
@@ -10,14 +10,25 @@ import type { BookingConfirmationStore } from "@/types/contexts/booking-confirma
import type { BookingConfirmationProviderProps } from "@/types/providers/booking-confirmation"
export default function BookingConfirmationProvider({
+ bookingCode,
children,
currencyCode,
+ fromDate,
+ toDate,
rooms,
+ vat,
}: BookingConfirmationProviderProps) {
const storeRef = useRef()
if (!storeRef.current) {
- const initialData = { rooms, currencyCode }
+ const initialData = {
+ bookingCode,
+ currencyCode,
+ fromDate,
+ toDate,
+ rooms,
+ vat,
+ }
storeRef.current = createBookingConfirmationStore(initialData)
}
diff --git a/apps/scandic-web/server/routers/booking/output.ts b/apps/scandic-web/server/routers/booking/output.ts
index 36568c95c..5f6b4c3d2 100644
--- a/apps/scandic-web/server/routers/booking/output.ts
+++ b/apps/scandic-web/server/routers/booking/output.ts
@@ -85,7 +85,7 @@ export type Guest = z.output
export const packageSchema = z
.object({
type: z.string().nullable(),
- description: z.string().nullable().default(""),
+ description: nullableStringValidator,
code: z.string().nullable().default(""),
price: z.object({
unit: z.number().int().nullable(),
diff --git a/apps/scandic-web/stores/booking-confirmation/index.ts b/apps/scandic-web/stores/booking-confirmation/index.ts
index 1ee64bc33..6f47cdfc8 100644
--- a/apps/scandic-web/stores/booking-confirmation/index.ts
+++ b/apps/scandic-web/stores/booking-confirmation/index.ts
@@ -11,7 +11,11 @@ import type {
export function createBookingConfirmationStore(initialState: InitialState) {
return create()((set) => ({
rooms: initialState.rooms,
+ bookingCode: initialState.bookingCode,
currencyCode: initialState.currencyCode,
+ fromDate: initialState.fromDate,
+ toDate: initialState.toDate,
+ vat: initialState.vat,
actions: {
setRoom: (room, idx) => {
set((state) => {
diff --git a/apps/scandic-web/stores/enter-details/index.ts b/apps/scandic-web/stores/enter-details/index.ts
index 0e7e695ba..f15e4879c 100644
--- a/apps/scandic-web/stores/enter-details/index.ts
+++ b/apps/scandic-web/stores/enter-details/index.ts
@@ -19,7 +19,7 @@ import {
writeToSessionStorage,
} from "./helpers"
-import type { BreakfastPackages } from "@/types/components/hotelReservation/enterDetails/breakfast"
+import type { BreakfastPackages } from "@/types/components/hotelReservation/breakfast"
import { StepEnum } from "@/types/enums/step"
import type {
DetailsState,
diff --git a/apps/scandic-web/types/components/hotelReservation/enterDetails/breakfast.ts b/apps/scandic-web/types/components/hotelReservation/breakfast.ts
similarity index 100%
rename from apps/scandic-web/types/components/hotelReservation/enterDetails/breakfast.ts
rename to apps/scandic-web/types/components/hotelReservation/breakfast.ts
diff --git a/apps/scandic-web/types/contexts/details/room.ts b/apps/scandic-web/types/contexts/details/room.ts
index f58d6bbe2..04685a3f3 100644
--- a/apps/scandic-web/types/contexts/details/room.ts
+++ b/apps/scandic-web/types/contexts/details/room.ts
@@ -1,5 +1,5 @@
+import type { BreakfastPackage } from "@/types/components/hotelReservation/breakfast"
import type { BedTypeSchema } from "@/types/components/hotelReservation/enterDetails/bedType"
-import type { BreakfastPackage } from "@/types/components/hotelReservation/enterDetails/breakfast"
import type { DetailsSchema } from "@/types/components/hotelReservation/enterDetails/details"
import type { StepEnum } from "@/types/enums/step"
import type { RoomState } from "@/types/stores/enter-details"
diff --git a/apps/scandic-web/types/providers/booking-confirmation.ts b/apps/scandic-web/types/providers/booking-confirmation.ts
index 796a9ddde..12be63a61 100644
--- a/apps/scandic-web/types/providers/booking-confirmation.ts
+++ b/apps/scandic-web/types/providers/booking-confirmation.ts
@@ -2,6 +2,10 @@ import type { Room } from "../stores/booking-confirmation"
export interface BookingConfirmationProviderProps
extends React.PropsWithChildren {
+ bookingCode: string | null
currencyCode: string
+ fromDate: Date
rooms: (Room | null)[]
+ toDate: Date
+ vat: number
}
diff --git a/apps/scandic-web/types/providers/enter-details.ts b/apps/scandic-web/types/providers/enter-details.ts
index a6430cd11..1fe4c3fa4 100644
--- a/apps/scandic-web/types/providers/enter-details.ts
+++ b/apps/scandic-web/types/providers/enter-details.ts
@@ -1,6 +1,6 @@
import type { Room } from "@/types/providers/details/room"
import type { SafeUser } from "@/types/user"
-import type { BreakfastPackages } from "../components/hotelReservation/enterDetails/breakfast"
+import type { BreakfastPackages } from "../components/hotelReservation/breakfast"
import type { SelectRateSearchParams } from "../components/hotelReservation/selectRate/selectRate"
export interface DetailsProviderProps extends React.PropsWithChildren {
diff --git a/apps/scandic-web/types/stores/booking-confirmation.ts b/apps/scandic-web/types/stores/booking-confirmation.ts
index 0a2917e21..75ee07585 100644
--- a/apps/scandic-web/types/stores/booking-confirmation.ts
+++ b/apps/scandic-web/types/stores/booking-confirmation.ts
@@ -1,30 +1,48 @@
+import type { ChildBedTypeEnum } from "@/constants/booking"
import type {
BookingConfirmation,
PackageSchema,
} from "../trpc/routers/booking/confirmation"
+export interface ChildBedPreference {
+ quantity: number
+ bedType: ChildBedTypeEnum
+}
+
export interface Room {
adults: number
bedDescription: string
+ breakfast?: PackageSchema
breakfastIncluded: boolean
children?: number
+ childBedPreferences: ChildBedPreference[]
confirmationNumber: string
fromDate: Date
name: string
rateDefinition: BookingConfirmation["booking"]["rateDefinition"]
+ roomFeatures?: PackageSchema[] | null
roomPrice: number
- selectedBreakfast?: PackageSchema
toDate: Date
totalPrice: number
+ totalPriceExVat: number
+ vatAmount: number
}
export interface InitialState {
+ bookingCode: string | null
+ fromDate: Date
rooms: (Room | null)[]
+ toDate: Date
currencyCode: string
+ vat: number
}
export interface BookingConfirmationState {
+ bookingCode: string | null
rooms: (Room | null)[]
currencyCode: string
+ vat: number
+ fromDate: Date
+ toDate: Date
actions: { setRoom: (room: Room, idx: number) => void }
}
diff --git a/apps/scandic-web/types/stores/enter-details.ts b/apps/scandic-web/types/stores/enter-details.ts
index 882092848..ca0b21b6c 100644
--- a/apps/scandic-web/types/stores/enter-details.ts
+++ b/apps/scandic-web/types/stores/enter-details.ts
@@ -1,11 +1,11 @@
+import type {
+ BreakfastPackage,
+ BreakfastPackages,
+} from "@/types/components/hotelReservation/breakfast"
import type {
BedTypeSchema,
BedTypeSelection,
} from "@/types/components/hotelReservation/enterDetails/bedType"
-import type {
- BreakfastPackage,
- BreakfastPackages,
-} from "@/types/components/hotelReservation/enterDetails/breakfast"
import type {
DetailsSchema,
MultiroomDetailsSchema,