feat: SW-1422 Updated UX for booking code desktop and mobile
This commit is contained in:
@@ -85,7 +85,7 @@ export default function BookingWidgetClient({
|
|||||||
|
|
||||||
const selectedBookingCode = bookingWidgetSearchData
|
const selectedBookingCode = bookingWidgetSearchData
|
||||||
? bookingWidgetSearchData.bookingCode
|
? bookingWidgetSearchData.bookingCode
|
||||||
: undefined
|
: ""
|
||||||
|
|
||||||
const defaultRoomsData: BookingWidgetSchema["rooms"] =
|
const defaultRoomsData: BookingWidgetSchema["rooms"] =
|
||||||
bookingWidgetSearchData?.rooms?.map((room) => ({
|
bookingWidgetSearchData?.rooms?.map((room) => ({
|
||||||
@@ -113,7 +113,7 @@ export default function BookingWidgetClient({
|
|||||||
: now.utc().add(1, "day").format("YYYY-MM-DD"),
|
: now.utc().add(1, "day").format("YYYY-MM-DD"),
|
||||||
},
|
},
|
||||||
bookingCode: {
|
bookingCode: {
|
||||||
value: selectedBookingCode ?? "",
|
value: selectedBookingCode,
|
||||||
remember: false,
|
remember: false,
|
||||||
},
|
},
|
||||||
redemption: false,
|
redemption: false,
|
||||||
@@ -156,36 +156,36 @@ export default function BookingWidgetClient({
|
|||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const sessionStorageSearchData =
|
if (typeof window !== "undefined" && !selectedLocation) {
|
||||||
typeof window !== "undefined"
|
const sessionStorageSearchData = sessionStorage.getItem("searchData")
|
||||||
? sessionStorage.getItem("searchData")
|
|
||||||
: undefined
|
|
||||||
|
|
||||||
const initialSelectedLocation: Location | undefined =
|
const initialSelectedLocation: Location | undefined =
|
||||||
sessionStorageSearchData && isValidJson(sessionStorageSearchData)
|
sessionStorageSearchData && isValidJson(sessionStorageSearchData)
|
||||||
? JSON.parse(sessionStorageSearchData)
|
? JSON.parse(sessionStorageSearchData)
|
||||||
: undefined
|
: undefined
|
||||||
|
|
||||||
!selectedLocation?.name &&
|
|
||||||
initialSelectedLocation?.name &&
|
initialSelectedLocation?.name &&
|
||||||
methods.setValue("search", initialSelectedLocation.name)
|
methods.setValue("search", initialSelectedLocation.name)
|
||||||
!selectedLocation &&
|
|
||||||
sessionStorageSearchData &&
|
sessionStorageSearchData &&
|
||||||
methods.setValue("location", encodeURIComponent(sessionStorageSearchData))
|
methods.setValue(
|
||||||
|
"location",
|
||||||
|
encodeURIComponent(sessionStorageSearchData)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}, [methods, selectedLocation])
|
||||||
|
|
||||||
const storedBookingCode =
|
useEffect(() => {
|
||||||
typeof window !== "undefined"
|
if (typeof window !== "undefined" && !selectedBookingCode) {
|
||||||
? localStorage.getItem("bookingCode")
|
const storedBookingCode = localStorage.getItem("bookingCode")
|
||||||
: undefined
|
const initialBookingCode: BookingCodeSchema | undefined =
|
||||||
const initialBookingCode: BookingCodeSchema | undefined =
|
storedBookingCode && isValidJson(storedBookingCode)
|
||||||
storedBookingCode && isValidJson(storedBookingCode)
|
? JSON.parse(storedBookingCode)
|
||||||
? JSON.parse(storedBookingCode)
|
: undefined
|
||||||
: undefined
|
|
||||||
!selectedBookingCode &&
|
initialBookingCode?.remember &&
|
||||||
initialBookingCode &&
|
methods.setValue("bookingCode", initialBookingCode)
|
||||||
initialBookingCode.remember &&
|
}
|
||||||
methods.setValue("bookingCode", initialBookingCode)
|
}, [methods, selectedBookingCode])
|
||||||
}, [methods, selectedLocation, selectedBookingCode])
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<FormProvider {...methods}>
|
<FormProvider {...methods}>
|
||||||
|
|||||||
@@ -1,7 +1,12 @@
|
|||||||
|
.container {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
.bookingCodeLabel {
|
.bookingCodeLabel {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: var(--Spacing-x-half);
|
gap: var(--Spacing-x-half);
|
||||||
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
.error {
|
.error {
|
||||||
@@ -13,10 +18,33 @@
|
|||||||
min-width: 20px;
|
min-width: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.bookingCodeRemember {
|
.bookingCodeRemember,
|
||||||
display: flex;
|
.bookingCodeRememberVisible {
|
||||||
gap: var(--Spacing-x1);
|
|
||||||
|
|
||||||
/* ToDo: Remove once remember checkbox design are ready */
|
|
||||||
display: none;
|
display: none;
|
||||||
|
gap: var(--Spacing-x1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.bookingCodeRememberVisible {
|
||||||
|
display: flex;
|
||||||
|
position: absolute;
|
||||||
|
top: calc(100% + 16px);
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 768px) {
|
||||||
|
.hideOnMobile {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (min-width: 1367px) {
|
||||||
|
.bookingCodeRememberVisible {
|
||||||
|
padding: var(--Spacing-x2);
|
||||||
|
border-radius: var(--Spacing-x-one-and-half);
|
||||||
|
width: 320px;
|
||||||
|
background: white;
|
||||||
|
top: calc(100% + 24px);
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,14 @@
|
|||||||
|
import { useCallback, useEffect, useRef, useState } from "react"
|
||||||
|
import { Dialog, DialogTrigger, Popover } from "react-aria-components"
|
||||||
import { useFormContext } from "react-hook-form"
|
import { useFormContext } from "react-hook-form"
|
||||||
import { useIntl } from "react-intl"
|
import { useIntl } from "react-intl"
|
||||||
|
import { useMediaQuery } from "usehooks-ts"
|
||||||
|
|
||||||
import { ErrorCircleIcon, InfoCircleIcon } from "@/components/Icons"
|
import { ErrorCircleIcon, InfoCircleIcon } from "@/components/Icons"
|
||||||
import Modal from "@/components/Modal"
|
import Modal from "@/components/Modal"
|
||||||
import Button from "@/components/TempDesignSystem/Button"
|
import Button from "@/components/TempDesignSystem/Button"
|
||||||
import Checkbox from "@/components/TempDesignSystem/Form/Checkbox"
|
import Checkbox from "@/components/TempDesignSystem/Form/Checkbox"
|
||||||
|
import Switch from "@/components/TempDesignSystem/Form/Switch"
|
||||||
import Body from "@/components/TempDesignSystem/Text/Body"
|
import Body from "@/components/TempDesignSystem/Text/Body"
|
||||||
import Caption from "@/components/TempDesignSystem/Text/Caption"
|
import Caption from "@/components/TempDesignSystem/Text/Caption"
|
||||||
|
|
||||||
@@ -19,72 +23,228 @@ import type {
|
|||||||
|
|
||||||
export default function BookingCode() {
|
export default function BookingCode() {
|
||||||
const intl = useIntl()
|
const intl = useIntl()
|
||||||
|
const checkIsTablet = useMediaQuery(
|
||||||
|
"(min-width: 768px) and (max-width: 1367px)"
|
||||||
|
)
|
||||||
|
const checkIsDesktop = useMediaQuery("(min-width: 1367px)")
|
||||||
|
const [isTablet, setIsTablet] = useState(false)
|
||||||
|
const [isDesktop, setIsDesktop] = useState(false)
|
||||||
const {
|
const {
|
||||||
setValue,
|
setValue,
|
||||||
formState: { errors },
|
formState: { errors },
|
||||||
getValues,
|
getValues,
|
||||||
} = useFormContext<BookingWidgetSchema>()
|
} = useFormContext<BookingWidgetSchema>()
|
||||||
const codeError = errors["bookingCode"]?.value
|
|
||||||
|
|
||||||
|
const bookingCode: BookingCodeSchema = getValues("bookingCode")
|
||||||
|
const [isOpen, setIsOpen] = useState(!!bookingCode?.value)
|
||||||
|
const [showRemember, setShowRemember] = useState(false)
|
||||||
|
const [showRememberMobile, setShowRememberMobile] = useState(false)
|
||||||
|
const codeError = errors["bookingCode"]?.value
|
||||||
const codeVoucher = intl.formatMessage({ id: "Code / Voucher" })
|
const codeVoucher = intl.formatMessage({ id: "Code / Voucher" })
|
||||||
const addCode = intl.formatMessage({ id: "Add code" })
|
const addCode = intl.formatMessage({ id: "Add code" })
|
||||||
const bookingCodeTooltipText = intl.formatMessage({
|
const bookingCodeTooltipText = intl.formatMessage({
|
||||||
id: "booking.codes.information",
|
id: "If you're booking a promotional offer or a Corporate negotiated rate you'll need a special booking code. Don't use any special characters such as (.) (,) (-) (:). If you would like to make a booking with code VOF, please call us +46 8 517 517 20.Save your booking code for the next time you visit the page by ticking the box “Remember”. Don't tick the box if you're using a public computer to avoid unauthorized access to your booking code.",
|
||||||
})
|
})
|
||||||
const bookingCode: BookingCodeSchema = getValues("bookingCode")
|
const ref = useRef<HTMLDivElement | null>(null)
|
||||||
|
|
||||||
function updateBookingCodeFormValue(value: string) {
|
function updateBookingCodeFormValue(value: string) {
|
||||||
setValue("bookingCode.value", value, { shouldValidate: true })
|
setValue("bookingCode.value", value, { shouldValidate: true })
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
function toggleModal(isOpen: boolean) {
|
||||||
|
if (!isOpen && codeError) {
|
||||||
|
// console.log("Cannot be closed!!")
|
||||||
|
// setValue("bookingCode.flag", false)
|
||||||
|
} else if (!isOpen && !bookingCode?.value) {
|
||||||
|
setValue("bookingCode.flag", false)
|
||||||
|
setIsOpen(isOpen)
|
||||||
|
} else {
|
||||||
|
setIsOpen(isOpen)
|
||||||
|
if (isOpen || bookingCode?.value) {
|
||||||
|
setValue("bookingCode.flag", true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const closeIfOutside = useCallback(
|
||||||
|
(target: HTMLElement) => {
|
||||||
|
if (ref.current && target && !ref.current.contains(target)) {
|
||||||
|
setShowRemember(false)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[setShowRemember, ref]
|
||||||
|
)
|
||||||
|
|
||||||
|
function showRememberCheck() {
|
||||||
|
setShowRemember(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setIsTablet(checkIsTablet)
|
||||||
|
}, [checkIsTablet])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setIsDesktop(checkIsDesktop)
|
||||||
|
}, [checkIsDesktop])
|
||||||
|
|
||||||
|
const isRememberMobileVisible =
|
||||||
|
!isDesktop && (showRemember || !!bookingCode?.remember)
|
||||||
|
useEffect(() => {
|
||||||
|
setShowRememberMobile(isRememberMobileVisible)
|
||||||
|
}, [isRememberMobileVisible])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
function handleClickOutside(evt: Event) {
|
||||||
|
if (showRemember) {
|
||||||
|
const target = evt.target as HTMLElement
|
||||||
|
closeIfOutside(target)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
document.body.addEventListener("click", handleClickOutside)
|
||||||
|
return () => {
|
||||||
|
document.body.removeEventListener("click", handleClickOutside)
|
||||||
|
}
|
||||||
|
}, [closeIfOutside, showRemember])
|
||||||
|
|
||||||
|
return isTablet ? (
|
||||||
<>
|
<>
|
||||||
<label htmlFor="booking-code">
|
<DialogTrigger isOpen={isOpen} onOpenChange={toggleModal}>
|
||||||
<div className={styles.bookingCodeLabel}>
|
<Button type="button" intent="text">
|
||||||
<Caption color="uiTextMediumContrast" type="bold" asChild>
|
<Checkbox name="bookingCode.flag" checked={!!bookingCode?.value}>
|
||||||
<span>{codeVoucher}</span>
|
<Caption color="uiTextMediumContrast" type="bold" asChild>
|
||||||
</Caption>
|
<span>{codeVoucher}</span>
|
||||||
<Modal
|
</Caption>
|
||||||
trigger={
|
</Checkbox>
|
||||||
<Button intent="text">
|
</Button>
|
||||||
<InfoCircleIcon
|
<Popover
|
||||||
color="uiTextPlaceholder"
|
className="guests_picker_popover"
|
||||||
height={20}
|
placement="bottom start"
|
||||||
width={20}
|
offset={36}
|
||||||
|
>
|
||||||
|
<Dialog className={styles.pickerContainerDesktop}>
|
||||||
|
{({ close }) => (
|
||||||
|
<div className={styles.popover}>
|
||||||
|
<Input
|
||||||
|
type="text"
|
||||||
|
placeholder={addCode}
|
||||||
|
name="bookingCode"
|
||||||
|
id="booking-code"
|
||||||
|
onChange={(event) =>
|
||||||
|
updateBookingCodeFormValue(event.target.value)
|
||||||
|
}
|
||||||
|
defaultValue={bookingCode?.value}
|
||||||
/>
|
/>
|
||||||
</Button>
|
{codeError?.message ? (
|
||||||
}
|
<Caption color="red" className={styles.error}>
|
||||||
title={codeVoucher}
|
<ErrorCircleIcon color="red" className={styles.errorIcon} />
|
||||||
>
|
{intl.formatMessage({ id: codeError.message })}
|
||||||
<Body color="uiTextHighContrast">{bookingCodeTooltipText}</Body>
|
</Caption>
|
||||||
</Modal>
|
) : null}
|
||||||
</div>
|
<div className={styles.bookingCode}>
|
||||||
<Input
|
<Checkbox name="bookingCode.remember">
|
||||||
type="text"
|
<Caption asChild>
|
||||||
placeholder={addCode}
|
<span>{intl.formatMessage({ id: "Remember code" })}</span>
|
||||||
name="bookingCode"
|
</Caption>
|
||||||
id="booking-code"
|
</Checkbox>
|
||||||
onChange={(event) => updateBookingCodeFormValue(event.target.value)}
|
<Button
|
||||||
defaultValue={bookingCode?.value}
|
size="small"
|
||||||
/>
|
intent="primary"
|
||||||
</label>
|
type="button"
|
||||||
{codeError && codeError.message ? (
|
onClick={close}
|
||||||
|
disabled={codeError ? true : undefined}
|
||||||
|
>
|
||||||
|
{intl.formatMessage({ id: "Apply" })}
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</Dialog>
|
||||||
|
</Popover>
|
||||||
|
</DialogTrigger>
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<div
|
||||||
|
className={styles.container}
|
||||||
|
ref={ref}
|
||||||
|
onBlur={(e) => closeIfOutside(e.nativeEvent.relatedTarget as HTMLElement)}
|
||||||
|
>
|
||||||
|
<div className={styles.bookingCodeLabel}>
|
||||||
|
<Caption color="uiTextMediumContrast" type="bold" asChild>
|
||||||
|
<span>{codeVoucher}</span>
|
||||||
|
</Caption>
|
||||||
|
<Modal
|
||||||
|
trigger={
|
||||||
|
<Button intent="text">
|
||||||
|
<InfoCircleIcon
|
||||||
|
color="uiTextPlaceholder"
|
||||||
|
height={20}
|
||||||
|
width={20}
|
||||||
|
/>
|
||||||
|
</Button>
|
||||||
|
}
|
||||||
|
title={codeVoucher}
|
||||||
|
>
|
||||||
|
<Body color="uiTextHighContrast">{bookingCodeTooltipText}</Body>
|
||||||
|
</Modal>
|
||||||
|
</div>
|
||||||
|
<Input
|
||||||
|
type="text"
|
||||||
|
placeholder={addCode}
|
||||||
|
name="bookingCode"
|
||||||
|
id="booking-code"
|
||||||
|
onChange={(event) => updateBookingCodeFormValue(event.target.value)}
|
||||||
|
defaultValue={bookingCode?.value}
|
||||||
|
onFocus={showRememberCheck}
|
||||||
|
onBlur={(e) =>
|
||||||
|
closeIfOutside(e.nativeEvent.relatedTarget as HTMLElement)
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
{codeError?.message ? (
|
||||||
<Caption color="red" className={styles.error}>
|
<Caption color="red" className={styles.error}>
|
||||||
<ErrorCircleIcon color="red" className={styles.errorIcon} />
|
<ErrorCircleIcon color="red" className={styles.errorIcon} />
|
||||||
{intl.formatMessage({ id: codeError.message })}
|
{intl.formatMessage({ id: codeError.message })}
|
||||||
</Caption>
|
</Caption>
|
||||||
) : null}
|
) : null}
|
||||||
{/* ToDo: Update styles once designs are ready */}
|
{isDesktop ? (
|
||||||
<div className={styles.bookingCodeRemember}>
|
<div
|
||||||
<Checkbox name="bookingCode.remember">
|
className={
|
||||||
<Caption asChild>
|
showRemember
|
||||||
<span>{intl.formatMessage({ id: "Remember code" })}</span>
|
? styles.bookingCodeRememberVisible
|
||||||
</Caption>
|
: styles.bookingCodeRemember
|
||||||
</Checkbox>
|
}
|
||||||
<Button size="small" intent="primary" type="button">
|
>
|
||||||
{intl.formatMessage({ id: "Apply" })}
|
<Checkbox name="bookingCode.remember">
|
||||||
</Button>
|
<Caption asChild>
|
||||||
</div>
|
<span>{intl.formatMessage({ id: "Remember code" })}</span>
|
||||||
</>
|
</Caption>
|
||||||
|
</Checkbox>
|
||||||
|
{bookingCode?.value ? (
|
||||||
|
<Button
|
||||||
|
size="small"
|
||||||
|
className={styles.hideOnMobile}
|
||||||
|
intent="secondary"
|
||||||
|
type="button"
|
||||||
|
onClick={() => setShowRemember(false)}
|
||||||
|
>
|
||||||
|
{intl.formatMessage({ id: "Apply" })}
|
||||||
|
</Button>
|
||||||
|
) : null}
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
{!isDesktop ? (
|
||||||
|
<div
|
||||||
|
className={
|
||||||
|
showRememberMobile
|
||||||
|
? styles.bookingCodeRememberVisible
|
||||||
|
: styles.bookingCodeRemember
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Switch name="bookingCode.remember" className="mobile-switch">
|
||||||
|
<Caption asChild>
|
||||||
|
<span>{intl.formatMessage({ id: "Remember code" })}</span>
|
||||||
|
</Caption>
|
||||||
|
</Switch>
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,6 +32,12 @@
|
|||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 767px) {
|
||||||
|
.vouchers {
|
||||||
|
margin-bottom: var(--Spacing-x5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@media screen and (min-width: 768px) {
|
@media screen and (min-width: 768px) {
|
||||||
.vouchers {
|
.vouchers {
|
||||||
display: none;
|
display: none;
|
||||||
|
|||||||
@@ -31,7 +31,8 @@ export default function Form({
|
|||||||
type,
|
type,
|
||||||
})
|
})
|
||||||
|
|
||||||
const { handleSubmit, register } = useFormContext<BookingWidgetSchema>()
|
const { handleSubmit, register, setValue } =
|
||||||
|
useFormContext<BookingWidgetSchema>()
|
||||||
|
|
||||||
function onSubmit(data: BookingWidgetSchema) {
|
function onSubmit(data: BookingWidgetSchema) {
|
||||||
const locationData: Location = JSON.parse(decodeURIComponent(data.location))
|
const locationData: Location = JSON.parse(decodeURIComponent(data.location))
|
||||||
@@ -44,7 +45,7 @@ export default function Form({
|
|||||||
...(locationData.type == "cities"
|
...(locationData.type == "cities"
|
||||||
? { city: locationData.name }
|
? { city: locationData.name }
|
||||||
: { hotel: locationData.operaId || "" }),
|
: { hotel: locationData.operaId || "" }),
|
||||||
...(data.bookingCode && data.bookingCode.value
|
...(data.bookingCode?.value
|
||||||
? { bookingCode: data.bookingCode.value }
|
? { bookingCode: data.bookingCode.value }
|
||||||
: {}),
|
: {}),
|
||||||
})
|
})
|
||||||
@@ -54,6 +55,9 @@ export default function Form({
|
|||||||
if (data.bookingCode?.remember) {
|
if (data.bookingCode?.remember) {
|
||||||
localStorage.setItem("bookingCode", JSON.stringify(data.bookingCode))
|
localStorage.setItem("bookingCode", JSON.stringify(data.bookingCode))
|
||||||
}
|
}
|
||||||
|
if (!data.bookingCode?.value) {
|
||||||
|
setValue("bookingCode.remember", false)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -37,22 +37,26 @@ export const guestRoomsSchema = z.array(guestRoomSchema)
|
|||||||
|
|
||||||
export const bookingCodeSchema = z
|
export const bookingCodeSchema = z
|
||||||
.object({
|
.object({
|
||||||
value: z.string().refine(
|
value: z
|
||||||
(value) => {
|
.string()
|
||||||
if (
|
.refine(
|
||||||
!value ||
|
(value) => {
|
||||||
/(^D\d*$)|(^DSH[0-9a-z]*$)|(^L\d*$)|(^LH[0-9a-z]*$)|(^B[a-z]{3}\d{6})|(^VO[0-9a-z]*$)|^[0-9a-z]*$/i.test(
|
if (
|
||||||
value
|
!value ||
|
||||||
)
|
/(^D\d*$)|(^DSH[0-9a-z]*$)|(^L\d*$)|(^LH[0-9a-z]*$)|(^B[a-z]{3}\d{6})|(^VO[0-9a-z]*$)|^[0-9a-z]*$/i.test(
|
||||||
) {
|
value
|
||||||
return true
|
)
|
||||||
} else {
|
) {
|
||||||
return false
|
return true
|
||||||
}
|
} else {
|
||||||
},
|
return false
|
||||||
{ message: "Invalid booking code" }
|
}
|
||||||
),
|
},
|
||||||
remember: z.boolean(),
|
{ message: "Invalid booking code" }
|
||||||
|
)
|
||||||
|
.default(""),
|
||||||
|
remember: z.boolean().default(false),
|
||||||
|
flag: z.boolean().default(false),
|
||||||
})
|
})
|
||||||
.optional()
|
.optional()
|
||||||
|
|
||||||
|
|||||||
@@ -32,20 +32,14 @@ export default function Switch({
|
|||||||
isDisabled={registerOptions?.disabled}
|
isDisabled={registerOptions?.disabled}
|
||||||
excludeFromTabOrder
|
excludeFromTabOrder
|
||||||
>
|
>
|
||||||
{({ isSelected }) => (
|
{children}
|
||||||
<>
|
<span className={styles.switch} tabIndex={0}></span>
|
||||||
<span className={styles.switchContainer}>
|
{fieldState.error ? (
|
||||||
{children}
|
<Caption className={styles.error} fontOnly>
|
||||||
<span className={styles.switch} tabIndex={0}></span>
|
<InfoCircleIcon color="red" />
|
||||||
</span>
|
{fieldState.error.message}
|
||||||
{fieldState.error ? (
|
</Caption>
|
||||||
<Caption className={styles.error} fontOnly>
|
) : null}
|
||||||
<InfoCircleIcon color="red" />
|
|
||||||
{fieldState.error.message}
|
|
||||||
</Caption>
|
|
||||||
) : null}
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</AriaSwitch>
|
</AriaSwitch>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,8 @@
|
|||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
color: var(--text-color);
|
color: var(--text-color);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
width: 100%;
|
||||||
|
justify-content: space-between;
|
||||||
}
|
}
|
||||||
|
|
||||||
.switch {
|
.switch {
|
||||||
|
|||||||
@@ -223,6 +223,7 @@
|
|||||||
"I accept the terms and conditions": "Jeg accepterer vilkårene",
|
"I accept the terms and conditions": "Jeg accepterer vilkårene",
|
||||||
"I would like to get my booking confirmation via sms": "Jeg vil gerne få min booking bekræftelse via SMS",
|
"I would like to get my booking confirmation via sms": "Jeg vil gerne få min booking bekræftelse via SMS",
|
||||||
"If you are not redirected automatically, please <loginLink>click here</loginLink>.": "If you are not redirected automatically, please <loginLink>click here</loginLink>.",
|
"If you are not redirected automatically, please <loginLink>click here</loginLink>.": "If you are not redirected automatically, please <loginLink>click here</loginLink>.",
|
||||||
|
"If you're booking a promotional offer or a Corporate negotiated rate you'll need a special booking code. Don't use any special characters such as (.) (,) (-) (:). If you would like to make a booking with code VOF, please call us +46 8 517 517 20.Save your booking code for the next time you visit the page by ticking the box “Remember”. Don't tick the box if you're using a public computer to avoid unauthorized access to your booking code.": "Hvis du bestiller et kampagnetilbud eller en firmaaftalepris, skal du bruge en bookingkode. Brug ikke specialtegn som (.) (,) (-) (:).Gem din bookingkode til næste gang du besøger siden ved at klikke “Husk bookingkode”. Vælg ikke dette, hvis du bruger en offentlig computer for at undgå uautoriseret anvendelse af din bookingkode.",
|
||||||
"In adults bed": "i de voksnes seng",
|
"In adults bed": "i de voksnes seng",
|
||||||
"In crib": "i tremmeseng",
|
"In crib": "i tremmeseng",
|
||||||
"In extra bed": "i ekstra seng",
|
"In extra bed": "i ekstra seng",
|
||||||
@@ -566,7 +567,6 @@
|
|||||||
"Zoom in": "Zoom ind",
|
"Zoom in": "Zoom ind",
|
||||||
"Zoom out": "Zoom ud",
|
"Zoom out": "Zoom ud",
|
||||||
"as of today": "pr. dags dato",
|
"as of today": "pr. dags dato",
|
||||||
"booking.codes.information": "Hvis du bestiller et kampagnetilbud eller en firmaaftalepris, skal du bruge en bookingkode. Brug ikke specialtegn som (.) (,) (-) (:).Gem din bookingkode til næste gang du besøger siden ved at klikke “Husk bookingkode”. Vælg ikke dette, hvis du bruger en offentlig computer for at undgå uautoriseret anvendelse af din bookingkode.",
|
|
||||||
"booking.confirmation.text": "Tak fordi du bookede hos os! Vi glæder os til at byde dig velkommen og håber du får et behageligt ophold. Hvis du har spørgsmål eller har brug for at foretage ændringer i din reservation, bedes du <emailLink>kontakte os.</emailLink>",
|
"booking.confirmation.text": "Tak fordi du bookede hos os! Vi glæder os til at byde dig velkommen og håber du får et behageligt ophold. Hvis du har spørgsmål eller har brug for at foretage ændringer i din reservation, bedes du <emailLink>kontakte os.</emailLink>",
|
||||||
"booking.confirmation.title": "Booking bekræftelse",
|
"booking.confirmation.title": "Booking bekræftelse",
|
||||||
"booking.guests": "Maks {max, plural, one {{range} gæst} other {{range} gæster}}",
|
"booking.guests": "Maks {max, plural, one {{range} gæst} other {{range} gæster}}",
|
||||||
|
|||||||
@@ -222,6 +222,7 @@
|
|||||||
"I accept the terms and conditions": "Ich akzeptiere die Geschäftsbedingungen",
|
"I accept the terms and conditions": "Ich akzeptiere die Geschäftsbedingungen",
|
||||||
"I would like to get my booking confirmation via sms": "Ich möchte meine Buchungsbestätigung per SMS erhalten",
|
"I would like to get my booking confirmation via sms": "Ich möchte meine Buchungsbestätigung per SMS erhalten",
|
||||||
"If you are not redirected automatically, please <loginLink>click here</loginLink>.": "If you are not redirected automatically, please <loginLink>click here</loginLink>.",
|
"If you are not redirected automatically, please <loginLink>click here</loginLink>.": "If you are not redirected automatically, please <loginLink>click here</loginLink>.",
|
||||||
|
"If you're booking a promotional offer or a Corporate negotiated rate you'll need a special booking code. Don't use any special characters such as (.) (,) (-) (:). If you would like to make a booking with code VOF, please call us +46 8 517 517 20.Save your booking code for the next time you visit the page by ticking the box “Remember”. Don't tick the box if you're using a public computer to avoid unauthorized access to your booking code.": "Um ein Aktionsangebot oder einen Unternehmenstarif in Anspruch zu nehmen, benötigen Sie einen speziellen Buchungscode. Verwenden Sie keine Sonderzeichen wie (.) (,) (-) (:).Wählen Sie das Kästchen aus, um beim nächsten Besuch der Seite Ihren Buchungscode zu speichern. “Buchungscode speichern”. Deaktivieren Sie das Feld, wenn Sie einen öffentlich zugänglichen Computer verwenden, um unautorisierte Zugriffe auf Ihren Buchungscode zu verhindern.",
|
||||||
"In adults bed": "Im Bett der Eltern",
|
"In adults bed": "Im Bett der Eltern",
|
||||||
"In crib": "im Kinderbett",
|
"In crib": "im Kinderbett",
|
||||||
"In extra bed": "im zusätzlichen Bett",
|
"In extra bed": "im zusätzlichen Bett",
|
||||||
@@ -564,7 +565,6 @@
|
|||||||
"Zoom in": "Vergrößern",
|
"Zoom in": "Vergrößern",
|
||||||
"Zoom out": "Verkleinern",
|
"Zoom out": "Verkleinern",
|
||||||
"as of today": "Stand heute",
|
"as of today": "Stand heute",
|
||||||
"booking.codes.information": "Um ein Aktionsangebot oder einen Unternehmenstarif in Anspruch zu nehmen, benötigen Sie einen speziellen Buchungscode. Verwenden Sie keine Sonderzeichen wie (.) (,) (-) (:).Wählen Sie das Kästchen aus, um beim nächsten Besuch der Seite Ihren Buchungscode zu speichern. “Buchungscode speichern”. Deaktivieren Sie das Feld, wenn Sie einen öffentlich zugänglichen Computer verwenden, um unautorisierte Zugriffe auf Ihren Buchungscode zu verhindern.",
|
|
||||||
"booking.confirmation.text": "Vielen Dank, dass Sie bei uns gebucht haben! Wir freuen uns, Sie bei uns begrüßen zu dürfen und wünschen Ihnen einen angenehmen Aufenthalt. Wenn Sie Fragen haben oder Änderungen an Ihrer Buchung vornehmen müssen, <emailLink>kontaktieren Sie uns bitte.</emailLink>.",
|
"booking.confirmation.text": "Vielen Dank, dass Sie bei uns gebucht haben! Wir freuen uns, Sie bei uns begrüßen zu dürfen und wünschen Ihnen einen angenehmen Aufenthalt. Wenn Sie Fragen haben oder Änderungen an Ihrer Buchung vornehmen müssen, <emailLink>kontaktieren Sie uns bitte.</emailLink>.",
|
||||||
"booking.confirmation.title": "Buchungsbestätigung",
|
"booking.confirmation.title": "Buchungsbestätigung",
|
||||||
"booking.guests": "Max {max, plural, one {{range} gast} other {{range} gäste}}",
|
"booking.guests": "Max {max, plural, one {{range} gast} other {{range} gäste}}",
|
||||||
|
|||||||
@@ -244,6 +244,7 @@
|
|||||||
"I accept the terms and conditions": "I accept the terms and conditions",
|
"I accept the terms and conditions": "I accept the terms and conditions",
|
||||||
"I would like to get my booking confirmation via sms": "I would like to get my booking confirmation via sms",
|
"I would like to get my booking confirmation via sms": "I would like to get my booking confirmation via sms",
|
||||||
"If you are not redirected automatically, please <loginLink>click here</loginLink>.": "If you are not redirected automatically, please <loginLink>click here</loginLink>.",
|
"If you are not redirected automatically, please <loginLink>click here</loginLink>.": "If you are not redirected automatically, please <loginLink>click here</loginLink>.",
|
||||||
|
"If you're booking a promotional offer or a Corporate negotiated rate you'll need a special booking code. Don't use any special characters such as (.) (,) (-) (:). If you would like to make a booking with code VOF, please call us +46 8 517 517 20.Save your booking code for the next time you visit the page by ticking the box “Remember”. Don't tick the box if you're using a public computer to avoid unauthorized access to your booking code.": "If you're booking a promotional offer or a Corporate negotiated rate you'll need a special booking code. Don't use any special characters such as (.) (,) (-) (:). If you would like to make a booking with code VOF, please call us +46 8 517 517 20.Save your booking code for the next time you visit the page by ticking the box “Remember”. Don't tick the box if you're using a public computer to avoid unauthorized access to your booking code.",
|
||||||
"In adults bed": "In adults bed",
|
"In adults bed": "In adults bed",
|
||||||
"In crib": "In crib",
|
"In crib": "In crib",
|
||||||
"In extra bed": "In extra bed",
|
"In extra bed": "In extra bed",
|
||||||
@@ -621,7 +622,6 @@
|
|||||||
"Zoom in": "Zoom in",
|
"Zoom in": "Zoom in",
|
||||||
"Zoom out": "Zoom out",
|
"Zoom out": "Zoom out",
|
||||||
"as of today": "as of today",
|
"as of today": "as of today",
|
||||||
"booking.codes.information": "If you're booking a promotional offer or a Corporate negotiated rate you'll need a special booking code. Don't use any special characters such as (.) (,) (-) (:). If you would like to make a booking with code VOF, please call us +46 8 517 517 20.Save your booking code for the next time you visit the page by ticking the box “Remember”. Don't tick the box if you're using a public computer to avoid unauthorized access to your booking code.",
|
|
||||||
"booking.selectRoom": "Select room",
|
"booking.selectRoom": "Select room",
|
||||||
"booking.thisRoomIsEquippedWith": "This room is equipped with",
|
"booking.thisRoomIsEquippedWith": "This room is equipped with",
|
||||||
"friday": "friday",
|
"friday": "friday",
|
||||||
|
|||||||
@@ -223,6 +223,7 @@
|
|||||||
"I accept the terms and conditions": "Hyväksyn käyttöehdot",
|
"I accept the terms and conditions": "Hyväksyn käyttöehdot",
|
||||||
"I would like to get my booking confirmation via sms": "Haluan saada varauksen vahvistuksen SMS-viestillä",
|
"I would like to get my booking confirmation via sms": "Haluan saada varauksen vahvistuksen SMS-viestillä",
|
||||||
"If you are not redirected automatically, please <loginLink>click here</loginLink>.": "If you are not redirected automatically, please <loginLink>click here</loginLink>.",
|
"If you are not redirected automatically, please <loginLink>click here</loginLink>.": "If you are not redirected automatically, please <loginLink>click here</loginLink>.",
|
||||||
|
"If you're booking a promotional offer or a Corporate negotiated rate you'll need a special booking code. Don't use any special characters such as (.) (,) (-) (:). If you would like to make a booking with code VOF, please call us +46 8 517 517 20.Save your booking code for the next time you visit the page by ticking the box “Remember”. Don't tick the box if you're using a public computer to avoid unauthorized access to your booking code.": "Jos varaat tarjoushinnalla tai yrityksen sopimushinnalla, tarvitset varauskoodin. Älä käytä erikoismerkkejä, kuten (.) (,) (-) (:).Jos haluat tallentaa varauskoodisi seuraavaa varausta varten, rastita tämä ruutu. Älä rastita ruutua, mikäli käytät yleistä tietokonetta ja haluat välttää varauskoodin väärinkäyttöä.",
|
||||||
"In adults bed": "Aikuisten vuoteessa",
|
"In adults bed": "Aikuisten vuoteessa",
|
||||||
"In crib": "Pinnasängyssä",
|
"In crib": "Pinnasängyssä",
|
||||||
"In extra bed": "Oma vuodepaikka",
|
"In extra bed": "Oma vuodepaikka",
|
||||||
@@ -564,7 +565,6 @@
|
|||||||
"Zoom in": "Lähennä",
|
"Zoom in": "Lähennä",
|
||||||
"Zoom out": "Loitonna",
|
"Zoom out": "Loitonna",
|
||||||
"as of today": "tänään",
|
"as of today": "tänään",
|
||||||
"booking.codes.information": "Jos varaat tarjoushinnalla tai yrityksen sopimushinnalla, tarvitset varauskoodin. Älä käytä erikoismerkkejä, kuten (.) (,) (-) (:).Jos haluat tallentaa varauskoodisi seuraavaa varausta varten, rastita tämä ruutu. Älä rastita ruutua, mikäli käytät yleistä tietokonetta ja haluat välttää varauskoodin väärinkäyttöä.",
|
|
||||||
"booking.confirmation.text": "Kiitos, että teit varauksen meiltä! Toivotamme sinut tervetulleeksi ja toivomme sinulle miellyttävää oleskelua. Jos sinulla on kysyttävää tai haluat tehdä muutoksia varaukseesi, <emailLink>ota meihin yhteyttä.</emailLink>",
|
"booking.confirmation.text": "Kiitos, että teit varauksen meiltä! Toivotamme sinut tervetulleeksi ja toivomme sinulle miellyttävää oleskelua. Jos sinulla on kysyttävää tai haluat tehdä muutoksia varaukseesi, <emailLink>ota meihin yhteyttä.</emailLink>",
|
||||||
"booking.confirmation.title": "Varausvahvistus",
|
"booking.confirmation.title": "Varausvahvistus",
|
||||||
"booking.guests": "Max {max, plural, one {{range} vieras} other {{range} vieraita}}",
|
"booking.guests": "Max {max, plural, one {{range} vieras} other {{range} vieraita}}",
|
||||||
|
|||||||
@@ -222,6 +222,7 @@
|
|||||||
"I accept the terms and conditions": "Jeg aksepterer vilkårene",
|
"I accept the terms and conditions": "Jeg aksepterer vilkårene",
|
||||||
"I would like to get my booking confirmation via sms": "Jeg vil gjerne motta bekreftelsen av bestillingen min via sms",
|
"I would like to get my booking confirmation via sms": "Jeg vil gjerne motta bekreftelsen av bestillingen min via sms",
|
||||||
"If you are not redirected automatically, please <loginLink>click here</loginLink>.": "If you are not redirected automatically, please <loginLink>click here</loginLink>.",
|
"If you are not redirected automatically, please <loginLink>click here</loginLink>.": "If you are not redirected automatically, please <loginLink>click here</loginLink>.",
|
||||||
|
"If you're booking a promotional offer or a Corporate negotiated rate you'll need a special booking code. Don't use any special characters such as (.) (,) (-) (:). If you would like to make a booking with code VOF, please call us +46 8 517 517 20.Save your booking code for the next time you visit the page by ticking the box “Remember”. Don't tick the box if you're using a public computer to avoid unauthorized access to your booking code.": "Om du bestiller et tilbud eller en avtalepris kreves en spesiell bookingkode. Ikke benytt spesialtegn som (.) (,) (-) (:). Lagre din bookingkode til neste gang du besøker siden ved å klikke på \"Husk\". Klikk ikke på \"Husk\" dersom du bruker en offentlig datamaskin, da uvedkommede kan få tilgang til din bookingkode.",
|
||||||
"In adults bed": "i voksnes seng",
|
"In adults bed": "i voksnes seng",
|
||||||
"In crib": "i sprinkelseng",
|
"In crib": "i sprinkelseng",
|
||||||
"In extra bed": "i ekstraseng",
|
"In extra bed": "i ekstraseng",
|
||||||
@@ -565,7 +566,6 @@
|
|||||||
"Zoom in": "Zoom inn",
|
"Zoom in": "Zoom inn",
|
||||||
"Zoom out": "Zoom ut",
|
"Zoom out": "Zoom ut",
|
||||||
"as of today": "per i dag",
|
"as of today": "per i dag",
|
||||||
"booking.codes.information": "Om du bestiller et tilbud eller en avtalepris kreves en spesiell bookingkode. Ikke benytt spesialtegn som (.) (,) (-) (:). Lagre din bookingkode til neste gang du besøker siden ved å klikke på \"Husk\". Klikk ikke på \"Husk\" dersom du bruker en offentlig datamaskin, da uvedkommede kan få tilgang til din bookingkode.",
|
|
||||||
"booking.confirmation.text": "Takk for at du booket hos oss! Vi ser frem til å ønske deg velkommen og håper du får et hyggelig opphold. Hvis du har spørsmål eller trenger å gjøre endringer i bestillingen din, vennligst <emailLink>kontakt oss.</emailLink>",
|
"booking.confirmation.text": "Takk for at du booket hos oss! Vi ser frem til å ønske deg velkommen og håper du får et hyggelig opphold. Hvis du har spørsmål eller trenger å gjøre endringer i bestillingen din, vennligst <emailLink>kontakt oss.</emailLink>",
|
||||||
"booking.confirmation.title": "Bestillingsbekreftelse",
|
"booking.confirmation.title": "Bestillingsbekreftelse",
|
||||||
"booking.guests": "Maks {max, plural, one {{range} gjest} other {{range} gjester}}",
|
"booking.guests": "Maks {max, plural, one {{range} gjest} other {{range} gjester}}",
|
||||||
|
|||||||
@@ -222,6 +222,7 @@
|
|||||||
"I accept the terms and conditions": "Jag accepterar villkoren",
|
"I accept the terms and conditions": "Jag accepterar villkoren",
|
||||||
"I would like to get my booking confirmation via sms": "Jag vill få min bokningsbekräftelse via sms",
|
"I would like to get my booking confirmation via sms": "Jag vill få min bokningsbekräftelse via sms",
|
||||||
"If you are not redirected automatically, please <loginLink>click here</loginLink>.": "If you are not redirected automatically, please <loginLink>click here</loginLink>.",
|
"If you are not redirected automatically, please <loginLink>click here</loginLink>.": "If you are not redirected automatically, please <loginLink>click here</loginLink>.",
|
||||||
|
"If you're booking a promotional offer or a Corporate negotiated rate you'll need a special booking code. Don't use any special characters such as (.) (,) (-) (:). If you would like to make a booking with code VOF, please call us +46 8 517 517 20.Save your booking code for the next time you visit the page by ticking the box “Remember”. Don't tick the box if you're using a public computer to avoid unauthorized access to your booking code.": "Om du bokar ett erbjudande eller avtalspris krävs en särskild bokningskod. Använd inga specialtecken som (.) (,) (-) (:). För bokning med koden VOF ber vi dig ringa oss 08-517 517 00.Spara din bokningskod till nästa gång du besöker sidan, genom att klicka i rutan \"Kom ihåg\". Klicka inte i rutan om du använder en allmän dator, då kan obehöriga komma åt din bokningskod.",
|
||||||
"In adults bed": "I vuxens säng",
|
"In adults bed": "I vuxens säng",
|
||||||
"In crib": "I spjälsäng",
|
"In crib": "I spjälsäng",
|
||||||
"In extra bed": "Egen sängplats",
|
"In extra bed": "Egen sängplats",
|
||||||
@@ -565,7 +566,6 @@
|
|||||||
"Zoom in": "Zooma in",
|
"Zoom in": "Zooma in",
|
||||||
"Zoom out": "Zooma ut",
|
"Zoom out": "Zooma ut",
|
||||||
"as of today": "från och med idag",
|
"as of today": "från och med idag",
|
||||||
"booking.codes.information": "Om du bokar ett erbjudande eller avtalspris krävs en särskild bokningskod. Använd inga specialtecken som (.) (,) (-) (:). För bokning med koden VOF ber vi dig ringa oss 08-517 517 00.Spara din bokningskod till nästa gång du besöker sidan, genom att klicka i rutan \"Kom ihåg\". Klicka inte i rutan om du använder en allmän dator, då kan obehöriga komma åt din bokningskod.",
|
|
||||||
"booking.confirmation.text": "Tack för att du bokar hos oss! Vi ser fram emot att välkomna dig och hoppas att du får en trevlig vistelse. Om du har några frågor eller behöver göra ändringar i din bokning, vänligen <emailLink>kontakta oss.</emailLink>",
|
"booking.confirmation.text": "Tack för att du bokar hos oss! Vi ser fram emot att välkomna dig och hoppas att du får en trevlig vistelse. Om du har några frågor eller behöver göra ändringar i din bokning, vänligen <emailLink>kontakta oss.</emailLink>",
|
||||||
"booking.confirmation.title": "Bokningsbekräftelse",
|
"booking.confirmation.title": "Bokningsbekräftelse",
|
||||||
"booking.guests": "Max {max, plural, one {{range} gäst} other {{range} gäster}}",
|
"booking.guests": "Max {max, plural, one {{range} gäst} other {{range} gäster}}",
|
||||||
|
|||||||
Reference in New Issue
Block a user