Merged in fix/STAY-73-opt-in-email (pull request #3028)

Fix/STAY-73 opt in email

* fix: let user opt-in for modification email when adding ancillaries

* fix: add toast when successfully removing an ancillary


Approved-by: Erik Tiekstra
Approved-by: Elin Svedin
This commit is contained in:
Christel Westerberg
2025-10-29 12:45:18 +00:00
parent 333636c81a
commit 377c8886ad
8 changed files with 53 additions and 4 deletions

View File

@@ -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({
<Checkbox
name="termsAndConditions"
registerOptions={{ required: true }}
errorCodeMessages={{
[ancillaryError.TERMS_NOT_ACCEPTED]: intl.formatMessage({
id: "common.mustAcceptTermsError",
defaultMessage: "You must accept the terms and conditions",
}),
}}
>
<Typography variant="Body/Supporting text (caption)/smRegular">
<span>
@@ -229,6 +237,17 @@ export default function ConfirmationStep({
</span>
</Typography>
</Checkbox>
<Checkbox name="emailOptOut">
<Typography variant="Body/Supporting text (caption)/smRegular">
<span>
{intl.formatMessage({
id: "addAncillary.confirmationStep.optInForEmail",
defaultMessage:
"I want to receive an updated booking confirmation email reflecting this add-on",
})}
</span>
</Typography>
</Checkbox>
</div>
</div>
)

View File

@@ -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,
},

View File

@@ -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"],
}
)