feat: SW-1422 Updated UX for booking code desktop and mobile

This commit is contained in:
Hrishikesh Vaipurkar
2025-01-30 23:14:07 +01:00
parent 6741a0a21c
commit 63f456da5a
14 changed files with 313 additions and 115 deletions

View File

@@ -85,7 +85,7 @@ export default function BookingWidgetClient({
const selectedBookingCode = bookingWidgetSearchData
? bookingWidgetSearchData.bookingCode
: undefined
: ""
const defaultRoomsData: BookingWidgetSchema["rooms"] =
bookingWidgetSearchData?.rooms?.map((room) => ({
@@ -113,7 +113,7 @@ export default function BookingWidgetClient({
: now.utc().add(1, "day").format("YYYY-MM-DD"),
},
bookingCode: {
value: selectedBookingCode ?? "",
value: selectedBookingCode,
remember: false,
},
redemption: false,
@@ -156,36 +156,36 @@ export default function BookingWidgetClient({
}, [])
useEffect(() => {
const sessionStorageSearchData =
typeof window !== "undefined"
? sessionStorage.getItem("searchData")
: undefined
if (typeof window !== "undefined" && !selectedLocation) {
const sessionStorageSearchData = sessionStorage.getItem("searchData")
const initialSelectedLocation: Location | undefined =
sessionStorageSearchData && isValidJson(sessionStorageSearchData)
? JSON.parse(sessionStorageSearchData)
: undefined
const initialSelectedLocation: Location | undefined =
sessionStorageSearchData && isValidJson(sessionStorageSearchData)
? JSON.parse(sessionStorageSearchData)
: undefined
!selectedLocation?.name &&
initialSelectedLocation?.name &&
methods.setValue("search", initialSelectedLocation.name)
!selectedLocation &&
methods.setValue("search", initialSelectedLocation.name)
sessionStorageSearchData &&
methods.setValue("location", encodeURIComponent(sessionStorageSearchData))
methods.setValue(
"location",
encodeURIComponent(sessionStorageSearchData)
)
}
}, [methods, selectedLocation])
const storedBookingCode =
typeof window !== "undefined"
? localStorage.getItem("bookingCode")
: undefined
const initialBookingCode: BookingCodeSchema | undefined =
storedBookingCode && isValidJson(storedBookingCode)
? JSON.parse(storedBookingCode)
: undefined
!selectedBookingCode &&
initialBookingCode &&
initialBookingCode.remember &&
methods.setValue("bookingCode", initialBookingCode)
}, [methods, selectedLocation, selectedBookingCode])
useEffect(() => {
if (typeof window !== "undefined" && !selectedBookingCode) {
const storedBookingCode = localStorage.getItem("bookingCode")
const initialBookingCode: BookingCodeSchema | undefined =
storedBookingCode && isValidJson(storedBookingCode)
? JSON.parse(storedBookingCode)
: undefined
initialBookingCode?.remember &&
methods.setValue("bookingCode", initialBookingCode)
}
}, [methods, selectedBookingCode])
return (
<FormProvider {...methods}>

View File

@@ -1,7 +1,12 @@
.container {
position: relative;
}
.bookingCodeLabel {
display: flex;
align-items: center;
gap: var(--Spacing-x-half);
position: relative;
}
.error {
@@ -13,10 +18,33 @@
min-width: 20px;
}
.bookingCodeRemember {
display: flex;
gap: var(--Spacing-x1);
/* ToDo: Remove once remember checkbox design are ready */
.bookingCodeRemember,
.bookingCodeRememberVisible {
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;
}
}

View File

@@ -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 { useIntl } from "react-intl"
import { useMediaQuery } from "usehooks-ts"
import { ErrorCircleIcon, InfoCircleIcon } from "@/components/Icons"
import Modal from "@/components/Modal"
import Button from "@/components/TempDesignSystem/Button"
import Checkbox from "@/components/TempDesignSystem/Form/Checkbox"
import Switch from "@/components/TempDesignSystem/Form/Switch"
import Body from "@/components/TempDesignSystem/Text/Body"
import Caption from "@/components/TempDesignSystem/Text/Caption"
@@ -19,72 +23,228 @@ import type {
export default function BookingCode() {
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 {
setValue,
formState: { errors },
getValues,
} = 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 addCode = intl.formatMessage({ id: "Add code" })
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) {
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">
<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}
<DialogTrigger isOpen={isOpen} onOpenChange={toggleModal}>
<Button type="button" intent="text">
<Checkbox name="bookingCode.flag" checked={!!bookingCode?.value}>
<Caption color="uiTextMediumContrast" type="bold" asChild>
<span>{codeVoucher}</span>
</Caption>
</Checkbox>
</Button>
<Popover
className="guests_picker_popover"
placement="bottom start"
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>
}
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}
/>
</label>
{codeError && codeError.message ? (
{codeError?.message ? (
<Caption color="red" className={styles.error}>
<ErrorCircleIcon color="red" className={styles.errorIcon} />
{intl.formatMessage({ id: codeError.message })}
</Caption>
) : null}
<div className={styles.bookingCode}>
<Checkbox name="bookingCode.remember">
<Caption asChild>
<span>{intl.formatMessage({ id: "Remember code" })}</span>
</Caption>
</Checkbox>
<Button
size="small"
intent="primary"
type="button"
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}>
<ErrorCircleIcon color="red" className={styles.errorIcon} />
{intl.formatMessage({ id: codeError.message })}
</Caption>
) : null}
{/* ToDo: Update styles once designs are ready */}
<div className={styles.bookingCodeRemember}>
<Checkbox name="bookingCode.remember">
<Caption asChild>
<span>{intl.formatMessage({ id: "Remember code" })}</span>
</Caption>
</Checkbox>
<Button size="small" intent="primary" type="button">
{intl.formatMessage({ id: "Apply" })}
</Button>
</div>
</>
{isDesktop ? (
<div
className={
showRemember
? styles.bookingCodeRememberVisible
: styles.bookingCodeRemember
}
>
<Checkbox name="bookingCode.remember">
<Caption asChild>
<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>
)
}

View File

@@ -32,6 +32,12 @@
display: none;
}
@media screen and (max-width: 767px) {
.vouchers {
margin-bottom: var(--Spacing-x5);
}
}
@media screen and (min-width: 768px) {
.vouchers {
display: none;

View File

@@ -31,7 +31,8 @@ export default function Form({
type,
})
const { handleSubmit, register } = useFormContext<BookingWidgetSchema>()
const { handleSubmit, register, setValue } =
useFormContext<BookingWidgetSchema>()
function onSubmit(data: BookingWidgetSchema) {
const locationData: Location = JSON.parse(decodeURIComponent(data.location))
@@ -44,7 +45,7 @@ export default function Form({
...(locationData.type == "cities"
? { city: locationData.name }
: { hotel: locationData.operaId || "" }),
...(data.bookingCode && data.bookingCode.value
...(data.bookingCode?.value
? { bookingCode: data.bookingCode.value }
: {}),
})
@@ -54,6 +55,9 @@ export default function Form({
if (data.bookingCode?.remember) {
localStorage.setItem("bookingCode", JSON.stringify(data.bookingCode))
}
if (!data.bookingCode?.value) {
setValue("bookingCode.remember", false)
}
}
return (

View File

@@ -37,22 +37,26 @@ export const guestRoomsSchema = z.array(guestRoomSchema)
export const bookingCodeSchema = z
.object({
value: z.string().refine(
(value) => {
if (
!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
}
},
{ message: "Invalid booking code" }
),
remember: z.boolean(),
value: z
.string()
.refine(
(value) => {
if (
!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
}
},
{ message: "Invalid booking code" }
)
.default(""),
remember: z.boolean().default(false),
flag: z.boolean().default(false),
})
.optional()

View File

@@ -32,20 +32,14 @@ export default function Switch({
isDisabled={registerOptions?.disabled}
excludeFromTabOrder
>
{({ isSelected }) => (
<>
<span className={styles.switchContainer}>
{children}
<span className={styles.switch} tabIndex={0}></span>
</span>
{fieldState.error ? (
<Caption className={styles.error} fontOnly>
<InfoCircleIcon color="red" />
{fieldState.error.message}
</Caption>
) : null}
</>
)}
{children}
<span className={styles.switch} tabIndex={0}></span>
{fieldState.error ? (
<Caption className={styles.error} fontOnly>
<InfoCircleIcon color="red" />
{fieldState.error.message}
</Caption>
) : null}
</AriaSwitch>
)
}

View File

@@ -3,6 +3,8 @@
flex-direction: row;
color: var(--text-color);
cursor: pointer;
width: 100%;
justify-content: space-between;
}
.switch {

View File

@@ -223,6 +223,7 @@
"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",
"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 crib": "i tremmeseng",
"In extra bed": "i ekstra seng",
@@ -566,7 +567,6 @@
"Zoom in": "Zoom ind",
"Zoom out": "Zoom ud",
"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.title": "Booking bekræftelse",
"booking.guests": "Maks {max, plural, one {{range} gæst} other {{range} gæster}}",

View File

@@ -222,6 +222,7 @@
"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",
"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 crib": "im Kinderbett",
"In extra bed": "im zusätzlichen Bett",
@@ -564,7 +565,6 @@
"Zoom in": "Vergrößern",
"Zoom out": "Verkleinern",
"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.title": "Buchungsbestätigung",
"booking.guests": "Max {max, plural, one {{range} gast} other {{range} gäste}}",

View File

@@ -244,6 +244,7 @@
"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",
"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 crib": "In crib",
"In extra bed": "In extra bed",
@@ -621,7 +622,6 @@
"Zoom in": "Zoom in",
"Zoom out": "Zoom out",
"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.thisRoomIsEquippedWith": "This room is equipped with",
"friday": "friday",

View File

@@ -223,6 +223,7 @@
"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ä",
"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 crib": "Pinnasängyssä",
"In extra bed": "Oma vuodepaikka",
@@ -564,7 +565,6 @@
"Zoom in": "Lähennä",
"Zoom out": "Loitonna",
"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.title": "Varausvahvistus",
"booking.guests": "Max {max, plural, one {{range} vieras} other {{range} vieraita}}",

View File

@@ -222,6 +222,7 @@
"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",
"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 crib": "i sprinkelseng",
"In extra bed": "i ekstraseng",
@@ -565,7 +566,6 @@
"Zoom in": "Zoom inn",
"Zoom out": "Zoom ut",
"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.title": "Bestillingsbekreftelse",
"booking.guests": "Maks {max, plural, one {{range} gjest} other {{range} gjester}}",

View File

@@ -222,6 +222,7 @@
"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",
"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 crib": "I spjälsäng",
"In extra bed": "Egen sängplats",
@@ -565,7 +566,6 @@
"Zoom in": "Zooma in",
"Zoom out": "Zooma ut",
"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.title": "Bokningsbekräftelse",
"booking.guests": "Max {max, plural, one {{range} gäst} other {{range} gäster}}",