Merge branch 'develop' into feat/sw-222-staycard-link
This commit is contained in:
@@ -1,6 +1,10 @@
|
|||||||
import { redirect } from "next/navigation"
|
import { redirect } from "next/navigation"
|
||||||
|
|
||||||
import { serverClient } from "@/lib/trpc/server"
|
import {
|
||||||
|
getCreditCardsSafely,
|
||||||
|
getHotelData,
|
||||||
|
getProfileSafely,
|
||||||
|
} from "@/lib/trpc/memoizedRequests"
|
||||||
|
|
||||||
import EnterDetailsProvider from "@/components/HotelReservation/EnterDetails/Provider"
|
import EnterDetailsProvider from "@/components/HotelReservation/EnterDetails/Provider"
|
||||||
import SelectedRoom from "@/components/HotelReservation/EnterDetails/SelectedRoom"
|
import SelectedRoom from "@/components/HotelReservation/EnterDetails/SelectedRoom"
|
||||||
@@ -14,15 +18,20 @@ import styles from "./layout.module.css"
|
|||||||
import { StepEnum } from "@/types/components/enterDetails/step"
|
import { StepEnum } from "@/types/components/enterDetails/step"
|
||||||
import type { LangParams, LayoutArgs } from "@/types/params"
|
import type { LangParams, LayoutArgs } from "@/types/params"
|
||||||
|
|
||||||
|
function preload(id: string, lang: string) {
|
||||||
|
void getHotelData(id, lang)
|
||||||
|
void getProfileSafely()
|
||||||
|
void getCreditCardsSafely()
|
||||||
|
}
|
||||||
|
|
||||||
export default async function StepLayout({
|
export default async function StepLayout({
|
||||||
children,
|
children,
|
||||||
params,
|
params,
|
||||||
}: React.PropsWithChildren<LayoutArgs<LangParams & { step: StepEnum }>>) {
|
}: React.PropsWithChildren<LayoutArgs<LangParams & { step: StepEnum }>>) {
|
||||||
setLang(params.lang)
|
setLang(params.lang)
|
||||||
const hotel = await serverClient().hotel.hotelData.get({
|
preload("811", params.lang)
|
||||||
hotelId: "811",
|
|
||||||
language: params.lang,
|
const hotel = await getHotelData("811", params.lang)
|
||||||
})
|
|
||||||
|
|
||||||
if (!hotel?.data) {
|
if (!hotel?.data) {
|
||||||
redirect(`/${params.lang}`)
|
redirect(`/${params.lang}`)
|
||||||
|
|||||||
@@ -1,14 +1,17 @@
|
|||||||
import { notFound } from "next/navigation"
|
import { notFound } from "next/navigation"
|
||||||
|
|
||||||
import { getProfileSafely } from "@/lib/trpc/memoizedRequests"
|
import {
|
||||||
import { serverClient } from "@/lib/trpc/server"
|
getCreditCardsSafely,
|
||||||
|
getHotelData,
|
||||||
|
getProfileSafely,
|
||||||
|
} from "@/lib/trpc/memoizedRequests"
|
||||||
|
|
||||||
import BedType from "@/components/HotelReservation/EnterDetails/BedType"
|
import BedType from "@/components/HotelReservation/EnterDetails/BedType"
|
||||||
import Breakfast from "@/components/HotelReservation/EnterDetails/Breakfast"
|
import Breakfast from "@/components/HotelReservation/EnterDetails/Breakfast"
|
||||||
import Details from "@/components/HotelReservation/EnterDetails/Details"
|
import Details from "@/components/HotelReservation/EnterDetails/Details"
|
||||||
import HistoryStateManager from "@/components/HotelReservation/EnterDetails/HistoryStateManager"
|
import HistoryStateManager from "@/components/HotelReservation/EnterDetails/HistoryStateManager"
|
||||||
|
import Payment from "@/components/HotelReservation/EnterDetails/Payment"
|
||||||
import SectionAccordion from "@/components/HotelReservation/EnterDetails/SectionAccordion"
|
import SectionAccordion from "@/components/HotelReservation/EnterDetails/SectionAccordion"
|
||||||
import Payment from "@/components/HotelReservation/SelectRate/Payment"
|
|
||||||
import { getIntl } from "@/i18n"
|
import { getIntl } from "@/i18n"
|
||||||
|
|
||||||
import { StepEnum } from "@/types/components/enterDetails/step"
|
import { StepEnum } from "@/types/components/enterDetails/step"
|
||||||
@@ -25,12 +28,9 @@ export default async function StepPage({
|
|||||||
|
|
||||||
const intl = await getIntl()
|
const intl = await getIntl()
|
||||||
|
|
||||||
const hotel = await serverClient().hotel.hotelData.get({
|
const hotel = await getHotelData("811", lang)
|
||||||
hotelId: "811",
|
|
||||||
language: lang,
|
|
||||||
})
|
|
||||||
|
|
||||||
const user = await getProfileSafely()
|
const user = await getProfileSafely()
|
||||||
|
const savedCreditCards = await getCreditCardsSafely()
|
||||||
|
|
||||||
if (!isValidStep(step) || !hotel) {
|
if (!isValidStep(step) || !hotel) {
|
||||||
return notFound()
|
return notFound()
|
||||||
@@ -65,7 +65,14 @@ export default async function StepPage({
|
|||||||
step={StepEnum.payment}
|
step={StepEnum.payment}
|
||||||
label={intl.formatMessage({ id: "Select payment method" })}
|
label={intl.formatMessage({ id: "Select payment method" })}
|
||||||
>
|
>
|
||||||
<Payment hotel={hotel.data.attributes} />
|
<Payment
|
||||||
|
hotelId={hotel.data.attributes.operaId}
|
||||||
|
otherPaymentOptions={
|
||||||
|
hotel.data.attributes.merchantInformationData
|
||||||
|
.alternatePaymentOptions
|
||||||
|
}
|
||||||
|
savedCreditCards={savedCreditCards}
|
||||||
|
/>
|
||||||
</SectionAccordion>
|
</SectionAccordion>
|
||||||
</section>
|
</section>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: var(--Spacing-x3);
|
gap: var(--Spacing-x3);
|
||||||
padding: var(--Spacing-x3) var(--Spacing-x4);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.column {
|
.column {
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
.grid {
|
.grid {
|
||||||
display: grid;
|
display: grid;
|
||||||
gap: var(--Spacing-x3);
|
gap: var(--Spacing-x3);
|
||||||
padding: var(--Spacing-x3) var(--Spacing-x4);
|
|
||||||
}
|
}
|
||||||
@media screen and (min-width: 767px) {
|
@media screen and (min-width: 767px) {
|
||||||
.grid {
|
.grid {
|
||||||
|
|||||||
@@ -37,6 +37,7 @@
|
|||||||
display: grid;
|
display: grid;
|
||||||
padding: var(--Spacing-x4) var(--Spacing-x2) 0;
|
padding: var(--Spacing-x4) var(--Spacing-x2) 0;
|
||||||
gap: var(--Spacing-x4);
|
gap: var(--Spacing-x4);
|
||||||
|
align-items: start;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mainContent {
|
.mainContent {
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ export default async function ContentPage() {
|
|||||||
<Hero
|
<Hero
|
||||||
alt={hero_image.meta.alt || hero_image.meta.caption || ""}
|
alt={hero_image.meta.alt || hero_image.meta.caption || ""}
|
||||||
src={hero_image.url}
|
src={hero_image.url}
|
||||||
|
focalPoint={hero_image.focalPoint}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
) : null}
|
) : null}
|
||||||
|
|||||||
@@ -397,6 +397,7 @@ export const renderOptions: RenderOptions = {
|
|||||||
height={365}
|
height={365}
|
||||||
src={image.url}
|
src={image.url}
|
||||||
width={width}
|
width={width}
|
||||||
|
focalPoint={image.focalPoint}
|
||||||
{...props}
|
{...props}
|
||||||
/>
|
/>
|
||||||
<Caption>{image.meta.caption}</Caption>
|
<Caption>{image.meta.caption}</Caption>
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
|
import type { FocalPoint } from "@/types/components/image"
|
||||||
|
|
||||||
export interface HeroProps {
|
export interface HeroProps {
|
||||||
alt: string
|
alt: string
|
||||||
src: string
|
src: string
|
||||||
|
focalPoint?: FocalPoint
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { HeroProps } from "./hero"
|
|||||||
|
|
||||||
import styles from "./hero.module.css"
|
import styles from "./hero.module.css"
|
||||||
|
|
||||||
export default async function Hero({ alt, src }: HeroProps) {
|
export default async function Hero({ alt, src, focalPoint }: HeroProps) {
|
||||||
return (
|
return (
|
||||||
<Image
|
<Image
|
||||||
className={styles.hero}
|
className={styles.hero}
|
||||||
@@ -12,6 +12,7 @@ export default async function Hero({ alt, src }: HeroProps) {
|
|||||||
height={480}
|
height={480}
|
||||||
width={1196}
|
width={1196}
|
||||||
src={src}
|
src={src}
|
||||||
|
focalPoint={focalPoint}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,49 @@
|
|||||||
|
import Image from "next/image"
|
||||||
|
import { useFormContext } from "react-hook-form"
|
||||||
|
|
||||||
|
import { PAYMENT_METHOD_ICONS, PaymentMethodEnum } from "@/constants/booking"
|
||||||
|
|
||||||
|
import Body from "@/components/TempDesignSystem/Text/Body"
|
||||||
|
import Caption from "@/components/TempDesignSystem/Text/Caption"
|
||||||
|
|
||||||
|
import { PaymentOptionProps } from "./paymentOption"
|
||||||
|
|
||||||
|
import styles from "./paymentOption.module.css"
|
||||||
|
|
||||||
|
export default function PaymentOption({
|
||||||
|
name,
|
||||||
|
value,
|
||||||
|
label,
|
||||||
|
cardNumber,
|
||||||
|
registerOptions = {},
|
||||||
|
}: PaymentOptionProps) {
|
||||||
|
const { register } = useFormContext()
|
||||||
|
|
||||||
|
return (
|
||||||
|
<label key={value} className={styles.paymentOption}>
|
||||||
|
<div className={styles.titleContainer}>
|
||||||
|
<input
|
||||||
|
aria-hidden
|
||||||
|
hidden
|
||||||
|
type="radio"
|
||||||
|
id={value}
|
||||||
|
value={value}
|
||||||
|
{...register(name, registerOptions)}
|
||||||
|
/>
|
||||||
|
<span className={styles.radio} />
|
||||||
|
<Body>{label}</Body>
|
||||||
|
</div>
|
||||||
|
{cardNumber ? (
|
||||||
|
<Caption color="uiTextMediumContrast">•••• {cardNumber}</Caption>
|
||||||
|
) : (
|
||||||
|
<Image
|
||||||
|
className={styles.paymentOptionIcon}
|
||||||
|
src={PAYMENT_METHOD_ICONS[value as PaymentMethodEnum]}
|
||||||
|
alt={label}
|
||||||
|
width={48}
|
||||||
|
height={32}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</label>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
import { RegisterOptions } from "react-hook-form"
|
import { RegisterOptions } from "react-hook-form"
|
||||||
|
|
||||||
import { PaymentMethodEnum } from "@/constants/booking"
|
|
||||||
|
|
||||||
export interface PaymentOptionProps {
|
export interface PaymentOptionProps {
|
||||||
name: string
|
name: string
|
||||||
value: PaymentMethodEnum
|
value: string
|
||||||
label: string
|
label: string
|
||||||
|
cardNumber?: string
|
||||||
registerOptions?: RegisterOptions
|
registerOptions?: RegisterOptions
|
||||||
|
onChange?: () => void
|
||||||
}
|
}
|
||||||
@@ -23,6 +23,7 @@ import LoadingSpinner from "@/components/LoadingSpinner"
|
|||||||
import Button from "@/components/TempDesignSystem/Button"
|
import Button from "@/components/TempDesignSystem/Button"
|
||||||
import Checkbox from "@/components/TempDesignSystem/Checkbox"
|
import Checkbox from "@/components/TempDesignSystem/Checkbox"
|
||||||
import Link from "@/components/TempDesignSystem/Link"
|
import Link from "@/components/TempDesignSystem/Link"
|
||||||
|
import Body from "@/components/TempDesignSystem/Text/Body"
|
||||||
import Caption from "@/components/TempDesignSystem/Text/Caption"
|
import Caption from "@/components/TempDesignSystem/Text/Caption"
|
||||||
import { toast } from "@/components/TempDesignSystem/Toasts"
|
import { toast } from "@/components/TempDesignSystem/Toasts"
|
||||||
import { useHandleBookingStatus } from "@/hooks/booking/useHandleBookingStatus"
|
import { useHandleBookingStatus } from "@/hooks/booking/useHandleBookingStatus"
|
||||||
@@ -38,7 +39,15 @@ import { PaymentProps } from "@/types/components/hotelReservation/selectRate/sec
|
|||||||
const maxRetries = 40
|
const maxRetries = 40
|
||||||
const retryInterval = 2000
|
const retryInterval = 2000
|
||||||
|
|
||||||
export default function Payment({ hotel }: PaymentProps) {
|
function isPaymentMethodEnum(value: string): value is PaymentMethodEnum {
|
||||||
|
return Object.values(PaymentMethodEnum).includes(value as PaymentMethodEnum)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function Payment({
|
||||||
|
hotelId,
|
||||||
|
otherPaymentOptions,
|
||||||
|
savedCreditCards,
|
||||||
|
}: PaymentProps) {
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const lang = useLang()
|
const lang = useLang()
|
||||||
const intl = useIntl()
|
const intl = useIntl()
|
||||||
@@ -46,7 +55,9 @@ export default function Payment({ hotel }: PaymentProps) {
|
|||||||
|
|
||||||
const methods = useForm<PaymentFormData>({
|
const methods = useForm<PaymentFormData>({
|
||||||
defaultValues: {
|
defaultValues: {
|
||||||
paymentMethod: PaymentMethodEnum.card,
|
paymentMethod: savedCreditCards?.length
|
||||||
|
? savedCreditCards[0].id
|
||||||
|
: PaymentMethodEnum.card,
|
||||||
smsConfirmation: false,
|
smsConfirmation: false,
|
||||||
termsAndConditions: false,
|
termsAndConditions: false,
|
||||||
},
|
},
|
||||||
@@ -87,8 +98,17 @@ export default function Payment({ hotel }: PaymentProps) {
|
|||||||
}, [confirmationNumber, bookingStatus, router])
|
}, [confirmationNumber, bookingStatus, router])
|
||||||
|
|
||||||
function handleSubmit(data: PaymentFormData) {
|
function handleSubmit(data: PaymentFormData) {
|
||||||
|
// set payment method to card if saved card is submitted
|
||||||
|
const paymentMethod = isPaymentMethodEnum(data.paymentMethod)
|
||||||
|
? data.paymentMethod
|
||||||
|
: PaymentMethodEnum.card
|
||||||
|
|
||||||
|
const savedCreditCard = savedCreditCards?.find(
|
||||||
|
(card) => card.id === data.paymentMethod
|
||||||
|
)
|
||||||
|
|
||||||
initiateBooking.mutate({
|
initiateBooking.mutate({
|
||||||
hotelId: hotel.operaId,
|
hotelId: hotelId,
|
||||||
checkInDate: "2024-12-10",
|
checkInDate: "2024-12-10",
|
||||||
checkOutDate: "2024-12-11",
|
checkOutDate: "2024-12-11",
|
||||||
rooms: [
|
rooms: [
|
||||||
@@ -116,7 +136,14 @@ export default function Payment({ hotel }: PaymentProps) {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
payment: {
|
payment: {
|
||||||
paymentMethod: data.paymentMethod,
|
paymentMethod,
|
||||||
|
card: savedCreditCard
|
||||||
|
? {
|
||||||
|
alias: savedCreditCard.alias,
|
||||||
|
expiryDate: savedCreditCard.expirationDate,
|
||||||
|
cardType: savedCreditCard.cardType,
|
||||||
|
}
|
||||||
|
: undefined,
|
||||||
cardHolder: {
|
cardHolder: {
|
||||||
email: "test.user@scandichotels.com",
|
email: "test.user@scandichotels.com",
|
||||||
name: "Test User",
|
name: "Test User",
|
||||||
@@ -143,65 +170,94 @@ export default function Payment({ hotel }: PaymentProps) {
|
|||||||
className={styles.paymentContainer}
|
className={styles.paymentContainer}
|
||||||
onSubmit={methods.handleSubmit(handleSubmit)}
|
onSubmit={methods.handleSubmit(handleSubmit)}
|
||||||
>
|
>
|
||||||
<div className={styles.paymentOptionContainer}>
|
{savedCreditCards?.length ? (
|
||||||
<PaymentOption
|
<section className={styles.section}>
|
||||||
name="paymentMethod"
|
<Body color="uiTextHighContrast" textTransform="bold">
|
||||||
value={PaymentMethodEnum.card}
|
{intl.formatMessage({ id: "MY SAVED CARDS" })}
|
||||||
label={intl.formatMessage({ id: "Credit card" })}
|
</Body>
|
||||||
/>
|
<div className={styles.paymentOptionContainer}>
|
||||||
{hotel.merchantInformationData.alternatePaymentOptions.map(
|
{savedCreditCards?.map((savedCreditCard) => (
|
||||||
(paymentMethod) => (
|
<PaymentOption
|
||||||
|
key={savedCreditCard.id}
|
||||||
|
name="paymentMethod"
|
||||||
|
value={savedCreditCard.id}
|
||||||
|
label={
|
||||||
|
PAYMENT_METHOD_TITLES[
|
||||||
|
savedCreditCard.cardType as PaymentMethodEnum
|
||||||
|
]
|
||||||
|
}
|
||||||
|
cardNumber={savedCreditCard.truncatedNumber}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
) : null}
|
||||||
|
<section className={styles.section}>
|
||||||
|
{savedCreditCards?.length ? (
|
||||||
|
<Body color="uiTextHighContrast" textTransform="bold">
|
||||||
|
{intl.formatMessage({ id: "OTHER PAYMENT METHODS" })}
|
||||||
|
</Body>
|
||||||
|
) : null}
|
||||||
|
<div className={styles.paymentOptionContainer}>
|
||||||
|
<PaymentOption
|
||||||
|
name="paymentMethod"
|
||||||
|
value={PaymentMethodEnum.card}
|
||||||
|
label={intl.formatMessage({ id: "Credit card" })}
|
||||||
|
/>
|
||||||
|
{otherPaymentOptions.map((paymentMethod) => (
|
||||||
<PaymentOption
|
<PaymentOption
|
||||||
key={paymentMethod}
|
key={paymentMethod}
|
||||||
name="paymentMethod"
|
name="paymentMethod"
|
||||||
value={paymentMethod as PaymentMethodEnum}
|
value={paymentMethod}
|
||||||
label={
|
label={
|
||||||
PAYMENT_METHOD_TITLES[paymentMethod as PaymentMethodEnum]
|
PAYMENT_METHOD_TITLES[paymentMethod as PaymentMethodEnum]
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
)
|
))}
|
||||||
)}
|
</div>
|
||||||
</div>
|
</section>
|
||||||
<Checkbox name="smsConfirmation">
|
<section className={styles.section}>
|
||||||
<Caption>
|
<Checkbox name="smsConfirmation">
|
||||||
{intl.formatMessage({
|
<Caption>
|
||||||
id: "I would like to get my booking confirmation via sms",
|
{intl.formatMessage({
|
||||||
})}
|
id: "I would like to get my booking confirmation via sms",
|
||||||
</Caption>
|
})}
|
||||||
</Checkbox>
|
</Caption>
|
||||||
|
</Checkbox>
|
||||||
|
|
||||||
<AriaLabel className={styles.terms}>
|
<AriaLabel className={styles.terms}>
|
||||||
<Checkbox name="termsAndConditions" />
|
<Checkbox name="termsAndConditions" />
|
||||||
<Caption>
|
<Caption>
|
||||||
{intl.formatMessage<React.ReactNode>(
|
{intl.formatMessage<React.ReactNode>(
|
||||||
{
|
{
|
||||||
id: "booking.terms",
|
id: "booking.terms",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
termsLink: (str) => (
|
termsLink: (str) => (
|
||||||
<Link
|
<Link
|
||||||
className={styles.link}
|
className={styles.link}
|
||||||
variant="underscored"
|
variant="underscored"
|
||||||
href={bookingTermsAndConditions[lang]}
|
href={bookingTermsAndConditions[lang]}
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
{str}
|
{str}
|
||||||
</Link>
|
</Link>
|
||||||
),
|
),
|
||||||
privacyLink: (str) => (
|
privacyLink: (str) => (
|
||||||
<Link
|
<Link
|
||||||
className={styles.link}
|
className={styles.link}
|
||||||
variant="underscored"
|
variant="underscored"
|
||||||
href={privacyPolicy[lang]}
|
href={privacyPolicy[lang]}
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
{str}
|
{str}
|
||||||
</Link>
|
</Link>
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
)}
|
)}
|
||||||
</Caption>
|
</Caption>
|
||||||
</AriaLabel>
|
</AriaLabel>
|
||||||
|
</section>
|
||||||
<Button
|
<Button
|
||||||
type="submit"
|
type="submit"
|
||||||
className={styles.submitButton}
|
className={styles.submitButton}
|
||||||
@@ -1,10 +1,16 @@
|
|||||||
.paymentContainer {
|
.paymentContainer {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: var(--Spacing-x3);
|
gap: var(--Spacing-x4);
|
||||||
max-width: 480px;
|
max-width: 480px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.section {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: var(--Spacing-x2);
|
||||||
|
}
|
||||||
|
|
||||||
.paymentOptionContainer {
|
.paymentOptionContainer {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
@@ -1,9 +1,7 @@
|
|||||||
import { z } from "zod"
|
import { z } from "zod"
|
||||||
|
|
||||||
import { PaymentMethodEnum } from "@/constants/booking"
|
|
||||||
|
|
||||||
export const paymentSchema = z.object({
|
export const paymentSchema = z.object({
|
||||||
paymentMethod: z.nativeEnum(PaymentMethodEnum),
|
paymentMethod: z.string(),
|
||||||
smsConfirmation: z.boolean(),
|
smsConfirmation: z.boolean(),
|
||||||
termsAndConditions: z.boolean().refine((value) => value === true, {
|
termsAndConditions: z.boolean().refine((value) => value === true, {
|
||||||
message: "You must accept the terms and conditions",
|
message: "You must accept the terms and conditions",
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
"use client"
|
"use client"
|
||||||
import { useEffect, useRef, useState } from "react"
|
import { useEffect, useState } from "react"
|
||||||
import { useIntl } from "react-intl"
|
import { useIntl } from "react-intl"
|
||||||
|
|
||||||
import { useEnterDetailsStore } from "@/stores/enter-details"
|
import { useEnterDetailsStore } from "@/stores/enter-details"
|
||||||
|
|||||||
@@ -1,43 +0,0 @@
|
|||||||
import Image from "next/image"
|
|
||||||
import { useFormContext } from "react-hook-form"
|
|
||||||
|
|
||||||
import { PAYMENT_METHOD_ICONS } from "@/constants/booking"
|
|
||||||
|
|
||||||
import Body from "@/components/TempDesignSystem/Text/Body"
|
|
||||||
|
|
||||||
import { PaymentOptionProps } from "./paymentOption"
|
|
||||||
|
|
||||||
import styles from "./paymentOption.module.css"
|
|
||||||
|
|
||||||
export default function PaymentOption({
|
|
||||||
name,
|
|
||||||
value,
|
|
||||||
label,
|
|
||||||
}: PaymentOptionProps) {
|
|
||||||
const { register } = useFormContext()
|
|
||||||
return (
|
|
||||||
<label key={value} className={styles.paymentOption} htmlFor={value}>
|
|
||||||
<div className={styles.titleContainer}>
|
|
||||||
<input
|
|
||||||
aria-hidden
|
|
||||||
hidden
|
|
||||||
type="radio"
|
|
||||||
id={value}
|
|
||||||
value={value}
|
|
||||||
{...register(name)}
|
|
||||||
/>
|
|
||||||
<span className={styles.radio} />
|
|
||||||
<Body asChild>
|
|
||||||
<label htmlFor={value}>{label}</label>
|
|
||||||
</Body>
|
|
||||||
</div>
|
|
||||||
<Image
|
|
||||||
className={styles.paymentOptionIcon}
|
|
||||||
src={PAYMENT_METHOD_ICONS[value]}
|
|
||||||
alt={label}
|
|
||||||
width={48}
|
|
||||||
height={32}
|
|
||||||
/>
|
|
||||||
</label>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -2,7 +2,10 @@
|
|||||||
|
|
||||||
import NextImage from "next/image"
|
import NextImage from "next/image"
|
||||||
|
|
||||||
import type { ImageLoaderProps, ImageProps } from "next/image"
|
import type { ImageLoaderProps } from "next/image"
|
||||||
|
import type { CSSProperties } from "react"
|
||||||
|
|
||||||
|
import type { ImageProps } from "@/types/components/image"
|
||||||
|
|
||||||
function imageLoader({ quality, src, width }: ImageLoaderProps) {
|
function imageLoader({ quality, src, width }: ImageLoaderProps) {
|
||||||
const hasQS = src.indexOf("?") !== -1
|
const hasQS = src.indexOf("?") !== -1
|
||||||
@@ -10,6 +13,14 @@ function imageLoader({ quality, src, width }: ImageLoaderProps) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Next/Image adds & instead of ? before the params
|
// Next/Image adds & instead of ? before the params
|
||||||
export default function Image(props: ImageProps) {
|
export default function Image({ focalPoint, style, ...props }: ImageProps) {
|
||||||
return <NextImage {...props} loader={imageLoader} />
|
const styles: CSSProperties = focalPoint
|
||||||
|
? {
|
||||||
|
objectFit: "cover",
|
||||||
|
objectPosition: `${focalPoint.x}% ${focalPoint.y}%`,
|
||||||
|
...style,
|
||||||
|
}
|
||||||
|
: { ...style }
|
||||||
|
|
||||||
|
return <NextImage {...props} style={styles} loader={imageLoader} />
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ export default function ImageContainer({
|
|||||||
height={365}
|
height={365}
|
||||||
width={600}
|
width={600}
|
||||||
alt={leftImage.meta.alt || leftImage.title}
|
alt={leftImage.meta.alt || leftImage.title}
|
||||||
|
focalPoint={leftImage.focalPoint}
|
||||||
/>
|
/>
|
||||||
<Caption>{leftImage.meta.caption}</Caption>
|
<Caption>{leftImage.meta.caption}</Caption>
|
||||||
</article>
|
</article>
|
||||||
@@ -28,6 +29,7 @@ export default function ImageContainer({
|
|||||||
height={365}
|
height={365}
|
||||||
width={600}
|
width={600}
|
||||||
alt={rightImage.meta.alt || rightImage.title}
|
alt={rightImage.meta.alt || rightImage.title}
|
||||||
|
focalPoint={rightImage.focalPoint}
|
||||||
/>
|
/>
|
||||||
<Caption>{leftImage.meta.caption}</Caption>
|
<Caption>{leftImage.meta.caption}</Caption>
|
||||||
</article>
|
</article>
|
||||||
|
|||||||
@@ -396,6 +396,7 @@ export const renderOptions: RenderOptions = {
|
|||||||
height={365}
|
height={365}
|
||||||
src={image.url}
|
src={image.url}
|
||||||
width={width}
|
width={width}
|
||||||
|
focalPoint={image.focalPoint}
|
||||||
{...props}
|
{...props}
|
||||||
/>
|
/>
|
||||||
<Caption>{image.meta.caption}</Caption>
|
<Caption>{image.meta.caption}</Caption>
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
import JsonToHtml from "@/components/JsonToHtml"
|
import JsonToHtml from "@/components/JsonToHtml"
|
||||||
|
|
||||||
|
import ShortcutsList from "../Blocks/ShortcutsList"
|
||||||
|
import Card from "../TempDesignSystem/Card"
|
||||||
|
import TeaserCard from "../TempDesignSystem/TeaserCard"
|
||||||
import JoinLoyaltyContact from "./JoinLoyalty"
|
import JoinLoyaltyContact from "./JoinLoyalty"
|
||||||
import MyPagesNavigation from "./MyPagesNavigation"
|
import MyPagesNavigation from "./MyPagesNavigation"
|
||||||
|
|
||||||
@@ -40,6 +43,35 @@ export default function Sidebar({ blocks }: SidebarProps) {
|
|||||||
key={`${block.typename}-${idx}`}
|
key={`${block.typename}-${idx}`}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
|
case SidebarEnums.blocks.ScriptedCard:
|
||||||
|
return (
|
||||||
|
<Card
|
||||||
|
key={block.scripted_card.system.uid}
|
||||||
|
heading={block.scripted_card.heading}
|
||||||
|
secondaryButton={block.scripted_card.secondaryButton}
|
||||||
|
primaryButton={block.scripted_card.primaryButton}
|
||||||
|
bodyText={block.scripted_card.body_text}
|
||||||
|
scriptedTopTitle={block.scripted_card.scripted_top_title}
|
||||||
|
theme={block.scripted_card.theme ?? "image"}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
case SidebarEnums.blocks.TeaserCard:
|
||||||
|
return (
|
||||||
|
<TeaserCard
|
||||||
|
title={block.teaser_card.heading}
|
||||||
|
description={block.teaser_card.body_text}
|
||||||
|
style={block.teaser_card.theme}
|
||||||
|
key={block.teaser_card.system.uid}
|
||||||
|
primaryButton={block.teaser_card.primaryButton}
|
||||||
|
secondaryButton={block.teaser_card.secondaryButton}
|
||||||
|
sidePeekButton={block.teaser_card.sidePeekButton}
|
||||||
|
sidePeekContent={block.teaser_card.sidePeekContent}
|
||||||
|
image={block.teaser_card.image}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
case SidebarEnums.blocks.QuickLinks:
|
||||||
|
return <ShortcutsList {...block.shortcuts} hasTwoColumns={false} />
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,10 @@
|
|||||||
display: grid;
|
display: grid;
|
||||||
container-name: sidebar;
|
container-name: sidebar;
|
||||||
container-type: inline-size;
|
container-type: inline-size;
|
||||||
|
gap: var(--Spacing-x3);
|
||||||
|
|
||||||
|
border-top: 1px solid var(--Base-Border-Subtle);
|
||||||
|
padding-top: var(--Spacing-x4);
|
||||||
}
|
}
|
||||||
|
|
||||||
.content {
|
.content {
|
||||||
@@ -11,8 +15,10 @@
|
|||||||
@media screen and (min-width: 1367px) {
|
@media screen and (min-width: 1367px) {
|
||||||
.aside {
|
.aside {
|
||||||
align-content: flex-start;
|
align-content: flex-start;
|
||||||
display: grid;
|
|
||||||
gap: var(--Spacing-x4);
|
gap: var(--Spacing-x4);
|
||||||
|
|
||||||
|
border-top: 0;
|
||||||
|
padding-top: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ export default function CardImage({
|
|||||||
alt={backgroundImage.title}
|
alt={backgroundImage.title}
|
||||||
width={180}
|
width={180}
|
||||||
height={180}
|
height={180}
|
||||||
|
focalPoint={backgroundImage.focalPoint}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ export default function Card({
|
|||||||
|
|
||||||
imageWidth =
|
imageWidth =
|
||||||
imageWidth ||
|
imageWidth ||
|
||||||
(backgroundImage && "dimensions" in backgroundImage
|
(backgroundImage?.dimensions
|
||||||
? backgroundImage.dimensions.aspectRatio * imageHeight
|
? backgroundImage.dimensions.aspectRatio * imageHeight
|
||||||
: 420)
|
: 420)
|
||||||
|
|
||||||
@@ -53,6 +53,7 @@ export default function Card({
|
|||||||
alt={backgroundImage.meta.alt || backgroundImage.title}
|
alt={backgroundImage.meta.alt || backgroundImage.title}
|
||||||
width={imageWidth}
|
width={imageWidth}
|
||||||
height={imageHeight}
|
height={imageHeight}
|
||||||
|
focalPoint={backgroundImage.focalPoint}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ export default function Card({
|
|||||||
const { register } = useFormContext()
|
const { register } = useFormContext()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<label className={styles.label} data-declined={declined}>
|
<label className={styles.label} data-declined={declined} tabIndex={0}>
|
||||||
<Caption className={styles.title} type="label" uppercase>
|
<Caption className={styles.title} type="label" uppercase>
|
||||||
{title}
|
{title}
|
||||||
</Caption>
|
</Caption>
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ export default function LoyaltyCard({
|
|||||||
height={160}
|
height={160}
|
||||||
className={styles.image}
|
className={styles.image}
|
||||||
alt={image.meta.alt || image.title}
|
alt={image.meta.alt || image.title}
|
||||||
|
focalPoint={image.focalPoint}
|
||||||
/>
|
/>
|
||||||
) : null}
|
) : null}
|
||||||
<Title as="h5" level="h3" textAlign="center">
|
<Title as="h5" level="h3" textAlign="center">
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ export default function TeaserCard({
|
|||||||
className={styles.backgroundImage}
|
className={styles.backgroundImage}
|
||||||
width={399}
|
width={399}
|
||||||
height={201}
|
height={201}
|
||||||
|
focalPoint={image.focalPoint}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
border-radius: var(--Corner-radius-Medium);
|
border-radius: var(--Corner-radius-Medium);
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
max-width: 399px;
|
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,15 @@ export enum PaymentMethodEnum {
|
|||||||
weChatPay = "weChatPay",
|
weChatPay = "weChatPay",
|
||||||
payPal = "payPal",
|
payPal = "payPal",
|
||||||
klarna = "klarna",
|
klarna = "klarna",
|
||||||
|
americanExpress = "americanExpress",
|
||||||
|
dankort = "dankort",
|
||||||
|
dinersClub = "dinersClub",
|
||||||
|
jcb = "jcb",
|
||||||
|
masterCard = "masterCard",
|
||||||
|
visa = "visa",
|
||||||
|
maestro = "maestro",
|
||||||
|
chinaUnionPay = "chinaUnionPay",
|
||||||
|
discover = "discover",
|
||||||
}
|
}
|
||||||
|
|
||||||
export const PAYMENT_METHOD_TITLES: Record<
|
export const PAYMENT_METHOD_TITLES: Record<
|
||||||
@@ -33,6 +42,15 @@ export const PAYMENT_METHOD_TITLES: Record<
|
|||||||
weChatPay: "WeChat Pay",
|
weChatPay: "WeChat Pay",
|
||||||
payPal: "PayPal",
|
payPal: "PayPal",
|
||||||
klarna: "Klarna",
|
klarna: "Klarna",
|
||||||
|
americanExpress: "American Express",
|
||||||
|
dankort: "Dankort",
|
||||||
|
dinersClub: "Diners Club",
|
||||||
|
jcb: "JCB",
|
||||||
|
masterCard: "Mastercard",
|
||||||
|
visa: "Visa",
|
||||||
|
maestro: "Maestro",
|
||||||
|
chinaUnionPay: "China UnionPay",
|
||||||
|
discover: "Discover",
|
||||||
}
|
}
|
||||||
|
|
||||||
export const PAYMENT_METHOD_ICONS: Record<
|
export const PAYMENT_METHOD_ICONS: Record<
|
||||||
@@ -49,4 +67,13 @@ export const PAYMENT_METHOD_ICONS: Record<
|
|||||||
weChatPay: "/_static/icons/payment/wechat-pay.svg",
|
weChatPay: "/_static/icons/payment/wechat-pay.svg",
|
||||||
payPal: "/_static/icons/payment/paypal.svg",
|
payPal: "/_static/icons/payment/paypal.svg",
|
||||||
klarna: "/_static/icons/payment/klarna.svg",
|
klarna: "/_static/icons/payment/klarna.svg",
|
||||||
|
americanExpress: "/_static/icons/payment/american-express.svg",
|
||||||
|
dankort: "/_static/icons/payment/dankort.svg",
|
||||||
|
dinersClub: "/_static/icons/payment/diners-club.svg",
|
||||||
|
jcb: "/_static/icons/payment/jcb.svg",
|
||||||
|
masterCard: "/_static/icons/payment/mastercard.svg",
|
||||||
|
visa: "/_static/icons/payment/visa.svg",
|
||||||
|
maestro: "/_static/icons/payment/maestro.svg",
|
||||||
|
chinaUnionPay: "/_static/icons/payment/china-union-pay.svg",
|
||||||
|
discover: "/_static/icons/payment/discover.svg",
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,8 +9,8 @@
|
|||||||
"Add code": "Tilføj kode",
|
"Add code": "Tilføj kode",
|
||||||
"Add new card": "Tilføj nyt kort",
|
"Add new card": "Tilføj nyt kort",
|
||||||
"Address": "Adresse",
|
"Address": "Adresse",
|
||||||
"Airport": "Lufthavn",
|
|
||||||
"Adults": "voksne",
|
"Adults": "voksne",
|
||||||
|
"Airport": "Lufthavn",
|
||||||
"All our breakfast buffets offer gluten free, vegan, and allergy-friendly options.": "Alle vores morgenmadsbuffeter tilbyder glutenfrie, veganske og allergivenlige muligheder.",
|
"All our breakfast buffets offer gluten free, vegan, and allergy-friendly options.": "Alle vores morgenmadsbuffeter tilbyder glutenfrie, veganske og allergivenlige muligheder.",
|
||||||
"Already a friend?": "Allerede en ven?",
|
"Already a friend?": "Allerede en ven?",
|
||||||
"Amenities": "Faciliteter",
|
"Amenities": "Faciliteter",
|
||||||
@@ -23,6 +23,7 @@
|
|||||||
"Approx.": "Ca.",
|
"Approx.": "Ca.",
|
||||||
"Are you sure you want to remove the card ending with {lastFourDigits} from your member profile?": "Er du sikker på, at du vil fjerne kortet, der slutter me {lastFourDigits} fra din medlemsprofil?",
|
"Are you sure you want to remove the card ending with {lastFourDigits} from your member profile?": "Er du sikker på, at du vil fjerne kortet, der slutter me {lastFourDigits} fra din medlemsprofil?",
|
||||||
"Arrival date": "Ankomstdato",
|
"Arrival date": "Ankomstdato",
|
||||||
|
"as of today": "pr. dags dato",
|
||||||
"As our": "Som vores {level}",
|
"As our": "Som vores {level}",
|
||||||
"As our Close Friend": "Som vores nære ven",
|
"As our Close Friend": "Som vores nære ven",
|
||||||
"At latest": "Senest",
|
"At latest": "Senest",
|
||||||
@@ -35,6 +36,12 @@
|
|||||||
"Book": "Book",
|
"Book": "Book",
|
||||||
"Book reward night": "Book bonusnat",
|
"Book reward night": "Book bonusnat",
|
||||||
"Booking number": "Bookingnummer",
|
"Booking number": "Bookingnummer",
|
||||||
|
"booking.adults": "{totalAdults, plural, one {# voksen} other {# voksne}}",
|
||||||
|
"booking.children": "{totalChildren, plural, one {# barn} other {# børn}}",
|
||||||
|
"booking.guests": "Maks {nrOfGuests, plural, one {# gæst} other {# gæster}}",
|
||||||
|
"booking.nights": "{totalNights, plural, one {# nat} other {# nætter}}",
|
||||||
|
"booking.rooms": "{totalRooms, plural, one {# værelse} other {# værelser}}",
|
||||||
|
"booking.terms": "Ved at betale med en af de tilgængelige betalingsmetoder, accepterer jeg vilkårene for denne booking og de generelle <termsLink>Vilkår og betingelser</termsLink>, og forstår, at Scandic vil behandle min personlige data i forbindelse med denne booking i henhold til <privacyLink>Scandics Privatlivspolitik</privacyLink>. Jeg accepterer, at Scandic kræver et gyldigt kreditkort under min besøg i tilfælde af, at noget er tilbagebetalt.",
|
||||||
"Breakfast": "Morgenmad",
|
"Breakfast": "Morgenmad",
|
||||||
"Breakfast buffet": "Morgenbuffet",
|
"Breakfast buffet": "Morgenbuffet",
|
||||||
"Breakfast excluded": "Morgenmad ikke inkluderet",
|
"Breakfast excluded": "Morgenmad ikke inkluderet",
|
||||||
@@ -43,7 +50,9 @@
|
|||||||
"Breakfast selection in next step.": "Valg af morgenmad i næste trin.",
|
"Breakfast selection in next step.": "Valg af morgenmad i næste trin.",
|
||||||
"Bus terminal": "Busstation",
|
"Bus terminal": "Busstation",
|
||||||
"Business": "Forretning",
|
"Business": "Forretning",
|
||||||
|
"by": "inden",
|
||||||
"Cancel": "Afbestille",
|
"Cancel": "Afbestille",
|
||||||
|
"characters": "tegn",
|
||||||
"Check in": "Check ind",
|
"Check in": "Check ind",
|
||||||
"Check out": "Check ud",
|
"Check out": "Check ud",
|
||||||
"Check out the credit cards saved to your profile. Pay with a saved card when signed in for a smoother web experience.": "Tjek de kreditkort, der er gemt på din profil. Betal med et gemt kort, når du er logget ind for en mere jævn weboplevelse.",
|
"Check out the credit cards saved to your profile. Pay with a saved card when signed in for a smoother web experience.": "Tjek de kreditkort, der er gemt på din profil. Betal med et gemt kort, når du er logget ind for en mere jævn weboplevelse.",
|
||||||
@@ -101,9 +110,9 @@
|
|||||||
"Explore all levels and benefits": "Udforsk alle niveauer og fordele",
|
"Explore all levels and benefits": "Udforsk alle niveauer og fordele",
|
||||||
"Explore nearby": "Udforsk i nærheden",
|
"Explore nearby": "Udforsk i nærheden",
|
||||||
"Extras to your booking": "Tillæg til din booking",
|
"Extras to your booking": "Tillæg til din booking",
|
||||||
"FAQ": "Ofte stillede spørgsmål",
|
|
||||||
"Failed to delete credit card, please try again later.": "Kunne ikke slette kreditkort. Prøv venligst igen senere.",
|
"Failed to delete credit card, please try again later.": "Kunne ikke slette kreditkort. Prøv venligst igen senere.",
|
||||||
"Fair": "Messe",
|
"Fair": "Messe",
|
||||||
|
"FAQ": "Ofte stillede spørgsmål",
|
||||||
"Find booking": "Find booking",
|
"Find booking": "Find booking",
|
||||||
"Find hotels": "Find hotel",
|
"Find hotels": "Find hotel",
|
||||||
"First name": "Fornavn",
|
"First name": "Fornavn",
|
||||||
@@ -117,7 +126,9 @@
|
|||||||
"Get member benefits & offers": "Få medlemsfordele og tilbud",
|
"Get member benefits & offers": "Få medlemsfordele og tilbud",
|
||||||
"Go back to edit": "Gå tilbage til redigering",
|
"Go back to edit": "Gå tilbage til redigering",
|
||||||
"Go back to overview": "Gå tilbage til oversigten",
|
"Go back to overview": "Gå tilbage til oversigten",
|
||||||
|
"guest": "gæst",
|
||||||
"Guest information": "Gæsteinformation",
|
"Guest information": "Gæsteinformation",
|
||||||
|
"guests": "gæster",
|
||||||
"Guests & Rooms": "Gæster & værelser",
|
"Guests & Rooms": "Gæster & værelser",
|
||||||
"Hi": "Hei",
|
"Hi": "Hei",
|
||||||
"Highest level": "Højeste niveau",
|
"Highest level": "Højeste niveau",
|
||||||
@@ -125,6 +136,9 @@
|
|||||||
"Hotel": "Hotel",
|
"Hotel": "Hotel",
|
||||||
"Hotel facilities": "Hotel faciliteter",
|
"Hotel facilities": "Hotel faciliteter",
|
||||||
"Hotel surroundings": "Hotel omgivelser",
|
"Hotel surroundings": "Hotel omgivelser",
|
||||||
|
"hotelPages.rooms.roomCard.person": "person",
|
||||||
|
"hotelPages.rooms.roomCard.persons": "personer",
|
||||||
|
"hotelPages.rooms.roomCard.seeRoomDetails": "Se værelsesdetaljer",
|
||||||
"Hotels": "Hoteller",
|
"Hotels": "Hoteller",
|
||||||
"How do you want to sleep?": "Hvordan vil du sove?",
|
"How do you want to sleep?": "Hvordan vil du sove?",
|
||||||
"How it works": "Hvordan det virker",
|
"How it works": "Hvordan det virker",
|
||||||
@@ -135,9 +149,10 @@
|
|||||||
"In extra bed": "i ekstra seng",
|
"In extra bed": "i ekstra seng",
|
||||||
"Included": "Inkluderet",
|
"Included": "Inkluderet",
|
||||||
"It is not posible to manage your communication preferences right now, please try again later or contact support if the problem persists.": "Det er ikke muligt at administrere dine kommunikationspræferencer lige nu, prøv venligst igen senere eller kontakt support, hvis problemet fortsætter.",
|
"It is not posible to manage your communication preferences right now, please try again later or contact support if the problem persists.": "Det er ikke muligt at administrere dine kommunikationspræferencer lige nu, prøv venligst igen senere eller kontakt support, hvis problemet fortsætter.",
|
||||||
"Join Scandic Friends": "Tilmeld dig Scandic Friends",
|
|
||||||
"Join at no cost": "Tilmeld dig uden omkostninger",
|
"Join at no cost": "Tilmeld dig uden omkostninger",
|
||||||
|
"Join Scandic Friends": "Tilmeld dig Scandic Friends",
|
||||||
"King bed": "Kingsize-seng",
|
"King bed": "Kingsize-seng",
|
||||||
|
"km to city center": "km til byens centrum",
|
||||||
"Language": "Sprog",
|
"Language": "Sprog",
|
||||||
"Last name": "Efternavn",
|
"Last name": "Efternavn",
|
||||||
"Latest searches": "Seneste søgninger",
|
"Latest searches": "Seneste søgninger",
|
||||||
@@ -157,6 +172,7 @@
|
|||||||
"Log in here": "Log ind her",
|
"Log in here": "Log ind her",
|
||||||
"Log in/Join": "Log på/Tilmeld dig",
|
"Log in/Join": "Log på/Tilmeld dig",
|
||||||
"Log out": "Log ud",
|
"Log out": "Log ud",
|
||||||
|
"lowercase letter": "lille bogstav",
|
||||||
"Main menu": "Hovedmenu",
|
"Main menu": "Hovedmenu",
|
||||||
"Manage preferences": "Administrer præferencer",
|
"Manage preferences": "Administrer præferencer",
|
||||||
"Map": "Kort",
|
"Map": "Kort",
|
||||||
@@ -166,9 +182,9 @@
|
|||||||
"Member price": "Medlemspris",
|
"Member price": "Medlemspris",
|
||||||
"Member price from": "Medlemspris fra",
|
"Member price from": "Medlemspris fra",
|
||||||
"Members": "Medlemmer",
|
"Members": "Medlemmer",
|
||||||
|
"Membership cards": "Medlemskort",
|
||||||
"Membership ID": "Medlems-id",
|
"Membership ID": "Medlems-id",
|
||||||
"Membership ID copied to clipboard": "Medlems-ID kopieret til udklipsholder",
|
"Membership ID copied to clipboard": "Medlems-ID kopieret til udklipsholder",
|
||||||
"Membership cards": "Medlemskort",
|
|
||||||
"Menu": "Menu",
|
"Menu": "Menu",
|
||||||
"Modify": "Ændre",
|
"Modify": "Ændre",
|
||||||
"Month": "Måned",
|
"Month": "Måned",
|
||||||
@@ -178,11 +194,16 @@
|
|||||||
"My pages": "Mine sider",
|
"My pages": "Mine sider",
|
||||||
"My pages menu": "Mine sider menu",
|
"My pages menu": "Mine sider menu",
|
||||||
"My payment cards": "Mine betalingskort",
|
"My payment cards": "Mine betalingskort",
|
||||||
|
"MY SAVED CARDS": "MINE SAVEDE KORT",
|
||||||
"My wishes": "Mine ønsker",
|
"My wishes": "Mine ønsker",
|
||||||
|
"n/a": "n/a",
|
||||||
"Nearby": "I nærheden",
|
"Nearby": "I nærheden",
|
||||||
"Nearby companies": "Nærliggende virksomheder",
|
"Nearby companies": "Nærliggende virksomheder",
|
||||||
"New password": "Nyt kodeord",
|
"New password": "Nyt kodeord",
|
||||||
"Next": "Næste",
|
"Next": "Næste",
|
||||||
|
"next level:": "Næste niveau:",
|
||||||
|
"night": "nat",
|
||||||
|
"nights": "nætter",
|
||||||
"Nights needed to level up": "Nætter nødvendige for at komme i niveau",
|
"Nights needed to level up": "Nætter nødvendige for at komme i niveau",
|
||||||
"No breakfast": "Ingen morgenmad",
|
"No breakfast": "Ingen morgenmad",
|
||||||
"No content published": "Intet indhold offentliggjort",
|
"No content published": "Intet indhold offentliggjort",
|
||||||
@@ -195,11 +216,14 @@
|
|||||||
"Nordic Swan Ecolabel": "Svanemærket",
|
"Nordic Swan Ecolabel": "Svanemærket",
|
||||||
"Not found": "Ikke fundet",
|
"Not found": "Ikke fundet",
|
||||||
"Nr night, nr adult": "{nights, number} nat, {adults, number} voksen",
|
"Nr night, nr adult": "{nights, number} nat, {adults, number} voksen",
|
||||||
|
"number": "nummer",
|
||||||
"On your journey": "På din rejse",
|
"On your journey": "På din rejse",
|
||||||
"Open": "Åben",
|
"Open": "Åben",
|
||||||
"Open language menu": "Åbn sprogmenuen",
|
"Open language menu": "Åbn sprogmenuen",
|
||||||
"Open menu": "Åbn menuen",
|
"Open menu": "Åbn menuen",
|
||||||
"Open my pages menu": "Åbn mine sider menuen",
|
"Open my pages menu": "Åbn mine sider menuen",
|
||||||
|
"or": "eller",
|
||||||
|
"OTHER PAYMENT METHODS": "ANDRE BETALINGSMETODER",
|
||||||
"Overview": "Oversigt",
|
"Overview": "Oversigt",
|
||||||
"Parking": "Parkering",
|
"Parking": "Parkering",
|
||||||
"Parking / Garage": "Parkering / Garage",
|
"Parking / Garage": "Parkering / Garage",
|
||||||
@@ -211,6 +235,7 @@
|
|||||||
"Phone is required": "Telefonnummer er påkrævet",
|
"Phone is required": "Telefonnummer er påkrævet",
|
||||||
"Phone number": "Telefonnummer",
|
"Phone number": "Telefonnummer",
|
||||||
"Please enter a valid phone number": "Indtast venligst et gyldigt telefonnummer",
|
"Please enter a valid phone number": "Indtast venligst et gyldigt telefonnummer",
|
||||||
|
"points": "Point",
|
||||||
"Points": "Point",
|
"Points": "Point",
|
||||||
"Points being calculated": "Point udregnes",
|
"Points being calculated": "Point udregnes",
|
||||||
"Points earned prior to May 1, 2021": "Point optjent inden 1. maj 2021",
|
"Points earned prior to May 1, 2021": "Point optjent inden 1. maj 2021",
|
||||||
@@ -233,9 +258,9 @@
|
|||||||
"Restaurant & Bar": "Restaurant & Bar",
|
"Restaurant & Bar": "Restaurant & Bar",
|
||||||
"Restaurants & Bars": "Restaurants & Bars",
|
"Restaurants & Bars": "Restaurants & Bars",
|
||||||
"Retype new password": "Gentag den nye adgangskode",
|
"Retype new password": "Gentag den nye adgangskode",
|
||||||
|
"Room": "Værelse",
|
||||||
"Room & Terms": "Værelse & Vilkår",
|
"Room & Terms": "Værelse & Vilkår",
|
||||||
"Room facilities": "Værelsesfaciliteter",
|
"Room facilities": "Værelsesfaciliteter",
|
||||||
"Room": "Værelse",
|
|
||||||
"Rooms": "Værelser",
|
"Rooms": "Værelser",
|
||||||
"Rooms & Guests": "Værelser & gæster",
|
"Rooms & Guests": "Værelser & gæster",
|
||||||
"Sauna and gym": "Sauna and gym",
|
"Sauna and gym": "Sauna and gym",
|
||||||
@@ -272,27 +297,31 @@
|
|||||||
"Something went wrong and we couldn't add your card. Please try again later.": "Noget gik galt, og vi kunne ikke tilføje dit kort. Prøv venligst igen senere.",
|
"Something went wrong and we couldn't add your card. Please try again later.": "Noget gik galt, og vi kunne ikke tilføje dit kort. Prøv venligst igen senere.",
|
||||||
"Something went wrong and we couldn't remove your card. Please try again later.": "Noget gik galt, og vi kunne ikke fjerne dit kort. Prøv venligst igen senere.",
|
"Something went wrong and we couldn't remove your card. Please try again later.": "Noget gik galt, og vi kunne ikke fjerne dit kort. Prøv venligst igen senere.",
|
||||||
"Something went wrong!": "Noget gik galt!",
|
"Something went wrong!": "Noget gik galt!",
|
||||||
|
"special character": "speciel karakter",
|
||||||
|
"spendable points expiring by": "{points} Brugbare point udløber den {date}",
|
||||||
"Sports": "Sport",
|
"Sports": "Sport",
|
||||||
"Standard price": "Standardpris",
|
"Standard price": "Standardpris",
|
||||||
"Street": "Gade",
|
"Street": "Gade",
|
||||||
"Successfully updated profile!": "Profilen er opdateret med succes!",
|
"Successfully updated profile!": "Profilen er opdateret med succes!",
|
||||||
"Summary": "Opsummering",
|
"Summary": "Opsummering",
|
||||||
"TUI Points": "TUI Points",
|
|
||||||
"Tell us what information and updates you'd like to receive, and how, by clicking the link below.": "Fortæl os, hvilke oplysninger og opdateringer du gerne vil modtage, og hvordan, ved at klikke på linket nedenfor.",
|
"Tell us what information and updates you'd like to receive, and how, by clicking the link below.": "Fortæl os, hvilke oplysninger og opdateringer du gerne vil modtage, og hvordan, ved at klikke på linket nedenfor.",
|
||||||
"Terms and conditions": "Vilkår og betingelser",
|
"Terms and conditions": "Vilkår og betingelser",
|
||||||
"Thank you": "Tak",
|
"Thank you": "Tak",
|
||||||
"Theatre": "Teater",
|
"Theatre": "Teater",
|
||||||
"There are no transactions to display": "Der er ingen transaktioner at vise",
|
"There are no transactions to display": "Der er ingen transaktioner at vise",
|
||||||
"Things nearby HOTEL_NAME": "Ting i nærheden af {hotelName}",
|
"Things nearby HOTEL_NAME": "Ting i nærheden af {hotelName}",
|
||||||
"Total Points": "Samlet antal point",
|
"to": "til",
|
||||||
"Total incl VAT": "Inkl. moms",
|
"Total incl VAT": "Inkl. moms",
|
||||||
|
"Total Points": "Samlet antal point",
|
||||||
"Tourist": "Turist",
|
"Tourist": "Turist",
|
||||||
"Transaction date": "Overførselsdato",
|
"Transaction date": "Overførselsdato",
|
||||||
"Transactions": "Transaktioner",
|
"Transactions": "Transaktioner",
|
||||||
"Transportations": "Transport",
|
"Transportations": "Transport",
|
||||||
"Tripadvisor reviews": "{rating} ({count} anmeldelser på Tripadvisor)",
|
"Tripadvisor reviews": "{rating} ({count} anmeldelser på Tripadvisor)",
|
||||||
|
"TUI Points": "TUI Points",
|
||||||
"Type of bed": "Sengtype",
|
"Type of bed": "Sengtype",
|
||||||
"Type of room": "Værelsestype",
|
"Type of room": "Værelsestype",
|
||||||
|
"uppercase letter": "stort bogstav",
|
||||||
"Use bonus cheque": "Brug Bonus Cheque",
|
"Use bonus cheque": "Brug Bonus Cheque",
|
||||||
"Use code/voucher": "Brug kode/voucher",
|
"Use code/voucher": "Brug kode/voucher",
|
||||||
"User information": "Brugeroplysninger",
|
"User information": "Brugeroplysninger",
|
||||||
@@ -314,16 +343,16 @@
|
|||||||
"Where to": "Hvor",
|
"Where to": "Hvor",
|
||||||
"Which room class suits you the best?": "Hvilken rumklasse passer bedst til dig",
|
"Which room class suits you the best?": "Hvilken rumklasse passer bedst til dig",
|
||||||
"Year": "År",
|
"Year": "År",
|
||||||
"Yes, I accept the Terms and conditions for Scandic Friends and understand that Scandic will process my personal data in accordance with": "Ja, jeg accepterer vilkårene for Scandic Friends og forstår, at Scandic vil behandle mine personlige oplysninger i henhold til",
|
|
||||||
"Yes, discard changes": "Ja, kasser ændringer",
|
"Yes, discard changes": "Ja, kasser ændringer",
|
||||||
|
"Yes, I accept the Terms and conditions for Scandic Friends and understand that Scandic will process my personal data in accordance with": "Ja, jeg accepterer vilkårene for Scandic Friends og forstår, at Scandic vil behandle mine personlige oplysninger i henhold til",
|
||||||
"Yes, remove my card": "Ja, fjern mit kort",
|
"Yes, remove my card": "Ja, fjern mit kort",
|
||||||
"You can always change your mind later and add breakfast at the hotel.": "Du kan altid ombestemme dig senere og tilføje morgenmad på hotellet.",
|
"You can always change your mind later and add breakfast at the hotel.": "Du kan altid ombestemme dig senere og tilføje morgenmad på hotellet.",
|
||||||
"You canceled adding a new credit card.": "Du har annulleret tilføjelsen af et nyt kreditkort.",
|
"You canceled adding a new credit card.": "Du har annulleret tilføjelsen af et nyt kreditkort.",
|
||||||
"You have no previous stays.": "Du har ingen tidligere ophold.",
|
"You have no previous stays.": "Du har ingen tidligere ophold.",
|
||||||
"You have no upcoming stays.": "Du har ingen kommende ophold.",
|
"You have no upcoming stays.": "Du har ingen kommende ophold.",
|
||||||
"Your Challenges Conquer & Earn!": "Dine udfordringer Overvind og tjen!",
|
|
||||||
"Your card was successfully removed!": "Dit kort blev fjernet!",
|
"Your card was successfully removed!": "Dit kort blev fjernet!",
|
||||||
"Your card was successfully saved!": "Dit kort blev gemt!",
|
"Your card was successfully saved!": "Dit kort blev gemt!",
|
||||||
|
"Your Challenges Conquer & Earn!": "Dine udfordringer Overvind og tjen!",
|
||||||
"Your current level": "Dit nuværende niveau",
|
"Your current level": "Dit nuværende niveau",
|
||||||
"Your details": "Dine oplysninger",
|
"Your details": "Dine oplysninger",
|
||||||
"Your level": "Dit niveau",
|
"Your level": "Dit niveau",
|
||||||
@@ -333,33 +362,6 @@
|
|||||||
"Zoo": "Zoo",
|
"Zoo": "Zoo",
|
||||||
"Zoom in": "Zoom ind",
|
"Zoom in": "Zoom ind",
|
||||||
"Zoom out": "Zoom ud",
|
"Zoom out": "Zoom ud",
|
||||||
"as of today": "pr. dags dato",
|
|
||||||
"booking.adults": "{totalAdults, plural, one {# voksen} other {# voksne}}",
|
|
||||||
"booking.children": "{totalChildren, plural, one {# barn} other {# børn}}",
|
|
||||||
"booking.guests": "Maks {nrOfGuests, plural, one {# gæst} other {# gæster}}",
|
|
||||||
"booking.nights": "{totalNights, plural, one {# nat} other {# nætter}}",
|
|
||||||
"booking.rooms": "{totalRooms, plural, one {# værelse} other {# værelser}}",
|
|
||||||
"booking.terms": "Ved at betale med en af de tilgængelige betalingsmetoder, accepterer jeg vilkårene for denne booking og de generelle <termsLink>Vilkår og betingelser</termsLink>, og forstår, at Scandic vil behandle min personlige data i forbindelse med denne booking i henhold til <privacyLink>Scandics Privatlivspolitik</privacyLink>. Jeg accepterer, at Scandic kræver et gyldigt kreditkort under min besøg i tilfælde af, at noget er tilbagebetalt.",
|
|
||||||
"by": "inden",
|
|
||||||
"characters": "tegn",
|
|
||||||
"guest": "gæst",
|
|
||||||
"guests": "gæster",
|
|
||||||
"hotelPages.rooms.roomCard.person": "person",
|
|
||||||
"hotelPages.rooms.roomCard.persons": "personer",
|
|
||||||
"hotelPages.rooms.roomCard.seeRoomDetails": "Se værelsesdetaljer",
|
|
||||||
"km to city center": "km til byens centrum",
|
|
||||||
"lowercase letter": "lille bogstav",
|
|
||||||
"n/a": "n/a",
|
|
||||||
"next level:": "Næste niveau:",
|
|
||||||
"night": "nat",
|
|
||||||
"nights": "nætter",
|
|
||||||
"number": "nummer",
|
|
||||||
"or": "eller",
|
|
||||||
"points": "Point",
|
|
||||||
"special character": "speciel karakter",
|
|
||||||
"spendable points expiring by": "{points} Brugbare point udløber den {date}",
|
|
||||||
"to": "til",
|
|
||||||
"uppercase letter": "stort bogstav",
|
|
||||||
"{amount} {currency}": "{amount} {currency}",
|
"{amount} {currency}": "{amount} {currency}",
|
||||||
"{difference}{amount} {currency}": "{difference}{amount} {currency}",
|
"{difference}{amount} {currency}": "{difference}{amount} {currency}",
|
||||||
"{width} cm × {length} cm": "{width} cm × {length} cm"
|
"{width} cm × {length} cm": "{width} cm × {length} cm"
|
||||||
|
|||||||
@@ -9,8 +9,8 @@
|
|||||||
"Add code": "Code hinzufügen",
|
"Add code": "Code hinzufügen",
|
||||||
"Add new card": "Neue Karte hinzufügen",
|
"Add new card": "Neue Karte hinzufügen",
|
||||||
"Address": "Adresse",
|
"Address": "Adresse",
|
||||||
"Airport": "Flughafen",
|
|
||||||
"Adults": "Erwachsene",
|
"Adults": "Erwachsene",
|
||||||
|
"Airport": "Flughafen",
|
||||||
"All our breakfast buffets offer gluten free, vegan, and allergy-friendly options.": "Alle unsere Frühstücksbuffets bieten glutenfreie, vegane und allergikerfreundliche Speisen.",
|
"All our breakfast buffets offer gluten free, vegan, and allergy-friendly options.": "Alle unsere Frühstücksbuffets bieten glutenfreie, vegane und allergikerfreundliche Speisen.",
|
||||||
"Already a friend?": "Sind wir schon Freunde?",
|
"Already a friend?": "Sind wir schon Freunde?",
|
||||||
"Amenities": "Annehmlichkeiten",
|
"Amenities": "Annehmlichkeiten",
|
||||||
@@ -23,6 +23,7 @@
|
|||||||
"Approx.": "Ca.",
|
"Approx.": "Ca.",
|
||||||
"Are you sure you want to remove the card ending with {lastFourDigits} from your member profile?": "Möchten Sie die Karte mit der Endung {lastFourDigits} wirklich aus Ihrem Mitgliedsprofil entfernen?",
|
"Are you sure you want to remove the card ending with {lastFourDigits} from your member profile?": "Möchten Sie die Karte mit der Endung {lastFourDigits} wirklich aus Ihrem Mitgliedsprofil entfernen?",
|
||||||
"Arrival date": "Ankunftsdatum",
|
"Arrival date": "Ankunftsdatum",
|
||||||
|
"as of today": "Stand heute",
|
||||||
"As our": "Als unser {level}",
|
"As our": "Als unser {level}",
|
||||||
"As our Close Friend": "Als unser enger Freund",
|
"As our Close Friend": "Als unser enger Freund",
|
||||||
"At latest": "Spätestens",
|
"At latest": "Spätestens",
|
||||||
@@ -35,6 +36,12 @@
|
|||||||
"Book": "Buchen",
|
"Book": "Buchen",
|
||||||
"Book reward night": "Bonusnacht buchen",
|
"Book reward night": "Bonusnacht buchen",
|
||||||
"Booking number": "Buchungsnummer",
|
"Booking number": "Buchungsnummer",
|
||||||
|
"booking.adults": "{totalAdults, plural, one {# erwachsene} other {# erwachsene}}",
|
||||||
|
"booking.children": "{totalChildren, plural, one {# kind} other {# kinder}}",
|
||||||
|
"booking.guests": "Max {nrOfGuests, plural, one {# gast} other {# gäste}}",
|
||||||
|
"booking.nights": "{totalNights, plural, one {# nacht} other {# Nächte}}",
|
||||||
|
"booking.rooms": "{totalRooms, plural, one {# zimmer} other {# räume}}",
|
||||||
|
"booking.terms": "Ved at betale med en af de tilgængelige betalingsmetoder, accepterer jeg vilkårene for denne booking og de generelle <termsLink>Vilkår og betingelser</termsLink>, og forstår, at Scandic vil behandle min personlige data i forbindelse med denne booking i henhold til <privacyLink>Scandics Privatlivspolitik</privacyLink>. Jeg accepterer, at Scandic kræver et gyldigt kreditkort under min besøg i tilfælde af, at noget er tilbagebetalt.",
|
||||||
"Breakfast": "Frühstück",
|
"Breakfast": "Frühstück",
|
||||||
"Breakfast buffet": "Frühstücksbuffet",
|
"Breakfast buffet": "Frühstücksbuffet",
|
||||||
"Breakfast excluded": "Frühstück nicht inbegriffen",
|
"Breakfast excluded": "Frühstück nicht inbegriffen",
|
||||||
@@ -43,7 +50,9 @@
|
|||||||
"Breakfast selection in next step.": "Frühstücksauswahl in nächsten Schritt.",
|
"Breakfast selection in next step.": "Frühstücksauswahl in nächsten Schritt.",
|
||||||
"Bus terminal": "Busbahnhof",
|
"Bus terminal": "Busbahnhof",
|
||||||
"Business": "Geschäft",
|
"Business": "Geschäft",
|
||||||
|
"by": "bis",
|
||||||
"Cancel": "Stornieren",
|
"Cancel": "Stornieren",
|
||||||
|
"characters": "figuren",
|
||||||
"Check in": "Einchecken",
|
"Check in": "Einchecken",
|
||||||
"Check out": "Auschecken",
|
"Check out": "Auschecken",
|
||||||
"Check out the credit cards saved to your profile. Pay with a saved card when signed in for a smoother web experience.": "Sehen Sie sich die in Ihrem Profil gespeicherten Kreditkarten an. Bezahlen Sie mit einer gespeicherten Karte, wenn Sie angemeldet sind, für ein reibungsloseres Web-Erlebnis.",
|
"Check out the credit cards saved to your profile. Pay with a saved card when signed in for a smoother web experience.": "Sehen Sie sich die in Ihrem Profil gespeicherten Kreditkarten an. Bezahlen Sie mit einer gespeicherten Karte, wenn Sie angemeldet sind, für ein reibungsloseres Web-Erlebnis.",
|
||||||
@@ -101,9 +110,9 @@
|
|||||||
"Explore all levels and benefits": "Entdecken Sie alle Levels und Vorteile",
|
"Explore all levels and benefits": "Entdecken Sie alle Levels und Vorteile",
|
||||||
"Explore nearby": "Erkunden Sie die Umgebung",
|
"Explore nearby": "Erkunden Sie die Umgebung",
|
||||||
"Extras to your booking": "Extras zu Ihrer Buchung",
|
"Extras to your booking": "Extras zu Ihrer Buchung",
|
||||||
"FAQ": "Häufig gestellte Fragen",
|
|
||||||
"Failed to delete credit card, please try again later.": "Kreditkarte konnte nicht gelöscht werden. Bitte versuchen Sie es später noch einmal.",
|
"Failed to delete credit card, please try again later.": "Kreditkarte konnte nicht gelöscht werden. Bitte versuchen Sie es später noch einmal.",
|
||||||
"Fair": "Messe",
|
"Fair": "Messe",
|
||||||
|
"FAQ": "Häufig gestellte Fragen",
|
||||||
"Find booking": "Buchung finden",
|
"Find booking": "Buchung finden",
|
||||||
"Find hotels": "Hotels finden",
|
"Find hotels": "Hotels finden",
|
||||||
"First name": "Vorname",
|
"First name": "Vorname",
|
||||||
@@ -117,7 +126,9 @@
|
|||||||
"Get member benefits & offers": "Holen Sie sich Vorteile und Angebote für Mitglieder",
|
"Get member benefits & offers": "Holen Sie sich Vorteile und Angebote für Mitglieder",
|
||||||
"Go back to edit": "Zurück zum Bearbeiten",
|
"Go back to edit": "Zurück zum Bearbeiten",
|
||||||
"Go back to overview": "Zurück zur Übersicht",
|
"Go back to overview": "Zurück zur Übersicht",
|
||||||
|
"guest": "gast",
|
||||||
"Guest information": "Informationen für Gäste",
|
"Guest information": "Informationen für Gäste",
|
||||||
|
"guests": "gäste",
|
||||||
"Guests & Rooms": "Gäste & Zimmer",
|
"Guests & Rooms": "Gäste & Zimmer",
|
||||||
"Hi": "Hallo",
|
"Hi": "Hallo",
|
||||||
"Highest level": "Höchstes Level",
|
"Highest level": "Höchstes Level",
|
||||||
@@ -125,6 +136,9 @@
|
|||||||
"Hotel": "Hotel",
|
"Hotel": "Hotel",
|
||||||
"Hotel facilities": "Hotel-Infos",
|
"Hotel facilities": "Hotel-Infos",
|
||||||
"Hotel surroundings": "Umgebung des Hotels",
|
"Hotel surroundings": "Umgebung des Hotels",
|
||||||
|
"hotelPages.rooms.roomCard.person": "person",
|
||||||
|
"hotelPages.rooms.roomCard.persons": "personen",
|
||||||
|
"hotelPages.rooms.roomCard.seeRoomDetails": "Zimmerdetails ansehen",
|
||||||
"Hotels": "Hotels",
|
"Hotels": "Hotels",
|
||||||
"How do you want to sleep?": "Wie möchtest du schlafen?",
|
"How do you want to sleep?": "Wie möchtest du schlafen?",
|
||||||
"How it works": "Wie es funktioniert",
|
"How it works": "Wie es funktioniert",
|
||||||
@@ -135,9 +149,10 @@
|
|||||||
"In extra bed": "im zusätzlichen Bett",
|
"In extra bed": "im zusätzlichen Bett",
|
||||||
"Included": "Iinklusive",
|
"Included": "Iinklusive",
|
||||||
"It is not posible to manage your communication preferences right now, please try again later or contact support if the problem persists.": "Es ist derzeit nicht möglich, Ihre Kommunikationseinstellungen zu verwalten. Bitte versuchen Sie es später erneut oder wenden Sie sich an den Support, wenn das Problem weiterhin besteht.",
|
"It is not posible to manage your communication preferences right now, please try again later or contact support if the problem persists.": "Es ist derzeit nicht möglich, Ihre Kommunikationseinstellungen zu verwalten. Bitte versuchen Sie es später erneut oder wenden Sie sich an den Support, wenn das Problem weiterhin besteht.",
|
||||||
"Join Scandic Friends": "Treten Sie Scandic Friends bei",
|
|
||||||
"Join at no cost": "Kostenlos beitreten",
|
"Join at no cost": "Kostenlos beitreten",
|
||||||
|
"Join Scandic Friends": "Treten Sie Scandic Friends bei",
|
||||||
"King bed": "Kingsize-Bett",
|
"King bed": "Kingsize-Bett",
|
||||||
|
"km to city center": "km bis zum Stadtzentrum",
|
||||||
"Language": "Sprache",
|
"Language": "Sprache",
|
||||||
"Last name": "Nachname",
|
"Last name": "Nachname",
|
||||||
"Latest searches": "Letzte Suchanfragen",
|
"Latest searches": "Letzte Suchanfragen",
|
||||||
@@ -157,6 +172,7 @@
|
|||||||
"Log in here": "Hier einloggen",
|
"Log in here": "Hier einloggen",
|
||||||
"Log in/Join": "Log in/Anmelden",
|
"Log in/Join": "Log in/Anmelden",
|
||||||
"Log out": "Ausloggen",
|
"Log out": "Ausloggen",
|
||||||
|
"lowercase letter": "Kleinbuchstabe",
|
||||||
"Main menu": "Hauptmenü",
|
"Main menu": "Hauptmenü",
|
||||||
"Manage preferences": "Verwalten von Voreinstellungen",
|
"Manage preferences": "Verwalten von Voreinstellungen",
|
||||||
"Map": "Karte",
|
"Map": "Karte",
|
||||||
@@ -166,9 +182,9 @@
|
|||||||
"Member price": "Mitgliederpreis",
|
"Member price": "Mitgliederpreis",
|
||||||
"Member price from": "Mitgliederpreis ab",
|
"Member price from": "Mitgliederpreis ab",
|
||||||
"Members": "Mitglieder",
|
"Members": "Mitglieder",
|
||||||
|
"Membership cards": "Mitgliedskarten",
|
||||||
"Membership ID": "Mitglieds-ID",
|
"Membership ID": "Mitglieds-ID",
|
||||||
"Membership ID copied to clipboard": "Mitglieds-ID in die Zwischenablage kopiert",
|
"Membership ID copied to clipboard": "Mitglieds-ID in die Zwischenablage kopiert",
|
||||||
"Membership cards": "Mitgliedskarten",
|
|
||||||
"Menu": "Menu",
|
"Menu": "Menu",
|
||||||
"Modify": "Ändern",
|
"Modify": "Ändern",
|
||||||
"Month": "Monat",
|
"Month": "Monat",
|
||||||
@@ -178,11 +194,16 @@
|
|||||||
"My pages": "Meine Seiten",
|
"My pages": "Meine Seiten",
|
||||||
"My pages menu": "Meine Seite Menü",
|
"My pages menu": "Meine Seite Menü",
|
||||||
"My payment cards": "Meine Zahlungskarten",
|
"My payment cards": "Meine Zahlungskarten",
|
||||||
|
"MY SAVED CARDS": "MEINE SAVEDEN KARTEN",
|
||||||
"My wishes": "Meine Wünsche",
|
"My wishes": "Meine Wünsche",
|
||||||
|
"n/a": "n/a",
|
||||||
"Nearby": "In der Nähe",
|
"Nearby": "In der Nähe",
|
||||||
"Nearby companies": "Nahe gelegene Unternehmen",
|
"Nearby companies": "Nahe gelegene Unternehmen",
|
||||||
"New password": "Neues Kennwort",
|
"New password": "Neues Kennwort",
|
||||||
"Next": "Nächste",
|
"Next": "Nächste",
|
||||||
|
"next level:": "Nächstes Level:",
|
||||||
|
"night": "nacht",
|
||||||
|
"nights": "Nächte",
|
||||||
"Nights needed to level up": "Nächte, die zum Levelaufstieg benötigt werden",
|
"Nights needed to level up": "Nächte, die zum Levelaufstieg benötigt werden",
|
||||||
"No breakfast": "Kein Frühstück",
|
"No breakfast": "Kein Frühstück",
|
||||||
"No content published": "Kein Inhalt veröffentlicht",
|
"No content published": "Kein Inhalt veröffentlicht",
|
||||||
@@ -195,11 +216,14 @@
|
|||||||
"Nordic Swan Ecolabel": "Nordic Swan Ecolabel",
|
"Nordic Swan Ecolabel": "Nordic Swan Ecolabel",
|
||||||
"Not found": "Nicht gefunden",
|
"Not found": "Nicht gefunden",
|
||||||
"Nr night, nr adult": "{nights, number} Nacht, {adults, number} Erwachsener",
|
"Nr night, nr adult": "{nights, number} Nacht, {adults, number} Erwachsener",
|
||||||
|
"number": "nummer",
|
||||||
"On your journey": "Auf deiner Reise",
|
"On your journey": "Auf deiner Reise",
|
||||||
"Open": "Offen",
|
"Open": "Offen",
|
||||||
"Open language menu": "Sprachmenü öffnen",
|
"Open language menu": "Sprachmenü öffnen",
|
||||||
"Open menu": "Menü öffnen",
|
"Open menu": "Menü öffnen",
|
||||||
"Open my pages menu": "Meine Seiten Menü öffnen",
|
"Open my pages menu": "Meine Seiten Menü öffnen",
|
||||||
|
"or": "oder",
|
||||||
|
"OTHER PAYMENT METHODS": "ANDERE BEZAHLMETHODE",
|
||||||
"Overview": "Übersicht",
|
"Overview": "Übersicht",
|
||||||
"Parking": "Parken",
|
"Parking": "Parken",
|
||||||
"Parking / Garage": "Parken / Garage",
|
"Parking / Garage": "Parken / Garage",
|
||||||
@@ -211,6 +235,7 @@
|
|||||||
"Phone is required": "Telefon ist erforderlich",
|
"Phone is required": "Telefon ist erforderlich",
|
||||||
"Phone number": "Telefonnummer",
|
"Phone number": "Telefonnummer",
|
||||||
"Please enter a valid phone number": "Bitte geben Sie eine gültige Telefonnummer ein",
|
"Please enter a valid phone number": "Bitte geben Sie eine gültige Telefonnummer ein",
|
||||||
|
"points": "Punkte",
|
||||||
"Points": "Punkte",
|
"Points": "Punkte",
|
||||||
"Points being calculated": "Punkte werden berechnet",
|
"Points being calculated": "Punkte werden berechnet",
|
||||||
"Points earned prior to May 1, 2021": "Zusammengeführte Punkte vor dem 1. Mai 2021",
|
"Points earned prior to May 1, 2021": "Zusammengeführte Punkte vor dem 1. Mai 2021",
|
||||||
@@ -233,10 +258,10 @@
|
|||||||
"Restaurant & Bar": "Restaurant & Bar",
|
"Restaurant & Bar": "Restaurant & Bar",
|
||||||
"Restaurants & Bars": "Restaurants & Bars",
|
"Restaurants & Bars": "Restaurants & Bars",
|
||||||
"Retype new password": "Neues Passwort erneut eingeben",
|
"Retype new password": "Neues Passwort erneut eingeben",
|
||||||
|
"Room": "Zimmer",
|
||||||
"Room & Terms": "Zimmer & Bedingungen",
|
"Room & Terms": "Zimmer & Bedingungen",
|
||||||
"Room facilities": "Zimmerausstattung",
|
"Room facilities": "Zimmerausstattung",
|
||||||
"Rooms": "Räume",
|
"Rooms": "Räume",
|
||||||
"Room": "Zimmer",
|
|
||||||
"Rooms & Guests": "Zimmer & Gäste",
|
"Rooms & Guests": "Zimmer & Gäste",
|
||||||
"Sauna and gym": "Sauna and gym",
|
"Sauna and gym": "Sauna and gym",
|
||||||
"Save": "Speichern",
|
"Save": "Speichern",
|
||||||
@@ -272,27 +297,31 @@
|
|||||||
"Something went wrong and we couldn't add your card. Please try again later.": "Ein Fehler ist aufgetreten und wir konnten Ihre Karte nicht hinzufügen. Bitte versuchen Sie es später erneut.",
|
"Something went wrong and we couldn't add your card. Please try again later.": "Ein Fehler ist aufgetreten und wir konnten Ihre Karte nicht hinzufügen. Bitte versuchen Sie es später erneut.",
|
||||||
"Something went wrong and we couldn't remove your card. Please try again later.": "Ein Fehler ist aufgetreten und wir konnten Ihre Karte nicht entfernen. Bitte versuchen Sie es später noch einmal.",
|
"Something went wrong and we couldn't remove your card. Please try again later.": "Ein Fehler ist aufgetreten und wir konnten Ihre Karte nicht entfernen. Bitte versuchen Sie es später noch einmal.",
|
||||||
"Something went wrong!": "Etwas ist schief gelaufen!",
|
"Something went wrong!": "Etwas ist schief gelaufen!",
|
||||||
|
"special character": "sonderzeichen",
|
||||||
|
"spendable points expiring by": "{points} Einlösbare punkte verfallen bis zum {date}",
|
||||||
"Sports": "Sport",
|
"Sports": "Sport",
|
||||||
"Standard price": "Standardpreis",
|
"Standard price": "Standardpreis",
|
||||||
"Street": "Straße",
|
"Street": "Straße",
|
||||||
"Successfully updated profile!": "Profil erfolgreich aktualisiert!",
|
"Successfully updated profile!": "Profil erfolgreich aktualisiert!",
|
||||||
"Summary": "Zusammenfassung",
|
"Summary": "Zusammenfassung",
|
||||||
"TUI Points": "TUI Points",
|
|
||||||
"Tell us what information and updates you'd like to receive, and how, by clicking the link below.": "Teilen Sie uns mit, welche Informationen und Updates Sie wie erhalten möchten, indem Sie auf den unten stehenden Link klicken.",
|
"Tell us what information and updates you'd like to receive, and how, by clicking the link below.": "Teilen Sie uns mit, welche Informationen und Updates Sie wie erhalten möchten, indem Sie auf den unten stehenden Link klicken.",
|
||||||
"Terms and conditions": "Geschäftsbedingungen",
|
"Terms and conditions": "Geschäftsbedingungen",
|
||||||
"Thank you": "Danke",
|
"Thank you": "Danke",
|
||||||
"Theatre": "Theater",
|
"Theatre": "Theater",
|
||||||
"There are no transactions to display": "Es sind keine Transaktionen zum Anzeigen vorhanden",
|
"There are no transactions to display": "Es sind keine Transaktionen zum Anzeigen vorhanden",
|
||||||
"Things nearby HOTEL_NAME": "Dinge in der Nähe von {hotelName}",
|
"Things nearby HOTEL_NAME": "Dinge in der Nähe von {hotelName}",
|
||||||
"Total Points": "Gesamtpunktzahl",
|
"to": "zu",
|
||||||
"Total incl VAT": "Gesamt inkl. MwSt.",
|
"Total incl VAT": "Gesamt inkl. MwSt.",
|
||||||
|
"Total Points": "Gesamtpunktzahl",
|
||||||
"Tourist": "Tourist",
|
"Tourist": "Tourist",
|
||||||
"Transaction date": "Transaktionsdatum",
|
"Transaction date": "Transaktionsdatum",
|
||||||
"Transactions": "Transaktionen",
|
"Transactions": "Transaktionen",
|
||||||
"Transportations": "Transportmittel",
|
"Transportations": "Transportmittel",
|
||||||
"Tripadvisor reviews": "{rating} ({count} Bewertungen auf Tripadvisor)",
|
"Tripadvisor reviews": "{rating} ({count} Bewertungen auf Tripadvisor)",
|
||||||
|
"TUI Points": "TUI Points",
|
||||||
"Type of bed": "Bettentyp",
|
"Type of bed": "Bettentyp",
|
||||||
"Type of room": "Zimmerart",
|
"Type of room": "Zimmerart",
|
||||||
|
"uppercase letter": "großbuchstabe",
|
||||||
"Use bonus cheque": "Bonusscheck nutzen",
|
"Use bonus cheque": "Bonusscheck nutzen",
|
||||||
"Use code/voucher": "Code/Gutschein nutzen",
|
"Use code/voucher": "Code/Gutschein nutzen",
|
||||||
"User information": "Nutzerinformation",
|
"User information": "Nutzerinformation",
|
||||||
@@ -314,16 +343,16 @@
|
|||||||
"Where to": "Wohin",
|
"Where to": "Wohin",
|
||||||
"Which room class suits you the best?": "Welche Zimmerklasse passt am besten zu Ihnen?",
|
"Which room class suits you the best?": "Welche Zimmerklasse passt am besten zu Ihnen?",
|
||||||
"Year": "Jahr",
|
"Year": "Jahr",
|
||||||
"Yes, I accept the Terms and conditions for Scandic Friends and understand that Scandic will process my personal data in accordance with": "Ja, ich akzeptiere die Geschäftsbedingungen für Scandic Friends und erkenne an, dass Scandic meine persönlichen Daten in Übereinstimmung mit",
|
|
||||||
"Yes, discard changes": "Ja, Änderungen verwerfen",
|
"Yes, discard changes": "Ja, Änderungen verwerfen",
|
||||||
|
"Yes, I accept the Terms and conditions for Scandic Friends and understand that Scandic will process my personal data in accordance with": "Ja, ich akzeptiere die Geschäftsbedingungen für Scandic Friends und erkenne an, dass Scandic meine persönlichen Daten in Übereinstimmung mit",
|
||||||
"Yes, remove my card": "Ja, meine Karte entfernen",
|
"Yes, remove my card": "Ja, meine Karte entfernen",
|
||||||
"You can always change your mind later and add breakfast at the hotel.": "Sie können es sich später jederzeit anders überlegen und das Frühstück im Hotel hinzufügen.",
|
"You can always change your mind later and add breakfast at the hotel.": "Sie können es sich später jederzeit anders überlegen und das Frühstück im Hotel hinzufügen.",
|
||||||
"You canceled adding a new credit card.": "Sie haben das Hinzufügen einer neuen Kreditkarte abgebrochen.",
|
"You canceled adding a new credit card.": "Sie haben das Hinzufügen einer neuen Kreditkarte abgebrochen.",
|
||||||
"You have no previous stays.": "Sie haben keine vorherigen Aufenthalte.",
|
"You have no previous stays.": "Sie haben keine vorherigen Aufenthalte.",
|
||||||
"You have no upcoming stays.": "Sie haben keine bevorstehenden Aufenthalte.",
|
"You have no upcoming stays.": "Sie haben keine bevorstehenden Aufenthalte.",
|
||||||
"Your Challenges Conquer & Earn!": "Meistern Sie Ihre Herausforderungen und verdienen Sie Geld!",
|
|
||||||
"Your card was successfully removed!": "Ihre Karte wurde erfolgreich entfernt!",
|
"Your card was successfully removed!": "Ihre Karte wurde erfolgreich entfernt!",
|
||||||
"Your card was successfully saved!": "Ihre Karte wurde erfolgreich gespeichert!",
|
"Your card was successfully saved!": "Ihre Karte wurde erfolgreich gespeichert!",
|
||||||
|
"Your Challenges Conquer & Earn!": "Meistern Sie Ihre Herausforderungen und verdienen Sie Geld!",
|
||||||
"Your current level": "Ihr aktuelles Level",
|
"Your current level": "Ihr aktuelles Level",
|
||||||
"Your details": "Ihre Angaben",
|
"Your details": "Ihre Angaben",
|
||||||
"Your level": "Dein level",
|
"Your level": "Dein level",
|
||||||
@@ -333,33 +362,6 @@
|
|||||||
"Zoo": "Zoo",
|
"Zoo": "Zoo",
|
||||||
"Zoom in": "Vergrößern",
|
"Zoom in": "Vergrößern",
|
||||||
"Zoom out": "Verkleinern",
|
"Zoom out": "Verkleinern",
|
||||||
"as of today": "Stand heute",
|
|
||||||
"booking.adults": "{totalAdults, plural, one {# erwachsene} other {# erwachsene}}",
|
|
||||||
"booking.children": "{totalChildren, plural, one {# kind} other {# kinder}}",
|
|
||||||
"booking.guests": "Max {nrOfGuests, plural, one {# gast} other {# gäste}}",
|
|
||||||
"booking.nights": "{totalNights, plural, one {# nacht} other {# Nächte}}",
|
|
||||||
"booking.rooms": "{totalRooms, plural, one {# zimmer} other {# räume}}",
|
|
||||||
"booking.terms": "Ved at betale med en af de tilgængelige betalingsmetoder, accepterer jeg vilkårene for denne booking og de generelle <termsLink>Vilkår og betingelser</termsLink>, og forstår, at Scandic vil behandle min personlige data i forbindelse med denne booking i henhold til <privacyLink>Scandics Privatlivspolitik</privacyLink>. Jeg accepterer, at Scandic kræver et gyldigt kreditkort under min besøg i tilfælde af, at noget er tilbagebetalt.",
|
|
||||||
"by": "bis",
|
|
||||||
"characters": "figuren",
|
|
||||||
"guest": "gast",
|
|
||||||
"guests": "gäste",
|
|
||||||
"hotelPages.rooms.roomCard.person": "person",
|
|
||||||
"hotelPages.rooms.roomCard.persons": "personen",
|
|
||||||
"hotelPages.rooms.roomCard.seeRoomDetails": "Zimmerdetails ansehen",
|
|
||||||
"km to city center": "km bis zum Stadtzentrum",
|
|
||||||
"lowercase letter": "Kleinbuchstabe",
|
|
||||||
"n/a": "n/a",
|
|
||||||
"next level:": "Nächstes Level:",
|
|
||||||
"night": "nacht",
|
|
||||||
"nights": "Nächte",
|
|
||||||
"number": "nummer",
|
|
||||||
"or": "oder",
|
|
||||||
"points": "Punkte",
|
|
||||||
"special character": "sonderzeichen",
|
|
||||||
"spendable points expiring by": "{points} Einlösbare punkte verfallen bis zum {date}",
|
|
||||||
"to": "zu",
|
|
||||||
"uppercase letter": "großbuchstabe",
|
|
||||||
"{amount} {currency}": "{amount} {currency}",
|
"{amount} {currency}": "{amount} {currency}",
|
||||||
"{difference}{amount} {currency}": "{difference}{amount} {currency}",
|
"{difference}{amount} {currency}": "{difference}{amount} {currency}",
|
||||||
"{width} cm × {length} cm": "{width} cm × {length} cm"
|
"{width} cm × {length} cm": "{width} cm × {length} cm"
|
||||||
|
|||||||
@@ -25,6 +25,7 @@
|
|||||||
"Approx.": "Approx.",
|
"Approx.": "Approx.",
|
||||||
"Are you sure you want to remove the card ending with {lastFourDigits} from your member profile?": "Are you sure you want to remove the card ending with {lastFourDigits} from your member profile?",
|
"Are you sure you want to remove the card ending with {lastFourDigits} from your member profile?": "Are you sure you want to remove the card ending with {lastFourDigits} from your member profile?",
|
||||||
"Arrival date": "Arrival date",
|
"Arrival date": "Arrival date",
|
||||||
|
"as of today": "as of today",
|
||||||
"As our": "As our {level}",
|
"As our": "As our {level}",
|
||||||
"As our Close Friend": "As our Close Friend",
|
"As our Close Friend": "As our Close Friend",
|
||||||
"At latest": "At latest",
|
"At latest": "At latest",
|
||||||
@@ -38,6 +39,12 @@
|
|||||||
"Book": "Book",
|
"Book": "Book",
|
||||||
"Book reward night": "Book reward night",
|
"Book reward night": "Book reward night",
|
||||||
"Booking number": "Booking number",
|
"Booking number": "Booking number",
|
||||||
|
"booking.adults": "{totalAdults, plural, one {# adult} other {# adults}}",
|
||||||
|
"booking.children": "{totalChildren, plural, one {# child} other {# children}}",
|
||||||
|
"booking.guests": "Max {nrOfGuests, plural, one {# guest} other {# guests}}",
|
||||||
|
"booking.nights": "{totalNights, plural, one {# night} other {# nights}}",
|
||||||
|
"booking.rooms": "{totalRooms, plural, one {# room} other {# rooms}}",
|
||||||
|
"booking.terms": "By paying with any of the payment methods available, I accept the terms for this booking and the general <termsLink>Terms & Conditions</termsLink>, and understand that Scandic will process my personal data for this booking in accordance with <privacyLink>Scandic's Privacy policy</privacyLink>. I also accept that Scandic require a valid credit card during my visit in case anything is left unpaid.",
|
||||||
"Breakfast": "Breakfast",
|
"Breakfast": "Breakfast",
|
||||||
"Breakfast buffet": "Breakfast buffet",
|
"Breakfast buffet": "Breakfast buffet",
|
||||||
"Breakfast excluded": "Breakfast excluded",
|
"Breakfast excluded": "Breakfast excluded",
|
||||||
@@ -46,7 +53,9 @@
|
|||||||
"Breakfast selection in next step.": "Breakfast selection in next step.",
|
"Breakfast selection in next step.": "Breakfast selection in next step.",
|
||||||
"Bus terminal": "Bus terminal",
|
"Bus terminal": "Bus terminal",
|
||||||
"Business": "Business",
|
"Business": "Business",
|
||||||
|
"by": "by",
|
||||||
"Cancel": "Cancel",
|
"Cancel": "Cancel",
|
||||||
|
"characters": "characters",
|
||||||
"Check in": "Check in",
|
"Check in": "Check in",
|
||||||
"Check out": "Check out",
|
"Check out": "Check out",
|
||||||
"Check out the credit cards saved to your profile. Pay with a saved card when signed in for a smoother web experience.": "Check out the credit cards saved to your profile. Pay with a saved card when signed in for a smoother web experience.",
|
"Check out the credit cards saved to your profile. Pay with a saved card when signed in for a smoother web experience.": "Check out the credit cards saved to your profile. Pay with a saved card when signed in for a smoother web experience.",
|
||||||
@@ -105,9 +114,9 @@
|
|||||||
"Explore all levels and benefits": "Explore all levels and benefits",
|
"Explore all levels and benefits": "Explore all levels and benefits",
|
||||||
"Explore nearby": "Explore nearby",
|
"Explore nearby": "Explore nearby",
|
||||||
"Extras to your booking": "Extras to your booking",
|
"Extras to your booking": "Extras to your booking",
|
||||||
"FAQ": "FAQ",
|
|
||||||
"Failed to delete credit card, please try again later.": "Failed to delete credit card, please try again later.",
|
"Failed to delete credit card, please try again later.": "Failed to delete credit card, please try again later.",
|
||||||
"Fair": "Fair",
|
"Fair": "Fair",
|
||||||
|
"FAQ": "FAQ",
|
||||||
"Find booking": "Find booking",
|
"Find booking": "Find booking",
|
||||||
"Find hotels": "Find hotels",
|
"Find hotels": "Find hotels",
|
||||||
"First name": "First name",
|
"First name": "First name",
|
||||||
@@ -121,7 +130,9 @@
|
|||||||
"Get member benefits & offers": "Get member benefits & offers",
|
"Get member benefits & offers": "Get member benefits & offers",
|
||||||
"Go back to edit": "Go back to edit",
|
"Go back to edit": "Go back to edit",
|
||||||
"Go back to overview": "Go back to overview",
|
"Go back to overview": "Go back to overview",
|
||||||
|
"guest": "guest",
|
||||||
"Guest information": "Guest information",
|
"Guest information": "Guest information",
|
||||||
|
"guests": "guests",
|
||||||
"Guests & Rooms": "Guests & Rooms",
|
"Guests & Rooms": "Guests & Rooms",
|
||||||
"Hi": "Hi",
|
"Hi": "Hi",
|
||||||
"Highest level": "Highest level",
|
"Highest level": "Highest level",
|
||||||
@@ -129,6 +140,9 @@
|
|||||||
"Hotel": "Hotel",
|
"Hotel": "Hotel",
|
||||||
"Hotel facilities": "Hotel facilities",
|
"Hotel facilities": "Hotel facilities",
|
||||||
"Hotel surroundings": "Hotel surroundings",
|
"Hotel surroundings": "Hotel surroundings",
|
||||||
|
"hotelPages.rooms.roomCard.person": "person",
|
||||||
|
"hotelPages.rooms.roomCard.persons": "persons",
|
||||||
|
"hotelPages.rooms.roomCard.seeRoomDetails": "See room details",
|
||||||
"Hotels": "Hotels",
|
"Hotels": "Hotels",
|
||||||
"How do you want to sleep?": "How do you want to sleep?",
|
"How do you want to sleep?": "How do you want to sleep?",
|
||||||
"How it works": "How it works",
|
"How it works": "How it works",
|
||||||
@@ -139,9 +153,10 @@
|
|||||||
"In extra bed": "In extra bed",
|
"In extra bed": "In extra bed",
|
||||||
"Included": "Included",
|
"Included": "Included",
|
||||||
"It is not posible to manage your communication preferences right now, please try again later or contact support if the problem persists.": "It is not posible to manage your communication preferences right now, please try again later or contact support if the problem persists.",
|
"It is not posible to manage your communication preferences right now, please try again later or contact support if the problem persists.": "It is not posible to manage your communication preferences right now, please try again later or contact support if the problem persists.",
|
||||||
"Join Scandic Friends": "Join Scandic Friends",
|
|
||||||
"Join at no cost": "Join at no cost",
|
"Join at no cost": "Join at no cost",
|
||||||
|
"Join Scandic Friends": "Join Scandic Friends",
|
||||||
"King bed": "King bed",
|
"King bed": "King bed",
|
||||||
|
"km to city center": "km to city center",
|
||||||
"Language": "Language",
|
"Language": "Language",
|
||||||
"Last name": "Last name",
|
"Last name": "Last name",
|
||||||
"Latest searches": "Latest searches",
|
"Latest searches": "Latest searches",
|
||||||
@@ -161,6 +176,7 @@
|
|||||||
"Log in here": "Log in here",
|
"Log in here": "Log in here",
|
||||||
"Log in/Join": "Log in/Join",
|
"Log in/Join": "Log in/Join",
|
||||||
"Log out": "Log out",
|
"Log out": "Log out",
|
||||||
|
"lowercase letter": "lowercase letter",
|
||||||
"Main menu": "Main menu",
|
"Main menu": "Main menu",
|
||||||
"Manage preferences": "Manage preferences",
|
"Manage preferences": "Manage preferences",
|
||||||
"Map": "Map",
|
"Map": "Map",
|
||||||
@@ -170,9 +186,9 @@
|
|||||||
"Member price": "Member price",
|
"Member price": "Member price",
|
||||||
"Member price from": "Member price from",
|
"Member price from": "Member price from",
|
||||||
"Members": "Members",
|
"Members": "Members",
|
||||||
|
"Membership cards": "Membership cards",
|
||||||
"Membership ID": "Membership ID",
|
"Membership ID": "Membership ID",
|
||||||
"Membership ID copied to clipboard": "Membership ID copied to clipboard",
|
"Membership ID copied to clipboard": "Membership ID copied to clipboard",
|
||||||
"Membership cards": "Membership cards",
|
|
||||||
"Menu": "Menu",
|
"Menu": "Menu",
|
||||||
"Modify": "Modify",
|
"Modify": "Modify",
|
||||||
"Month": "Month",
|
"Month": "Month",
|
||||||
@@ -182,11 +198,16 @@
|
|||||||
"My pages": "My pages",
|
"My pages": "My pages",
|
||||||
"My pages menu": "My pages menu",
|
"My pages menu": "My pages menu",
|
||||||
"My payment cards": "My payment cards",
|
"My payment cards": "My payment cards",
|
||||||
|
"MY SAVED CARDS": "MY SAVED CARDS",
|
||||||
"My wishes": "My wishes",
|
"My wishes": "My wishes",
|
||||||
|
"n/a": "n/a",
|
||||||
"Nearby": "Nearby",
|
"Nearby": "Nearby",
|
||||||
"Nearby companies": "Nearby companies",
|
"Nearby companies": "Nearby companies",
|
||||||
"New password": "New password",
|
"New password": "New password",
|
||||||
"Next": "Next",
|
"Next": "Next",
|
||||||
|
"next level:": "next level:",
|
||||||
|
"night": "night",
|
||||||
|
"nights": "nights",
|
||||||
"Nights needed to level up": "Nights needed to level up",
|
"Nights needed to level up": "Nights needed to level up",
|
||||||
"No breakfast": "No breakfast",
|
"No breakfast": "No breakfast",
|
||||||
"No content published": "No content published",
|
"No content published": "No content published",
|
||||||
@@ -199,11 +220,14 @@
|
|||||||
"Nordic Swan Ecolabel": "Nordic Swan Ecolabel",
|
"Nordic Swan Ecolabel": "Nordic Swan Ecolabel",
|
||||||
"Not found": "Not found",
|
"Not found": "Not found",
|
||||||
"Nr night, nr adult": "{nights, number} night, {adults, number} adult",
|
"Nr night, nr adult": "{nights, number} night, {adults, number} adult",
|
||||||
|
"number": "number",
|
||||||
"On your journey": "On your journey",
|
"On your journey": "On your journey",
|
||||||
"Open": "Open",
|
"Open": "Open",
|
||||||
"Open language menu": "Open language menu",
|
"Open language menu": "Open language menu",
|
||||||
"Open menu": "Open menu",
|
"Open menu": "Open menu",
|
||||||
"Open my pages menu": "Open my pages menu",
|
"Open my pages menu": "Open my pages menu",
|
||||||
|
"or": "or",
|
||||||
|
"OTHER PAYMENT METHODS": "OTHER PAYMENT METHODS",
|
||||||
"Overview": "Overview",
|
"Overview": "Overview",
|
||||||
"Parking": "Parking",
|
"Parking": "Parking",
|
||||||
"Parking / Garage": "Parking / Garage",
|
"Parking / Garage": "Parking / Garage",
|
||||||
@@ -215,6 +239,7 @@
|
|||||||
"Phone is required": "Phone is required",
|
"Phone is required": "Phone is required",
|
||||||
"Phone number": "Phone number",
|
"Phone number": "Phone number",
|
||||||
"Please enter a valid phone number": "Please enter a valid phone number",
|
"Please enter a valid phone number": "Please enter a valid phone number",
|
||||||
|
"points": "Points",
|
||||||
"Points": "Points",
|
"Points": "Points",
|
||||||
"Points being calculated": "Points being calculated",
|
"Points being calculated": "Points being calculated",
|
||||||
"Points earned prior to May 1, 2021": "Points earned prior to May 1, 2021",
|
"Points earned prior to May 1, 2021": "Points earned prior to May 1, 2021",
|
||||||
@@ -276,27 +301,31 @@
|
|||||||
"Something went wrong and we couldn't add your card. Please try again later.": "Something went wrong and we couldn't add your card. Please try again later.",
|
"Something went wrong and we couldn't add your card. Please try again later.": "Something went wrong and we couldn't add your card. Please try again later.",
|
||||||
"Something went wrong and we couldn't remove your card. Please try again later.": "Something went wrong and we couldn't remove your card. Please try again later.",
|
"Something went wrong and we couldn't remove your card. Please try again later.": "Something went wrong and we couldn't remove your card. Please try again later.",
|
||||||
"Something went wrong!": "Something went wrong!",
|
"Something went wrong!": "Something went wrong!",
|
||||||
|
"special character": "special character",
|
||||||
|
"spendable points expiring by": "{points} spendable points expiring by {date}",
|
||||||
"Sports": "Sports",
|
"Sports": "Sports",
|
||||||
"Standard price": "Standard price",
|
"Standard price": "Standard price",
|
||||||
"Street": "Street",
|
"Street": "Street",
|
||||||
"Successfully updated profile!": "Successfully updated profile!",
|
"Successfully updated profile!": "Successfully updated profile!",
|
||||||
"Summary": "Summary",
|
"Summary": "Summary",
|
||||||
"TUI Points": "TUI Points",
|
|
||||||
"Tell us what information and updates you'd like to receive, and how, by clicking the link below.": "Tell us what information and updates you'd like to receive, and how, by clicking the link below.",
|
"Tell us what information and updates you'd like to receive, and how, by clicking the link below.": "Tell us what information and updates you'd like to receive, and how, by clicking the link below.",
|
||||||
"Terms and conditions": "Terms and conditions",
|
"Terms and conditions": "Terms and conditions",
|
||||||
"Thank you": "Thank you",
|
"Thank you": "Thank you",
|
||||||
"Theatre": "Theatre",
|
"Theatre": "Theatre",
|
||||||
"There are no transactions to display": "There are no transactions to display",
|
"There are no transactions to display": "There are no transactions to display",
|
||||||
"Things nearby HOTEL_NAME": "Things nearby {hotelName}",
|
"Things nearby HOTEL_NAME": "Things nearby {hotelName}",
|
||||||
"Total Points": "Total Points",
|
"to": "to",
|
||||||
"Total incl VAT": "Total incl VAT",
|
"Total incl VAT": "Total incl VAT",
|
||||||
|
"Total Points": "Total Points",
|
||||||
"Tourist": "Tourist",
|
"Tourist": "Tourist",
|
||||||
"Transaction date": "Transaction date",
|
"Transaction date": "Transaction date",
|
||||||
"Transactions": "Transactions",
|
"Transactions": "Transactions",
|
||||||
"Transportations": "Transportations",
|
"Transportations": "Transportations",
|
||||||
"Tripadvisor reviews": "{rating} ({count} reviews on Tripadvisor)",
|
"Tripadvisor reviews": "{rating} ({count} reviews on Tripadvisor)",
|
||||||
|
"TUI Points": "TUI Points",
|
||||||
"Type of bed": "Type of bed",
|
"Type of bed": "Type of bed",
|
||||||
"Type of room": "Type of room",
|
"Type of room": "Type of room",
|
||||||
|
"uppercase letter": "uppercase letter",
|
||||||
"Use bonus cheque": "Use bonus cheque",
|
"Use bonus cheque": "Use bonus cheque",
|
||||||
"Use code/voucher": "Use code/voucher",
|
"Use code/voucher": "Use code/voucher",
|
||||||
"User information": "User information",
|
"User information": "User information",
|
||||||
@@ -318,16 +347,16 @@
|
|||||||
"Where to": "Where to",
|
"Where to": "Where to",
|
||||||
"Which room class suits you the best?": "Which room class suits you the best?",
|
"Which room class suits you the best?": "Which room class suits you the best?",
|
||||||
"Year": "Year",
|
"Year": "Year",
|
||||||
"Yes, I accept the Terms and conditions for Scandic Friends and understand that Scandic will process my personal data in accordance with": "Yes, I accept the Terms and conditions for Scandic Friends and understand that Scandic will process my personal data in accordance with",
|
|
||||||
"Yes, discard changes": "Yes, discard changes",
|
"Yes, discard changes": "Yes, discard changes",
|
||||||
|
"Yes, I accept the Terms and conditions for Scandic Friends and understand that Scandic will process my personal data in accordance with": "Yes, I accept the Terms and conditions for Scandic Friends and understand that Scandic will process my personal data in accordance with",
|
||||||
"Yes, remove my card": "Yes, remove my card",
|
"Yes, remove my card": "Yes, remove my card",
|
||||||
"You can always change your mind later and add breakfast at the hotel.": "You can always change your mind later and add breakfast at the hotel.",
|
"You can always change your mind later and add breakfast at the hotel.": "You can always change your mind later and add breakfast at the hotel.",
|
||||||
"You canceled adding a new credit card.": "You canceled adding a new credit card.",
|
"You canceled adding a new credit card.": "You canceled adding a new credit card.",
|
||||||
"You have no previous stays.": "You have no previous stays.",
|
"You have no previous stays.": "You have no previous stays.",
|
||||||
"You have no upcoming stays.": "You have no upcoming stays.",
|
"You have no upcoming stays.": "You have no upcoming stays.",
|
||||||
"Your Challenges Conquer & Earn!": "Your Challenges Conquer & Earn!",
|
|
||||||
"Your card was successfully removed!": "Your card was successfully removed!",
|
"Your card was successfully removed!": "Your card was successfully removed!",
|
||||||
"Your card was successfully saved!": "Your card was successfully saved!",
|
"Your card was successfully saved!": "Your card was successfully saved!",
|
||||||
|
"Your Challenges Conquer & Earn!": "Your Challenges Conquer & Earn!",
|
||||||
"Your current level": "Your current level",
|
"Your current level": "Your current level",
|
||||||
"Your details": "Your details",
|
"Your details": "Your details",
|
||||||
"Your level": "Your level",
|
"Your level": "Your level",
|
||||||
@@ -337,33 +366,6 @@
|
|||||||
"Zoo": "Zoo",
|
"Zoo": "Zoo",
|
||||||
"Zoom in": "Zoom in",
|
"Zoom in": "Zoom in",
|
||||||
"Zoom out": "Zoom out",
|
"Zoom out": "Zoom out",
|
||||||
"as of today": "as of today",
|
|
||||||
"booking.adults": "{totalAdults, plural, one {# adult} other {# adults}}",
|
|
||||||
"booking.children": "{totalChildren, plural, one {# child} other {# children}}",
|
|
||||||
"booking.guests": "Max {nrOfGuests, plural, one {# guest} other {# guests}}",
|
|
||||||
"booking.nights": "{totalNights, plural, one {# night} other {# nights}}",
|
|
||||||
"booking.rooms": "{totalRooms, plural, one {# room} other {# rooms}}",
|
|
||||||
"booking.terms": "By paying with any of the payment methods available, I accept the terms for this booking and the general <termsLink>Terms & Conditions</termsLink>, and understand that Scandic will process my personal data for this booking in accordance with <privacyLink>Scandic's Privacy policy</privacyLink>. I also accept that Scandic require a valid credit card during my visit in case anything is left unpaid.",
|
|
||||||
"by": "by",
|
|
||||||
"characters": "characters",
|
|
||||||
"guest": "guest",
|
|
||||||
"guests": "guests",
|
|
||||||
"hotelPages.rooms.roomCard.person": "person",
|
|
||||||
"hotelPages.rooms.roomCard.persons": "persons",
|
|
||||||
"hotelPages.rooms.roomCard.seeRoomDetails": "See room details",
|
|
||||||
"km to city center": "km to city center",
|
|
||||||
"lowercase letter": "lowercase letter",
|
|
||||||
"n/a": "n/a",
|
|
||||||
"next level:": "next level:",
|
|
||||||
"night": "night",
|
|
||||||
"nights": "nights",
|
|
||||||
"number": "number",
|
|
||||||
"or": "or",
|
|
||||||
"points": "Points",
|
|
||||||
"special character": "special character",
|
|
||||||
"spendable points expiring by": "{points} spendable points expiring by {date}",
|
|
||||||
"to": "to",
|
|
||||||
"uppercase letter": "uppercase letter",
|
|
||||||
"{amount} {currency}": "{amount} {currency}",
|
"{amount} {currency}": "{amount} {currency}",
|
||||||
"{difference}{amount} {currency}": "{difference}{amount} {currency}",
|
"{difference}{amount} {currency}": "{difference}{amount} {currency}",
|
||||||
"{width} cm × {length} cm": "{width} cm × {length} cm"
|
"{width} cm × {length} cm": "{width} cm × {length} cm"
|
||||||
|
|||||||
@@ -9,8 +9,8 @@
|
|||||||
"Add code": "Lisää koodi",
|
"Add code": "Lisää koodi",
|
||||||
"Add new card": "Lisää uusi kortti",
|
"Add new card": "Lisää uusi kortti",
|
||||||
"Address": "Osoite",
|
"Address": "Osoite",
|
||||||
"Airport": "Lentokenttä",
|
|
||||||
"Adults": "Aikuista",
|
"Adults": "Aikuista",
|
||||||
|
"Airport": "Lentokenttä",
|
||||||
"All our breakfast buffets offer gluten free, vegan, and allergy-friendly options.": "Kaikki aamiaisbuffettimme tarjoavat gluteenittomia, vegaanisia ja allergiaystävällisiä vaihtoehtoja.",
|
"All our breakfast buffets offer gluten free, vegan, and allergy-friendly options.": "Kaikki aamiaisbuffettimme tarjoavat gluteenittomia, vegaanisia ja allergiaystävällisiä vaihtoehtoja.",
|
||||||
"Already a friend?": "Oletko jo ystävä?",
|
"Already a friend?": "Oletko jo ystävä?",
|
||||||
"Amenities": "Mukavuudet",
|
"Amenities": "Mukavuudet",
|
||||||
@@ -23,6 +23,7 @@
|
|||||||
"Approx.": "N.",
|
"Approx.": "N.",
|
||||||
"Are you sure you want to remove the card ending with {lastFourDigits} from your member profile?": "Haluatko varmasti poistaa kortin, joka päättyy numeroon {lastFourDigits} jäsenprofiilistasi?",
|
"Are you sure you want to remove the card ending with {lastFourDigits} from your member profile?": "Haluatko varmasti poistaa kortin, joka päättyy numeroon {lastFourDigits} jäsenprofiilistasi?",
|
||||||
"Arrival date": "Saapumispäivä",
|
"Arrival date": "Saapumispäivä",
|
||||||
|
"as of today": "tänään",
|
||||||
"As our": "{level}-etu",
|
"As our": "{level}-etu",
|
||||||
"As our Close Friend": "Läheisenä ystävänämme",
|
"As our Close Friend": "Läheisenä ystävänämme",
|
||||||
"At latest": "Viimeistään",
|
"At latest": "Viimeistään",
|
||||||
@@ -35,6 +36,12 @@
|
|||||||
"Book": "Varaa",
|
"Book": "Varaa",
|
||||||
"Book reward night": "Kirjapalkinto-ilta",
|
"Book reward night": "Kirjapalkinto-ilta",
|
||||||
"Booking number": "Varausnumero",
|
"Booking number": "Varausnumero",
|
||||||
|
"booking.adults": "{totalAdults, plural, one {# aikuinen} other {# aikuiset}}",
|
||||||
|
"booking.children": "{totalChildren, plural, one {# lapsi} other {# lasta}}",
|
||||||
|
"booking.guests": "Max {nrOfGuests, plural, one {# vieras} other {# vieraita}}",
|
||||||
|
"booking.nights": "{totalNights, plural, one {# yö} other {# yötä}}",
|
||||||
|
"booking.rooms": "{totalRooms, plural, one {# huone} other {# sviitti}}",
|
||||||
|
"booking.terms": "Maksamalla minkä tahansa saatavilla olevan maksutavan avulla hyväksyn tämän varauksen ehdot ja yleiset <termsLink>ehdot ja ehtoja</termsLink>, ja ymmärrän, että Scandic käsittelee minun henkilötietoni tässä varauksessa mukaisesti <privacyLink>Scandicin tietosuojavaltuuden</privacyLink> mukaisesti. Hyväksyn myös, että Scandic vaatii validin luottokortin majoituksen ajan, jos jokin jää maksamatta.",
|
||||||
"Breakfast": "Aamiainen",
|
"Breakfast": "Aamiainen",
|
||||||
"Breakfast buffet": "Aamiaisbuffet",
|
"Breakfast buffet": "Aamiaisbuffet",
|
||||||
"Breakfast excluded": "Aamiainen ei sisälly",
|
"Breakfast excluded": "Aamiainen ei sisälly",
|
||||||
@@ -43,7 +50,9 @@
|
|||||||
"Breakfast selection in next step.": "Aamiaisvalinta seuraavassa vaiheessa.",
|
"Breakfast selection in next step.": "Aamiaisvalinta seuraavassa vaiheessa.",
|
||||||
"Bus terminal": "Bussiasema",
|
"Bus terminal": "Bussiasema",
|
||||||
"Business": "Business",
|
"Business": "Business",
|
||||||
|
"by": "mennessä",
|
||||||
"Cancel": "Peruuttaa",
|
"Cancel": "Peruuttaa",
|
||||||
|
"characters": "hahmoja",
|
||||||
"Check in": "Sisäänkirjautuminen",
|
"Check in": "Sisäänkirjautuminen",
|
||||||
"Check out": "Uloskirjautuminen",
|
"Check out": "Uloskirjautuminen",
|
||||||
"Check out the credit cards saved to your profile. Pay with a saved card when signed in for a smoother web experience.": "Tarkista profiiliisi tallennetut luottokortit. Maksa tallennetulla kortilla kirjautuneena, jotta verkkokokemus on sujuvampi.",
|
"Check out the credit cards saved to your profile. Pay with a saved card when signed in for a smoother web experience.": "Tarkista profiiliisi tallennetut luottokortit. Maksa tallennetulla kortilla kirjautuneena, jotta verkkokokemus on sujuvampi.",
|
||||||
@@ -101,9 +110,9 @@
|
|||||||
"Explore all levels and benefits": "Tutustu kaikkiin tasoihin ja etuihin",
|
"Explore all levels and benefits": "Tutustu kaikkiin tasoihin ja etuihin",
|
||||||
"Explore nearby": "Tutustu lähialueeseen",
|
"Explore nearby": "Tutustu lähialueeseen",
|
||||||
"Extras to your booking": "Varauksessa lisäpalveluita",
|
"Extras to your booking": "Varauksessa lisäpalveluita",
|
||||||
"FAQ": "UKK",
|
|
||||||
"Failed to delete credit card, please try again later.": "Luottokortin poistaminen epäonnistui, yritä myöhemmin uudelleen.",
|
"Failed to delete credit card, please try again later.": "Luottokortin poistaminen epäonnistui, yritä myöhemmin uudelleen.",
|
||||||
"Fair": "Messukeskus",
|
"Fair": "Messukeskus",
|
||||||
|
"FAQ": "UKK",
|
||||||
"Find booking": "Etsi varaus",
|
"Find booking": "Etsi varaus",
|
||||||
"Find hotels": "Etsi hotelleja",
|
"Find hotels": "Etsi hotelleja",
|
||||||
"First name": "Etunimi",
|
"First name": "Etunimi",
|
||||||
@@ -117,7 +126,9 @@
|
|||||||
"Get member benefits & offers": "Hanki jäsenetuja ja -tarjouksia",
|
"Get member benefits & offers": "Hanki jäsenetuja ja -tarjouksia",
|
||||||
"Go back to edit": "Palaa muokkaamaan",
|
"Go back to edit": "Palaa muokkaamaan",
|
||||||
"Go back to overview": "Palaa yleiskatsaukseen",
|
"Go back to overview": "Palaa yleiskatsaukseen",
|
||||||
|
"guest": "Vieras",
|
||||||
"Guest information": "Vieraan tiedot",
|
"Guest information": "Vieraan tiedot",
|
||||||
|
"guests": "Vieraita",
|
||||||
"Guests & Rooms": "Vieraat & Huoneet",
|
"Guests & Rooms": "Vieraat & Huoneet",
|
||||||
"Hi": "Hi",
|
"Hi": "Hi",
|
||||||
"Highest level": "Korkein taso",
|
"Highest level": "Korkein taso",
|
||||||
@@ -125,6 +136,9 @@
|
|||||||
"Hotel": "Hotelli",
|
"Hotel": "Hotelli",
|
||||||
"Hotel facilities": "Hotellin palvelut",
|
"Hotel facilities": "Hotellin palvelut",
|
||||||
"Hotel surroundings": "Hotellin ympäristö",
|
"Hotel surroundings": "Hotellin ympäristö",
|
||||||
|
"hotelPages.rooms.roomCard.person": "henkilö",
|
||||||
|
"hotelPages.rooms.roomCard.persons": "Henkilöä",
|
||||||
|
"hotelPages.rooms.roomCard.seeRoomDetails": "Katso huoneen tiedot",
|
||||||
"Hotels": "Hotellit",
|
"Hotels": "Hotellit",
|
||||||
"How do you want to sleep?": "Kuinka haluat nukkua?",
|
"How do you want to sleep?": "Kuinka haluat nukkua?",
|
||||||
"How it works": "Kuinka se toimii",
|
"How it works": "Kuinka se toimii",
|
||||||
@@ -135,9 +149,10 @@
|
|||||||
"In extra bed": "Oma vuodepaikka",
|
"In extra bed": "Oma vuodepaikka",
|
||||||
"Included": "Sisälly hintaan",
|
"Included": "Sisälly hintaan",
|
||||||
"It is not posible to manage your communication preferences right now, please try again later or contact support if the problem persists.": "Viestintäasetuksiasi ei voi hallita juuri nyt. Yritä myöhemmin uudelleen tai ota yhteyttä tukeen, jos ongelma jatkuu.",
|
"It is not posible to manage your communication preferences right now, please try again later or contact support if the problem persists.": "Viestintäasetuksiasi ei voi hallita juuri nyt. Yritä myöhemmin uudelleen tai ota yhteyttä tukeen, jos ongelma jatkuu.",
|
||||||
"Join Scandic Friends": "Liity jäseneksi",
|
|
||||||
"Join at no cost": "Liity maksutta",
|
"Join at no cost": "Liity maksutta",
|
||||||
|
"Join Scandic Friends": "Liity jäseneksi",
|
||||||
"King bed": "King-vuode",
|
"King bed": "King-vuode",
|
||||||
|
"km to city center": "km keskustaan",
|
||||||
"Language": "Kieli",
|
"Language": "Kieli",
|
||||||
"Last name": "Sukunimi",
|
"Last name": "Sukunimi",
|
||||||
"Latest searches": "Viimeisimmät haut",
|
"Latest searches": "Viimeisimmät haut",
|
||||||
@@ -157,6 +172,7 @@
|
|||||||
"Log in here": "Kirjaudu sisään",
|
"Log in here": "Kirjaudu sisään",
|
||||||
"Log in/Join": "Kirjaudu sisään/Liittyä",
|
"Log in/Join": "Kirjaudu sisään/Liittyä",
|
||||||
"Log out": "Kirjaudu ulos",
|
"Log out": "Kirjaudu ulos",
|
||||||
|
"lowercase letter": "pien kirjain",
|
||||||
"Main menu": "Päävalikko",
|
"Main menu": "Päävalikko",
|
||||||
"Manage preferences": "Asetusten hallinta",
|
"Manage preferences": "Asetusten hallinta",
|
||||||
"Map": "Kartta",
|
"Map": "Kartta",
|
||||||
@@ -166,9 +182,9 @@
|
|||||||
"Member price": "Jäsenhinta",
|
"Member price": "Jäsenhinta",
|
||||||
"Member price from": "Jäsenhinta alkaen",
|
"Member price from": "Jäsenhinta alkaen",
|
||||||
"Members": "Jäsenet",
|
"Members": "Jäsenet",
|
||||||
|
"Membership cards": "Jäsenkortit",
|
||||||
"Membership ID": "Jäsentunnus",
|
"Membership ID": "Jäsentunnus",
|
||||||
"Membership ID copied to clipboard": "Jäsenyystunnus kopioitu leikepöydälle",
|
"Membership ID copied to clipboard": "Jäsenyystunnus kopioitu leikepöydälle",
|
||||||
"Membership cards": "Jäsenkortit",
|
|
||||||
"Menu": "Valikko",
|
"Menu": "Valikko",
|
||||||
"Modify": "Muokkaa",
|
"Modify": "Muokkaa",
|
||||||
"Month": "Kuukausi",
|
"Month": "Kuukausi",
|
||||||
@@ -178,11 +194,16 @@
|
|||||||
"My pages": "Omat sivut",
|
"My pages": "Omat sivut",
|
||||||
"My pages menu": "Omat sivut -valikko",
|
"My pages menu": "Omat sivut -valikko",
|
||||||
"My payment cards": "Minun maksukortit",
|
"My payment cards": "Minun maksukortit",
|
||||||
|
"MY SAVED CARDS": "MINUN SAVED CARDS",
|
||||||
"My wishes": "Toiveeni",
|
"My wishes": "Toiveeni",
|
||||||
|
"n/a": "n/a",
|
||||||
"Nearby": "Lähistöllä",
|
"Nearby": "Lähistöllä",
|
||||||
"Nearby companies": "Läheiset yritykset",
|
"Nearby companies": "Läheiset yritykset",
|
||||||
"New password": "Uusi salasana",
|
"New password": "Uusi salasana",
|
||||||
"Next": "Seuraava",
|
"Next": "Seuraava",
|
||||||
|
"next level:": "pistettä tasolle:",
|
||||||
|
"night": "yö",
|
||||||
|
"nights": "yötä",
|
||||||
"Nights needed to level up": "Yöt, joita tarvitaan tasolle",
|
"Nights needed to level up": "Yöt, joita tarvitaan tasolle",
|
||||||
"No breakfast": "Ei aamiaista",
|
"No breakfast": "Ei aamiaista",
|
||||||
"No content published": "Ei julkaistua sisältöä",
|
"No content published": "Ei julkaistua sisältöä",
|
||||||
@@ -195,11 +216,14 @@
|
|||||||
"Nordic Swan Ecolabel": "Ympäristömerkki Miljömärkt",
|
"Nordic Swan Ecolabel": "Ympäristömerkki Miljömärkt",
|
||||||
"Not found": "Ei löydetty",
|
"Not found": "Ei löydetty",
|
||||||
"Nr night, nr adult": "{nights, number} yö, {adults, number} aikuinen",
|
"Nr night, nr adult": "{nights, number} yö, {adults, number} aikuinen",
|
||||||
|
"number": "määrä",
|
||||||
"On your journey": "Matkallasi",
|
"On your journey": "Matkallasi",
|
||||||
"Open": "Avata",
|
"Open": "Avata",
|
||||||
"Open language menu": "Avaa kielivalikko",
|
"Open language menu": "Avaa kielivalikko",
|
||||||
"Open menu": "Avaa valikko",
|
"Open menu": "Avaa valikko",
|
||||||
"Open my pages menu": "Avaa omat sivut -valikko",
|
"Open my pages menu": "Avaa omat sivut -valikko",
|
||||||
|
"or": "tai",
|
||||||
|
"OTHER PAYMENT METHODS": "MUISE KORT",
|
||||||
"Overview": "Yleiskatsaus",
|
"Overview": "Yleiskatsaus",
|
||||||
"Parking": "Pysäköinti",
|
"Parking": "Pysäköinti",
|
||||||
"Parking / Garage": "Pysäköinti / Autotalli",
|
"Parking / Garage": "Pysäköinti / Autotalli",
|
||||||
@@ -211,6 +235,7 @@
|
|||||||
"Phone is required": "Puhelin vaaditaan",
|
"Phone is required": "Puhelin vaaditaan",
|
||||||
"Phone number": "Puhelinnumero",
|
"Phone number": "Puhelinnumero",
|
||||||
"Please enter a valid phone number": "Ole hyvä ja näppäile voimassaoleva puhelinnumero",
|
"Please enter a valid phone number": "Ole hyvä ja näppäile voimassaoleva puhelinnumero",
|
||||||
|
"points": "pistettä",
|
||||||
"Points": "Pisteet",
|
"Points": "Pisteet",
|
||||||
"Points being calculated": "Pisteitä lasketaan",
|
"Points being calculated": "Pisteitä lasketaan",
|
||||||
"Points earned prior to May 1, 2021": "Pisteet, jotka ansaittu ennen 1.5.2021",
|
"Points earned prior to May 1, 2021": "Pisteet, jotka ansaittu ennen 1.5.2021",
|
||||||
@@ -233,9 +258,9 @@
|
|||||||
"Restaurant & Bar": "Ravintola & Baari",
|
"Restaurant & Bar": "Ravintola & Baari",
|
||||||
"Restaurants & Bars": "Restaurants & Bars",
|
"Restaurants & Bars": "Restaurants & Bars",
|
||||||
"Retype new password": "Kirjoita uusi salasana uudelleen",
|
"Retype new password": "Kirjoita uusi salasana uudelleen",
|
||||||
|
"Room": "Huone",
|
||||||
"Room & Terms": "Huone & Ehdot",
|
"Room & Terms": "Huone & Ehdot",
|
||||||
"Room facilities": "Huoneen varustelu",
|
"Room facilities": "Huoneen varustelu",
|
||||||
"Room": "Huone",
|
|
||||||
"Rooms": "Huoneet",
|
"Rooms": "Huoneet",
|
||||||
"Rooms & Guests": "Huoneet & Vieraat",
|
"Rooms & Guests": "Huoneet & Vieraat",
|
||||||
"Rooms & Guestss": "Huoneet & Vieraat",
|
"Rooms & Guestss": "Huoneet & Vieraat",
|
||||||
@@ -273,27 +298,31 @@
|
|||||||
"Something went wrong and we couldn't add your card. Please try again later.": "Jotain meni pieleen, emmekä voineet lisätä korttiasi. Yritä myöhemmin uudelleen.",
|
"Something went wrong and we couldn't add your card. Please try again later.": "Jotain meni pieleen, emmekä voineet lisätä korttiasi. Yritä myöhemmin uudelleen.",
|
||||||
"Something went wrong and we couldn't remove your card. Please try again later.": "Jotain meni pieleen, emmekä voineet poistaa korttiasi. Yritä myöhemmin uudelleen.",
|
"Something went wrong and we couldn't remove your card. Please try again later.": "Jotain meni pieleen, emmekä voineet poistaa korttiasi. Yritä myöhemmin uudelleen.",
|
||||||
"Something went wrong!": "Jotain meni pieleen!",
|
"Something went wrong!": "Jotain meni pieleen!",
|
||||||
|
"special character": "erikoishahmo",
|
||||||
|
"spendable points expiring by": "{points} pistettä vanhenee {date} mennessä",
|
||||||
"Sports": "Urheilu",
|
"Sports": "Urheilu",
|
||||||
"Standard price": "Normaali hinta",
|
"Standard price": "Normaali hinta",
|
||||||
"Street": "Katu",
|
"Street": "Katu",
|
||||||
"Successfully updated profile!": "Profiilin päivitys onnistui!",
|
"Successfully updated profile!": "Profiilin päivitys onnistui!",
|
||||||
"Summary": "Yhteenveto",
|
"Summary": "Yhteenveto",
|
||||||
"TUI Points": "TUI Points",
|
|
||||||
"Tell us what information and updates you'd like to receive, and how, by clicking the link below.": "Kerro meille, mitä tietoja ja päivityksiä haluat saada ja miten, napsauttamalla alla olevaa linkkiä.",
|
"Tell us what information and updates you'd like to receive, and how, by clicking the link below.": "Kerro meille, mitä tietoja ja päivityksiä haluat saada ja miten, napsauttamalla alla olevaa linkkiä.",
|
||||||
"Terms and conditions": "Käyttöehdot",
|
"Terms and conditions": "Käyttöehdot",
|
||||||
"Thank you": "Kiitos",
|
"Thank you": "Kiitos",
|
||||||
"Theatre": "Teatteri",
|
"Theatre": "Teatteri",
|
||||||
"There are no transactions to display": "Näytettäviä tapahtumia ei ole",
|
"There are no transactions to display": "Näytettäviä tapahtumia ei ole",
|
||||||
"Things nearby HOTEL_NAME": "Lähellä olevia asioita {hotelName}",
|
"Things nearby HOTEL_NAME": "Lähellä olevia asioita {hotelName}",
|
||||||
"Total Points": "Kokonaispisteet",
|
"to": "to",
|
||||||
"Total incl VAT": "Yhteensä sis. alv",
|
"Total incl VAT": "Yhteensä sis. alv",
|
||||||
|
"Total Points": "Kokonaispisteet",
|
||||||
"Tourist": "Turisti",
|
"Tourist": "Turisti",
|
||||||
"Transaction date": "Tapahtuman päivämäärä",
|
"Transaction date": "Tapahtuman päivämäärä",
|
||||||
"Transactions": "Tapahtumat",
|
"Transactions": "Tapahtumat",
|
||||||
"Transportations": "Kuljetukset",
|
"Transportations": "Kuljetukset",
|
||||||
"Tripadvisor reviews": "{rating} ({count} arvostelua TripAdvisorissa)",
|
"Tripadvisor reviews": "{rating} ({count} arvostelua TripAdvisorissa)",
|
||||||
|
"TUI Points": "TUI Points",
|
||||||
"Type of bed": "Vuodetyyppi",
|
"Type of bed": "Vuodetyyppi",
|
||||||
"Type of room": "Huonetyyppi",
|
"Type of room": "Huonetyyppi",
|
||||||
|
"uppercase letter": "iso kirjain",
|
||||||
"Use bonus cheque": "Käytä bonussekkiä",
|
"Use bonus cheque": "Käytä bonussekkiä",
|
||||||
"Use code/voucher": "Käytä koodia/voucheria",
|
"Use code/voucher": "Käytä koodia/voucheria",
|
||||||
"User information": "Käyttäjän tiedot",
|
"User information": "Käyttäjän tiedot",
|
||||||
@@ -315,16 +344,16 @@
|
|||||||
"Where to": "Minne",
|
"Where to": "Minne",
|
||||||
"Which room class suits you the best?": "Mikä huoneluokka sopii sinulle parhaiten?",
|
"Which room class suits you the best?": "Mikä huoneluokka sopii sinulle parhaiten?",
|
||||||
"Year": "Vuosi",
|
"Year": "Vuosi",
|
||||||
"Yes, I accept the Terms and conditions for Scandic Friends and understand that Scandic will process my personal data in accordance with": "Kyllä, hyväksyn Scandic Friends -käyttöehdot ja ymmärrän, että Scandic käsittelee minun henkilötietoni asianmukaisesti",
|
|
||||||
"Yes, discard changes": "Kyllä, hylkää muutokset",
|
"Yes, discard changes": "Kyllä, hylkää muutokset",
|
||||||
|
"Yes, I accept the Terms and conditions for Scandic Friends and understand that Scandic will process my personal data in accordance with": "Kyllä, hyväksyn Scandic Friends -käyttöehdot ja ymmärrän, että Scandic käsittelee minun henkilötietoni asianmukaisesti",
|
||||||
"Yes, remove my card": "Kyllä, poista korttini",
|
"Yes, remove my card": "Kyllä, poista korttini",
|
||||||
"You can always change your mind later and add breakfast at the hotel.": "Voit aina muuttaa mieltäsi myöhemmin ja lisätä aamiaisen hotelliin.",
|
"You can always change your mind later and add breakfast at the hotel.": "Voit aina muuttaa mieltäsi myöhemmin ja lisätä aamiaisen hotelliin.",
|
||||||
"You canceled adding a new credit card.": "Peruutit uuden luottokortin lisäämisen.",
|
"You canceled adding a new credit card.": "Peruutit uuden luottokortin lisäämisen.",
|
||||||
"You have no previous stays.": "Sinulla ei ole aiempia majoituksia.",
|
"You have no previous stays.": "Sinulla ei ole aiempia majoituksia.",
|
||||||
"You have no upcoming stays.": "Sinulla ei ole tulevia majoituksia.",
|
"You have no upcoming stays.": "Sinulla ei ole tulevia majoituksia.",
|
||||||
"Your Challenges Conquer & Earn!": "Voita ja ansaitse haasteesi!",
|
|
||||||
"Your card was successfully removed!": "Korttisi poistettiin onnistuneesti!",
|
"Your card was successfully removed!": "Korttisi poistettiin onnistuneesti!",
|
||||||
"Your card was successfully saved!": "Korttisi tallennettu onnistuneesti!",
|
"Your card was successfully saved!": "Korttisi tallennettu onnistuneesti!",
|
||||||
|
"Your Challenges Conquer & Earn!": "Voita ja ansaitse haasteesi!",
|
||||||
"Your current level": "Nykyinen tasosi",
|
"Your current level": "Nykyinen tasosi",
|
||||||
"Your details": "Tietosi",
|
"Your details": "Tietosi",
|
||||||
"Your level": "Tasosi",
|
"Your level": "Tasosi",
|
||||||
@@ -334,33 +363,6 @@
|
|||||||
"Zoo": "Eläintarha",
|
"Zoo": "Eläintarha",
|
||||||
"Zoom in": "Lähennä",
|
"Zoom in": "Lähennä",
|
||||||
"Zoom out": "Loitonna",
|
"Zoom out": "Loitonna",
|
||||||
"as of today": "tänään",
|
|
||||||
"booking.adults": "{totalAdults, plural, one {# aikuinen} other {# aikuiset}}",
|
|
||||||
"booking.children": "{totalChildren, plural, one {# lapsi} other {# lasta}}",
|
|
||||||
"booking.guests": "Max {nrOfGuests, plural, one {# vieras} other {# vieraita}}",
|
|
||||||
"booking.nights": "{totalNights, plural, one {# yö} other {# yötä}}",
|
|
||||||
"booking.rooms": "{totalRooms, plural, one {# huone} other {# sviitti}}",
|
|
||||||
"booking.terms": "Maksamalla minkä tahansa saatavilla olevan maksutavan avulla hyväksyn tämän varauksen ehdot ja yleiset <termsLink>ehdot ja ehtoja</termsLink>, ja ymmärrän, että Scandic käsittelee minun henkilötietoni tässä varauksessa mukaisesti <privacyLink>Scandicin tietosuojavaltuuden</privacyLink> mukaisesti. Hyväksyn myös, että Scandic vaatii validin luottokortin majoituksen ajan, jos jokin jää maksamatta.",
|
|
||||||
"by": "mennessä",
|
|
||||||
"characters": "hahmoja",
|
|
||||||
"guest": "Vieras",
|
|
||||||
"guests": "Vieraita",
|
|
||||||
"hotelPages.rooms.roomCard.person": "henkilö",
|
|
||||||
"hotelPages.rooms.roomCard.persons": "Henkilöä",
|
|
||||||
"hotelPages.rooms.roomCard.seeRoomDetails": "Katso huoneen tiedot",
|
|
||||||
"km to city center": "km keskustaan",
|
|
||||||
"lowercase letter": "pien kirjain",
|
|
||||||
"n/a": "n/a",
|
|
||||||
"next level:": "pistettä tasolle:",
|
|
||||||
"night": "yö",
|
|
||||||
"nights": "yötä",
|
|
||||||
"number": "määrä",
|
|
||||||
"or": "tai",
|
|
||||||
"points": "pistettä",
|
|
||||||
"special character": "erikoishahmo",
|
|
||||||
"spendable points expiring by": "{points} pistettä vanhenee {date} mennessä",
|
|
||||||
"to": "to",
|
|
||||||
"uppercase letter": "iso kirjain",
|
|
||||||
"{amount} {currency}": "{amount} {currency}",
|
"{amount} {currency}": "{amount} {currency}",
|
||||||
"{difference}{amount} {currency}": "{difference}{amount} {currency}",
|
"{difference}{amount} {currency}": "{difference}{amount} {currency}",
|
||||||
"{width} cm × {length} cm": "{width} cm × {length} cm"
|
"{width} cm × {length} cm": "{width} cm × {length} cm"
|
||||||
|
|||||||
@@ -9,8 +9,8 @@
|
|||||||
"Add code": "Legg til kode",
|
"Add code": "Legg til kode",
|
||||||
"Add new card": "Legg til nytt kort",
|
"Add new card": "Legg til nytt kort",
|
||||||
"Address": "Adresse",
|
"Address": "Adresse",
|
||||||
"Airport": "Flyplass",
|
|
||||||
"Adults": "Voksne",
|
"Adults": "Voksne",
|
||||||
|
"Airport": "Flyplass",
|
||||||
"All our breakfast buffets offer gluten free, vegan, and allergy-friendly options.": "Alle våre frokostbufféer tilbyr glutenfrie, veganske og allergivennlige alternativer.",
|
"All our breakfast buffets offer gluten free, vegan, and allergy-friendly options.": "Alle våre frokostbufféer tilbyr glutenfrie, veganske og allergivennlige alternativer.",
|
||||||
"Already a friend?": "Allerede Friend?",
|
"Already a friend?": "Allerede Friend?",
|
||||||
"Amenities": "Fasiliteter",
|
"Amenities": "Fasiliteter",
|
||||||
@@ -23,6 +23,7 @@
|
|||||||
"Approx.": "Ca.",
|
"Approx.": "Ca.",
|
||||||
"Are you sure you want to remove the card ending with {lastFourDigits} from your member profile?": "Er du sikker på at du vil fjerne kortet som slutter på {lastFourDigits} fra medlemsprofilen din?",
|
"Are you sure you want to remove the card ending with {lastFourDigits} from your member profile?": "Er du sikker på at du vil fjerne kortet som slutter på {lastFourDigits} fra medlemsprofilen din?",
|
||||||
"Arrival date": "Ankomstdato",
|
"Arrival date": "Ankomstdato",
|
||||||
|
"as of today": "per i dag",
|
||||||
"As our": "Som vår {level}",
|
"As our": "Som vår {level}",
|
||||||
"As our Close Friend": "Som vår nære venn",
|
"As our Close Friend": "Som vår nære venn",
|
||||||
"At latest": "Senest",
|
"At latest": "Senest",
|
||||||
@@ -35,6 +36,11 @@
|
|||||||
"Book": "Bestill",
|
"Book": "Bestill",
|
||||||
"Book reward night": "Bestill belønningskveld",
|
"Book reward night": "Bestill belønningskveld",
|
||||||
"Booking number": "Bestillingsnummer",
|
"Booking number": "Bestillingsnummer",
|
||||||
|
"booking.adults": "{totalAdults, plural, one {# voksen} other {# voksne}}",
|
||||||
|
"booking.children": "{totalChildren, plural, one {# barn} other {# barn}}",
|
||||||
|
"booking.guests": "Maks {nrOfGuests, plural, one {# gjest} other {# gjester}}",
|
||||||
|
"booking.nights": "{totalNights, plural, one {# natt} other {# netter}}",
|
||||||
|
"booking.rooms": "{totalRooms, plural, one {# rom} other {# rom}}",
|
||||||
"Breakfast": "Frokost",
|
"Breakfast": "Frokost",
|
||||||
"Breakfast buffet": "Breakfast buffet",
|
"Breakfast buffet": "Breakfast buffet",
|
||||||
"Breakfast excluded": "Frokost ekskludert",
|
"Breakfast excluded": "Frokost ekskludert",
|
||||||
@@ -43,7 +49,9 @@
|
|||||||
"Breakfast selection in next step.": "Frokostvalg i neste steg.",
|
"Breakfast selection in next step.": "Frokostvalg i neste steg.",
|
||||||
"Bus terminal": "Bussterminal",
|
"Bus terminal": "Bussterminal",
|
||||||
"Business": "Forretnings",
|
"Business": "Forretnings",
|
||||||
|
"by": "innen",
|
||||||
"Cancel": "Avbryt",
|
"Cancel": "Avbryt",
|
||||||
|
"characters": "tegn",
|
||||||
"Check in": "Sjekk inn",
|
"Check in": "Sjekk inn",
|
||||||
"Check out": "Sjekk ut",
|
"Check out": "Sjekk ut",
|
||||||
"Check out the credit cards saved to your profile. Pay with a saved card when signed in for a smoother web experience.": "Sjekk ut kredittkortene som er lagret på profilen din. Betal med et lagret kort når du er pålogget for en jevnere nettopplevelse.",
|
"Check out the credit cards saved to your profile. Pay with a saved card when signed in for a smoother web experience.": "Sjekk ut kredittkortene som er lagret på profilen din. Betal med et lagret kort når du er pålogget for en jevnere nettopplevelse.",
|
||||||
@@ -100,9 +108,9 @@
|
|||||||
"Explore all levels and benefits": "Utforsk alle nivåer og fordeler",
|
"Explore all levels and benefits": "Utforsk alle nivåer og fordeler",
|
||||||
"Explore nearby": "Utforsk i nærheten",
|
"Explore nearby": "Utforsk i nærheten",
|
||||||
"Extras to your booking": "Tilvalg til bestillingen din",
|
"Extras to your booking": "Tilvalg til bestillingen din",
|
||||||
"FAQ": "FAQ",
|
|
||||||
"Failed to delete credit card, please try again later.": "Kunne ikke slette kredittkortet, prøv igjen senere.",
|
"Failed to delete credit card, please try again later.": "Kunne ikke slette kredittkortet, prøv igjen senere.",
|
||||||
"Fair": "Messe",
|
"Fair": "Messe",
|
||||||
|
"FAQ": "FAQ",
|
||||||
"Find booking": "Finn booking",
|
"Find booking": "Finn booking",
|
||||||
"Find hotels": "Finn hotell",
|
"Find hotels": "Finn hotell",
|
||||||
"First name": "Fornavn",
|
"First name": "Fornavn",
|
||||||
@@ -116,7 +124,9 @@
|
|||||||
"Get member benefits & offers": "Få medlemsfordeler og tilbud",
|
"Get member benefits & offers": "Få medlemsfordeler og tilbud",
|
||||||
"Go back to edit": "Gå tilbake til redigering",
|
"Go back to edit": "Gå tilbake til redigering",
|
||||||
"Go back to overview": "Gå tilbake til oversikten",
|
"Go back to overview": "Gå tilbake til oversikten",
|
||||||
|
"guest": "gjest",
|
||||||
"Guest information": "Informasjon til gjester",
|
"Guest information": "Informasjon til gjester",
|
||||||
|
"guests": "gjester",
|
||||||
"Guests & Rooms": "Gjester & rom",
|
"Guests & Rooms": "Gjester & rom",
|
||||||
"Hi": "Hei",
|
"Hi": "Hei",
|
||||||
"Highest level": "Høyeste nivå",
|
"Highest level": "Høyeste nivå",
|
||||||
@@ -124,6 +134,9 @@
|
|||||||
"Hotel": "Hotel",
|
"Hotel": "Hotel",
|
||||||
"Hotel facilities": "Hotelfaciliteter",
|
"Hotel facilities": "Hotelfaciliteter",
|
||||||
"Hotel surroundings": "Hotellomgivelser",
|
"Hotel surroundings": "Hotellomgivelser",
|
||||||
|
"hotelPages.rooms.roomCard.person": "person",
|
||||||
|
"hotelPages.rooms.roomCard.persons": "personer",
|
||||||
|
"hotelPages.rooms.roomCard.seeRoomDetails": "Se detaljer om rommet",
|
||||||
"Hotels": "Hoteller",
|
"Hotels": "Hoteller",
|
||||||
"How do you want to sleep?": "Hvordan vil du sove?",
|
"How do you want to sleep?": "Hvordan vil du sove?",
|
||||||
"How it works": "Hvordan det fungerer",
|
"How it works": "Hvordan det fungerer",
|
||||||
@@ -133,9 +146,10 @@
|
|||||||
"In extra bed": "i ekstraseng",
|
"In extra bed": "i ekstraseng",
|
||||||
"Included": "Inkludert",
|
"Included": "Inkludert",
|
||||||
"It is not posible to manage your communication preferences right now, please try again later or contact support if the problem persists.": "Det er ikke mulig å administrere kommunikasjonspreferansene dine akkurat nå, prøv igjen senere eller kontakt support hvis problemet vedvarer.",
|
"It is not posible to manage your communication preferences right now, please try again later or contact support if the problem persists.": "Det er ikke mulig å administrere kommunikasjonspreferansene dine akkurat nå, prøv igjen senere eller kontakt support hvis problemet vedvarer.",
|
||||||
"Join Scandic Friends": "Bli med i Scandic Friends",
|
|
||||||
"Join at no cost": "Bli med uten kostnad",
|
"Join at no cost": "Bli med uten kostnad",
|
||||||
|
"Join Scandic Friends": "Bli med i Scandic Friends",
|
||||||
"King bed": "King-size-seng",
|
"King bed": "King-size-seng",
|
||||||
|
"km to city center": "km til sentrum",
|
||||||
"Language": "Språk",
|
"Language": "Språk",
|
||||||
"Last name": "Etternavn",
|
"Last name": "Etternavn",
|
||||||
"Latest searches": "Siste søk",
|
"Latest searches": "Siste søk",
|
||||||
@@ -155,6 +169,7 @@
|
|||||||
"Log in here": "Logg inn her",
|
"Log in here": "Logg inn her",
|
||||||
"Log in/Join": "Logg på/Bli med",
|
"Log in/Join": "Logg på/Bli med",
|
||||||
"Log out": "Logg ut",
|
"Log out": "Logg ut",
|
||||||
|
"lowercase letter": "liten bokstav",
|
||||||
"Main menu": "Hovedmeny",
|
"Main menu": "Hovedmeny",
|
||||||
"Manage preferences": "Administrer preferanser",
|
"Manage preferences": "Administrer preferanser",
|
||||||
"Map": "Kart",
|
"Map": "Kart",
|
||||||
@@ -164,9 +179,9 @@
|
|||||||
"Member price": "Medlemspris",
|
"Member price": "Medlemspris",
|
||||||
"Member price from": "Medlemspris fra",
|
"Member price from": "Medlemspris fra",
|
||||||
"Members": "Medlemmer",
|
"Members": "Medlemmer",
|
||||||
|
"Membership cards": "Medlemskort",
|
||||||
"Membership ID": "Medlems-ID",
|
"Membership ID": "Medlems-ID",
|
||||||
"Membership ID copied to clipboard": "Medlems-ID kopiert til utklippstavlen",
|
"Membership ID copied to clipboard": "Medlems-ID kopiert til utklippstavlen",
|
||||||
"Membership cards": "Medlemskort",
|
|
||||||
"Menu": "Menu",
|
"Menu": "Menu",
|
||||||
"Modify": "Endre",
|
"Modify": "Endre",
|
||||||
"Month": "Måned",
|
"Month": "Måned",
|
||||||
@@ -176,11 +191,16 @@
|
|||||||
"My pages": "Mine sider",
|
"My pages": "Mine sider",
|
||||||
"My pages menu": "Mine sider-menyen",
|
"My pages menu": "Mine sider-menyen",
|
||||||
"My payment cards": "Mine betalingskort",
|
"My payment cards": "Mine betalingskort",
|
||||||
|
"MY SAVED CARDS": "MINE SAVEDE KORT",
|
||||||
"My wishes": "Mine ønsker",
|
"My wishes": "Mine ønsker",
|
||||||
|
"n/a": "n/a",
|
||||||
"Nearby": "I nærheten",
|
"Nearby": "I nærheten",
|
||||||
"Nearby companies": "Nærliggende selskaper",
|
"Nearby companies": "Nærliggende selskaper",
|
||||||
"New password": "Nytt passord",
|
"New password": "Nytt passord",
|
||||||
"Next": "Neste",
|
"Next": "Neste",
|
||||||
|
"next level:": "Neste nivå:",
|
||||||
|
"night": "natt",
|
||||||
|
"nights": "netter",
|
||||||
"Nights needed to level up": "Netter som trengs for å komme opp i nivå",
|
"Nights needed to level up": "Netter som trengs for å komme opp i nivå",
|
||||||
"No breakfast": "Ingen frokost",
|
"No breakfast": "Ingen frokost",
|
||||||
"No content published": "Ingen innhold publisert",
|
"No content published": "Ingen innhold publisert",
|
||||||
@@ -193,11 +213,14 @@
|
|||||||
"Nordic Swan Ecolabel": "Svanemerket",
|
"Nordic Swan Ecolabel": "Svanemerket",
|
||||||
"Not found": "Ikke funnet",
|
"Not found": "Ikke funnet",
|
||||||
"Nr night, nr adult": "{nights, number} natt, {adults, number} voksen",
|
"Nr night, nr adult": "{nights, number} natt, {adults, number} voksen",
|
||||||
|
"number": "antall",
|
||||||
"On your journey": "På reisen din",
|
"On your journey": "På reisen din",
|
||||||
"Open": "Åpen",
|
"Open": "Åpen",
|
||||||
"Open language menu": "Åpne språkmenyen",
|
"Open language menu": "Åpne språkmenyen",
|
||||||
"Open menu": "Åpne menyen",
|
"Open menu": "Åpne menyen",
|
||||||
"Open my pages menu": "Åpne mine sider menyen",
|
"Open my pages menu": "Åpne mine sider menyen",
|
||||||
|
"or": "eller",
|
||||||
|
"OTHER PAYMENT METHODS": "ANDRE BETALINGSMETODER",
|
||||||
"Overview": "Oversikt",
|
"Overview": "Oversikt",
|
||||||
"Parking": "Parkering",
|
"Parking": "Parkering",
|
||||||
"Parking / Garage": "Parkering / Garasje",
|
"Parking / Garage": "Parkering / Garasje",
|
||||||
@@ -209,6 +232,7 @@
|
|||||||
"Phone is required": "Telefon kreves",
|
"Phone is required": "Telefon kreves",
|
||||||
"Phone number": "Telefonnummer",
|
"Phone number": "Telefonnummer",
|
||||||
"Please enter a valid phone number": "Vennligst oppgi et gyldig telefonnummer",
|
"Please enter a valid phone number": "Vennligst oppgi et gyldig telefonnummer",
|
||||||
|
"points": "poeng",
|
||||||
"Points": "Poeng",
|
"Points": "Poeng",
|
||||||
"Points being calculated": "Poeng beregnes",
|
"Points being calculated": "Poeng beregnes",
|
||||||
"Points earned prior to May 1, 2021": "Opptjente poeng før 1. mai 2021",
|
"Points earned prior to May 1, 2021": "Opptjente poeng før 1. mai 2021",
|
||||||
@@ -231,9 +255,9 @@
|
|||||||
"Restaurant & Bar": "Restaurant & Bar",
|
"Restaurant & Bar": "Restaurant & Bar",
|
||||||
"Restaurants & Bars": "Restaurants & Bars",
|
"Restaurants & Bars": "Restaurants & Bars",
|
||||||
"Retype new password": "Skriv inn nytt passord på nytt",
|
"Retype new password": "Skriv inn nytt passord på nytt",
|
||||||
|
"Room": "Rom",
|
||||||
"Room & Terms": "Rom & Vilkår",
|
"Room & Terms": "Rom & Vilkår",
|
||||||
"Room facilities": "Romfasiliteter",
|
"Room facilities": "Romfasiliteter",
|
||||||
"Room": "Rom",
|
|
||||||
"Rooms": "Rom",
|
"Rooms": "Rom",
|
||||||
"Rooms & Guests": "Rom og gjester",
|
"Rooms & Guests": "Rom og gjester",
|
||||||
"Sauna and gym": "Sauna and gym",
|
"Sauna and gym": "Sauna and gym",
|
||||||
@@ -270,27 +294,31 @@
|
|||||||
"Something went wrong and we couldn't add your card. Please try again later.": "Noe gikk galt, og vi kunne ikke legge til kortet ditt. Prøv igjen senere.",
|
"Something went wrong and we couldn't add your card. Please try again later.": "Noe gikk galt, og vi kunne ikke legge til kortet ditt. Prøv igjen senere.",
|
||||||
"Something went wrong and we couldn't remove your card. Please try again later.": "Noe gikk galt, og vi kunne ikke fjerne kortet ditt. Vennligst prøv igjen senere.",
|
"Something went wrong and we couldn't remove your card. Please try again later.": "Noe gikk galt, og vi kunne ikke fjerne kortet ditt. Vennligst prøv igjen senere.",
|
||||||
"Something went wrong!": "Noe gikk galt!",
|
"Something went wrong!": "Noe gikk galt!",
|
||||||
|
"special character": "spesiell karakter",
|
||||||
|
"spendable points expiring by": "{points} Brukbare poeng utløper innen {date}",
|
||||||
"Sports": "Sport",
|
"Sports": "Sport",
|
||||||
"Standard price": "Standardpris",
|
"Standard price": "Standardpris",
|
||||||
"Street": "Gate",
|
"Street": "Gate",
|
||||||
"Successfully updated profile!": "Vellykket oppdatert profil!",
|
"Successfully updated profile!": "Vellykket oppdatert profil!",
|
||||||
"Summary": "Sammendrag",
|
"Summary": "Sammendrag",
|
||||||
"TUI Points": "TUI Points",
|
|
||||||
"Tell us what information and updates you'd like to receive, and how, by clicking the link below.": "Fortell oss hvilken informasjon og hvilke oppdateringer du ønsker å motta, og hvordan, ved å klikke på lenken nedenfor.",
|
"Tell us what information and updates you'd like to receive, and how, by clicking the link below.": "Fortell oss hvilken informasjon og hvilke oppdateringer du ønsker å motta, og hvordan, ved å klikke på lenken nedenfor.",
|
||||||
"Terms and conditions": "Vilkår og betingelser",
|
"Terms and conditions": "Vilkår og betingelser",
|
||||||
"Thank you": "Takk",
|
"Thank you": "Takk",
|
||||||
"Theatre": "Teater",
|
"Theatre": "Teater",
|
||||||
"There are no transactions to display": "Det er ingen transaksjoner å vise",
|
"There are no transactions to display": "Det er ingen transaksjoner å vise",
|
||||||
"Things nearby HOTEL_NAME": "Ting i nærheten av {hotelName}",
|
"Things nearby HOTEL_NAME": "Ting i nærheten av {hotelName}",
|
||||||
"Total Points": "Totale poeng",
|
"to": "til",
|
||||||
"Total incl VAT": "Sum inkl mva",
|
"Total incl VAT": "Sum inkl mva",
|
||||||
|
"Total Points": "Totale poeng",
|
||||||
"Tourist": "Turist",
|
"Tourist": "Turist",
|
||||||
"Transaction date": "Transaksjonsdato",
|
"Transaction date": "Transaksjonsdato",
|
||||||
"Transactions": "Transaksjoner",
|
"Transactions": "Transaksjoner",
|
||||||
"Transportations": "Transport",
|
"Transportations": "Transport",
|
||||||
"Tripadvisor reviews": "{rating} ({count} anmeldelser på Tripadvisor)",
|
"Tripadvisor reviews": "{rating} ({count} anmeldelser på Tripadvisor)",
|
||||||
|
"TUI Points": "TUI Points",
|
||||||
"Type of bed": "Sengtype",
|
"Type of bed": "Sengtype",
|
||||||
"Type of room": "Romtype",
|
"Type of room": "Romtype",
|
||||||
|
"uppercase letter": "stor bokstav",
|
||||||
"Use bonus cheque": "Bruk bonussjekk",
|
"Use bonus cheque": "Bruk bonussjekk",
|
||||||
"Use code/voucher": "Bruk kode/voucher",
|
"Use code/voucher": "Bruk kode/voucher",
|
||||||
"User information": "Brukerinformasjon",
|
"User information": "Brukerinformasjon",
|
||||||
@@ -312,16 +340,16 @@
|
|||||||
"Where to": "Hvor skal du",
|
"Where to": "Hvor skal du",
|
||||||
"Which room class suits you the best?": "Hvilken romklasse passer deg best?",
|
"Which room class suits you the best?": "Hvilken romklasse passer deg best?",
|
||||||
"Year": "År",
|
"Year": "År",
|
||||||
"Yes, I accept the Terms and conditions for Scandic Friends and understand that Scandic will process my personal data in accordance with": "Ja, jeg aksepterer vilkårene for Scandic Friends og forstår at Scandic vil behandle mine personlige opplysninger i henhold til",
|
|
||||||
"Yes, discard changes": "Ja, forkast endringer",
|
"Yes, discard changes": "Ja, forkast endringer",
|
||||||
|
"Yes, I accept the Terms and conditions for Scandic Friends and understand that Scandic will process my personal data in accordance with": "Ja, jeg aksepterer vilkårene for Scandic Friends og forstår at Scandic vil behandle mine personlige opplysninger i henhold til",
|
||||||
"Yes, remove my card": "Ja, fjern kortet mitt",
|
"Yes, remove my card": "Ja, fjern kortet mitt",
|
||||||
"You can always change your mind later and add breakfast at the hotel.": "Du kan alltid ombestemme deg senere og legge til frokost på hotellet.",
|
"You can always change your mind later and add breakfast at the hotel.": "Du kan alltid ombestemme deg senere og legge til frokost på hotellet.",
|
||||||
"You canceled adding a new credit card.": "Du kansellerte å legge til et nytt kredittkort.",
|
"You canceled adding a new credit card.": "Du kansellerte å legge til et nytt kredittkort.",
|
||||||
"You have no previous stays.": "Du har ingen tidligere opphold.",
|
"You have no previous stays.": "Du har ingen tidligere opphold.",
|
||||||
"You have no upcoming stays.": "Du har ingen kommende opphold.",
|
"You have no upcoming stays.": "Du har ingen kommende opphold.",
|
||||||
"Your Challenges Conquer & Earn!": "Dine utfordringer Erobre og tjen!",
|
|
||||||
"Your card was successfully removed!": "Kortet ditt ble fjernet!",
|
"Your card was successfully removed!": "Kortet ditt ble fjernet!",
|
||||||
"Your card was successfully saved!": "Kortet ditt ble lagret!",
|
"Your card was successfully saved!": "Kortet ditt ble lagret!",
|
||||||
|
"Your Challenges Conquer & Earn!": "Dine utfordringer Erobre og tjen!",
|
||||||
"Your current level": "Ditt nåværende nivå",
|
"Your current level": "Ditt nåværende nivå",
|
||||||
"Your details": "Dine detaljer",
|
"Your details": "Dine detaljer",
|
||||||
"Your level": "Ditt nivå",
|
"Your level": "Ditt nivå",
|
||||||
@@ -331,32 +359,6 @@
|
|||||||
"Zoo": "Dyrehage",
|
"Zoo": "Dyrehage",
|
||||||
"Zoom in": "Zoom inn",
|
"Zoom in": "Zoom inn",
|
||||||
"Zoom out": "Zoom ut",
|
"Zoom out": "Zoom ut",
|
||||||
"as of today": "per i dag",
|
|
||||||
"booking.adults": "{totalAdults, plural, one {# voksen} other {# voksne}}",
|
|
||||||
"booking.children": "{totalChildren, plural, one {# barn} other {# barn}}",
|
|
||||||
"booking.guests": "Maks {nrOfGuests, plural, one {# gjest} other {# gjester}}",
|
|
||||||
"booking.nights": "{totalNights, plural, one {# natt} other {# netter}}",
|
|
||||||
"booking.rooms": "{totalRooms, plural, one {# rom} other {# rom}}",
|
|
||||||
"by": "innen",
|
|
||||||
"characters": "tegn",
|
|
||||||
"guest": "gjest",
|
|
||||||
"guests": "gjester",
|
|
||||||
"hotelPages.rooms.roomCard.person": "person",
|
|
||||||
"hotelPages.rooms.roomCard.persons": "personer",
|
|
||||||
"hotelPages.rooms.roomCard.seeRoomDetails": "Se detaljer om rommet",
|
|
||||||
"km to city center": "km til sentrum",
|
|
||||||
"lowercase letter": "liten bokstav",
|
|
||||||
"n/a": "n/a",
|
|
||||||
"next level:": "Neste nivå:",
|
|
||||||
"night": "natt",
|
|
||||||
"nights": "netter",
|
|
||||||
"number": "antall",
|
|
||||||
"or": "eller",
|
|
||||||
"points": "poeng",
|
|
||||||
"special character": "spesiell karakter",
|
|
||||||
"spendable points expiring by": "{points} Brukbare poeng utløper innen {date}",
|
|
||||||
"to": "til",
|
|
||||||
"uppercase letter": "stor bokstav",
|
|
||||||
"{amount} {currency}": "{amount} {currency}",
|
"{amount} {currency}": "{amount} {currency}",
|
||||||
"{difference}{amount} {currency}": "{difference}{amount} {currency}",
|
"{difference}{amount} {currency}": "{difference}{amount} {currency}",
|
||||||
"{width} cm × {length} cm": "{width} cm × {length} cm"
|
"{width} cm × {length} cm": "{width} cm × {length} cm"
|
||||||
|
|||||||
@@ -9,8 +9,8 @@
|
|||||||
"Add code": "Lägg till kod",
|
"Add code": "Lägg till kod",
|
||||||
"Add new card": "Lägg till nytt kort",
|
"Add new card": "Lägg till nytt kort",
|
||||||
"Address": "Adress",
|
"Address": "Adress",
|
||||||
"Airport": "Flygplats",
|
|
||||||
"Adults": "Vuxna",
|
"Adults": "Vuxna",
|
||||||
|
"Airport": "Flygplats",
|
||||||
"All our breakfast buffets offer gluten free, vegan, and allergy-friendly options.": "Alla våra frukostbufféer erbjuder glutenfria, veganska och allergivänliga alternativ.",
|
"All our breakfast buffets offer gluten free, vegan, and allergy-friendly options.": "Alla våra frukostbufféer erbjuder glutenfria, veganska och allergivänliga alternativ.",
|
||||||
"Already a friend?": "Är du redan en vän?",
|
"Already a friend?": "Är du redan en vän?",
|
||||||
"Amenities": "Bekvämligheter",
|
"Amenities": "Bekvämligheter",
|
||||||
@@ -23,6 +23,7 @@
|
|||||||
"Approx.": "Ca.",
|
"Approx.": "Ca.",
|
||||||
"Are you sure you want to remove the card ending with {lastFourDigits} from your member profile?": "Är du säker på att du vill ta bort kortet som slutar med {lastFourDigits} från din medlemsprofil?",
|
"Are you sure you want to remove the card ending with {lastFourDigits} from your member profile?": "Är du säker på att du vill ta bort kortet som slutar med {lastFourDigits} från din medlemsprofil?",
|
||||||
"Arrival date": "Ankomstdatum",
|
"Arrival date": "Ankomstdatum",
|
||||||
|
"as of today": "från och med idag",
|
||||||
"As our": "Som vår {level}",
|
"As our": "Som vår {level}",
|
||||||
"As our Close Friend": "Som vår nära vän",
|
"As our Close Friend": "Som vår nära vän",
|
||||||
"At latest": "Senast",
|
"At latest": "Senast",
|
||||||
@@ -35,6 +36,12 @@
|
|||||||
"Book": "Boka",
|
"Book": "Boka",
|
||||||
"Book reward night": "Boka frinatt",
|
"Book reward night": "Boka frinatt",
|
||||||
"Booking number": "Bokningsnummer",
|
"Booking number": "Bokningsnummer",
|
||||||
|
"booking.adults": "{totalAdults, plural, one {# vuxen} other {# vuxna}}",
|
||||||
|
"booking.children": "{totalChildren, plural, one {# barn} other {# barn}}",
|
||||||
|
"booking.guests": "Max {nrOfGuests, plural, one {# gäst} other {# gäster}}",
|
||||||
|
"booking.nights": "{totalNights, plural, one {# natt} other {# nätter}}",
|
||||||
|
"booking.rooms": "{totalRooms, plural, one {# rum} other {# rum}}",
|
||||||
|
"booking.terms": "Genom att betala med någon av de tillgängliga betalningsmetoderna accepterar jag villkoren för denna bokning och de generella <termsLink>Villkoren och villkoren</termsLink>, och förstår att Scandic kommer att behandla min personliga data i samband med denna bokning i enlighet med <privacyLink>Scandics integritetspolicy</privacyLink>. Jag accepterar att Scandic kräver ett giltigt kreditkort under min besök i fall att något är tillbaka betalt.",
|
||||||
"Breakfast": "Frukost",
|
"Breakfast": "Frukost",
|
||||||
"Breakfast buffet": "Frukostbuffé",
|
"Breakfast buffet": "Frukostbuffé",
|
||||||
"Breakfast excluded": "Frukost ingår ej",
|
"Breakfast excluded": "Frukost ingår ej",
|
||||||
@@ -43,7 +50,9 @@
|
|||||||
"Breakfast selection in next step.": "Frukostval i nästa steg.",
|
"Breakfast selection in next step.": "Frukostval i nästa steg.",
|
||||||
"Bus terminal": "Bussterminal",
|
"Bus terminal": "Bussterminal",
|
||||||
"Business": "Business",
|
"Business": "Business",
|
||||||
|
"by": "innan",
|
||||||
"Cancel": "Avbryt",
|
"Cancel": "Avbryt",
|
||||||
|
"characters": "tecken",
|
||||||
"Check in": "Checka in",
|
"Check in": "Checka in",
|
||||||
"Check out": "Checka ut",
|
"Check out": "Checka ut",
|
||||||
"Check out the credit cards saved to your profile. Pay with a saved card when signed in for a smoother web experience.": "Kolla in kreditkorten som sparats i din profil. Betala med ett sparat kort när du är inloggad för en smidigare webbupplevelse.",
|
"Check out the credit cards saved to your profile. Pay with a saved card when signed in for a smoother web experience.": "Kolla in kreditkorten som sparats i din profil. Betala med ett sparat kort när du är inloggad för en smidigare webbupplevelse.",
|
||||||
@@ -100,9 +109,9 @@
|
|||||||
"Explore all levels and benefits": "Utforska alla nivåer och fördelar",
|
"Explore all levels and benefits": "Utforska alla nivåer och fördelar",
|
||||||
"Explore nearby": "Utforska i närheten",
|
"Explore nearby": "Utforska i närheten",
|
||||||
"Extras to your booking": "Extra tillval till din bokning",
|
"Extras to your booking": "Extra tillval till din bokning",
|
||||||
"FAQ": "FAQ",
|
|
||||||
"Failed to delete credit card, please try again later.": "Det gick inte att ta bort kreditkortet, försök igen senare.",
|
"Failed to delete credit card, please try again later.": "Det gick inte att ta bort kreditkortet, försök igen senare.",
|
||||||
"Fair": "Mässa",
|
"Fair": "Mässa",
|
||||||
|
"FAQ": "FAQ",
|
||||||
"Find booking": "Hitta bokning",
|
"Find booking": "Hitta bokning",
|
||||||
"Find hotels": "Hitta hotell",
|
"Find hotels": "Hitta hotell",
|
||||||
"First name": "Förnamn",
|
"First name": "Förnamn",
|
||||||
@@ -116,7 +125,9 @@
|
|||||||
"Get member benefits & offers": "Ta del av medlemsförmåner och erbjudanden",
|
"Get member benefits & offers": "Ta del av medlemsförmåner och erbjudanden",
|
||||||
"Go back to edit": "Gå tillbaka till redigeringen",
|
"Go back to edit": "Gå tillbaka till redigeringen",
|
||||||
"Go back to overview": "Gå tillbaka till översikten",
|
"Go back to overview": "Gå tillbaka till översikten",
|
||||||
|
"guest": "gäst",
|
||||||
"Guest information": "Information till gästerna",
|
"Guest information": "Information till gästerna",
|
||||||
|
"guests": "gäster",
|
||||||
"Guests & Rooms": "Gäster & rum",
|
"Guests & Rooms": "Gäster & rum",
|
||||||
"Hi": "Hej",
|
"Hi": "Hej",
|
||||||
"Highest level": "Högsta nivå",
|
"Highest level": "Högsta nivå",
|
||||||
@@ -124,6 +135,9 @@
|
|||||||
"Hotel": "Hotell",
|
"Hotel": "Hotell",
|
||||||
"Hotel facilities": "Hotellfaciliteter",
|
"Hotel facilities": "Hotellfaciliteter",
|
||||||
"Hotel surroundings": "Hotellomgivning",
|
"Hotel surroundings": "Hotellomgivning",
|
||||||
|
"hotelPages.rooms.roomCard.person": "person",
|
||||||
|
"hotelPages.rooms.roomCard.persons": "personer",
|
||||||
|
"hotelPages.rooms.roomCard.seeRoomDetails": "Se information om rummet",
|
||||||
"Hotels": "Hotell",
|
"Hotels": "Hotell",
|
||||||
"How do you want to sleep?": "Hur vill du sova?",
|
"How do you want to sleep?": "Hur vill du sova?",
|
||||||
"How it works": "Hur det fungerar",
|
"How it works": "Hur det fungerar",
|
||||||
@@ -133,9 +147,10 @@
|
|||||||
"In extra bed": "Egen sängplats",
|
"In extra bed": "Egen sängplats",
|
||||||
"Included": "Inkluderad",
|
"Included": "Inkluderad",
|
||||||
"It is not posible to manage your communication preferences right now, please try again later or contact support if the problem persists.": "Det gick inte att hantera dina kommunikationsinställningar just nu, försök igen senare eller kontakta supporten om problemet kvarstår.",
|
"It is not posible to manage your communication preferences right now, please try again later or contact support if the problem persists.": "Det gick inte att hantera dina kommunikationsinställningar just nu, försök igen senare eller kontakta supporten om problemet kvarstår.",
|
||||||
"Join Scandic Friends": "Gå med i Scandic Friends",
|
|
||||||
"Join at no cost": "Gå med utan kostnad",
|
"Join at no cost": "Gå med utan kostnad",
|
||||||
|
"Join Scandic Friends": "Gå med i Scandic Friends",
|
||||||
"King bed": "King size-säng",
|
"King bed": "King size-säng",
|
||||||
|
"km to city center": "km till stadens centrum",
|
||||||
"Language": "Språk",
|
"Language": "Språk",
|
||||||
"Last name": "Efternamn",
|
"Last name": "Efternamn",
|
||||||
"Latest searches": "Senaste sökningarna",
|
"Latest searches": "Senaste sökningarna",
|
||||||
@@ -155,6 +170,7 @@
|
|||||||
"Log in here": "Logga in här",
|
"Log in here": "Logga in här",
|
||||||
"Log in/Join": "Logga in/Gå med",
|
"Log in/Join": "Logga in/Gå med",
|
||||||
"Log out": "Logga ut",
|
"Log out": "Logga ut",
|
||||||
|
"lowercase letter": "liten bokstav",
|
||||||
"Main menu": "Huvudmeny",
|
"Main menu": "Huvudmeny",
|
||||||
"Manage preferences": "Hantera inställningar",
|
"Manage preferences": "Hantera inställningar",
|
||||||
"Map": "Karta",
|
"Map": "Karta",
|
||||||
@@ -164,9 +180,9 @@
|
|||||||
"Member price": "Medlemspris",
|
"Member price": "Medlemspris",
|
||||||
"Member price from": "Medlemspris från",
|
"Member price from": "Medlemspris från",
|
||||||
"Members": "Medlemmar",
|
"Members": "Medlemmar",
|
||||||
|
"Membership cards": "Medlemskort",
|
||||||
"Membership ID": "Medlems-ID",
|
"Membership ID": "Medlems-ID",
|
||||||
"Membership ID copied to clipboard": "Medlems-ID kopierat till urklipp",
|
"Membership ID copied to clipboard": "Medlems-ID kopierat till urklipp",
|
||||||
"Membership cards": "Medlemskort",
|
|
||||||
"Menu": "Meny",
|
"Menu": "Meny",
|
||||||
"Modify": "Ändra",
|
"Modify": "Ändra",
|
||||||
"Month": "Månad",
|
"Month": "Månad",
|
||||||
@@ -176,11 +192,16 @@
|
|||||||
"My pages": "Mina sidor",
|
"My pages": "Mina sidor",
|
||||||
"My pages menu": "Mina sidor meny",
|
"My pages menu": "Mina sidor meny",
|
||||||
"My payment cards": "Mina betalningskort",
|
"My payment cards": "Mina betalningskort",
|
||||||
|
"MY SAVED CARDS": "MINE SAVEDE KORT",
|
||||||
"My wishes": "Mina önskningar",
|
"My wishes": "Mina önskningar",
|
||||||
|
"n/a": "n/a",
|
||||||
"Nearby": "I närheten",
|
"Nearby": "I närheten",
|
||||||
"Nearby companies": "Närliggande företag",
|
"Nearby companies": "Närliggande företag",
|
||||||
"New password": "Nytt lösenord",
|
"New password": "Nytt lösenord",
|
||||||
"Next": "Nästa",
|
"Next": "Nästa",
|
||||||
|
"next level:": "Nästa nivå:",
|
||||||
|
"night": "natt",
|
||||||
|
"nights": "nätter",
|
||||||
"Nights needed to level up": "Nätter som behövs för att gå upp i nivå",
|
"Nights needed to level up": "Nätter som behövs för att gå upp i nivå",
|
||||||
"No breakfast": "Ingen frukost",
|
"No breakfast": "Ingen frukost",
|
||||||
"No content published": "Inget innehåll publicerat",
|
"No content published": "Inget innehåll publicerat",
|
||||||
@@ -193,11 +214,14 @@
|
|||||||
"Nordic Swan Ecolabel": "Svanenmärkt",
|
"Nordic Swan Ecolabel": "Svanenmärkt",
|
||||||
"Not found": "Hittades inte",
|
"Not found": "Hittades inte",
|
||||||
"Nr night, nr adult": "{nights, number} natt, {adults, number} vuxen",
|
"Nr night, nr adult": "{nights, number} natt, {adults, number} vuxen",
|
||||||
|
"number": "nummer",
|
||||||
"On your journey": "På din resa",
|
"On your journey": "På din resa",
|
||||||
"Open": "Öppna",
|
"Open": "Öppna",
|
||||||
"Open language menu": "Öppna språkmenyn",
|
"Open language menu": "Öppna språkmenyn",
|
||||||
"Open menu": "Öppna menyn",
|
"Open menu": "Öppna menyn",
|
||||||
"Open my pages menu": "Öppna mina sidor menyn",
|
"Open my pages menu": "Öppna mina sidor menyn",
|
||||||
|
"or": "eller",
|
||||||
|
"OTHER PAYMENT METHODS": "ANDRE BETALINGSMETODER",
|
||||||
"Overview": "Översikt",
|
"Overview": "Översikt",
|
||||||
"Parking": "Parkering",
|
"Parking": "Parkering",
|
||||||
"Parking / Garage": "Parkering / Garage",
|
"Parking / Garage": "Parkering / Garage",
|
||||||
@@ -209,6 +233,7 @@
|
|||||||
"Phone is required": "Telefonnummer är obligatorisk",
|
"Phone is required": "Telefonnummer är obligatorisk",
|
||||||
"Phone number": "Telefonnummer",
|
"Phone number": "Telefonnummer",
|
||||||
"Please enter a valid phone number": "Var vänlig och ange ett giltigt telefonnummer",
|
"Please enter a valid phone number": "Var vänlig och ange ett giltigt telefonnummer",
|
||||||
|
"points": "poäng",
|
||||||
"Points": "Poäng",
|
"Points": "Poäng",
|
||||||
"Points being calculated": "Poäng beräknas",
|
"Points being calculated": "Poäng beräknas",
|
||||||
"Points earned prior to May 1, 2021": "Intjänade poäng före den 1 maj 2021",
|
"Points earned prior to May 1, 2021": "Intjänade poäng före den 1 maj 2021",
|
||||||
@@ -231,9 +256,9 @@
|
|||||||
"Restaurant & Bar": "Restaurang & Bar",
|
"Restaurant & Bar": "Restaurang & Bar",
|
||||||
"Restaurants & Bars": "Restaurants & Bars",
|
"Restaurants & Bars": "Restaurants & Bars",
|
||||||
"Retype new password": "Upprepa nytt lösenord",
|
"Retype new password": "Upprepa nytt lösenord",
|
||||||
|
"Room": "Rum",
|
||||||
"Room & Terms": "Rum & Villkor",
|
"Room & Terms": "Rum & Villkor",
|
||||||
"Room facilities": "Rumfaciliteter",
|
"Room facilities": "Rumfaciliteter",
|
||||||
"Room": "Rum",
|
|
||||||
"Rooms": "Rum",
|
"Rooms": "Rum",
|
||||||
"Rooms & Guests": "Rum och gäster",
|
"Rooms & Guests": "Rum och gäster",
|
||||||
"Sauna and gym": "Sauna and gym",
|
"Sauna and gym": "Sauna and gym",
|
||||||
@@ -270,27 +295,31 @@
|
|||||||
"Something went wrong and we couldn't add your card. Please try again later.": "Något gick fel och vi kunde inte lägga till ditt kort. Försök igen senare.",
|
"Something went wrong and we couldn't add your card. Please try again later.": "Något gick fel och vi kunde inte lägga till ditt kort. Försök igen senare.",
|
||||||
"Something went wrong and we couldn't remove your card. Please try again later.": "Något gick fel och vi kunde inte ta bort ditt kort. Försök igen senare.",
|
"Something went wrong and we couldn't remove your card. Please try again later.": "Något gick fel och vi kunde inte ta bort ditt kort. Försök igen senare.",
|
||||||
"Something went wrong!": "Något gick fel!",
|
"Something went wrong!": "Något gick fel!",
|
||||||
|
"special character": "speciell karaktär",
|
||||||
|
"spendable points expiring by": "{points} poäng förfaller {date}",
|
||||||
"Sports": "Sport",
|
"Sports": "Sport",
|
||||||
"Standard price": "Standardpris",
|
"Standard price": "Standardpris",
|
||||||
"Street": "Gata",
|
"Street": "Gata",
|
||||||
"Successfully updated profile!": "Profilen har uppdaterats framgångsrikt!",
|
"Successfully updated profile!": "Profilen har uppdaterats framgångsrikt!",
|
||||||
"Summary": "Sammanfattning",
|
"Summary": "Sammanfattning",
|
||||||
"TUI Points": "TUI Points",
|
|
||||||
"Tell us what information and updates you'd like to receive, and how, by clicking the link below.": "Berätta för oss vilken information och vilka uppdateringar du vill få och hur genom att klicka på länken nedan.",
|
"Tell us what information and updates you'd like to receive, and how, by clicking the link below.": "Berätta för oss vilken information och vilka uppdateringar du vill få och hur genom att klicka på länken nedan.",
|
||||||
"Terms and conditions": "Allmänna villkor",
|
"Terms and conditions": "Allmänna villkor",
|
||||||
"Thank you": "Tack",
|
"Thank you": "Tack",
|
||||||
"Theatre": "Teater",
|
"Theatre": "Teater",
|
||||||
"There are no transactions to display": "Det finns inga transaktioner att visa",
|
"There are no transactions to display": "Det finns inga transaktioner att visa",
|
||||||
"Things nearby HOTEL_NAME": "Saker i närheten av {hotelName}",
|
"Things nearby HOTEL_NAME": "Saker i närheten av {hotelName}",
|
||||||
"Total Points": "Poäng totalt",
|
"to": "till",
|
||||||
"Total incl VAT": "Totalt inkl moms",
|
"Total incl VAT": "Totalt inkl moms",
|
||||||
|
"Total Points": "Poäng totalt",
|
||||||
"Tourist": "Turist",
|
"Tourist": "Turist",
|
||||||
"Transaction date": "Transaktionsdatum",
|
"Transaction date": "Transaktionsdatum",
|
||||||
"Transactions": "Transaktioner",
|
"Transactions": "Transaktioner",
|
||||||
"Transportations": "Transport",
|
"Transportations": "Transport",
|
||||||
"Tripadvisor reviews": "{rating} ({count} recensioner på Tripadvisor)",
|
"Tripadvisor reviews": "{rating} ({count} recensioner på Tripadvisor)",
|
||||||
|
"TUI Points": "TUI Points",
|
||||||
"Type of bed": "Sängtyp",
|
"Type of bed": "Sängtyp",
|
||||||
"Type of room": "Rumstyp",
|
"Type of room": "Rumstyp",
|
||||||
|
"uppercase letter": "stor bokstav",
|
||||||
"Use bonus cheque": "Använd bonuscheck",
|
"Use bonus cheque": "Använd bonuscheck",
|
||||||
"Use code/voucher": "Använd kod/voucher",
|
"Use code/voucher": "Använd kod/voucher",
|
||||||
"User information": "Användarinformation",
|
"User information": "Användarinformation",
|
||||||
@@ -312,16 +341,16 @@
|
|||||||
"Where to": "Vart",
|
"Where to": "Vart",
|
||||||
"Which room class suits you the best?": "Vilken rumsklass passar dig bäst?",
|
"Which room class suits you the best?": "Vilken rumsklass passar dig bäst?",
|
||||||
"Year": "År",
|
"Year": "År",
|
||||||
"Yes, I accept the Terms and conditions for Scandic Friends and understand that Scandic will process my personal data in accordance with": "Ja, jag accepterar villkoren för Scandic Friends och förstår att Scandic kommer att bearbeta mina personliga uppgifter i enlighet med",
|
|
||||||
"Yes, discard changes": "Ja, ignorera ändringar",
|
"Yes, discard changes": "Ja, ignorera ändringar",
|
||||||
|
"Yes, I accept the Terms and conditions for Scandic Friends and understand that Scandic will process my personal data in accordance with": "Ja, jag accepterar villkoren för Scandic Friends och förstår att Scandic kommer att bearbeta mina personliga uppgifter i enlighet med",
|
||||||
"Yes, remove my card": "Ja, ta bort mitt kort",
|
"Yes, remove my card": "Ja, ta bort mitt kort",
|
||||||
"You can always change your mind later and add breakfast at the hotel.": "Du kan alltid ändra dig senare och lägga till frukost på hotellet.",
|
"You can always change your mind later and add breakfast at the hotel.": "Du kan alltid ändra dig senare och lägga till frukost på hotellet.",
|
||||||
"You canceled adding a new credit card.": "Du avbröt att lägga till ett nytt kreditkort.",
|
"You canceled adding a new credit card.": "Du avbröt att lägga till ett nytt kreditkort.",
|
||||||
"You have no previous stays.": "Du har inga tidigare vistelser.",
|
"You have no previous stays.": "Du har inga tidigare vistelser.",
|
||||||
"You have no upcoming stays.": "Du har inga planerade resor.",
|
"You have no upcoming stays.": "Du har inga planerade resor.",
|
||||||
"Your Challenges Conquer & Earn!": "Dina utmaningar Erövra och tjäna!",
|
|
||||||
"Your card was successfully removed!": "Ditt kort har tagits bort!",
|
"Your card was successfully removed!": "Ditt kort har tagits bort!",
|
||||||
"Your card was successfully saved!": "Ditt kort har sparats!",
|
"Your card was successfully saved!": "Ditt kort har sparats!",
|
||||||
|
"Your Challenges Conquer & Earn!": "Dina utmaningar Erövra och tjäna!",
|
||||||
"Your current level": "Din nuvarande nivå",
|
"Your current level": "Din nuvarande nivå",
|
||||||
"Your details": "Dina uppgifter",
|
"Your details": "Dina uppgifter",
|
||||||
"Your level": "Din nivå",
|
"Your level": "Din nivå",
|
||||||
@@ -331,33 +360,6 @@
|
|||||||
"Zoo": "Djurpark",
|
"Zoo": "Djurpark",
|
||||||
"Zoom in": "Zooma in",
|
"Zoom in": "Zooma in",
|
||||||
"Zoom out": "Zooma ut",
|
"Zoom out": "Zooma ut",
|
||||||
"as of today": "från och med idag",
|
|
||||||
"booking.adults": "{totalAdults, plural, one {# vuxen} other {# vuxna}}",
|
|
||||||
"booking.children": "{totalChildren, plural, one {# barn} other {# barn}}",
|
|
||||||
"booking.guests": "Max {nrOfGuests, plural, one {# gäst} other {# gäster}}",
|
|
||||||
"booking.nights": "{totalNights, plural, one {# natt} other {# nätter}}",
|
|
||||||
"booking.rooms": "{totalRooms, plural, one {# rum} other {# rum}}",
|
|
||||||
"booking.terms": "Genom att betala med någon av de tillgängliga betalningsmetoderna accepterar jag villkoren för denna bokning och de generella <termsLink>Villkoren och villkoren</termsLink>, och förstår att Scandic kommer att behandla min personliga data i samband med denna bokning i enlighet med <privacyLink>Scandics integritetspolicy</privacyLink>. Jag accepterar att Scandic kräver ett giltigt kreditkort under min besök i fall att något är tillbaka betalt.",
|
|
||||||
"by": "innan",
|
|
||||||
"characters": "tecken",
|
|
||||||
"guest": "gäst",
|
|
||||||
"guests": "gäster",
|
|
||||||
"hotelPages.rooms.roomCard.person": "person",
|
|
||||||
"hotelPages.rooms.roomCard.persons": "personer",
|
|
||||||
"hotelPages.rooms.roomCard.seeRoomDetails": "Se information om rummet",
|
|
||||||
"km to city center": "km till stadens centrum",
|
|
||||||
"lowercase letter": "liten bokstav",
|
|
||||||
"n/a": "n/a",
|
|
||||||
"next level:": "Nästa nivå:",
|
|
||||||
"night": "natt",
|
|
||||||
"nights": "nätter",
|
|
||||||
"number": "nummer",
|
|
||||||
"or": "eller",
|
|
||||||
"points": "poäng",
|
|
||||||
"special character": "speciell karaktär",
|
|
||||||
"spendable points expiring by": "{points} poäng förfaller {date}",
|
|
||||||
"to": "till",
|
|
||||||
"uppercase letter": "stor bokstav",
|
|
||||||
"{amount} {currency}": "{amount} {currency}",
|
"{amount} {currency}": "{amount} {currency}",
|
||||||
"{difference}{amount} {currency}": "{difference}{amount} {currency}",
|
"{difference}{amount} {currency}": "{difference}{amount} {currency}",
|
||||||
"{width} cm × {length} cm": "{width} cm × {length} cm"
|
"{width} cm × {length} cm": "{width} cm × {length} cm"
|
||||||
|
|||||||
88
lib/graphql/Fragments/Alert.graphql
Normal file
88
lib/graphql/Fragments/Alert.graphql
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
#import "./PageLink/AccountPageLink.graphql"
|
||||||
|
#import "./PageLink/ContentPageLink.graphql"
|
||||||
|
#import "./PageLink/HotelPageLink.graphql"
|
||||||
|
#import "./PageLink/LoyaltyPageLink.graphql"
|
||||||
|
|
||||||
|
#import "./AccountPage/Ref.graphql"
|
||||||
|
#import "./ContentPage/Ref.graphql"
|
||||||
|
#import "./HotelPage/Ref.graphql"
|
||||||
|
#import "./LoyaltyPage/Ref.graphql"
|
||||||
|
|
||||||
|
fragment Alert on Alert {
|
||||||
|
type
|
||||||
|
heading
|
||||||
|
text
|
||||||
|
phone_contact {
|
||||||
|
display_text
|
||||||
|
phone_number
|
||||||
|
footnote
|
||||||
|
}
|
||||||
|
has_link
|
||||||
|
link {
|
||||||
|
title
|
||||||
|
linkConnection {
|
||||||
|
edges {
|
||||||
|
node {
|
||||||
|
__typename
|
||||||
|
...AccountPageLink
|
||||||
|
...ContentPageLink
|
||||||
|
...HotelPageLink
|
||||||
|
...LoyaltyPageLink
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
has_sidepeek_button
|
||||||
|
sidepeek_button {
|
||||||
|
cta_text
|
||||||
|
}
|
||||||
|
sidepeek_content {
|
||||||
|
heading
|
||||||
|
content {
|
||||||
|
embedded_itemsConnection {
|
||||||
|
edges {
|
||||||
|
node {
|
||||||
|
__typename
|
||||||
|
...AccountPageLink
|
||||||
|
...ContentPageLink
|
||||||
|
...HotelPageLink
|
||||||
|
...LoyaltyPageLink
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
json
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fragment AlertRef on Alert {
|
||||||
|
link {
|
||||||
|
linkConnection {
|
||||||
|
edges {
|
||||||
|
node {
|
||||||
|
__typename
|
||||||
|
...AccountPageRef
|
||||||
|
...ContentPageRef
|
||||||
|
...HotelPageRef
|
||||||
|
...LoyaltyPageRef
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sidepeek_content {
|
||||||
|
content {
|
||||||
|
embedded_itemsConnection {
|
||||||
|
edges {
|
||||||
|
node {
|
||||||
|
__typename
|
||||||
|
...AccountPageRef
|
||||||
|
...ContentPageRef
|
||||||
|
...HotelPageRef
|
||||||
|
...LoyaltyPageRef
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
json
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
23
lib/graphql/Fragments/Sidebar/QuickLinks.graphql
Normal file
23
lib/graphql/Fragments/Sidebar/QuickLinks.graphql
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
#import "../AccountPage/Ref.graphql"
|
||||||
|
#import "../ContentPage/Ref.graphql"
|
||||||
|
#import "../LoyaltyPage/Ref.graphql"
|
||||||
|
|
||||||
|
#import "../PageLink/AccountPageLink.graphql"
|
||||||
|
#import "../PageLink/ContentPageLink.graphql"
|
||||||
|
#import "../PageLink/LoyaltyPageLink.graphql"
|
||||||
|
|
||||||
|
#import "../Blocks/Shortcuts.graphql"
|
||||||
|
|
||||||
|
fragment QuickLinksSidebar_ContentPage on ContentPageSidebarShortcuts {
|
||||||
|
__typename
|
||||||
|
shortcuts {
|
||||||
|
...Shortcuts
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fragment QuickLinksSidebar_ContentPageRefs on ContentPageSidebarShortcuts {
|
||||||
|
shortcuts {
|
||||||
|
__typename
|
||||||
|
...ShortcutsRefs
|
||||||
|
}
|
||||||
|
}
|
||||||
38
lib/graphql/Fragments/Sidebar/ScriptedCard.graphql
Normal file
38
lib/graphql/Fragments/Sidebar/ScriptedCard.graphql
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
#import "../AccountPage/Ref.graphql"
|
||||||
|
#import "../ContentPage/Ref.graphql"
|
||||||
|
#import "../LoyaltyPage/Ref.graphql"
|
||||||
|
|
||||||
|
#import "../PageLink/AccountPageLink.graphql"
|
||||||
|
#import "../PageLink/ContentPageLink.graphql"
|
||||||
|
#import "../PageLink/LoyaltyPageLink.graphql"
|
||||||
|
|
||||||
|
#import "../Blocks/Card.graphql"
|
||||||
|
#import "../Blocks/Refs/Card.graphql"
|
||||||
|
|
||||||
|
fragment ScriptedCardSidebar_ContentPage on ContentPageSidebarScriptedCard {
|
||||||
|
__typename
|
||||||
|
scripted_card {
|
||||||
|
theme
|
||||||
|
scripted_cardConnection {
|
||||||
|
edges {
|
||||||
|
node {
|
||||||
|
__typename
|
||||||
|
...CardBlock
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fragment ScriptedCardSidebar_ContentPageRefs on ContentPageSidebarScriptedCard {
|
||||||
|
scripted_card {
|
||||||
|
scripted_cardConnection {
|
||||||
|
edges {
|
||||||
|
node {
|
||||||
|
__typename
|
||||||
|
...CardBlockRef
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
38
lib/graphql/Fragments/Sidebar/TeaserCard.graphql
Normal file
38
lib/graphql/Fragments/Sidebar/TeaserCard.graphql
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
#import "../AccountPage/Ref.graphql"
|
||||||
|
#import "../ContentPage/Ref.graphql"
|
||||||
|
#import "../LoyaltyPage/Ref.graphql"
|
||||||
|
|
||||||
|
#import "../PageLink/AccountPageLink.graphql"
|
||||||
|
#import "../PageLink/ContentPageLink.graphql"
|
||||||
|
#import "../PageLink/LoyaltyPageLink.graphql"
|
||||||
|
|
||||||
|
#import "../Blocks/TeaserCard.graphql"
|
||||||
|
#import "../Blocks/Refs/TeaserCard.graphql"
|
||||||
|
|
||||||
|
fragment TeaserCardSidebar_ContentPage on ContentPageSidebarTeaserCard {
|
||||||
|
__typename
|
||||||
|
teaser_card {
|
||||||
|
theme
|
||||||
|
teaser_cardConnection {
|
||||||
|
edges {
|
||||||
|
node {
|
||||||
|
__typename
|
||||||
|
...TeaserCardBlock
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fragment TeaserCardSidebar_ContentPageRefs on ContentPageSidebarTeaserCard {
|
||||||
|
teaser_card {
|
||||||
|
teaser_cardConnection {
|
||||||
|
edges {
|
||||||
|
node {
|
||||||
|
__typename
|
||||||
|
...TeaserCardBlockRef
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -19,10 +19,12 @@ query GetContactConfig($locale: String!) {
|
|||||||
phone {
|
phone {
|
||||||
number
|
number
|
||||||
name
|
name
|
||||||
|
footnote
|
||||||
}
|
}
|
||||||
phone_loyalty {
|
phone_loyalty {
|
||||||
name
|
name
|
||||||
number
|
number
|
||||||
|
footnote
|
||||||
}
|
}
|
||||||
title
|
title
|
||||||
visiting_address {
|
visiting_address {
|
||||||
|
|||||||
@@ -13,6 +13,9 @@
|
|||||||
#import "../../Fragments/Sidebar/Content.graphql"
|
#import "../../Fragments/Sidebar/Content.graphql"
|
||||||
#import "../../Fragments/Sidebar/DynamicContent.graphql"
|
#import "../../Fragments/Sidebar/DynamicContent.graphql"
|
||||||
#import "../../Fragments/Sidebar/JoinLoyaltyContact.graphql"
|
#import "../../Fragments/Sidebar/JoinLoyaltyContact.graphql"
|
||||||
|
#import "../../Fragments/Sidebar/TeaserCard.graphql"
|
||||||
|
#import "../../Fragments/Sidebar/ScriptedCard.graphql"
|
||||||
|
#import "../../Fragments/Sidebar/QuickLinks.graphql"
|
||||||
|
|
||||||
query GetContentPage($locale: String!, $uid: String!) {
|
query GetContentPage($locale: String!, $uid: String!) {
|
||||||
content_page(uid: $uid, locale: $locale) {
|
content_page(uid: $uid, locale: $locale) {
|
||||||
@@ -28,6 +31,9 @@ query GetContentPage($locale: String!, $uid: String!) {
|
|||||||
...ContentSidebar_ContentPage
|
...ContentSidebar_ContentPage
|
||||||
...DynamicContentSidebar_ContentPage
|
...DynamicContentSidebar_ContentPage
|
||||||
...JoinLoyaltyContactSidebar_ContentPage
|
...JoinLoyaltyContactSidebar_ContentPage
|
||||||
|
...ScriptedCardSidebar_ContentPage
|
||||||
|
...TeaserCardSidebar_ContentPage
|
||||||
|
...QuickLinksSidebar_ContentPage
|
||||||
}
|
}
|
||||||
system {
|
system {
|
||||||
...System
|
...System
|
||||||
@@ -77,6 +83,22 @@ query GetContentPageRefs($locale: String!, $uid: String!) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
sidebar {
|
||||||
|
__typename
|
||||||
|
...ContentSidebar_ContentPageRefs
|
||||||
|
...JoinLoyaltyContactSidebar_ContentPageRefs
|
||||||
|
...ScriptedCardSidebar_ContentPageRefs
|
||||||
|
...TeaserCardSidebar_ContentPageRefs
|
||||||
|
...QuickLinksSidebar_ContentPageRefs
|
||||||
|
}
|
||||||
|
system {
|
||||||
|
...System
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
query GetContentPageBlocksRefs($locale: String!, $uid: String!) {
|
||||||
|
content_page(locale: $locale, uid: $uid) {
|
||||||
blocks {
|
blocks {
|
||||||
__typename
|
__typename
|
||||||
...Accordion_ContentPageRefs
|
...Accordion_ContentPageRefs
|
||||||
@@ -87,14 +109,6 @@ query GetContentPageRefs($locale: String!, $uid: String!) {
|
|||||||
...TextCols_ContentPageRef
|
...TextCols_ContentPageRef
|
||||||
...UspGrid_ContentPageRefs
|
...UspGrid_ContentPageRefs
|
||||||
}
|
}
|
||||||
sidebar {
|
|
||||||
__typename
|
|
||||||
...ContentSidebar_ContentPageRefs
|
|
||||||
...JoinLoyaltyContactSidebar_ContentPageRefs
|
|
||||||
}
|
|
||||||
system {
|
|
||||||
...System
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
39
lib/graphql/Query/SiteConfig.graphql
Normal file
39
lib/graphql/Query/SiteConfig.graphql
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
#import "../Fragments/System.graphql"
|
||||||
|
|
||||||
|
#import "../Fragments/Alert.graphql"
|
||||||
|
|
||||||
|
query GetSiteConfig($locale: String!) {
|
||||||
|
all_site_config(limit: 1, locale: $locale) {
|
||||||
|
items {
|
||||||
|
sitewide_alert {
|
||||||
|
booking_widget_disabled
|
||||||
|
alertConnection {
|
||||||
|
edges {
|
||||||
|
node {
|
||||||
|
...Alert
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
query GetSiteConfigRef($locale: String!) {
|
||||||
|
all_site_config(limit: 1, locale: $locale) {
|
||||||
|
items {
|
||||||
|
sitewide_alert {
|
||||||
|
alertConnection {
|
||||||
|
edges {
|
||||||
|
node {
|
||||||
|
...AlertRef
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
system {
|
||||||
|
...System
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -16,6 +16,22 @@ export const getProfileSafely = cache(
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
export const getCreditCardsSafely = cache(
|
||||||
|
async function getMemoizedCreditCardsSafely() {
|
||||||
|
return serverClient().user.safeCreditCards()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
export const getHotelData = cache(async function getMemoizedHotelData(
|
||||||
|
hotelId: string,
|
||||||
|
language: string
|
||||||
|
) {
|
||||||
|
return serverClient().hotel.hotelData.get({
|
||||||
|
hotelId,
|
||||||
|
language,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
export const getFooter = cache(async function getMemoizedFooter() {
|
export const getFooter = cache(async function getMemoizedFooter() {
|
||||||
return serverClient().contentstack.base.footer()
|
return serverClient().contentstack.base.footer()
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -14,7 +14,8 @@ import { removeMultipleSlashes } from "@/utils/url"
|
|||||||
|
|
||||||
import { systemSchema } from "../schemas/system"
|
import { systemSchema } from "../schemas/system"
|
||||||
|
|
||||||
import { Image } from "@/types/image"
|
import { AlertTypeEnum } from "@/types/enums/alert"
|
||||||
|
import type { Image } from "@/types/image"
|
||||||
|
|
||||||
// Help me write this zod schema based on the type ContactConfig
|
// Help me write this zod schema based on the type ContactConfig
|
||||||
export const validateContactConfigSchema = z.object({
|
export const validateContactConfigSchema = z.object({
|
||||||
@@ -39,10 +40,12 @@ export const validateContactConfigSchema = z.object({
|
|||||||
phone: z.object({
|
phone: z.object({
|
||||||
number: z.string().nullable(),
|
number: z.string().nullable(),
|
||||||
name: z.string().nullable(),
|
name: z.string().nullable(),
|
||||||
|
footnote: z.string().nullable(),
|
||||||
}),
|
}),
|
||||||
phone_loyalty: z.object({
|
phone_loyalty: z.object({
|
||||||
number: z.string().nullable(),
|
number: z.string().nullable(),
|
||||||
name: z.string().nullable(),
|
name: z.string().nullable(),
|
||||||
|
footnote: z.string().nullable(),
|
||||||
}),
|
}),
|
||||||
visiting_address: z.object({
|
visiting_address: z.object({
|
||||||
zip: z.string().nullable(),
|
zip: z.string().nullable(),
|
||||||
@@ -538,6 +541,7 @@ export const headerRefsSchema = z
|
|||||||
})
|
})
|
||||||
|
|
||||||
const linkUnionSchema = z.discriminatedUnion("__typename", [
|
const linkUnionSchema = z.discriminatedUnion("__typename", [
|
||||||
|
pageLinks.accountPageSchema,
|
||||||
pageLinks.contentPageSchema,
|
pageLinks.contentPageSchema,
|
||||||
pageLinks.hotelPageSchema,
|
pageLinks.hotelPageSchema,
|
||||||
pageLinks.loyaltyPageSchema,
|
pageLinks.loyaltyPageSchema,
|
||||||
@@ -660,3 +664,166 @@ export const headerSchema = z
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
export const alertSchema = z
|
||||||
|
.object({
|
||||||
|
type: z.nativeEnum(AlertTypeEnum),
|
||||||
|
text: z.string(),
|
||||||
|
heading: z.string(),
|
||||||
|
phone_contact: z.object({
|
||||||
|
display_text: z.string(),
|
||||||
|
phone_number: z.string().nullable(),
|
||||||
|
footnote: z.string().nullable(),
|
||||||
|
}),
|
||||||
|
has_link: z.boolean(),
|
||||||
|
link: linkAndTitleSchema,
|
||||||
|
has_sidepeek_button: z.boolean(),
|
||||||
|
sidepeek_button: z.object({
|
||||||
|
cta_text: z.string(),
|
||||||
|
}),
|
||||||
|
sidepeek_content: z.object({
|
||||||
|
heading: z.string(),
|
||||||
|
content: z.object({
|
||||||
|
json: z.any(),
|
||||||
|
embedded_itemsConnection: z.object({
|
||||||
|
edges: z.array(
|
||||||
|
z.object({
|
||||||
|
node: z
|
||||||
|
.discriminatedUnion("__typename", [
|
||||||
|
pageLinks.accountPageSchema,
|
||||||
|
pageLinks.contentPageSchema,
|
||||||
|
pageLinks.hotelPageSchema,
|
||||||
|
pageLinks.loyaltyPageSchema,
|
||||||
|
])
|
||||||
|
.transform((data) => {
|
||||||
|
const link = pageLinks.transform(data)
|
||||||
|
if (link) {
|
||||||
|
return link
|
||||||
|
}
|
||||||
|
return data
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
),
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
.transform(
|
||||||
|
({
|
||||||
|
type,
|
||||||
|
heading,
|
||||||
|
text,
|
||||||
|
phone_contact,
|
||||||
|
has_link,
|
||||||
|
link,
|
||||||
|
has_sidepeek_button,
|
||||||
|
sidepeek_button,
|
||||||
|
sidepeek_content,
|
||||||
|
}) => {
|
||||||
|
const hasLink = has_link && link.link
|
||||||
|
return {
|
||||||
|
type,
|
||||||
|
text,
|
||||||
|
heading,
|
||||||
|
phoneContact:
|
||||||
|
phone_contact.display_text && phone_contact.phone_number
|
||||||
|
? {
|
||||||
|
displayText: phone_contact.display_text,
|
||||||
|
phoneNumber: phone_contact.phone_number,
|
||||||
|
footnote: phone_contact.footnote,
|
||||||
|
}
|
||||||
|
: null,
|
||||||
|
hasSidepeekButton: !!has_sidepeek_button,
|
||||||
|
link: hasLink
|
||||||
|
? {
|
||||||
|
url: link.link.url,
|
||||||
|
title: link.title,
|
||||||
|
}
|
||||||
|
: null,
|
||||||
|
sidepeekButton:
|
||||||
|
!hasLink && has_sidepeek_button ? sidepeek_button : null,
|
||||||
|
sidepeekContent:
|
||||||
|
!hasLink && has_sidepeek_button ? sidepeek_content : null,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
export const siteConfigSchema = z
|
||||||
|
.object({
|
||||||
|
all_site_config: z.object({
|
||||||
|
items: z
|
||||||
|
.array(
|
||||||
|
z.object({
|
||||||
|
sitewide_alert: z.object({
|
||||||
|
booking_widget_disabled: z.boolean(),
|
||||||
|
alertConnection: z.object({
|
||||||
|
edges: z
|
||||||
|
.array(
|
||||||
|
z.object({
|
||||||
|
node: alertSchema,
|
||||||
|
})
|
||||||
|
)
|
||||||
|
.max(1),
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
)
|
||||||
|
.max(1),
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
.transform((data) => {
|
||||||
|
if (!data.all_site_config.items.length) {
|
||||||
|
return {
|
||||||
|
sitewideAlert: null,
|
||||||
|
bookingWidgetDisabled: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const { sitewide_alert } = data.all_site_config.items[0]
|
||||||
|
|
||||||
|
return {
|
||||||
|
sitewideAlert: sitewide_alert.alertConnection.edges[0]?.node || null,
|
||||||
|
bookingWidgetDisabled: sitewide_alert.booking_widget_disabled,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const sidepeekContentRefSchema = z.object({
|
||||||
|
content: z.object({
|
||||||
|
embedded_itemsConnection: z.object({
|
||||||
|
edges: z.array(
|
||||||
|
z.object({
|
||||||
|
node: z.discriminatedUnion("__typename", [
|
||||||
|
pageLinks.accountPageRefSchema,
|
||||||
|
pageLinks.contentPageRefSchema,
|
||||||
|
pageLinks.hotelPageRefSchema,
|
||||||
|
pageLinks.loyaltyPageRefSchema,
|
||||||
|
]),
|
||||||
|
})
|
||||||
|
),
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
|
||||||
|
const alertConnectionRefSchema = z.object({
|
||||||
|
edges: z.array(
|
||||||
|
z.object({
|
||||||
|
node: z.object({
|
||||||
|
link: linkRefsSchema,
|
||||||
|
sidepeek_content: sidepeekContentRefSchema,
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
),
|
||||||
|
})
|
||||||
|
|
||||||
|
export const siteConfigRefSchema = z.object({
|
||||||
|
all_site_config: z.object({
|
||||||
|
items: z.array(
|
||||||
|
z.object({
|
||||||
|
sitewide_alert: z.object({
|
||||||
|
alertConnection: alertConnectionRefSchema,
|
||||||
|
}),
|
||||||
|
system: systemSchema,
|
||||||
|
})
|
||||||
|
),
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import { metrics } from "@opentelemetry/api"
|
import { Lang } from "@/constants/languages"
|
||||||
|
|
||||||
import { GetContactConfig } from "@/lib/graphql/Query/ContactConfig.graphql"
|
import { GetContactConfig } from "@/lib/graphql/Query/ContactConfig.graphql"
|
||||||
import {
|
import {
|
||||||
GetCurrentFooter,
|
GetCurrentFooter,
|
||||||
@@ -11,6 +10,10 @@ import {
|
|||||||
} from "@/lib/graphql/Query/Current/Header.graphql"
|
} from "@/lib/graphql/Query/Current/Header.graphql"
|
||||||
import { GetFooter, GetFooterRef } from "@/lib/graphql/Query/Footer.graphql"
|
import { GetFooter, GetFooterRef } from "@/lib/graphql/Query/Footer.graphql"
|
||||||
import { GetHeader, GetHeaderRef } from "@/lib/graphql/Query/Header.graphql"
|
import { GetHeader, GetHeaderRef } from "@/lib/graphql/Query/Header.graphql"
|
||||||
|
import {
|
||||||
|
GetSiteConfig,
|
||||||
|
GetSiteConfigRef,
|
||||||
|
} from "@/lib/graphql/Query/SiteConfig.graphql"
|
||||||
import { request } from "@/lib/graphql/request"
|
import { request } from "@/lib/graphql/request"
|
||||||
import { notFound } from "@/server/errors/trpc"
|
import { notFound } from "@/server/errors/trpc"
|
||||||
import { contentstackBaseProcedure, router } from "@/server/trpc"
|
import { contentstackBaseProcedure, router } from "@/server/trpc"
|
||||||
@@ -31,13 +34,50 @@ import {
|
|||||||
type GetCurrentHeaderData,
|
type GetCurrentHeaderData,
|
||||||
headerRefsSchema,
|
headerRefsSchema,
|
||||||
headerSchema,
|
headerSchema,
|
||||||
|
siteConfigRefSchema,
|
||||||
|
siteConfigSchema,
|
||||||
validateContactConfigSchema,
|
validateContactConfigSchema,
|
||||||
validateCurrentFooterConfigSchema,
|
validateCurrentFooterConfigSchema,
|
||||||
validateCurrentHeaderConfigSchema,
|
validateCurrentHeaderConfigSchema,
|
||||||
validateFooterConfigSchema,
|
validateFooterConfigSchema,
|
||||||
validateFooterRefConfigSchema,
|
validateFooterRefConfigSchema,
|
||||||
} from "./output"
|
} from "./output"
|
||||||
import { getConnections, getFooterConnections } from "./utils"
|
import {
|
||||||
|
getContactConfigCounter,
|
||||||
|
getContactConfigFailCounter,
|
||||||
|
getContactConfigSuccessCounter,
|
||||||
|
getCurrentFooterCounter,
|
||||||
|
getCurrentFooterFailCounter,
|
||||||
|
getCurrentFooterRefCounter,
|
||||||
|
getCurrentFooterSuccessCounter,
|
||||||
|
getCurrentHeaderCounter,
|
||||||
|
getCurrentHeaderFailCounter,
|
||||||
|
getCurrentHeaderRefCounter,
|
||||||
|
getCurrentHeaderSuccessCounter,
|
||||||
|
getFooterCounter,
|
||||||
|
getFooterFailCounter,
|
||||||
|
getFooterRefCounter,
|
||||||
|
getFooterRefFailCounter,
|
||||||
|
getFooterRefSuccessCounter,
|
||||||
|
getFooterSuccessCounter,
|
||||||
|
getHeaderCounter,
|
||||||
|
getHeaderFailCounter,
|
||||||
|
getHeaderRefsCounter,
|
||||||
|
getHeaderRefsFailCounter,
|
||||||
|
getHeaderRefsSuccessCounter,
|
||||||
|
getHeaderSuccessCounter,
|
||||||
|
getSiteConfigCounter,
|
||||||
|
getSiteConfigFailCounter,
|
||||||
|
getSiteConfigRefCounter,
|
||||||
|
getSiteConfigRefFailCounter,
|
||||||
|
getSiteConfigRefSuccessCounter,
|
||||||
|
getSiteConfigSuccessCounter,
|
||||||
|
} from "./telemetry"
|
||||||
|
import {
|
||||||
|
getAlertPhoneContactData,
|
||||||
|
getConnections,
|
||||||
|
getFooterConnections,
|
||||||
|
} from "./utils"
|
||||||
|
|
||||||
import type {
|
import type {
|
||||||
FooterDataRaw,
|
FooterDataRaw,
|
||||||
@@ -47,157 +87,77 @@ import type {
|
|||||||
GetHeader as GetHeaderData,
|
GetHeader as GetHeaderData,
|
||||||
GetHeaderRefs,
|
GetHeaderRefs,
|
||||||
} from "@/types/trpc/routers/contentstack/header"
|
} from "@/types/trpc/routers/contentstack/header"
|
||||||
|
import type {
|
||||||
|
GetSiteConfigData,
|
||||||
|
GetSiteConfigRefData,
|
||||||
|
} from "@/types/trpc/routers/contentstack/siteConfig"
|
||||||
|
|
||||||
const meter = metrics.getMeter("trpc.contentstack.base")
|
async function getContactConfig(lang: Lang) {
|
||||||
// OpenTelemetry metrics: ContactConfig
|
getContactConfigCounter.add(1, { lang })
|
||||||
const getContactConfigCounter = meter.createCounter(
|
console.info(
|
||||||
"trpc.contentstack.contactConfig.get"
|
"contentstack.contactConfig start",
|
||||||
)
|
JSON.stringify({ query: { lang } })
|
||||||
const getContactConfigSuccessCounter = meter.createCounter(
|
)
|
||||||
"trpc.contentstack.contactConfig.get-success"
|
const response = await request<ContactConfigData>(
|
||||||
)
|
GetContactConfig,
|
||||||
const getContactConfigFailCounter = meter.createCounter(
|
{
|
||||||
"trpc.contentstack.contactConfig.get-fail"
|
locale: lang,
|
||||||
)
|
},
|
||||||
// OpenTelemetry metrics: CurrentHeader
|
{
|
||||||
const getCurrentHeaderRefCounter = meter.createCounter(
|
cache: "force-cache",
|
||||||
"trpc.contentstack.currentHeader.ref.get"
|
next: {
|
||||||
)
|
tags: [`${lang}:contact`],
|
||||||
const getCurrentHeaderRefSuccessCounter = meter.createCounter(
|
},
|
||||||
"trpc.contentstack.currentHeader.ref.get-success"
|
}
|
||||||
)
|
)
|
||||||
const getCurrentHeaderRefFailCounter = meter.createCounter(
|
|
||||||
"trpc.contentstack.currentHeader.ref.get-fail"
|
|
||||||
)
|
|
||||||
const getCurrentHeaderCounter = meter.createCounter(
|
|
||||||
"trpc.contentstack.currentHeader.get"
|
|
||||||
)
|
|
||||||
const getCurrentHeaderSuccessCounter = meter.createCounter(
|
|
||||||
"trpc.contentstack.currentHeader.get-success"
|
|
||||||
)
|
|
||||||
const getCurrentHeaderFailCounter = meter.createCounter(
|
|
||||||
"trpc.contentstack.currentHeader.get-fail"
|
|
||||||
)
|
|
||||||
|
|
||||||
// OpenTelemetry metrics: Header
|
if (!response.data) {
|
||||||
const getHeaderRefsCounter = meter.createCounter(
|
const notFoundError = notFound(response)
|
||||||
"trpc.contentstack.header.ref.get"
|
|
||||||
)
|
|
||||||
const getHeaderRefsSuccessCounter = meter.createCounter(
|
|
||||||
"trpc.contentstack.header.ref.get-success"
|
|
||||||
)
|
|
||||||
const getHeaderRefsFailCounter = meter.createCounter(
|
|
||||||
"trpc.contentstack.header.ref.get-fail"
|
|
||||||
)
|
|
||||||
const getHeaderCounter = meter.createCounter("trpc.contentstack.header.get")
|
|
||||||
const getHeaderSuccessCounter = meter.createCounter(
|
|
||||||
"trpc.contentstack.header.get-success"
|
|
||||||
)
|
|
||||||
const getHeaderFailCounter = meter.createCounter(
|
|
||||||
"trpc.contentstack.header.get-fail"
|
|
||||||
)
|
|
||||||
|
|
||||||
// OpenTelemetry metrics: CurrentHeader
|
getContactConfigFailCounter.add(1, {
|
||||||
const getCurrentFooterRefCounter = meter.createCounter(
|
lang,
|
||||||
"trpc.contentstack.currentFooter.ref.get"
|
error_type: "not_found",
|
||||||
)
|
error: JSON.stringify({ code: notFoundError.code }),
|
||||||
const getCurrentFooterRefSuccessCounter = meter.createCounter(
|
})
|
||||||
"trpc.contentstack.currentFooter.ref.get-success"
|
|
||||||
)
|
|
||||||
const getCurrentFooterRefFailCounter = meter.createCounter(
|
|
||||||
"trpc.contentstack.currentFooter.ref.get-fail"
|
|
||||||
)
|
|
||||||
const getCurrentFooterCounter = meter.createCounter(
|
|
||||||
"trpc.contentstack.currentFooter.get"
|
|
||||||
)
|
|
||||||
const getCurrentFooterSuccessCounter = meter.createCounter(
|
|
||||||
"trpc.contentstack.currentFooter.get-success"
|
|
||||||
)
|
|
||||||
const getCurrentFooterFailCounter = meter.createCounter(
|
|
||||||
"trpc.contentstack.currentFooter.get-fail"
|
|
||||||
)
|
|
||||||
|
|
||||||
// OpenTelemetry metrics: Footer
|
console.error(
|
||||||
const getFooterRefCounter = meter.createCounter(
|
"contentstack.config not found error",
|
||||||
"trpc.contentstack.footer.ref.get"
|
JSON.stringify({ query: { lang }, error: { code: notFoundError.code } })
|
||||||
)
|
)
|
||||||
const getFooterRefSuccessCounter = meter.createCounter(
|
|
||||||
"trpc.contentstack.footer.ref.get-success"
|
throw notFoundError
|
||||||
)
|
}
|
||||||
const getFooterRefFailCounter = meter.createCounter(
|
|
||||||
"trpc.contentstack.footer.ref.get-fail"
|
const validatedContactConfigConfig = validateContactConfigSchema.safeParse(
|
||||||
)
|
response.data
|
||||||
const getFooterCounter = meter.createCounter("trpc.contentstack.footer.get")
|
)
|
||||||
const getFooterSuccessCounter = meter.createCounter(
|
|
||||||
"trpc.contentstack.footer.get-success"
|
if (!validatedContactConfigConfig.success) {
|
||||||
)
|
getContactConfigFailCounter.add(1, {
|
||||||
const getFooterFailCounter = meter.createCounter(
|
lang,
|
||||||
"trpc.contentstack.footer.get-fail"
|
error_type: "validation_error",
|
||||||
)
|
error: JSON.stringify(validatedContactConfigConfig.error),
|
||||||
|
})
|
||||||
|
console.error(
|
||||||
|
"contentstack.contactConfig validation error",
|
||||||
|
JSON.stringify({
|
||||||
|
query: { lang },
|
||||||
|
error: validatedContactConfigConfig.error,
|
||||||
|
})
|
||||||
|
)
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
getContactConfigSuccessCounter.add(1, { lang })
|
||||||
|
console.info(
|
||||||
|
"contentstack.contactConfig success",
|
||||||
|
JSON.stringify({ query: { lang } })
|
||||||
|
)
|
||||||
|
return validatedContactConfigConfig.data.all_contact_config.items[0]
|
||||||
|
}
|
||||||
|
|
||||||
export const baseQueryRouter = router({
|
export const baseQueryRouter = router({
|
||||||
contact: contentstackBaseProcedure.query(async ({ ctx }) => {
|
contact: contentstackBaseProcedure.query(async ({ ctx }) => {
|
||||||
const { lang } = ctx
|
return await getContactConfig(ctx.lang)
|
||||||
getContactConfigCounter.add(1, { lang })
|
|
||||||
console.info(
|
|
||||||
"contentstack.contactConfig start",
|
|
||||||
JSON.stringify({ query: { lang } })
|
|
||||||
)
|
|
||||||
const response = await request<ContactConfigData>(
|
|
||||||
GetContactConfig,
|
|
||||||
{
|
|
||||||
locale: lang,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
cache: "force-cache",
|
|
||||||
next: {
|
|
||||||
tags: [`${lang}:contact`],
|
|
||||||
},
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
if (!response.data) {
|
|
||||||
const notFoundError = notFound(response)
|
|
||||||
|
|
||||||
getContactConfigFailCounter.add(1, {
|
|
||||||
lang,
|
|
||||||
error_type: "not_found",
|
|
||||||
error: JSON.stringify({ code: notFoundError.code }),
|
|
||||||
})
|
|
||||||
|
|
||||||
console.error(
|
|
||||||
"contentstack.config not found error",
|
|
||||||
JSON.stringify({ query: { lang }, error: { code: notFoundError.code } })
|
|
||||||
)
|
|
||||||
|
|
||||||
throw notFoundError
|
|
||||||
}
|
|
||||||
|
|
||||||
const validatedContactConfigConfig = validateContactConfigSchema.safeParse(
|
|
||||||
response.data
|
|
||||||
)
|
|
||||||
|
|
||||||
if (!validatedContactConfigConfig.success) {
|
|
||||||
getContactConfigFailCounter.add(1, {
|
|
||||||
lang,
|
|
||||||
error_type: "validation_error",
|
|
||||||
error: JSON.stringify(validatedContactConfigConfig.error),
|
|
||||||
})
|
|
||||||
console.error(
|
|
||||||
"contentstack.contactConfig validation error",
|
|
||||||
JSON.stringify({
|
|
||||||
query: { lang },
|
|
||||||
error: validatedContactConfigConfig.error,
|
|
||||||
})
|
|
||||||
)
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
getContactConfigSuccessCounter.add(1, { lang })
|
|
||||||
console.info(
|
|
||||||
"contentstack.contactConfig success",
|
|
||||||
JSON.stringify({ query: { lang } })
|
|
||||||
)
|
|
||||||
return validatedContactConfigConfig.data.all_contact_config.items[0]
|
|
||||||
}),
|
}),
|
||||||
header: contentstackBaseProcedure.query(async ({ ctx }) => {
|
header: contentstackBaseProcedure.query(async ({ ctx }) => {
|
||||||
const { lang } = ctx
|
const { lang } = ctx
|
||||||
@@ -652,4 +612,149 @@ export const baseQueryRouter = router({
|
|||||||
|
|
||||||
return validatedFooterConfig.data
|
return validatedFooterConfig.data
|
||||||
}),
|
}),
|
||||||
|
siteConfig: contentstackBaseProcedure.query(async ({ ctx }) => {
|
||||||
|
const { lang } = ctx
|
||||||
|
|
||||||
|
getSiteConfigRefCounter.add(1, { lang })
|
||||||
|
console.info(
|
||||||
|
"contentstack.siteConfig.ref start",
|
||||||
|
JSON.stringify({ query: { lang } })
|
||||||
|
)
|
||||||
|
const responseRef = await request<GetSiteConfigRefData>(
|
||||||
|
GetSiteConfigRef,
|
||||||
|
{
|
||||||
|
locale: lang,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
cache: "force-cache",
|
||||||
|
next: {
|
||||||
|
tags: [generateRefsResponseTag(lang, "siteConfig")],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
if (!responseRef.data) {
|
||||||
|
const notFoundError = notFound(responseRef)
|
||||||
|
getSiteConfigRefFailCounter.add(1, {
|
||||||
|
lang,
|
||||||
|
error_type: "not_found",
|
||||||
|
error: JSON.stringify({ code: notFoundError.code }),
|
||||||
|
})
|
||||||
|
console.error(
|
||||||
|
"contentstack.siteConfig.refs not found error",
|
||||||
|
JSON.stringify({
|
||||||
|
query: {
|
||||||
|
lang,
|
||||||
|
},
|
||||||
|
error: { code: notFoundError.code },
|
||||||
|
})
|
||||||
|
)
|
||||||
|
throw notFoundError
|
||||||
|
}
|
||||||
|
|
||||||
|
const validatedSiteConfigRef = siteConfigRefSchema.safeParse(
|
||||||
|
responseRef.data
|
||||||
|
)
|
||||||
|
|
||||||
|
if (!validatedSiteConfigRef.success) {
|
||||||
|
getSiteConfigRefFailCounter.add(1, {
|
||||||
|
lang,
|
||||||
|
error_type: "validation_error",
|
||||||
|
error: JSON.stringify(validatedSiteConfigRef.error),
|
||||||
|
})
|
||||||
|
console.error(
|
||||||
|
"contentstack.siteConfig.refs validation error",
|
||||||
|
JSON.stringify({
|
||||||
|
query: {
|
||||||
|
lang,
|
||||||
|
},
|
||||||
|
error: validatedSiteConfigRef.error,
|
||||||
|
})
|
||||||
|
)
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
getSiteConfigRefSuccessCounter.add(1, { lang })
|
||||||
|
console.info(
|
||||||
|
"contentstack.siteConfig.refs success",
|
||||||
|
JSON.stringify({ query: { lang } })
|
||||||
|
)
|
||||||
|
|
||||||
|
getSiteConfigCounter.add(1, { lang })
|
||||||
|
console.info(
|
||||||
|
"contentstack.siteConfig start",
|
||||||
|
JSON.stringify({ query: { lang } })
|
||||||
|
)
|
||||||
|
const [siteConfigResponse, contactConfig] = await Promise.all([
|
||||||
|
request<GetSiteConfigData>(
|
||||||
|
GetSiteConfig,
|
||||||
|
{
|
||||||
|
locale: lang,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
cache: "force-cache",
|
||||||
|
next: {
|
||||||
|
tags: [`${lang}:siteConfig`],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
),
|
||||||
|
getContactConfig(lang),
|
||||||
|
])
|
||||||
|
|
||||||
|
if (!siteConfigResponse.data) {
|
||||||
|
const notFoundError = notFound(siteConfigResponse)
|
||||||
|
|
||||||
|
getSiteConfigFailCounter.add(1, {
|
||||||
|
lang,
|
||||||
|
error_type: "not_found",
|
||||||
|
error: JSON.stringify({ code: notFoundError.code }),
|
||||||
|
})
|
||||||
|
|
||||||
|
console.error(
|
||||||
|
"contentstack.siteConfig not found error",
|
||||||
|
JSON.stringify({ query: { lang }, error: { code: notFoundError.code } })
|
||||||
|
)
|
||||||
|
|
||||||
|
throw notFoundError
|
||||||
|
}
|
||||||
|
|
||||||
|
const validatedSiteConfig = siteConfigSchema.safeParse(
|
||||||
|
siteConfigResponse.data
|
||||||
|
)
|
||||||
|
|
||||||
|
if (!validatedSiteConfig.success) {
|
||||||
|
getSiteConfigFailCounter.add(1, {
|
||||||
|
lang,
|
||||||
|
error_type: "validation_error",
|
||||||
|
error: JSON.stringify(validatedSiteConfig.error),
|
||||||
|
})
|
||||||
|
console.error(
|
||||||
|
"contentstack.siteConfig validation error",
|
||||||
|
JSON.stringify({
|
||||||
|
query: { lang },
|
||||||
|
error: validatedSiteConfig.error,
|
||||||
|
})
|
||||||
|
)
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
getSiteConfigSuccessCounter.add(1, { lang })
|
||||||
|
console.info(
|
||||||
|
"contentstack.siteConfig success",
|
||||||
|
JSON.stringify({ query: { lang } })
|
||||||
|
)
|
||||||
|
|
||||||
|
const { sitewideAlert } = validatedSiteConfig.data
|
||||||
|
|
||||||
|
return {
|
||||||
|
...validatedSiteConfig.data,
|
||||||
|
sitewideAlert: sitewideAlert
|
||||||
|
? {
|
||||||
|
...sitewideAlert,
|
||||||
|
phone_contact: contactConfig
|
||||||
|
? getAlertPhoneContactData(sitewideAlert, contactConfig)
|
||||||
|
: null,
|
||||||
|
}
|
||||||
|
: null,
|
||||||
|
}
|
||||||
|
}),
|
||||||
})
|
})
|
||||||
|
|||||||
112
server/routers/contentstack/base/telemetry.ts
Normal file
112
server/routers/contentstack/base/telemetry.ts
Normal file
@@ -0,0 +1,112 @@
|
|||||||
|
import { metrics } from "@opentelemetry/api"
|
||||||
|
|
||||||
|
const meter = metrics.getMeter("trpc.contentstack.base")
|
||||||
|
// OpenTelemetry metrics: ContactConfig
|
||||||
|
export const getContactConfigCounter = meter.createCounter(
|
||||||
|
"trpc.contentstack.contactConfig.get"
|
||||||
|
)
|
||||||
|
export const getContactConfigSuccessCounter = meter.createCounter(
|
||||||
|
"trpc.contentstack.contactConfig.get-success"
|
||||||
|
)
|
||||||
|
export const getContactConfigFailCounter = meter.createCounter(
|
||||||
|
"trpc.contentstack.contactConfig.get-fail"
|
||||||
|
)
|
||||||
|
// OpenTelemetry metrics: CurrentHeader
|
||||||
|
export const getCurrentHeaderRefCounter = meter.createCounter(
|
||||||
|
"trpc.contentstack.currentHeader.ref.get"
|
||||||
|
)
|
||||||
|
export const getCurrentHeaderRefSuccessCounter = meter.createCounter(
|
||||||
|
"trpc.contentstack.currentHeader.ref.get-success"
|
||||||
|
)
|
||||||
|
export const getCurrentHeaderRefFailCounter = meter.createCounter(
|
||||||
|
"trpc.contentstack.currentHeader.ref.get-fail"
|
||||||
|
)
|
||||||
|
export const getCurrentHeaderCounter = meter.createCounter(
|
||||||
|
"trpc.contentstack.currentHeader.get"
|
||||||
|
)
|
||||||
|
export const getCurrentHeaderSuccessCounter = meter.createCounter(
|
||||||
|
"trpc.contentstack.currentHeader.get-success"
|
||||||
|
)
|
||||||
|
export const getCurrentHeaderFailCounter = meter.createCounter(
|
||||||
|
"trpc.contentstack.currentHeader.get-fail"
|
||||||
|
)
|
||||||
|
|
||||||
|
// OpenTelemetry metrics: Header
|
||||||
|
export const getHeaderRefsCounter = meter.createCounter(
|
||||||
|
"trpc.contentstack.header.ref.get"
|
||||||
|
)
|
||||||
|
export const getHeaderRefsSuccessCounter = meter.createCounter(
|
||||||
|
"trpc.contentstack.header.ref.get-success"
|
||||||
|
)
|
||||||
|
export const getHeaderRefsFailCounter = meter.createCounter(
|
||||||
|
"trpc.contentstack.header.ref.get-fail"
|
||||||
|
)
|
||||||
|
export const getHeaderCounter = meter.createCounter(
|
||||||
|
"trpc.contentstack.header.get"
|
||||||
|
)
|
||||||
|
export const getHeaderSuccessCounter = meter.createCounter(
|
||||||
|
"trpc.contentstack.header.get-success"
|
||||||
|
)
|
||||||
|
export const getHeaderFailCounter = meter.createCounter(
|
||||||
|
"trpc.contentstack.header.get-fail"
|
||||||
|
)
|
||||||
|
|
||||||
|
// OpenTelemetry metrics: CurrentFooter
|
||||||
|
export const getCurrentFooterRefCounter = meter.createCounter(
|
||||||
|
"trpc.contentstack.currentFooter.ref.get"
|
||||||
|
)
|
||||||
|
export const getCurrentFooterRefSuccessCounter = meter.createCounter(
|
||||||
|
"trpc.contentstack.currentFooter.ref.get-success"
|
||||||
|
)
|
||||||
|
export const getCurrentFooterRefFailCounter = meter.createCounter(
|
||||||
|
"trpc.contentstack.currentFooter.ref.get-fail"
|
||||||
|
)
|
||||||
|
export const getCurrentFooterCounter = meter.createCounter(
|
||||||
|
"trpc.contentstack.currentFooter.get"
|
||||||
|
)
|
||||||
|
export const getCurrentFooterSuccessCounter = meter.createCounter(
|
||||||
|
"trpc.contentstack.currentFooter.get-success"
|
||||||
|
)
|
||||||
|
export const getCurrentFooterFailCounter = meter.createCounter(
|
||||||
|
"trpc.contentstack.currentFooter.get-fail"
|
||||||
|
)
|
||||||
|
|
||||||
|
// OpenTelemetry metrics: Footer
|
||||||
|
export const getFooterRefCounter = meter.createCounter(
|
||||||
|
"trpc.contentstack.footer.ref.get"
|
||||||
|
)
|
||||||
|
export const getFooterRefSuccessCounter = meter.createCounter(
|
||||||
|
"trpc.contentstack.footer.ref.get-success"
|
||||||
|
)
|
||||||
|
export const getFooterRefFailCounter = meter.createCounter(
|
||||||
|
"trpc.contentstack.footer.ref.get-fail"
|
||||||
|
)
|
||||||
|
export const getFooterCounter = meter.createCounter(
|
||||||
|
"trpc.contentstack.footer.get"
|
||||||
|
)
|
||||||
|
export const getFooterSuccessCounter = meter.createCounter(
|
||||||
|
"trpc.contentstack.footer.get-success"
|
||||||
|
)
|
||||||
|
export const getFooterFailCounter = meter.createCounter(
|
||||||
|
"trpc.contentstack.footer.get-fail"
|
||||||
|
)
|
||||||
|
|
||||||
|
// OpenTelemetry metrics: SiteConfig
|
||||||
|
export const getSiteConfigRefCounter = meter.createCounter(
|
||||||
|
"trpc.contentstack.SiteConfig.ref.get"
|
||||||
|
)
|
||||||
|
export const getSiteConfigRefSuccessCounter = meter.createCounter(
|
||||||
|
"trpc.contentstack.SiteConfig.ref.get-success"
|
||||||
|
)
|
||||||
|
export const getSiteConfigRefFailCounter = meter.createCounter(
|
||||||
|
"trpc.contentstack.SiteConfig.ref.get-fail"
|
||||||
|
)
|
||||||
|
export const getSiteConfigCounter = meter.createCounter(
|
||||||
|
"trpc.contentstack.SiteConfig.get"
|
||||||
|
)
|
||||||
|
export const getSiteConfigSuccessCounter = meter.createCounter(
|
||||||
|
"trpc.contentstack.SiteConfig.get-success"
|
||||||
|
)
|
||||||
|
export const getSiteConfigFailCounter = meter.createCounter(
|
||||||
|
"trpc.contentstack.SiteConfig.get-fail"
|
||||||
|
)
|
||||||
@@ -1,11 +1,12 @@
|
|||||||
import type {
|
import { getValueFromContactConfig } from "@/utils/contactConfig"
|
||||||
FooterLinkItem,
|
|
||||||
FooterRefDataRaw,
|
import type { FooterRefDataRaw } from "@/types/components/footer/footer"
|
||||||
} from "@/types/components/footer/footer"
|
import type { System } from "@/types/requests/system"
|
||||||
import { System } from "@/types/requests/system"
|
import type { Edges } from "@/types/requests/utils/edges"
|
||||||
import { Edges } from "@/types/requests/utils/edges"
|
import type { NodeRefs } from "@/types/requests/utils/refs"
|
||||||
import { NodeRefs } from "@/types/requests/utils/refs"
|
|
||||||
import type { HeaderRefs } from "@/types/trpc/routers/contentstack/header"
|
import type { HeaderRefs } from "@/types/trpc/routers/contentstack/header"
|
||||||
|
import type { Alert } from "@/types/trpc/routers/contentstack/siteConfig"
|
||||||
|
import type { ContactConfig } from "./output"
|
||||||
|
|
||||||
export function getConnections({ header }: HeaderRefs) {
|
export function getConnections({ header }: HeaderRefs) {
|
||||||
const connections: System["system"][] = [header.system]
|
const connections: System["system"][] = [header.system]
|
||||||
@@ -68,3 +69,21 @@ export function getFooterConnections(refs: FooterRefDataRaw) {
|
|||||||
|
|
||||||
return connections
|
return connections
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getAlertPhoneContactData(
|
||||||
|
alert: Alert,
|
||||||
|
contactConfig: ContactConfig
|
||||||
|
) {
|
||||||
|
if (alert.phoneContact) {
|
||||||
|
const { displayText, phoneNumber, footnote } = alert.phoneContact
|
||||||
|
|
||||||
|
return {
|
||||||
|
displayText,
|
||||||
|
phoneNumber: getValueFromContactConfig(phoneNumber, contactConfig),
|
||||||
|
footnote: footnote
|
||||||
|
? getValueFromContactConfig(footnote, contactConfig)
|
||||||
|
: null,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|||||||
@@ -39,6 +39,18 @@ import {
|
|||||||
joinLoyaltyContactRefsSchema,
|
joinLoyaltyContactRefsSchema,
|
||||||
joinLoyaltyContactSchema,
|
joinLoyaltyContactSchema,
|
||||||
} from "../schemas/sidebar/joinLoyaltyContact"
|
} from "../schemas/sidebar/joinLoyaltyContact"
|
||||||
|
import {
|
||||||
|
quickLinksRefschema,
|
||||||
|
quickLinksSchema,
|
||||||
|
} from "../schemas/sidebar/quickLinks"
|
||||||
|
import {
|
||||||
|
scriptedCardRefschema,
|
||||||
|
scriptedCardsSchema,
|
||||||
|
} from "../schemas/sidebar/scriptedCard"
|
||||||
|
import {
|
||||||
|
teaserCardRefschema,
|
||||||
|
teaserCardsSchema,
|
||||||
|
} from "../schemas/sidebar/teaserCard"
|
||||||
import { systemSchema } from "../schemas/system"
|
import { systemSchema } from "../schemas/system"
|
||||||
|
|
||||||
import { ContentPageEnum } from "@/types/enums/contentPage"
|
import { ContentPageEnum } from "@/types/enums/contentPage"
|
||||||
@@ -122,10 +134,31 @@ export const contentPageJoinLoyaltyContact = z
|
|||||||
})
|
})
|
||||||
.merge(joinLoyaltyContactSchema)
|
.merge(joinLoyaltyContactSchema)
|
||||||
|
|
||||||
|
export const contentPageSidebarScriptedCard = z
|
||||||
|
.object({
|
||||||
|
__typename: z.literal(ContentPageEnum.ContentStack.sidebar.ScriptedCard),
|
||||||
|
})
|
||||||
|
.merge(scriptedCardsSchema)
|
||||||
|
|
||||||
|
export const contentPageSidebarTeaserCard = z
|
||||||
|
.object({
|
||||||
|
__typename: z.literal(ContentPageEnum.ContentStack.sidebar.TeaserCard),
|
||||||
|
})
|
||||||
|
.merge(teaserCardsSchema)
|
||||||
|
|
||||||
|
export const contentPageSidebarQuicklinks = z
|
||||||
|
.object({
|
||||||
|
__typename: z.literal(ContentPageEnum.ContentStack.sidebar.QuickLinks),
|
||||||
|
})
|
||||||
|
.merge(quickLinksSchema)
|
||||||
|
|
||||||
export const sidebarSchema = z.discriminatedUnion("__typename", [
|
export const sidebarSchema = z.discriminatedUnion("__typename", [
|
||||||
contentPageSidebarContent,
|
contentPageSidebarContent,
|
||||||
contentPageSidebarDynamicContent,
|
contentPageSidebarDynamicContent,
|
||||||
contentPageJoinLoyaltyContact,
|
contentPageJoinLoyaltyContact,
|
||||||
|
contentPageSidebarScriptedCard,
|
||||||
|
contentPageSidebarTeaserCard,
|
||||||
|
contentPageSidebarQuicklinks,
|
||||||
])
|
])
|
||||||
|
|
||||||
const navigationLinksSchema = z
|
const navigationLinksSchema = z
|
||||||
@@ -238,9 +271,30 @@ const contentPageSidebarJoinLoyaltyContactRef = z
|
|||||||
})
|
})
|
||||||
.merge(joinLoyaltyContactRefsSchema)
|
.merge(joinLoyaltyContactRefsSchema)
|
||||||
|
|
||||||
|
const contentPageSidebarScriptedCardRef = z
|
||||||
|
.object({
|
||||||
|
__typename: z.literal(ContentPageEnum.ContentStack.sidebar.ScriptedCard),
|
||||||
|
})
|
||||||
|
.merge(scriptedCardRefschema)
|
||||||
|
|
||||||
|
const contentPageSidebarTeaserCardRef = z
|
||||||
|
.object({
|
||||||
|
__typename: z.literal(ContentPageEnum.ContentStack.sidebar.TeaserCard),
|
||||||
|
})
|
||||||
|
.merge(teaserCardRefschema)
|
||||||
|
|
||||||
|
const contentPageSidebarQuickLinksRef = z
|
||||||
|
.object({
|
||||||
|
__typename: z.literal(ContentPageEnum.ContentStack.sidebar.QuickLinks),
|
||||||
|
})
|
||||||
|
.merge(quickLinksRefschema)
|
||||||
|
|
||||||
const contentPageSidebarRefsItem = z.discriminatedUnion("__typename", [
|
const contentPageSidebarRefsItem = z.discriminatedUnion("__typename", [
|
||||||
contentPageSidebarContentRef,
|
contentPageSidebarContentRef,
|
||||||
contentPageSidebarJoinLoyaltyContactRef,
|
contentPageSidebarJoinLoyaltyContactRef,
|
||||||
|
contentPageSidebarScriptedCardRef,
|
||||||
|
contentPageSidebarTeaserCardRef,
|
||||||
|
contentPageSidebarQuickLinksRef,
|
||||||
])
|
])
|
||||||
|
|
||||||
const contentPageHeaderRefs = z.object({
|
const contentPageHeaderRefs = z.object({
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
import { metrics } from "@opentelemetry/api"
|
import { metrics } from "@opentelemetry/api"
|
||||||
|
|
||||||
import { Lang } from "@/constants/languages"
|
import { Lang } from "@/constants/languages"
|
||||||
import { GetContentPageRefs } from "@/lib/graphql/Query/ContentPage/ContentPage.graphql"
|
import {
|
||||||
|
GetContentPageBlocksRefs,
|
||||||
|
GetContentPageRefs,
|
||||||
|
} from "@/lib/graphql/Query/ContentPage/ContentPage.graphql"
|
||||||
import { request } from "@/lib/graphql/request"
|
import { request } from "@/lib/graphql/request"
|
||||||
import { notFound } from "@/server/errors/trpc"
|
import { notFound } from "@/server/errors/trpc"
|
||||||
|
|
||||||
@@ -41,18 +44,30 @@ export async function fetchContentPageRefs(lang: Lang, uid: string) {
|
|||||||
query: { lang, uid },
|
query: { lang, uid },
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
const refsResponse = await request<GetContentPageRefsSchema>(
|
const [mainRefsResponse, blockRefsResponse] = await Promise.all([
|
||||||
GetContentPageRefs,
|
request<GetContentPageRefsSchema>(
|
||||||
{ locale: lang, uid },
|
GetContentPageRefs,
|
||||||
{
|
{ locale: lang, uid },
|
||||||
cache: "force-cache",
|
{
|
||||||
next: {
|
cache: "force-cache",
|
||||||
tags: [generateTag(lang, uid)],
|
next: {
|
||||||
},
|
tags: [generateTag(lang, uid)],
|
||||||
}
|
},
|
||||||
)
|
}
|
||||||
if (!refsResponse.data) {
|
),
|
||||||
const notFoundError = notFound(refsResponse)
|
request<GetContentPageRefsSchema>(
|
||||||
|
GetContentPageBlocksRefs,
|
||||||
|
{ locale: lang, uid },
|
||||||
|
{
|
||||||
|
cache: "force-cache",
|
||||||
|
next: {
|
||||||
|
tags: [generateTag(lang, uid)],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
),
|
||||||
|
])
|
||||||
|
if (!mainRefsResponse.data) {
|
||||||
|
const notFoundError = notFound(mainRefsResponse)
|
||||||
getContentPageRefsFailCounter.add(1, {
|
getContentPageRefsFailCounter.add(1, {
|
||||||
lang,
|
lang,
|
||||||
uid,
|
uid,
|
||||||
@@ -73,8 +88,14 @@ export async function fetchContentPageRefs(lang: Lang, uid: string) {
|
|||||||
)
|
)
|
||||||
throw notFoundError
|
throw notFoundError
|
||||||
}
|
}
|
||||||
|
const responseData = {
|
||||||
return refsResponse.data
|
...mainRefsResponse.data,
|
||||||
|
content_page: {
|
||||||
|
...mainRefsResponse.data.content_page,
|
||||||
|
blocks: blockRefsResponse.data.content_page.blocks,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
return responseData
|
||||||
}
|
}
|
||||||
|
|
||||||
export function validateContentPageRefs(
|
export function validateContentPageRefs(
|
||||||
@@ -171,17 +192,30 @@ export function getConnections({ content_page }: ContentPageRefs) {
|
|||||||
connections.push(...block.content)
|
connections.push(...block.content)
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
|
|
||||||
case ContentPageEnum.ContentStack.sidebar.JoinLoyaltyContact:
|
case ContentPageEnum.ContentStack.sidebar.JoinLoyaltyContact:
|
||||||
if (block.join_loyalty_contact?.button) {
|
if (block.join_loyalty_contact?.button) {
|
||||||
connections.push(block.join_loyalty_contact.button)
|
connections.push(block.join_loyalty_contact.button)
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
|
case ContentPageEnum.ContentStack.sidebar.ScriptedCard:
|
||||||
|
if (block.scripted_card?.length) {
|
||||||
|
connections.push(...block.scripted_card)
|
||||||
|
}
|
||||||
|
break
|
||||||
|
case ContentPageEnum.ContentStack.sidebar.TeaserCard:
|
||||||
|
if (block.teaser_card?.length) {
|
||||||
|
connections.push(...block.teaser_card)
|
||||||
|
}
|
||||||
|
break
|
||||||
|
case ContentPageEnum.ContentStack.sidebar.QuickLinks:
|
||||||
|
if (block.shortcuts.shortcuts.length) {
|
||||||
|
connections.push(...block.shortcuts.shortcuts)
|
||||||
|
}
|
||||||
|
break
|
||||||
default:
|
default:
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
return connections
|
return connections
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,11 +4,7 @@ import * as pageLinks from "@/server/routers/contentstack/schemas/pageLinks"
|
|||||||
|
|
||||||
import { BlocksEnums } from "@/types/enums/blocks"
|
import { BlocksEnums } from "@/types/enums/blocks"
|
||||||
|
|
||||||
export const shortcutsSchema = z.object({
|
export const shortcutsBlockSchema = z.object({
|
||||||
typename: z
|
|
||||||
.literal(BlocksEnums.block.Shortcuts)
|
|
||||||
.optional()
|
|
||||||
.default(BlocksEnums.block.Shortcuts),
|
|
||||||
shortcuts: z
|
shortcuts: z
|
||||||
.object({
|
.object({
|
||||||
subtitle: z.string().nullable(),
|
subtitle: z.string().nullable(),
|
||||||
@@ -62,6 +58,15 @@ export const shortcutsSchema = z.object({
|
|||||||
}),
|
}),
|
||||||
})
|
})
|
||||||
|
|
||||||
|
export const shortcutsSchema = z
|
||||||
|
.object({
|
||||||
|
typename: z
|
||||||
|
.literal(BlocksEnums.block.Shortcuts)
|
||||||
|
.optional()
|
||||||
|
.default(BlocksEnums.block.Shortcuts),
|
||||||
|
})
|
||||||
|
.merge(shortcutsBlockSchema)
|
||||||
|
|
||||||
export const shortcutsRefsSchema = z.object({
|
export const shortcutsRefsSchema = z.object({
|
||||||
shortcuts: z.object({
|
shortcuts: z.object({
|
||||||
shortcuts: z
|
shortcuts: z
|
||||||
|
|||||||
@@ -11,6 +11,11 @@ const metaData = z.object({
|
|||||||
Value: z.string().nullable(),
|
Value: z.string().nullable(),
|
||||||
})
|
})
|
||||||
|
|
||||||
|
export const focalPointSchema = z.object({
|
||||||
|
x: z.number(),
|
||||||
|
y: z.number(),
|
||||||
|
})
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Defines a media asset, original or conversion
|
* Defines a media asset, original or conversion
|
||||||
*/
|
*/
|
||||||
@@ -94,6 +99,7 @@ export const imageVaultAssetSchema = z.object({
|
|||||||
* Name of the user that added the asset to ImageVault
|
* Name of the user that added the asset to ImageVault
|
||||||
*/
|
*/
|
||||||
AddedBy: z.string(),
|
AddedBy: z.string(),
|
||||||
|
FocalPoint: focalPointSchema.optional(),
|
||||||
})
|
})
|
||||||
|
|
||||||
export const imageVaultAssetTransformedSchema = imageVaultAssetSchema.transform(
|
export const imageVaultAssetTransformedSchema = imageVaultAssetSchema.transform(
|
||||||
@@ -124,6 +130,7 @@ export const imageVaultAssetTransformedSchema = imageVaultAssetSchema.transform(
|
|||||||
height: mediaConversion.Height,
|
height: mediaConversion.Height,
|
||||||
aspectRatio,
|
aspectRatio,
|
||||||
},
|
},
|
||||||
|
focalPoint: rawData.FocalPoint || { x: 50, y: 50 },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ import {
|
|||||||
|
|
||||||
import { ContentEnum } from "@/types/enums/content"
|
import { ContentEnum } from "@/types/enums/content"
|
||||||
import { SidebarEnums } from "@/types/enums/sidebar"
|
import { SidebarEnums } from "@/types/enums/sidebar"
|
||||||
import { System } from "@/types/requests/system"
|
|
||||||
|
|
||||||
export const contentSchema = z.object({
|
export const contentSchema = z.object({
|
||||||
typename: z
|
typename: z
|
||||||
|
|||||||
16
server/routers/contentstack/schemas/sidebar/quickLinks.ts
Normal file
16
server/routers/contentstack/schemas/sidebar/quickLinks.ts
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
import { z } from "zod"
|
||||||
|
|
||||||
|
import { shortcutsBlockSchema, shortcutsRefsSchema } from "../blocks/shortcuts"
|
||||||
|
|
||||||
|
import { SidebarEnums } from "@/types/enums/sidebar"
|
||||||
|
|
||||||
|
export const quickLinksSchema = z
|
||||||
|
.object({
|
||||||
|
typename: z
|
||||||
|
.literal(SidebarEnums.blocks.QuickLinks)
|
||||||
|
.optional()
|
||||||
|
.default(SidebarEnums.blocks.QuickLinks),
|
||||||
|
})
|
||||||
|
.merge(shortcutsBlockSchema)
|
||||||
|
|
||||||
|
export const quickLinksRefschema = shortcutsRefsSchema
|
||||||
66
server/routers/contentstack/schemas/sidebar/scriptedCard.ts
Normal file
66
server/routers/contentstack/schemas/sidebar/scriptedCard.ts
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
import { z } from "zod"
|
||||||
|
|
||||||
|
import {
|
||||||
|
cardBlockRefsSchema,
|
||||||
|
cardBlockSchema,
|
||||||
|
transformCardBlock,
|
||||||
|
transformCardBlockRefs,
|
||||||
|
} from "../blocks/cardsGrid"
|
||||||
|
|
||||||
|
import { SidebarEnums } from "@/types/enums/sidebar"
|
||||||
|
|
||||||
|
export const scriptedCardsSchema = z.object({
|
||||||
|
typename: z
|
||||||
|
.literal(SidebarEnums.blocks.ScriptedCard)
|
||||||
|
.optional()
|
||||||
|
.default(SidebarEnums.blocks.ScriptedCard),
|
||||||
|
scripted_card: z
|
||||||
|
.object({
|
||||||
|
theme: z
|
||||||
|
.enum([
|
||||||
|
"one",
|
||||||
|
"two",
|
||||||
|
"three",
|
||||||
|
"primaryDim",
|
||||||
|
"primaryDark",
|
||||||
|
"primaryInverted",
|
||||||
|
"primaryStrong",
|
||||||
|
])
|
||||||
|
.nullable(),
|
||||||
|
scripted_cardConnection: z.object({
|
||||||
|
edges: z.array(
|
||||||
|
z.object({
|
||||||
|
node: cardBlockSchema,
|
||||||
|
})
|
||||||
|
),
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
.transform((data) => {
|
||||||
|
return {
|
||||||
|
theme: data.theme,
|
||||||
|
...transformCardBlock(data.scripted_cardConnection.edges[0].node),
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
|
||||||
|
export const scriptedCardRefschema = z.object({
|
||||||
|
scripted_card: z
|
||||||
|
.object({
|
||||||
|
scripted_cardConnection: z.object({
|
||||||
|
edges: z.array(
|
||||||
|
z.object({
|
||||||
|
node: cardBlockRefsSchema,
|
||||||
|
})
|
||||||
|
),
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
.transform((data) => {
|
||||||
|
let card = null
|
||||||
|
if (data.scripted_cardConnection.edges.length) {
|
||||||
|
card = transformCardBlockRefs(
|
||||||
|
data.scripted_cardConnection.edges[0].node
|
||||||
|
)
|
||||||
|
}
|
||||||
|
return card
|
||||||
|
}),
|
||||||
|
})
|
||||||
54
server/routers/contentstack/schemas/sidebar/teaserCard.ts
Normal file
54
server/routers/contentstack/schemas/sidebar/teaserCard.ts
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
import { z } from "zod"
|
||||||
|
|
||||||
|
import {
|
||||||
|
teaserCardBlockRefsSchema,
|
||||||
|
teaserCardBlockSchema,
|
||||||
|
transformCardBlockRefs,
|
||||||
|
transformTeaserCardBlock,
|
||||||
|
} from "../blocks/cardsGrid"
|
||||||
|
|
||||||
|
import { SidebarEnums } from "@/types/enums/sidebar"
|
||||||
|
|
||||||
|
export const teaserCardsSchema = z.object({
|
||||||
|
typename: z
|
||||||
|
.literal(SidebarEnums.blocks.TeaserCard)
|
||||||
|
.optional()
|
||||||
|
.default(SidebarEnums.blocks.TeaserCard),
|
||||||
|
teaser_card: z
|
||||||
|
.object({
|
||||||
|
theme: z.enum(["featured", "default"]).nullable().default("default"),
|
||||||
|
teaser_cardConnection: z.object({
|
||||||
|
edges: z.array(
|
||||||
|
z.object({
|
||||||
|
node: teaserCardBlockSchema,
|
||||||
|
})
|
||||||
|
),
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
.transform((data) => {
|
||||||
|
return {
|
||||||
|
...transformTeaserCardBlock(data.teaser_cardConnection.edges[0].node),
|
||||||
|
theme: data.theme,
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
|
||||||
|
export const teaserCardRefschema = z.object({
|
||||||
|
teaser_card: z
|
||||||
|
.object({
|
||||||
|
teaser_cardConnection: z.object({
|
||||||
|
edges: z.array(
|
||||||
|
z.object({
|
||||||
|
node: teaserCardBlockRefsSchema,
|
||||||
|
})
|
||||||
|
),
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
.transform((data) => {
|
||||||
|
let card = null
|
||||||
|
if (data.teaser_cardConnection.edges.length) {
|
||||||
|
card = transformCardBlockRefs(data.teaser_cardConnection.edges[0].node)
|
||||||
|
}
|
||||||
|
return card
|
||||||
|
}),
|
||||||
|
})
|
||||||
@@ -196,9 +196,11 @@ export const creditCardSchema = z
|
|||||||
attribute: z.object({
|
attribute: z.object({
|
||||||
cardName: z.string().optional(),
|
cardName: z.string().optional(),
|
||||||
alias: z.string(),
|
alias: z.string(),
|
||||||
truncatedNumber: z.string(),
|
truncatedNumber: z.string().transform((s) => s.slice(-4)),
|
||||||
expirationDate: z.string(),
|
expirationDate: z.string(),
|
||||||
cardType: z.string(),
|
cardType: z
|
||||||
|
.string()
|
||||||
|
.transform((s) => s.charAt(0).toLowerCase() + s.slice(1)),
|
||||||
}),
|
}),
|
||||||
id: z.string(),
|
id: z.string(),
|
||||||
type: z.string(),
|
type: z.string(),
|
||||||
@@ -208,6 +210,9 @@ export const creditCardSchema = z
|
|||||||
id: apiResponse.id,
|
id: apiResponse.id,
|
||||||
type: apiResponse.attribute.cardType,
|
type: apiResponse.attribute.cardType,
|
||||||
truncatedNumber: apiResponse.attribute.truncatedNumber,
|
truncatedNumber: apiResponse.attribute.truncatedNumber,
|
||||||
|
alias: apiResponse.attribute.alias,
|
||||||
|
expirationDate: apiResponse.attribute.expirationDate,
|
||||||
|
cardType: apiResponse.attribute.cardType,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -206,6 +206,56 @@ function parsedUser(data: User, isMFA: boolean) {
|
|||||||
return user
|
return user
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function getCreditCards(session: Session) {
|
||||||
|
getCreditCardsCounter.add(1)
|
||||||
|
console.info("api.profile.creditCards start", JSON.stringify({}))
|
||||||
|
const apiResponse = await api.get(api.endpoints.v1.creditCards, {
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${session.token.access_token}`,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
if (!apiResponse.ok) {
|
||||||
|
const text = await apiResponse.text()
|
||||||
|
getCreditCardsFailCounter.add(1, {
|
||||||
|
error_type: "http_error",
|
||||||
|
error: JSON.stringify({
|
||||||
|
status: apiResponse.status,
|
||||||
|
statusText: apiResponse.statusText,
|
||||||
|
text,
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
console.error(
|
||||||
|
"api.profile.creditCards error ",
|
||||||
|
JSON.stringify({
|
||||||
|
error: {
|
||||||
|
status: apiResponse.status,
|
||||||
|
statusText: apiResponse.statusText,
|
||||||
|
text,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
)
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
const apiJson = await apiResponse.json()
|
||||||
|
const verifiedData = creditCardsSchema.safeParse(apiJson)
|
||||||
|
if (!verifiedData.success) {
|
||||||
|
getCreditCardsFailCounter.add(1, {
|
||||||
|
error_type: "validation_error",
|
||||||
|
error: JSON.stringify(verifiedData.error),
|
||||||
|
})
|
||||||
|
console.error(
|
||||||
|
"api.profile.creditCards validation error ",
|
||||||
|
JSON.stringify({ error: verifiedData.error })
|
||||||
|
)
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
getCreditCardsSuccessCounter.add(1)
|
||||||
|
console.info("api.profile.creditCards success", JSON.stringify({}))
|
||||||
|
return verifiedData.data.data
|
||||||
|
}
|
||||||
|
|
||||||
export const userQueryRouter = router({
|
export const userQueryRouter = router({
|
||||||
get: protectedProcedure
|
get: protectedProcedure
|
||||||
.use(async function (opts) {
|
.use(async function (opts) {
|
||||||
@@ -675,53 +725,14 @@ export const userQueryRouter = router({
|
|||||||
}),
|
}),
|
||||||
|
|
||||||
creditCards: protectedProcedure.query(async function ({ ctx }) {
|
creditCards: protectedProcedure.query(async function ({ ctx }) {
|
||||||
getCreditCardsCounter.add(1)
|
return await getCreditCards(ctx.session)
|
||||||
console.info("api.profile.creditCards start", JSON.stringify({}))
|
}),
|
||||||
const apiResponse = await api.get(api.endpoints.v1.creditCards, {
|
safeCreditCards: safeProtectedProcedure.query(async function ({ ctx }) {
|
||||||
headers: {
|
if (!ctx.session) {
|
||||||
Authorization: `Bearer ${ctx.session.token.access_token}`,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
if (!apiResponse.ok) {
|
|
||||||
const text = await apiResponse.text()
|
|
||||||
getCreditCardsFailCounter.add(1, {
|
|
||||||
error_type: "http_error",
|
|
||||||
error: JSON.stringify({
|
|
||||||
status: apiResponse.status,
|
|
||||||
statusText: apiResponse.statusText,
|
|
||||||
text,
|
|
||||||
}),
|
|
||||||
})
|
|
||||||
console.error(
|
|
||||||
"api.profile.creditCards error ",
|
|
||||||
JSON.stringify({
|
|
||||||
error: {
|
|
||||||
status: apiResponse.status,
|
|
||||||
statusText: apiResponse.statusText,
|
|
||||||
text,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
)
|
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
const apiJson = await apiResponse.json()
|
return await getCreditCards(ctx.session)
|
||||||
const verifiedData = creditCardsSchema.safeParse(apiJson)
|
|
||||||
if (!verifiedData.success) {
|
|
||||||
getCreditCardsFailCounter.add(1, {
|
|
||||||
error_type: "validation_error",
|
|
||||||
error: JSON.stringify(verifiedData.error),
|
|
||||||
})
|
|
||||||
console.error(
|
|
||||||
"api.profile.creditCards validation error ",
|
|
||||||
JSON.stringify({ error: verifiedData.error })
|
|
||||||
)
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
getCreditCardsSuccessCounter.add(1)
|
|
||||||
console.info("api.profile.creditCards success", JSON.stringify({}))
|
|
||||||
return verifiedData.data.data
|
|
||||||
}),
|
}),
|
||||||
|
|
||||||
membershipCards: protectedProcedure.query(async function ({ ctx }) {
|
membershipCards: protectedProcedure.query(async function ({ ctx }) {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { Hotel } from "@/types/hotel"
|
import { CreditCard } from "@/types/user"
|
||||||
|
|
||||||
export interface SectionProps {
|
export interface SectionProps {
|
||||||
nextPath: string
|
nextPath: string
|
||||||
@@ -28,7 +28,9 @@ export interface BreakfastSelectionProps extends SectionProps {
|
|||||||
export interface DetailsProps extends SectionProps {}
|
export interface DetailsProps extends SectionProps {}
|
||||||
|
|
||||||
export interface PaymentProps {
|
export interface PaymentProps {
|
||||||
hotel: Hotel
|
hotelId: string
|
||||||
|
otherPaymentOptions: string[]
|
||||||
|
savedCreditCards: CreditCard[] | null
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SectionPageProps {
|
export interface SectionPageProps {
|
||||||
|
|||||||
@@ -1,9 +1,32 @@
|
|||||||
export type ApiImage = {
|
import type { ImageProps as NextImageProps } from "next/image"
|
||||||
|
|
||||||
|
import type { ImageVaultAsset } from "./imageVault"
|
||||||
|
|
||||||
|
export interface FocalPoint {
|
||||||
|
x: number
|
||||||
|
y: number
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Dimensions {
|
||||||
|
width: number
|
||||||
|
height: number
|
||||||
|
aspectRatio: number
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Meta {
|
||||||
|
alt: string | undefined | null
|
||||||
|
caption: string | undefined | null
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ApiImage {
|
||||||
id: string
|
id: string
|
||||||
url: string
|
url: string
|
||||||
title: string
|
title: string
|
||||||
meta: {
|
meta: Meta
|
||||||
alt: string
|
dimensions?: Dimensions
|
||||||
caption: string
|
focalPoint?: FocalPoint
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface ImageProps extends NextImageProps {
|
||||||
|
focalPoint?: FocalPoint
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,8 @@ import { z } from "zod"
|
|||||||
|
|
||||||
import { imageVaultAssetSchema } from "@/server/routers/contentstack/schemas/imageVault"
|
import { imageVaultAssetSchema } from "@/server/routers/contentstack/schemas/imageVault"
|
||||||
|
|
||||||
|
import type { FocalPoint } from "./image"
|
||||||
|
|
||||||
export type ImageVaultAssetResponse = z.infer<typeof imageVaultAssetSchema>
|
export type ImageVaultAssetResponse = z.infer<typeof imageVaultAssetSchema>
|
||||||
|
|
||||||
export type ImageVaultAsset = {
|
export type ImageVaultAsset = {
|
||||||
@@ -23,4 +25,5 @@ export type ImageVaultAsset = {
|
|||||||
aspectRatio: number
|
aspectRatio: number
|
||||||
}
|
}
|
||||||
meta: { alt: string | undefined | null; caption: string | undefined | null }
|
meta: { alt: string | undefined | null; caption: string | undefined | null }
|
||||||
|
focalPoint: FocalPoint
|
||||||
}
|
}
|
||||||
|
|||||||
5
types/enums/alert.ts
Normal file
5
types/enums/alert.ts
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
export enum AlertTypeEnum {
|
||||||
|
Info = "info",
|
||||||
|
Warning = "warning",
|
||||||
|
Alarm = "alarm",
|
||||||
|
}
|
||||||
@@ -15,6 +15,9 @@ export namespace ContentPageEnum {
|
|||||||
Content = "ContentPageSidebarContent",
|
Content = "ContentPageSidebarContent",
|
||||||
DynamicContent = "ContentPageSidebarDynamicContent",
|
DynamicContent = "ContentPageSidebarDynamicContent",
|
||||||
JoinLoyaltyContact = "ContentPageSidebarJoinLoyaltyContact",
|
JoinLoyaltyContact = "ContentPageSidebarJoinLoyaltyContact",
|
||||||
|
ScriptedCard = "ContentPageSidebarScriptedCard",
|
||||||
|
TeaserCard = "ContentPageSidebarTeaserCard",
|
||||||
|
QuickLinks = "ContentPageSidebarShortcuts",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,5 +3,8 @@ export namespace SidebarEnums {
|
|||||||
Content = "Content",
|
Content = "Content",
|
||||||
DynamicContent = "DynamicContent",
|
DynamicContent = "DynamicContent",
|
||||||
JoinLoyaltyContact = "JoinLoyaltyContact",
|
JoinLoyaltyContact = "JoinLoyaltyContact",
|
||||||
|
ScriptedCard = "ScriptedCard",
|
||||||
|
TeaserCard = "TeaserCard",
|
||||||
|
QuickLinks = "QuickLinks",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
14
types/trpc/routers/contentstack/siteConfig.ts
Normal file
14
types/trpc/routers/contentstack/siteConfig.ts
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
import { z } from "zod"
|
||||||
|
|
||||||
|
import {
|
||||||
|
alertSchema,
|
||||||
|
siteConfigRefSchema,
|
||||||
|
siteConfigSchema,
|
||||||
|
} from "@/server/routers/contentstack/base/output"
|
||||||
|
|
||||||
|
export type GetSiteConfigRefData = z.infer<typeof siteConfigRefSchema>
|
||||||
|
|
||||||
|
export type GetSiteConfigData = z.input<typeof siteConfigSchema>
|
||||||
|
export type SiteConfig = z.output<typeof siteConfigSchema>
|
||||||
|
|
||||||
|
export type Alert = z.output<typeof alertSchema>
|
||||||
@@ -33,6 +33,7 @@ export function insertResponseToImageVaultAsset(
|
|||||||
height: mediaConversion.Height,
|
height: mediaConversion.Height,
|
||||||
aspectRatio,
|
aspectRatio,
|
||||||
},
|
},
|
||||||
|
focalPoint: response.FocalPoint || { x: 50, y: 50 },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user