From 5b90e15746ff7a2313bfa3959d4dbe4aab0ac99b Mon Sep 17 00:00:00 2001 From: Bianca Widstam Date: Thu, 12 Jun 2025 12:51:37 +0000 Subject: [PATCH] Merged in fix/SW-2626-error-message-multiroom-reward (pull request #2299) fix(SW-2626): add multiroom reward error message for mobile * fix(SW-2626): add multiroom reward error message for mobile * fix(SW-2626): error message to red color * fix(SW-2626): fix errorContainer * fix(SW-2626): fix button fullwidth * fix(SW-2626): fix button fullwidth * fix(SW-2626): add design * fix(SW-2626): add new colors for checkbox * fix(SW-2626): new color for input * fix(SW-2626): fix pr comment * fix(SW-2626): final ui for desktop and mobile Approved-by: Hrishikesh Vaipurkar --- .../BookingCode/booking-code.module.css | 24 +++++-- .../FormContent/BookingCode/index.tsx | 64 ++++++++++--------- .../FormContent/RewardNight/index.tsx | 38 +++++++---- .../RewardNight/reward-night.module.css | 36 ++++++++--- .../Forms/BookingWidget/FormContent/index.tsx | 13 ++-- .../Forms/BookingWidget/FormContent/utils.ts | 8 +++ .../components/GuestsRoomsPicker/Form.tsx | 64 ++++++++++++------- .../guests-rooms-picker.module.css | 16 ++++- .../components/GuestsRoomsPicker/index.tsx | 2 +- .../PaymentOption/paymentOption.module.css | 2 +- .../FilterCheckbox/filterCheckbox.module.css | 4 +- .../Form/Checkbox/checkbox.module.css | 2 +- .../Form/Switch/switch.module.css | 12 ++-- .../TempDesignSystem/Select/select.module.css | 2 +- .../Tooltip/tooltip.module.css | 40 ++++++++---- 15 files changed, 213 insertions(+), 114 deletions(-) create mode 100644 apps/scandic-web/components/Forms/BookingWidget/FormContent/utils.ts diff --git a/apps/scandic-web/components/Forms/BookingWidget/FormContent/BookingCode/booking-code.module.css b/apps/scandic-web/components/Forms/BookingWidget/FormContent/BookingCode/booking-code.module.css index e422d18ca..03bcb5173 100644 --- a/apps/scandic-web/components/Forms/BookingWidget/FormContent/BookingCode/booking-code.module.css +++ b/apps/scandic-web/components/Forms/BookingWidget/FormContent/BookingCode/booking-code.module.css @@ -16,20 +16,20 @@ align-items: center; gap: var(--Spacing-x-half); position: relative; + color: var(--Text-Accent-Primary); } .errorContainer { display: flex; flex-direction: column; - gap: var(--Spacing-x1); -} -.error { - display: flex; - gap: var(--Spacing-x-half); + gap: var(--Space-x2); } -.errorIcon { - min-width: 20px; +.error { + display: flex; + gap: var(--Space-x1); + white-space: break-spaces; + color: var(--UI-Text-Error); } .bookingCodeRemember, @@ -52,10 +52,17 @@ align-items: center; } +.removeButton { + width: 100%; +} + @media screen and (max-width: 767px) { .hideOnMobile { display: none; } + .removeButton { + display: none; + } } @media screen and (min-width: 768px) { @@ -69,6 +76,9 @@ justify-content: space-between; border-radius: var(--Spacing-x-one-and-half); } + .error { + color: var(--Text-Default); + } } @media screen and (min-width: 768px) and (max-width: 1366px) { diff --git a/apps/scandic-web/components/Forms/BookingWidget/FormContent/BookingCode/index.tsx b/apps/scandic-web/components/Forms/BookingWidget/FormContent/BookingCode/index.tsx index 8a53dd364..474a1edbb 100644 --- a/apps/scandic-web/components/Forms/BookingWidget/FormContent/BookingCode/index.tsx +++ b/apps/scandic-web/components/Forms/BookingWidget/FormContent/BookingCode/index.tsx @@ -5,6 +5,7 @@ import { useIntl } from "react-intl" import { useMediaQuery } from "usehooks-ts" import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon" +import { Typography } from "@scandic-hotels/design-system/Typography" import { REDEMPTION } from "@/constants/booking" @@ -17,8 +18,8 @@ import Switch from "@/components/TempDesignSystem/Form/Switch" import Body from "@/components/TempDesignSystem/Text/Body" import Caption from "@/components/TempDesignSystem/Text/Caption" -import { bookingWidgetErrors } from "../../schema" import { Input as BookingWidgetInput } from "../Input" +import { isMultiRoomError } from "../utils" import styles from "./booking-code.module.css" @@ -70,6 +71,7 @@ export default function BookingCode() { // Add delay to handle table mode rendering setTimeout(function () { setValue(REDEMPTION, false, { + shouldValidate: true, shouldDirty: true, }) }) @@ -147,13 +149,9 @@ export default function BookingCode() { >
- + {codeVoucher} - +
{codeError?.message ? ( - + ) : ( @@ -279,29 +278,36 @@ function CodeRemember({ bookingCodeValue, onApplyClick }: CodeRememberProps) { ) } -function BookingCodeError({ codeError }: { codeError: FieldError }) { +function BookingCodeError({ + codeError, + isDesktop = false, +}: { + codeError: FieldError + isDesktop?: boolean +}) { const intl = useIntl() - const isMultiroomErr = - codeError.message === - bookingWidgetErrors.MULTIROOM_BOOKING_CODE_UNAVAILABLE || - codeError.message === bookingWidgetErrors.MULTIROOM_REWARD_NIGHT_UNAVAILABLE - const isInvalidErr = - codeError.message === bookingWidgetErrors.BOOKING_CODE_INVALID + const isMultiroomError = isMultiRoomError(codeError.message) return (
- - - {getErrorMessage(intl, codeError.message)} - - {isMultiroomErr ? ( - + + + + {getErrorMessage(intl, codeError.message)} + + + {isMultiroomError ? ( +
+ +
) : null}
) @@ -325,7 +331,7 @@ export function RemoveExtraRooms({ ...props }: ButtonProps) { type="button" onClick={removeExtraRooms} size="small" - intent="primary" + intent="secondary" {...props} > {intl.formatMessage({ diff --git a/apps/scandic-web/components/Forms/BookingWidget/FormContent/RewardNight/index.tsx b/apps/scandic-web/components/Forms/BookingWidget/FormContent/RewardNight/index.tsx index 47b1af026..0c68634ac 100644 --- a/apps/scandic-web/components/Forms/BookingWidget/FormContent/RewardNight/index.tsx +++ b/apps/scandic-web/components/Forms/BookingWidget/FormContent/RewardNight/index.tsx @@ -3,6 +3,7 @@ import { useCallback, useEffect, useRef } from "react" import { useFormContext } from "react-hook-form" import { useIntl } from "react-intl" +import { useMediaQuery } from "usehooks-ts" import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon" import { Typography } from "@scandic-hotels/design-system/Typography" @@ -16,6 +17,7 @@ import { getErrorMessage } from "@/components/TempDesignSystem/Form/Input/errors import Caption from "@/components/TempDesignSystem/Text/Caption" import { RemoveExtraRooms } from "../BookingCode" +import { isMultiRoomError } from "../utils" import styles from "./reward-night.module.css" @@ -38,7 +40,7 @@ export default function RewardNight() { "To book a reward night, make sure you're logged in to your Scandic Friends account.", }) const redemptionErr = errors[REDEMPTION] - const isMultiRoomError = redemptionErr?.message?.indexOf("Multi-room") === 0 + const isDesktop = useMediaQuery("(min-width: 767px)") function validateRedemption(value: boolean) { // Validate redemption as per the rules defined in the schema @@ -55,10 +57,10 @@ export default function RewardNight() { } const resetOnMultiroomError = useCallback(() => { - if (isMultiRoomError) { + if (isMultiRoomError(redemptionErr?.message) && isDesktop) { setValue(REDEMPTION, false, { shouldValidate: true }) } - }, [isMultiRoomError, setValue]) + }, [redemptionErr?.message, setValue, isDesktop]) function closeOnBlur(evt: FocusEvent) { const target = evt.relatedTarget as HTMLElement @@ -119,16 +121,26 @@ export default function RewardNight() { {redemptionErr && (
- - - {getErrorMessage(intl, redemptionErr.message)} - - {isMultiRoomError ? : null} + + + + {getErrorMessage(intl, redemptionErr.message)} + + + {isMultiRoomError(redemptionErr.message) ? ( +
+ +
+ ) : null}
)}
diff --git a/apps/scandic-web/components/Forms/BookingWidget/FormContent/RewardNight/reward-night.module.css b/apps/scandic-web/components/Forms/BookingWidget/FormContent/RewardNight/reward-night.module.css index af1d13812..aa54fd4c0 100644 --- a/apps/scandic-web/components/Forms/BookingWidget/FormContent/RewardNight/reward-night.module.css +++ b/apps/scandic-web/components/Forms/BookingWidget/FormContent/RewardNight/reward-night.module.css @@ -1,23 +1,19 @@ .errorContainer { - background: var(--Base-Surface-Primary-light-Normal); - border-radius: var(--Spacing-x-one-and-half); display: grid; - gap: var(--Spacing-x1); - padding: var(--Spacing-x2); - position: absolute; - top: calc(100% + 16px); - width: 320px; + gap: var(--Space-x2); + margin-top: var(--Space-x2); } .error { display: flex; - gap: var(--Spacing-x-half); + gap: var(--Space-x1); + color: var(--UI-Text-Error); + white-space: break-spaces; } .errorIcon { min-width: 20px; } - .rewardNightLabel { align-items: center; display: flex; @@ -28,3 +24,25 @@ max-width: 560px; margin-top: var(--Spacing-x2); } + +@media screen and (max-width: 767px) { + .hideOnMobile { + display: none; + } +} + +@media screen and (min-width: 768px) { + .errorContainer { + border-radius: var(--Space-x15); + padding: var(--Space-x2); + background: var(--Base-Surface-Primary-light-Normal); + position: absolute; + top: calc(100% + 16px); + width: 320px; + margin-top: 0; + box-shadow: var(--popup-box-shadow); + } + .error { + color: var(--Text-Default); + } +} diff --git a/apps/scandic-web/components/Forms/BookingWidget/FormContent/index.tsx b/apps/scandic-web/components/Forms/BookingWidget/FormContent/index.tsx index 65a3e3df2..0a3ec00c1 100644 --- a/apps/scandic-web/components/Forms/BookingWidget/FormContent/index.tsx +++ b/apps/scandic-web/components/Forms/BookingWidget/FormContent/index.tsx @@ -7,6 +7,7 @@ import { useIntl } from "react-intl" import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon" import { Typography } from "@scandic-hotels/design-system/Typography" +import { REDEMPTION } from "@/constants/booking" import { hotelreservation } from "@/constants/routes/hotelReservation" import { dt } from "@/lib/dt" @@ -18,6 +19,7 @@ import useLang from "@/hooks/useLang" import { RemoveExtraRooms } from "./BookingCode" import { Search, SearchSkeleton } from "./Search" +import { isMultiRoomError } from "./utils" import ValidationError from "./ValidationError" import Voucher, { VoucherSkeleton } from "./Voucher" @@ -108,12 +110,11 @@ export default function FormContent({
- {errors.bookingCode?.value?.message?.indexOf("Multi-room") === 0 ? ( - + {isMultiRoomError(errors.bookingCode?.value?.message) || + isMultiRoomError(errors[REDEMPTION]?.message) ? ( +
+ +
) : null} +
+ - - {addRoomLabel} - - + + + {addRoomDisabledTextForSpecialRate} + + +
) : ( canAddRooms && ( @@ -151,7 +169,7 @@ export default function GuestsRoomsPickerDialog({
) diff --git a/apps/scandic-web/components/HotelReservation/PaymentOption/paymentOption.module.css b/apps/scandic-web/components/HotelReservation/PaymentOption/paymentOption.module.css index 4ea43e3d1..78206dfce 100644 --- a/apps/scandic-web/components/HotelReservation/PaymentOption/paymentOption.module.css +++ b/apps/scandic-web/components/HotelReservation/PaymentOption/paymentOption.module.css @@ -25,7 +25,7 @@ } .radio.selected { - border: 8px solid var(--UI-Input-Controls-Fill-Selected); + border: 8px solid var(--Surface-UI-Fill-Active); } .titleContainer { diff --git a/apps/scandic-web/components/HotelReservation/SelectHotel/HotelFilter/FilterCheckbox/filterCheckbox.module.css b/apps/scandic-web/components/HotelReservation/SelectHotel/HotelFilter/FilterCheckbox/filterCheckbox.module.css index b301a57b8..de855aa65 100644 --- a/apps/scandic-web/components/HotelReservation/SelectHotel/HotelFilter/FilterCheckbox/filterCheckbox.module.css +++ b/apps/scandic-web/components/HotelReservation/SelectHotel/HotelFilter/FilterCheckbox/filterCheckbox.module.css @@ -6,8 +6,8 @@ } .container[data-selected] .checkbox { - border: var(--UI-Input-Controls-Fill-Selected); - background: var(--UI-Input-Controls-Fill-Selected); + border: var(--Surface-UI-Fill-Active); + background: var(--Surface-UI-Fill-Active); } .container:focus-within .checkbox { diff --git a/apps/scandic-web/components/TempDesignSystem/Form/Checkbox/checkbox.module.css b/apps/scandic-web/components/TempDesignSystem/Form/Checkbox/checkbox.module.css index d93bdcd08..17df966ac 100644 --- a/apps/scandic-web/components/TempDesignSystem/Form/Checkbox/checkbox.module.css +++ b/apps/scandic-web/components/TempDesignSystem/Form/Checkbox/checkbox.module.css @@ -7,7 +7,7 @@ .container[data-selected] .checkbox { border: none; - background: var(--UI-Input-Controls-Fill-Selected); + background: var(--Surface-UI-Fill-Active); } .container[data-disabled] .checkbox { diff --git a/apps/scandic-web/components/TempDesignSystem/Form/Switch/switch.module.css b/apps/scandic-web/components/TempDesignSystem/Form/Switch/switch.module.css index 19aaa9bcb..4c1f2e491 100644 --- a/apps/scandic-web/components/TempDesignSystem/Form/Switch/switch.module.css +++ b/apps/scandic-web/components/TempDesignSystem/Form/Switch/switch.module.css @@ -10,8 +10,8 @@ .switch { width: 40px; height: 24px; - border: 2px solid var(--UI-Input-Controls-Border-Normal); - background: var(--UI-Input-Controls-Surface-Normal); + border: 2px solid var(--Surface-Secondary-Default-dark); + background: var(--Surface-Secondary-Default-dark); border-radius: 24px; transition: all 200ms; display: block; @@ -22,7 +22,7 @@ margin: 2px; width: 16px; height: 16px; - background: var(--UI-Input-Controls-Border-Normal); + background: var(--Surface-UI-Fill-Default); border-radius: 100%; transition: all 200ms; } @@ -30,11 +30,11 @@ .container[data-selected] { .switch { - border-color: var(--UI-Input-Controls-Fill-Selected); - background: var(--UI-Input-Controls-Fill-Selected); + border-color: var(--Surface-UI-Fill-Active); + background: var(--Surface-UI-Fill-Active); &:before { - background: var(--UI-Input-Controls-Surface-Normal); + background: var(--Surface-UI-Fill-Default); transform: translateX(100%); } } diff --git a/apps/scandic-web/components/TempDesignSystem/Select/select.module.css b/apps/scandic-web/components/TempDesignSystem/Select/select.module.css index b048bc536..38b0a153b 100644 --- a/apps/scandic-web/components/TempDesignSystem/Select/select.module.css +++ b/apps/scandic-web/components/TempDesignSystem/Select/select.module.css @@ -121,7 +121,7 @@ } .listBoxItem[data-selected="true"].showRadioButton:before { - box-shadow: inset 0 0 0 8px var(--UI-Input-Controls-Fill-Selected); + box-shadow: inset 0 0 0 8px var(--Surface-UI-Fill-Active); } /* Use global react aria classnames here since setting a css modules classname overrides diff --git a/apps/scandic-web/components/TempDesignSystem/Tooltip/tooltip.module.css b/apps/scandic-web/components/TempDesignSystem/Tooltip/tooltip.module.css index 8c17b7f6a..c521f814c 100644 --- a/apps/scandic-web/components/TempDesignSystem/Tooltip/tooltip.module.css +++ b/apps/scandic-web/components/TempDesignSystem/Tooltip/tooltip.module.css @@ -5,8 +5,8 @@ .tooltip { padding: var(--Spacing-x1); - background-color: var(--UI-Text-Active); - border: 0.5px solid var(--UI-Border-Active); + background-color: var(--Surface-UI-Fill-Intense); + border: 0.5px solid var(--Border-Interactive-Focus); border-radius: var(--Corner-radius-md); color: var(--Base-Text-Inverted); position: absolute; @@ -54,7 +54,8 @@ top: -8px; left: 16px; border-width: 0 7px 8px 7px; - border-color: transparent transparent var(--UI-Text-Active) transparent; + border-color: transparent transparent var(--Border-Interactive-Focus) + transparent; } .bottom.arrowCenter::before { @@ -62,21 +63,24 @@ left: 50%; transform: translateX(-50%); border-width: 0 7px 8px 7px; - border-color: transparent transparent var(--UI-Text-Active) transparent; + border-color: transparent transparent var(--Border-Interactive-Focus) + transparent; } .bottom.arrowRight::before { top: -8px; right: 16px; border-width: 0 7px 8px 7px; - border-color: transparent transparent var(--UI-Text-Active) transparent; + border-color: transparent transparent var(--Border-Interactive-Focus) + transparent; } .top.arrowLeft::before { bottom: -8px; left: 16px; border-width: 8px 7px 0 7px; - border-color: var(--UI-Text-Active) transparent transparent transparent; + border-color: var(--Border-Interactive-Focus) transparent transparent + transparent; } .top.arrowCenter::before { @@ -84,14 +88,16 @@ left: 50%; transform: translateX(-50%); border-width: 8px 7px 0 7px; - border-color: var(--UI-Text-Active) transparent transparent transparent; + border-color: var(--Border-Interactive-Focus) transparent transparent + transparent; } .top.arrowRight::before { bottom: -8px; right: 16px; border-width: 8px 7px 0 7px; - border-color: var(--UI-Text-Active) transparent transparent transparent; + border-color: var(--Border-Interactive-Focus) transparent transparent + transparent; } .left.arrowTop::before { @@ -99,7 +105,8 @@ right: -8px; transform: translateY(-50%); border-width: 7px 0 7px 8px; - border-color: transparent transparent transparent var(--UI-Text-Active); + border-color: transparent transparent transparent + var(--Border-Interactive-Focus); } .left.arrowCenter::before { @@ -107,7 +114,8 @@ right: -8px; transform: translateY(-50%); border-width: 7px 0 7px 8px; - border-color: transparent transparent transparent var(--UI-Text-Active); + border-color: transparent transparent transparent + var(--Border-Interactive-Focus); } .left.arrowBottom::before { @@ -115,7 +123,8 @@ right: -8px; transform: translateY(50%); border-width: 7px 0 7px 8px; - border-color: transparent transparent transparent var(--UI-Text-Active); + border-color: transparent transparent transparent + var(--Border-Interactive-Focus); } .right.arrowTop::before { @@ -123,7 +132,8 @@ left: -8px; transform: translateY(-50%); border-width: 7px 8px 7px 0; - border-color: transparent var(--UI-Text-Active) transparent transparent; + border-color: transparent var(--Border-Interactive-Focus) transparent + transparent; } .right.arrowCenter::before { @@ -131,7 +141,8 @@ left: -8px; transform: translateY(-50%); border-width: 7px 8px 7px 0; - border-color: transparent var(--UI-Text-Active) transparent transparent; + border-color: transparent var(--Border-Interactive-Focus) transparent + transparent; } .right.arrowBottom::before { @@ -139,7 +150,8 @@ left: -8px; transform: translateY(50%); border-width: 7px 8px 7px 0; - border-color: transparent var(--UI-Text-Active) transparent transparent; + border-color: transparent var(--Border-Interactive-Focus) transparent + transparent; } @media screen and (max-width: 767px) {