diff --git a/apps/scandic-web/components/HotelReservation/MyStay/Ancillaries/AddAncillaryFlow/AddAncillaryFlowModal/Steps/ConfirmationStep/index.tsx b/apps/scandic-web/components/HotelReservation/MyStay/Ancillaries/AddAncillaryFlow/AddAncillaryFlowModal/Steps/ConfirmationStep/index.tsx
index 32381c2f9..922d2f6f3 100644
--- a/apps/scandic-web/components/HotelReservation/MyStay/Ancillaries/AddAncillaryFlow/AddAncillaryFlowModal/Steps/ConfirmationStep/index.tsx
+++ b/apps/scandic-web/components/HotelReservation/MyStay/Ancillaries/AddAncillaryFlow/AddAncillaryFlowModal/Steps/ConfirmationStep/index.tsx
@@ -20,6 +20,8 @@ import { useAddAncillaryStore } from "@/stores/my-stay/add-ancillary-flow"
import useLang from "@/hooks/useLang"
import { trackUpdatePaymentMethod } from "@/utils/tracking"
+import { ancillaryError } from "../../../schema"
+
import styles from "./confirmationStep.module.css"
import type { ConfirmationStepProps } from "@/types/components/myPages/myStay/ancillaries"
@@ -219,6 +221,12 @@ export default function ConfirmationStep({
@@ -229,6 +237,17 @@ export default function ConfirmationStep({
+
+
+
+ {intl.formatMessage({
+ id: "addAncillary.confirmationStep.optInForEmail",
+ defaultMessage:
+ "I want to receive an updated booking confirmation email reflecting this add-on",
+ })}
+
+
+
)
diff --git a/apps/scandic-web/components/HotelReservation/MyStay/Ancillaries/AddAncillaryFlow/AddAncillaryFlowModal/index.tsx b/apps/scandic-web/components/HotelReservation/MyStay/Ancillaries/AddAncillaryFlow/AddAncillaryFlowModal/index.tsx
index 6e7edc4bd..08c391f37 100644
--- a/apps/scandic-web/components/HotelReservation/MyStay/Ancillaries/AddAncillaryFlow/AddAncillaryFlowModal/index.tsx
+++ b/apps/scandic-web/components/HotelReservation/MyStay/Ancillaries/AddAncillaryFlow/AddAncillaryFlowModal/index.tsx
@@ -97,6 +97,7 @@ export default function AddAncillaryFlowModal({
deliveryTime: defaultDeliveryTime,
optionalText: "",
termsAndConditions: false,
+ optInEmail: false,
paymentMethod: booking.guaranteeInfo
? PaymentMethodEnum.card
: savedCreditCards?.length
@@ -152,6 +153,7 @@ export default function AddAncillaryFlowModal({
ancillaryDeliveryTime: selectedAncillary?.requiresDeliveryTime
? data.deliveryTime
: undefined,
+ emailOptOut: !data.optInEmail,
packages: packages,
language: lang,
},
diff --git a/apps/scandic-web/components/HotelReservation/MyStay/Ancillaries/AddAncillaryFlow/schema.ts b/apps/scandic-web/components/HotelReservation/MyStay/Ancillaries/AddAncillaryFlow/schema.ts
index e2ed0d9c9..8ee928fc4 100644
--- a/apps/scandic-web/components/HotelReservation/MyStay/Ancillaries/AddAncillaryFlow/schema.ts
+++ b/apps/scandic-web/components/HotelReservation/MyStay/Ancillaries/AddAncillaryFlow/schema.ts
@@ -7,6 +7,11 @@ const quantitySchemaWithoutRefine = z.object({
quantityWithCard: z.number().nullable(),
})
+export const ancillaryError = {
+ TERMS_NOT_ACCEPTED: "TERMS_NOT_ACCEPTED",
+ MIN_QUANTITY_NOT_REACHED: "MIN_QUANTITY_NOT_REACHED",
+} as const
+
export const quantitySchema = z
.object({})
.merge(quantitySchemaWithoutRefine)
@@ -14,7 +19,7 @@ export const quantitySchema = z
(data) =>
(data.quantityWithPoints ?? 0) > 0 || (data.quantityWithCard ?? 0) > 0,
{
- message: "You must select at least one quantity",
+ message: ancillaryError.MIN_QUANTITY_NOT_REACHED,
path: ["quantityWithCard"],
}
)
@@ -23,7 +28,10 @@ export const ancillaryFormSchema = z
.object({
deliveryTime: z.string(),
optionalText: z.string(),
- termsAndConditions: z.boolean(),
+ termsAndConditions: z
+ .boolean()
+ .refine((value) => value === true, ancillaryError.TERMS_NOT_ACCEPTED),
+ optInEmail: z.boolean(),
paymentMethod: nullableStringValidator,
})
.merge(quantitySchemaWithoutRefine)
@@ -31,7 +39,7 @@ export const ancillaryFormSchema = z
(data) =>
(data.quantityWithPoints ?? 0) > 0 || (data.quantityWithCard ?? 0) > 0,
{
- message: "You must select at least one quantity",
+ message: ancillaryError.MIN_QUANTITY_NOT_REACHED,
path: ["quantityWithCard"],
}
)
diff --git a/apps/scandic-web/components/HotelReservation/MyStay/Ancillaries/AddedAncillaries/RemoveButton.tsx b/apps/scandic-web/components/HotelReservation/MyStay/Ancillaries/AddedAncillaries/RemoveButton.tsx
index 25e97b672..b0c200e3a 100644
--- a/apps/scandic-web/components/HotelReservation/MyStay/Ancillaries/AddedAncillaries/RemoveButton.tsx
+++ b/apps/scandic-web/components/HotelReservation/MyStay/Ancillaries/AddedAncillaries/RemoveButton.tsx
@@ -76,6 +76,13 @@ export default function RemoveButton({
if (!data) {
throw new Error()
}
+ toast.success(
+ intl.formatMessage({
+ id: "myStay.removeAncillary.success",
+ defaultMessage:
+ "The product has now been removed from your booking.",
+ })
+ )
utils.booking.get.invalidate({
refId: refId,
})
diff --git a/apps/scandic-web/components/HotelReservation/MyStay/Ancillaries/GuaranteeCallback/index.tsx b/apps/scandic-web/components/HotelReservation/MyStay/Ancillaries/GuaranteeCallback/index.tsx
index 2b9f92443..b781857a1 100644
--- a/apps/scandic-web/components/HotelReservation/MyStay/Ancillaries/GuaranteeCallback/index.tsx
+++ b/apps/scandic-web/components/HotelReservation/MyStay/Ancillaries/GuaranteeCallback/index.tsx
@@ -56,6 +56,7 @@ export default function GuaranteeAncillaryHandler({
ancillaryDeliveryTime: selectedAncillary.requiresDeliveryTime
? formData.deliveryTime
: undefined,
+ emailOptOut: !formData.optInEmail,
packages,
language: lang,
},
diff --git a/apps/scandic-web/utils/getErrorMessage.ts b/apps/scandic-web/utils/getErrorMessage.ts
index fc3c656e0..3ae8cde82 100644
--- a/apps/scandic-web/utils/getErrorMessage.ts
+++ b/apps/scandic-web/utils/getErrorMessage.ts
@@ -8,11 +8,22 @@ import { signupErrors } from "@scandic-hotels/trpc/routers/user/schemas"
import { editProfileErrors } from "@/components/Forms/Edit/Profile/schema"
import { findMyBookingErrors } from "@/components/HotelReservation/FindMyBooking/schema"
+import { ancillaryError } from "@/components/HotelReservation/MyStay/Ancillaries/AddAncillaryFlow/schema"
import type { IntlShape } from "react-intl"
export function getErrorMessage(intl: IntlShape, errorCode?: string) {
switch (errorCode) {
+ case ancillaryError.MIN_QUANTITY_NOT_REACHED:
+ return intl.formatMessage({
+ id: "addAncillary.selectQuantityStep.minQuantityNotReached",
+ defaultMessage: "You must select at least one quantity",
+ })
+ case ancillaryError.TERMS_NOT_ACCEPTED:
+ return intl.formatMessage({
+ id: "addAncillary.confirmationStep.termsAndConditionsNotice",
+ defaultMessage: "You must accept the terms and conditions to proceed",
+ })
case findMyBookingErrors.BOOKING_NUMBER_INVALID:
return intl.formatMessage({
id: "error.invalidBookingNumber",
diff --git a/packages/trpc/lib/routers/booking/input.ts b/packages/trpc/lib/routers/booking/input.ts
index 7cca42f3e..990a7d666 100644
--- a/packages/trpc/lib/routers/booking/input.ts
+++ b/packages/trpc/lib/routers/booking/input.ts
@@ -14,6 +14,7 @@ export const addPackageInput = z.object({
comment: z.string().optional(),
})
),
+ emailOptOut: z.boolean(),
language: z.nativeEnum(Lang).transform((val) => langToApiLang[val]),
})
diff --git a/packages/trpc/lib/routers/booking/mutation/index.ts b/packages/trpc/lib/routers/booking/mutation/index.ts
index 2878db24f..e864048b4 100644
--- a/packages/trpc/lib/routers/booking/mutation/index.ts
+++ b/packages/trpc/lib/routers/booking/mutation/index.ts
@@ -145,7 +145,7 @@ export const bookingMutationRouter = router({
headers,
body: body,
},
- { language }
+ { language, emailOptOut: input.emailOptOut }
)
if (!apiResponse.ok) {