Merged in feat/sw-1314-transfer-sas-points (pull request #1508)

SW-1314 Transfer SAS points

Approved-by: Linus Flood
This commit is contained in:
Anton Gunnarsson
2025-03-18 10:07:05 +00:00
parent d4fe8baa49
commit d0b6f3f8b3
32 changed files with 1799 additions and 12 deletions

View File

@@ -80,7 +80,8 @@ export async function GET(
if (
stateResult.data.intent === "link" ||
stateResult.data.intent === "unlink"
stateResult.data.intent === "unlink" ||
stateResult.data.intent === "transfer"
) {
const [data, error] = await safeTry(
serverClient().partner.sas.requestOtp({})

View File

@@ -20,7 +20,7 @@ import type { LangParams, PageArgs, SearchParams } from "@/types/params"
import type { State } from "../sasUtils"
const searchParamsSchema = z.object({
intent: z.enum(["link", "unlink"]),
intent: z.enum(["link", "unlink", "transfer"]),
})
type Intent = z.infer<typeof searchParamsSchema>["intent"]
@@ -58,6 +58,9 @@ export default async function SASxScandicLoginPage({
unlink: intl.formatMessage({
id: "Log in to your SAS Eurobonus account to confirm account unlinking.",
}),
transfer: intl.formatMessage({
id: "In order to transfer your points we will ask you to sign in to your SAS EuroBonus account.",
}),
}
return (

View File

@@ -8,7 +8,7 @@ import { serverClient } from "@/lib/trpc/server"
import { getIntl } from "@/i18n"
import { safeTry } from "@/utils/safeTry"
import { SAS_TOKEN_STORAGE_KEY } from "../sasUtils"
import { SAS_TOKEN_STORAGE_KEY, SAS_TRANSFER_POINT_KEY } from "../sasUtils"
import OneTimePasswordForm, {
type OnSubmitHandler,
} from "./OneTimePasswordForm"
@@ -19,7 +19,7 @@ import type { LangParams, PageArgs, SearchParams } from "@/types/params"
import type { Lang } from "@/constants/languages"
const otpError = z.enum(["invalidCode", "expiredCode"])
const intent = z.enum(["link", "unlink"])
const intent = z.enum(["link", "unlink", "transfer"])
const searchParamsSchema = z.object({
intent: intent,
to: z.string(),
@@ -95,6 +95,8 @@ export default async function SASxScandicOneTimePasswordPage({
return handleLinkAccount({ lang: params.lang })
case "unlink":
return handleUnlinkAccount({ lang: params.lang })
case "transfer":
return handleTransferPoints({ lang: params.lang })
}
}
@@ -118,6 +120,12 @@ export default async function SASxScandicOneTimePasswordPage({
},
{ maskedContactInfo }
),
transfer: intl.formatMessage(
{
id: "Please enter the code sent to <maskedContactInfo></maskedContactInfo> in order to transfer your points.",
},
{ maskedContactInfo }
),
}
return (
@@ -215,3 +223,44 @@ async function handleUnlinkAccount({
}
}
}
async function handleTransferPoints({
lang,
}: {
lang: Lang
}): ReturnType<OnSubmitHandler> {
const cookieStore = cookies()
const pointsCookie = cookieStore.get(SAS_TRANSFER_POINT_KEY)
const points = Number(pointsCookie?.value)
cookieStore.delete(SAS_TRANSFER_POINT_KEY)
if (!pointsCookie || !points || isNaN(points)) {
return {
url: `/${lang}/sas-x-scandic/error`,
type: "replace",
}
}
const [res, error] = await safeTry(
serverClient().partner.sas.transferPoints({
points,
})
)
if (!res || error) {
console.error("[SAS] transfer points error", error)
return {
// TODO better errors?
url: `/${lang}/sas-x-scandic/error`,
type: "replace",
}
}
console.log("[SAS] transfer points response", res)
return {
url: `/${lang}/sas-x-scandic/transfer/success?p=${points}`,
type: "replace",
}
}

View File

@@ -1,8 +1,9 @@
import { z } from "zod"
export const SAS_TOKEN_STORAGE_KEY = "sas-x-scandic-token"
export const SAS_TRANSFER_POINT_KEY = "sas-x-scandic-eb-points"
export const stateSchema = z.object({
intent: z.enum(["link", "unlink"]),
intent: z.enum(["link", "unlink", "transfer"]),
})
export type State = z.infer<typeof stateSchema>

View File

@@ -0,0 +1,159 @@
import Link from "next/link"
import React, { Suspense } from "react"
import { Typography } from "@scandic-hotels/design-system/Typography"
import { hotelreservation } from "@/constants/routes/hotelReservation"
import { partnerSas } from "@/constants/routes/myPages"
import { getProfileSafely } from "@/lib/trpc/memoizedRequests"
import { CalendarAddIcon } from "@/components/Icons"
import Image from "@/components/Image"
import SkeletonShimmer from "@/components/SkeletonShimmer"
import Button from "@/components/TempDesignSystem/Button"
import { getIntl } from "@/i18n"
import { SASModal } from "../../components/SASModal"
import styles from "./transferSuccess.module.css"
import type { LangParams, PageArgs, SearchParams } from "@/types/params"
import type { Lang } from "@/constants/languages"
export default async function SASxScandicTransferSuccessPage({
params,
searchParams,
}: PageArgs<LangParams> & SearchParams<{ p?: string }>) {
const intl = await getIntl()
const { lang } = params
const addedPoints = Number(searchParams.p) || 0
return (
<SASModal>
<Image
src="/_static/img/scandic-high-five.svg"
alt=""
width="111"
height="139"
sizes="100vw"
className={styles.image}
/>
<div className={styles.container}>
<Typography variant="Title/Subtitle/lg">
<h1>{intl.formatMessage({ id: "Point transfer completed!" })}</h1>
</Typography>
<TransactionCard addedPoints={addedPoints} lang={lang} />
<div className={styles.divider} />
<Button
theme="primaryLight"
asChild
fullWidth
className={styles.backButton}
>
<Link href={partnerSas[params.lang]} color="none">
{intl.formatMessage({
id: "Go back to My Pages",
})}
</Link>
</Button>
</div>
</SASModal>
)
}
async function TransactionCard({
addedPoints,
lang,
}: {
addedPoints: number
lang: Lang
}) {
const intl = await getIntl()
const profile = await getProfileSafely()
const transferredPoints = intl.formatNumber(addedPoints)
// TODO is this updated immediately?
const totalPoints = profile?.membership?.currentPoints ?? 0
const showBonusNight = totalPoints > 10_000
return (
<div className={styles.transactionBox}>
<Typography variant="Title/Subtitle/md">
<h2>{intl.formatMessage({ id: "Your transaction" })}</h2>
</Typography>
<div className={styles.transactionDetails}>
<div className={styles.transactionRow}>
<Typography variant="Title/Overline/sm">
<h3>{intl.formatMessage({ id: "Points added" })}</h3>
</Typography>
<Typography variant="Body/Paragraph/mdBold">
<p>+ {transferredPoints}</p>
</Typography>
</div>
<div className={styles.transactionRow}>
<Typography variant="Title/Overline/sm">
<h3>{intl.formatMessage({ id: "Your new total" })}</h3>
</Typography>
<Suspense fallback={<SkeletonShimmer width="15ch" height="24px" />}>
<TotalPoints />
</Suspense>
</div>
</div>
{showBonusNight && (
<div className={styles.bonusNight}>
<div className={styles.bonusNightDetails}>
<Typography variant="Body/Paragraph/mdBold">
<h3>
{intl.formatMessage({
id: "You have enough points for a bonus night!",
})}
</h3>
</Typography>
<Typography variant="Body/Paragraph/mdRegular">
<p>
{intl.formatMessage({
id: "Bonus Nights range from 10 000 - 80 000 points. Book your next stay with us today!",
})}
</p>
</Typography>
</div>
<Button
theme="primaryLight"
intent="secondary"
size="small"
fullWidth
className={styles.bookButton}
asChild
>
{/* TODO correct link */}
<Link href={hotelreservation(lang)} color="none">
{intl.formatMessage({ id: "Book now" })}{" "}
<CalendarAddIcon width={20} height={20} color="currentColor" />
</Link>
</Button>
</div>
)}
</div>
)
}
async function TotalPoints() {
const intl = await getIntl()
const profile = await getProfileSafely()
const points = profile?.membership?.currentPoints ?? 0
return (
<Typography variant="Body/Paragraph/mdBold">
<p>
={" "}
{intl.formatMessage(
{ id: "{points, number} points" },
{
points,
}
)}
</p>
</Typography>
)
}

View File

@@ -0,0 +1,79 @@
.image {
width: 120px;
height: auto;
}
.container {
display: flex;
flex-direction: column;
gap: var(--Spacing-x3);
align-items: center;
width: 100%;
}
.transactionBox {
box-shadow: 0px 0px 14px 6px #0000001a;
padding: var(--Spacing-x4) var(--Spacing-x3);
display: flex;
flex-direction: column;
gap: var(--Spacing-x3);
border-radius: var(--Corner-radius-Medium);
align-items: center;
width: 100%;
}
.transactionDetails {
display: flex;
flex-direction: column;
gap: var(--Spacing-x1);
width: 100%;
}
.transactionRow {
display: flex;
justify-content: space-between;
align-items: center;
color: var(--Text-Secondary);
}
.bonusNight {
border-top: 1px solid var(--Border-Divider-Default);
padding-top: var(--Spacing-x3);
display: flex;
flex-direction: column;
gap: var(--Spacing-x3);
align-items: center;
}
.bonusNightDetails {
display: flex;
flex-direction: column;
gap: var(--Spacing-x1);
}
.divider {
--divider-spacing: var(--Spacing-x3);
background: var(--Border-Divider-Subtle);
width: calc(100% + var(--divider-spacing) + var(--divider-spacing));
margin-inline: calc(var(--divider-spacing) * -1);
height: 1px;
}
@media screen and (min-width: 768px) {
.container {
padding-inline: var(--Spacing-x3);
}
.divider {
--divider-spacing: var(--Spacing-x6);
}
.bookButton {
max-width: 325px;
}
.backButton {
max-width: 350px;
}
}

View File

@@ -48,7 +48,7 @@ export default async function RootLayout({
window.adobeDataLayer = window.adobeDataLayer || []
`}</Script>
</head>
<body>
<body className="scandic">
<ServerIntlProvider intl={{ defaultLocale, locale, messages }}>
<TrpcProvider>
<RouterTracking />

View File

@@ -0,0 +1,165 @@
import { Typography } from "@scandic-hotels/design-system/Typography"
import { getProfileSafely } from "@/lib/trpc/memoizedRequests"
import ArrowFromIcon from "@/components/Icons/ArrowFrom"
import ArrowToIcon from "@/components/Icons/ArrowTo"
import Image from "@/components/Image"
import SkeletonShimmer from "@/components/SkeletonShimmer"
import { getIntl } from "@/i18n"
import { TransferPointsFormClient } from "./TransferPointsFormClient"
import styles from "./transferPoints.module.css"
import type { Lang } from "@/constants/languages"
const wait = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms))
export async function TransferPointsForm({ lang }: { lang: Lang }) {
const profile = await getProfileSafely()
const scandicPoints = profile?.membership?.currentPoints ?? 0
// TODO get from api
await wait(1_000)
const sasPoints = 250_000
const exchangeRate = 2
return (
<TransferPointsFormContent
sasPoints={sasPoints}
scandicPoints={scandicPoints}
exchangeRate={exchangeRate}
lang={lang}
/>
)
}
export async function TransferPointsFormSkeleton({ lang }: { lang: Lang }) {
return (
<TransferPointsFormContent
sasPoints={null}
scandicPoints={null}
exchangeRate={null}
lang={lang}
/>
)
}
async function TransferPointsFormContent({
sasPoints,
scandicPoints,
exchangeRate,
lang,
}: {
sasPoints: number | null
scandicPoints: number | null
exchangeRate: number | null
lang: Lang
}) {
const intl = await getIntl()
return (
<div className={styles.container}>
<section className={styles.card}>
<div className={styles.highFive}>
<Image
src="/_static/img/scandic-high-five.svg"
alt=""
width="111"
height="139"
sizes="100vw"
/>
</div>
<div className={styles.transferContainer}>
<div className={styles.transferFrom}>
<div>
<div className={styles.labelWithIcon}>
<Typography variant="Tag/sm">
<p>{intl.formatMessage({ id: "Transfer from" })}</p>
</Typography>
<ArrowFromIcon />
</div>
<Typography variant="Title/Subtitle/md">
<p>{intl.formatMessage({ id: "SAS EuroBonus" })}</p>
</Typography>
</div>
<div>
<Typography variant="Tag/sm">
<p className={styles.balanceLabel}>
{intl.formatMessage({ id: "Balance" })}
</p>
</Typography>
{sasPoints === null ? (
<SkeletonShimmer width="10ch" height="20px" />
) : (
<Typography variant="Body/Paragraph/mdRegular">
<p>
{intl.formatMessage(
{ id: "{points, number} p" },
{ points: sasPoints }
)}
</p>
</Typography>
)}
</div>
</div>
<div className={styles.noPointsWarning}>
{sasPoints === 0 && (
<Typography variant="Body/Paragraph/mdRegular">
<p>
{intl.formatMessage({
id: "You have no points to transfer.",
})}
</p>
</Typography>
)}
</div>
<div className={styles.transferTo}>
<div>
<div className={styles.labelWithIcon}>
<ArrowToIcon />
<Typography variant="Tag/sm">
<p>{intl.formatMessage({ id: "Transfer to" })}</p>
</Typography>
</div>
<Typography variant="Title/Subtitle/md">
<p>{intl.formatMessage({ id: "Scandic Friends" })}</p>
</Typography>
</div>
<div>
<Typography variant="Tag/sm">
<p className={styles.balanceLabel}>
{intl.formatMessage({ id: "Balance" })}
</p>
</Typography>
{scandicPoints === null ? (
<SkeletonShimmer width="10ch" height="20px" />
) : (
<Typography variant="Body/Paragraph/mdRegular">
<p>
{intl.formatMessage(
{ id: "{points, number} p" },
{ points: scandicPoints }
)}
</p>
</Typography>
)}
</div>
</div>
</div>
<TransferPointsFormClient
sasPoints={sasPoints}
exchangeRate={exchangeRate}
lang={lang}
/>
</section>
<Typography variant="Body/Supporting text (caption)/smRegular">
<p style={{ color: "var(--Text-Tertiary)" }}>
{intl.formatMessage({
id: "Transferred points will not be level qualifying",
})}
</p>
</Typography>
</div>
)
}

View File

@@ -0,0 +1,247 @@
"use client"
import Link from "next/link"
import { useParams } from "next/navigation"
import { useContext, useState } from "react"
import {
I18nProvider,
Slider,
SliderOutput,
SliderStateContext,
SliderThumb,
SliderTrack,
TextField,
} from "react-aria-components"
import { FormProvider, useForm } from "react-hook-form"
import { useIntl } from "react-intl"
import { Typography } from "@scandic-hotels/design-system/Typography"
import { SAS_TRANSFER_POINT_KEY } from "@/app/[lang]/(partner)/(sas)/(protected)/sas-x-scandic/sasUtils"
import SwipeIcon from "@/components/Icons/Swipe"
import Image from "@/components/Image"
import Modal from "@/components/Modal"
import Button from "@/components/TempDesignSystem/Button"
import AriaInputWithLabel from "@/components/TempDesignSystem/Form/Input/AriaInputWithLabel"
import styles from "./transferPoints.module.css"
import type { LangParams } from "@/types/params"
import type { Lang } from "@/constants/languages"
type TransferPointsFormClientProps = {
sasPoints: number | null
exchangeRate: number | null
lang: Lang
}
export function TransferPointsFormClient({
sasPoints,
exchangeRate,
lang,
}: TransferPointsFormClientProps) {
const intl = useIntl()
const formMethods = useForm()
const [pointState, setPointState] = useState<number | null>(0)
const selectedPoints = pointState ?? 0
const disabled = !exchangeRate
const parsedPoints = Math.min(selectedPoints, sasPoints ?? 0)
const calculatedPoints = parsedPoints * (exchangeRate ?? 0)
const handleUpdatePoints = (points: number | null) => {
setPointState(points)
}
const hasNoSasPoints = !sasPoints || sasPoints === 0
return (
<FormProvider {...formMethods}>
<I18nProvider locale={lang}>
<Slider
value={parsedPoints}
onChange={handleUpdatePoints}
className={styles.slider}
// Set max value to 1 if sasPoints is 0 since slider requires a range
maxValue={hasNoSasPoints ? 1 : sasPoints}
aria-label={intl.formatMessage({ id: "EB points to transfer" })}
formatOptions={{
useGrouping: true,
maximumFractionDigits: 0,
}}
isDisabled={disabled || hasNoSasPoints}
>
<SliderTrack className={styles.sliderTrack}>
<SliderFill />
<SliderThumb className={styles.sliderThumb}>
<SliderOutput className={styles.sliderOutput} />
<SwipeIcon color="white" />
</SliderThumb>
</SliderTrack>
</Slider>
</I18nProvider>
<div className={styles.inputsWrapper}>
<TextField type="number" isDisabled={disabled}>
<AriaInputWithLabel
label={intl.formatMessage({ id: "EB points to transfer" })}
type="number"
min={0}
value={pointState ?? ""}
className={styles.pointsInput}
disabled={disabled}
onChange={(e) => {
const value = parseInt(e.target.value, 10)
handleUpdatePoints(isNaN(value) ? null : value)
}}
onBlur={() => {
handleUpdatePoints(parsedPoints)
}}
/>
</TextField>
<Typography variant="Body/Supporting text (caption)/smRegular">
<p className={styles.conversionRate}>
{/* TODO maybe dynamic string based on exchange rate */}
{intl.formatMessage({
id: "1 EuroBonus point = 2 Scandic Friends points",
})}
</p>
</Typography>
<div className={styles.pointsOutput}>
<Typography variant="Label/xsRegular">
<p>{intl.formatMessage({ id: "SF points to receive" })}</p>
</Typography>
<Typography variant="Body/Paragraph/mdRegular">
<p>{intl.formatNumber(calculatedPoints)}</p>
</Typography>
</div>
</div>
<ConfirmModal
disabled={disabled || calculatedPoints === 0}
sasPoints={parsedPoints}
scandicPoints={calculatedPoints}
/>
</FormProvider>
)
}
function SliderFill() {
const state = useContext(SliderStateContext)!
return (
<div
style={{
width: `${state.getThumbPercent(0) * 100}%`,
}}
className={styles.sliderFill}
/>
)
}
type ConfirmModalProps = {
sasPoints: number
scandicPoints: number
disabled?: boolean
}
function ConfirmModal({
sasPoints,
scandicPoints,
disabled,
}: ConfirmModalProps) {
const { lang } = useParams<LangParams>()
const [isOpen, setIsOpen] = useState(false)
const intl = useIntl()
const handleToggle = (open: boolean) => {
setIsOpen(open)
if (open) {
const expireIn15Minutes = new Date(
Date.now() + 15 * 60 * 1000
).toUTCString()
document.cookie = `${SAS_TRANSFER_POINT_KEY}=${JSON.stringify(sasPoints)};path=/;expires=${expireIn15Minutes}`
} else {
document.cookie = `${SAS_TRANSFER_POINT_KEY}=;path=/;expires=Thu, 01 Jan 1970 00:00:01 GMT`
}
}
return (
<>
<Button
className={styles.transferButton}
onClick={() => handleToggle(true)}
disabled={disabled}
>
{intl.formatMessage({ id: "Transfer points" })}
</Button>
<Modal isOpen={isOpen} onToggle={handleToggle}>
<div className={styles.modalContainer}>
<Image
src="/_static/img/scandic-money-hand.svg"
alt=""
width="133"
height="119"
/>
<Typography variant="Title/Subtitle/lg">
<h3>
{intl.formatMessage({ id: "Proceed with point transfer?" })}
</h3>
</Typography>
<div>
<Typography variant="Body/Paragraph/mdRegular">
<p>{intl.formatMessage({ id: "You are about to exchange:" })}</p>
</Typography>
<Typography variant="Body/Paragraph/mdRegular">
<p>
{intl.formatMessage(
{
id: "<bold>{sasPoints, number} EuroBonus points</bold> to <bold>{scandicPoints, number} Scandic Friends points</bold>",
},
{
sasPoints,
scandicPoints,
bold: (text) => (
<Typography variant="Body/Paragraph/mdBold">
<span>{text}</span>
</Typography>
),
}
)}
</p>
</Typography>
</div>
<Typography variant="Body/Supporting text (caption)/smRegular">
<p className={styles.expiryText}>
{intl.formatMessage({
id: "Your exchanged points will retain their original expiry date with a maximum validity of 12 months.",
})}
</p>
</Typography>
<div className={styles.divider} />
<div className={styles.buttonContainer}>
<Button asChild theme="base" fullWidth>
<Link
href={`/${lang}/sas-x-scandic/login?intent=transfer`}
color="none"
>
{intl.formatMessage({
id: "Yes, I want to transfer my points",
})}
</Link>
</Button>
<Button
fullWidth
intent="text"
theme="base"
onClick={() => handleToggle(false)}
>
{intl.formatMessage({ id: "Cancel" })}
</Button>
</div>
</div>
</Modal>
</>
)
}

View File

@@ -0,0 +1,41 @@
import { Suspense } from "react"
import { env } from "@/env/server"
import SectionContainer from "@/components/Section/Container"
import SectionHeader from "@/components/Section/Header"
import SectionLink from "@/components/Section/Link"
import { getLang } from "@/i18n/serverContext"
import {
TransferPointsForm,
TransferPointsFormSkeleton,
} from "./TransferPointsForm"
type Props = {
title?: string
link?: { href: string; text: string }
subtitle?: string
}
export default async function SASTransferPoints({
title,
subtitle,
link,
}: Props) {
if (!env.SAS_ENABLED) {
return null
}
const lang = getLang()
return (
<SectionContainer>
<SectionHeader link={link} preamble={subtitle} title={title} />
<SectionLink link={link} variant="mobile" />
<Suspense fallback={<TransferPointsFormSkeleton lang={lang} />}>
<TransferPointsForm lang={lang} />
</Suspense>
</SectionContainer>
)
}

View File

@@ -0,0 +1,297 @@
.container {
display: flex;
flex-direction: column;
align-items: center;
gap: var(--Spacing-x3);
}
.card {
position: relative;
width: 100%;
display: flex;
flex-direction: column;
gap: var(--Spacing-x3);
padding: var(--Spacing-x3) var(--Spacing-x9);
background-color: var(--Background-Secondary);
border-radius: var(--Corner-radius-Large);
box-shadow: 0px 0px 4px 2px rgba(0, 0, 0, 0.1);
margin-top: var(--Spacing-x9);
}
.highFive {
height: 110px;
width: 110px;
position: absolute;
top: 0;
left: 50%;
transform: translate(-50%, -50%);
& > img {
position: absolute;
bottom: -5%;
width: 100%;
height: auto;
}
}
.labelWithIcon {
display: flex;
align-items: center;
gap: var(--Spacing-x-half);
color: var(--Text-Tertiary);
margin-bottom: var(--Spacing-x-half);
}
.transferContainer {
display: grid;
grid-template-columns: 1fr auto 1fr;
}
.transferFrom {
display: flex;
flex-direction: column;
}
.transferTo {
display: flex;
flex-direction: column;
text-align: right;
.labelWithIcon {
justify-content: flex-end;
}
}
.noPointsWarning {
align-self: end;
color: var(--Surface-Feedback-Information-Accent);
}
.balanceLabel {
color: var(--Text-Tertiary);
margin-top: var(--Spacing-x3);
}
.formWrapper {
display: flex;
flex-direction: column;
gap: var(--Spacing-x3);
width: 100%;
padding: var(--Spacing-x4);
padding-bottom: 0;
}
.slider {
color: var(--text-color);
width: 100%;
padding-top: 24px;
.sliderTrack {
position: relative;
height: 30px;
width: 100%;
&:before {
height: 10px;
width: 100%;
top: 50%;
transform: translateY(-50%);
content: "";
display: block;
position: absolute;
background-color: var(--Border-Divider-Accent);
border-radius: var(--Corner-radius-Small);
opacity: 0.3;
transition: background-color 300ms ease;
}
}
.sliderFill {
height: 10px;
background: linear-gradient(90deg, #8f4350 25.5%, #4d001b 100%);
position: relative;
top: 50%;
transform: translateY(-50%);
border-radius: var(--Corner-radius-Small);
}
.sliderOutput {
position: absolute;
top: -30px;
left: 50%;
transform: translateX(-50%) translateY(4px);
background-color: var(--Surface-Brand-Primary-1-OnSurface-Default);
color: var(--Text-Brand-OnPrimary-2-Accent);
padding: var(--Spacing-x-half) var(--Spacing-x1);
border-radius: var(--Corner-radius-Small);
opacity: 0;
transition:
opacity 0.15s,
transform 0.15s;
transition-delay: 0.1s;
}
.sliderThumb {
position: relative;
top: 50%;
width: 42px;
height: 42px;
border-radius: 50%;
background-color: var(--Surface-Brand-Primary-1-OnSurface-Default);
box-shadow: 0px 0px 14px 6px rgba(0, 0, 0, 0.1);
display: flex;
justify-content: center;
align-items: center;
transition: background-color 300ms ease;
& > svg {
width: 22px;
height: 22px;
transition: opacity 300ms ease;
}
&[data-focus-visible] {
outline: 2px solid var(--Surface-Feedback-Neutral);
}
&[data-dragging] .sliderOutput {
opacity: 1;
transform: translateX(-50%) translateY(0px);
}
}
&[data-disabled] {
.sliderTrack:before {
background-color: var(--Border-Interactive-Disabled);
}
.sliderThumb {
background-color: var(--Surface-UI-Fill-Disabled);
box-shadow: none;
& > svg {
opacity: 0;
}
}
}
}
.pointsInput {
width: 100%;
}
.conversionRate {
color: var(--Text-Tertiary);
font-style: italic;
}
.inputsWrapper {
display: grid;
gap: 36px;
width: 100%;
grid-template-columns: 1fr auto 1fr;
align-items: center;
}
.transferButton {
max-width: 260px;
width: 100%;
margin: 0 auto;
}
.modalContainer {
max-width: 512px;
display: flex;
flex-direction: column;
align-items: center;
text-align: center;
gap: var(--Spacing-x3);
padding-inline: var(--Spacing-x3);
}
.expiryText {
color: var(--Text-Tertiary);
}
.divider {
background-color: var(--Border-Divider-Subtle);
width: calc(100% + var(--Spacing-x6) + var(--Spacing-x6));
height: 1px;
margin-inline: calc(var(--Spacing-x6) * -1);
}
.buttonContainer {
display: flex;
flex-direction: column;
gap: var(--Spacing-x3);
}
.pointsOutput {
border-radius: var(--Corner-radius-Medium);
background-color: var(--Surface-Primary-Disabled);
height: 100%;
color: var(--Text-Tertiary);
padding: var(--Spacing-x1) var(--Spacing-x2);
display: flex;
flex-direction: column;
gap: var(--Spacing-x-half);
}
@media screen and (max-width: 767px) {
.card {
padding: var(--Spacing-x3);
padding-top: var(--Spacing-x6);
}
.highFive {
height: 75px;
width: 75px;
}
.transferContainer {
grid-template-columns: 1fr;
gap: var(--Spacing-x4);
}
.transferFrom {
flex-direction: row;
justify-content: space-between;
}
.transferTo {
flex-direction: row;
justify-content: space-between;
text-align: left;
.labelWithIcon {
flex-direction: row-reverse;
}
}
.noPointsWarning {
grid-row: 3;
}
.balanceLabel {
margin-top: 0;
text-align: right;
}
.inputsWrapper {
grid-template-columns: 1fr 1fr;
column-gap: var(--Spacing-x1);
}
.conversionRate {
grid-row: 2;
grid-column: span 2;
text-align: center;
}
.slider {
padding-top: 0;
}
.modalContainer {
padding-inline: var(--Spacing-x2);
}
}

View File

@@ -12,6 +12,7 @@ import PointsOverview from "@/components/Blocks/DynamicContent/Points/Overview"
import CurrentRewardsBlock from "@/components/Blocks/DynamicContent/Rewards/CurrentRewards"
import NextLevelRewardsBlock from "@/components/Blocks/DynamicContent/Rewards/NextLevel"
import SASLinkedAccount from "@/components/Blocks/DynamicContent/SAS/LinkedAccounts"
import SASTransferPoints from "@/components/Blocks/DynamicContent/SAS/TransferPoints"
import SASTierComparisonBlock from "@/components/Blocks/DynamicContent/SASTierComparison"
import SignupFormWrapper from "@/components/Blocks/DynamicContent/SignupFormWrapper"
import PreviousStays from "@/components/Blocks/DynamicContent/Stays/Previous"
@@ -67,6 +68,8 @@ function DynamicContentBlocks(props: DynamicContentProps) {
return <UpcomingStays {...dynamic_content} />
case DynamicContentEnum.Blocks.components.sas_linked_account:
return <SASLinkedAccount {...dynamic_content} />
case DynamicContentEnum.Blocks.components.sas_transfer_points:
return <SASTransferPoints {...dynamic_content} />
case DynamicContentEnum.Blocks.components.sas_tier_comparison:
return (
<SASTierComparisonBlock

View File

@@ -0,0 +1,37 @@
import { iconVariants } from "./variants"
import type { IconProps } from "@/types/components/icon"
export default function ArrowFromIcon({
className,
color,
...props
}: IconProps) {
const classNames = iconVariants({ className, color })
return (
<svg
className={classNames}
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}
>
<path
d="M12 5V15M12 5C11.2998 5 9.99153 6.9943 9.5 7.5M12 5C12.7002 5 14.0085 6.9943 14.5 7.5"
stroke="black"
strokeWidth="1.5"
strokeLinecap="round"
strokeLinejoin="round"
/>
<path
d="M5 19H19.0001"
stroke="black"
strokeWidth="1.5"
strokeLinecap="round"
strokeLinejoin="round"
/>
</svg>
)
}

View File

@@ -0,0 +1,33 @@
import { iconVariants } from "./variants"
import type { IconProps } from "@/types/components/icon"
export default function ArrowToIcon({ className, color, ...props }: IconProps) {
const classNames = iconVariants({ className, color })
return (
<svg
className={classNames}
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
{...props}
>
<path
d="M5 5H19.0001"
stroke="black"
strokeWidth="1.5"
strokeLinecap="round"
strokeLinejoin="round"
/>
<path
d="M12 9V19M12 9C11.2998 9 9.99153 10.9943 9.5 11.5M12 9C12.7002 9 14.0085 10.9943 14.5 11.5"
stroke="black"
strokeWidth="1.5"
strokeLinecap="round"
strokeLinejoin="round"
/>
</svg>
)
}

View File

@@ -0,0 +1,36 @@
import { iconVariants } from "./variants"
import type { IconProps } from "@/types/components/icon"
export default function SwipeIcon({ className, color, ...props }: IconProps) {
const classNames = iconVariants({ className, color })
return (
<svg
className={classNames}
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}
>
<mask
id="mask0_4743_35236"
style={{ maskType: "alpha" }}
maskUnits="userSpaceOnUse"
x="0"
y="0"
width="24"
height="24"
>
<rect width="24" height="24" fill="#D9D9D9" />
</mask>
<g mask="url(#mask0_4743_35236)">
<path
d="M11.825 22C11.425 22 11.0417 21.925 10.675 21.775C10.3083 21.625 9.98333 21.4083 9.7 21.125L4.6 16L5.35 15.225C5.61667 14.9583 5.92917 14.7792 6.2875 14.6875C6.64583 14.5958 7 14.6 7.35 14.7L9 15.175V7C9 6.71667 9.09583 6.47917 9.2875 6.2875C9.47917 6.09583 9.71667 6 10 6C10.2833 6 10.5208 6.09583 10.7125 6.2875C10.9042 6.47917 11 6.71667 11 7V17.825L8.575 17.15L11.125 19.7C11.2083 19.7833 11.3125 19.8542 11.4375 19.9125C11.5625 19.9708 11.6917 20 11.825 20H16C16.55 20 17.0208 19.8042 17.4125 19.4125C17.8042 19.0208 18 18.55 18 18V14C18 13.7167 18.0958 13.4792 18.2875 13.2875C18.4792 13.0958 18.7167 13 19 13C19.2833 13 19.5208 13.0958 19.7125 13.2875C19.9042 13.4792 20 13.7167 20 14V18C20 19.1 19.6083 20.0417 18.825 20.825C18.0417 21.6083 17.1 22 16 22H11.825ZM12 15V11C12 10.7167 12.0958 10.4792 12.2875 10.2875C12.4792 10.0958 12.7167 10 13 10C13.2833 10 13.5208 10.0958 13.7125 10.2875C13.9042 10.4792 14 10.7167 14 11V15H12ZM15 15V12C15 11.7167 15.0958 11.4792 15.2875 11.2875C15.4792 11.0958 15.7167 11 16 11C16.2833 11 16.5208 11.0958 16.7125 11.2875C16.9042 11.4792 17 11.7167 17 12V15H15ZM22 7H17V5.5H19.9C18.8 4.53333 17.575 3.79167 16.225 3.275C14.875 2.75833 13.4667 2.5 12 2.5C10.5333 2.5 9.125 2.75833 7.775 3.275C6.425 3.79167 5.2 4.53333 4.1 5.5H7V7H2V2H3.5V4.025C4.7 3.04167 6.025 2.29167 7.475 1.775C8.925 1.25833 10.4333 1 12 1C13.5667 1 15.075 1.25833 16.525 1.775C17.975 2.29167 19.3 3.04167 20.5 4.025V2H22V7Z"
fill="white"
/>
</g>
</svg>
)
}

View File

@@ -4,7 +4,9 @@ import {
AccountCircleIcon,
AirIcon,
AirplaneIcon,
ArrowFromIcon,
ArrowRightIcon,
ArrowToIcon,
BarIcon,
BedIcon,
BikingIcon,
@@ -106,6 +108,7 @@ import {
StarFilledIcon,
StreetIcon,
SwimIcon,
SwipeIcon,
ThermostatIcon,
TrainIcon,
TripAdvisorIcon,
@@ -135,8 +138,12 @@ export function getIconByIconName(
return AirIcon
case IconName.Airplane:
return AirplaneIcon
case IconName.ArrowFrom:
return ArrowFromIcon
case IconName.ArrowRight:
return ArrowRightIcon
case IconName.ArrowTo:
return ArrowToIcon
case IconName.Bar:
return BarIcon
case IconName.Bed:
@@ -339,6 +346,8 @@ export function getIconByIconName(
return StreetIcon
case IconName.Swim:
return SwimIcon
case IconName.Swipe:
return SwipeIcon
case IconName.Thermostat:
return ThermostatIcon
case IconName.Tshirt:

View File

@@ -5,7 +5,9 @@ export { default as AccountCircleIcon } from "./AccountCircle"
export { default as AirIcon } from "./Air"
export { default as AirplaneIcon } from "./Airplane"
export { default as AllergyIcon } from "./Allergy"
export { default as ArrowFromIcon } from "./ArrowFrom"
export { default as ArrowRightIcon } from "./ArrowRight"
export { default as ArrowToIcon } from "./ArrowTo"
export { default as ArrowUpIcon } from "./ArrowUp"
export { default as BalconyIcon } from "./Balcony"
export { default as BarIcon } from "./Bar"
@@ -170,6 +172,7 @@ export { default as StoreIcon } from "./Store"
export { default as StreetIcon } from "./Street"
export { default as SurpriseIcon } from "./Surprise"
export { default as SwimIcon } from "./Swim"
export { default as SwipeIcon } from "./Swipe"
export { default as ThermostatIcon } from "./Thermostat"
export { default as TrainIcon } from "./Train"
export { default as TripAdvisorIcon } from "./TripAdvisor"

View File

@@ -19,7 +19,7 @@ export type ModalProps = {
| {
trigger?: never
isOpen: boolean
onToggle: Dispatch<SetStateAction<boolean>>
onToggle: (open: boolean) => void
}
)

View File

@@ -1,3 +1,4 @@
import { cx } from "class-variance-authority"
import { type ForwardedRef, forwardRef, useId } from "react"
import { Input as AriaInput, Label as AriaLabel } from "react-aria-components"
@@ -18,7 +19,12 @@ const AriaInputWithLabel = forwardRef(function AriaInputWithLabelComponent(
return (
<AriaLabel className={styles.container} htmlFor={inputId}>
<Body asChild fontOnly>
<AriaInput {...props} className={styles.input} ref={ref} id={inputId} />
<AriaInput
{...props}
className={cx(styles.input, props.className)}
ref={ref}
id={inputId}
/>
</Body>
<Label required={!!props.required}>{label}</Label>
</AriaLabel>

View File

@@ -34,6 +34,7 @@ export default function Input({
evt.currentTarget.blur()
}
}
return (
<Controller
disabled={disabled}

View File

@@ -1,8 +1,10 @@
{
"+46 8 517 517 00": "+46 8 517 517 00",
"/night per adult": "/nat per voksen",
"1 EuroBonus point = 2 Scandic Friends points": "1 EuroBonus point = 2 Scandic Friends points",
"<b>Included</b> (based on availability)": "<b>Inkluderet</b> (baseret på tilgængelighed)",
"<b>Total price</b> (incl VAT)": "<b>Samlet pris</b> (inkl. moms)",
"<bold>{sasPoints, number} EuroBonus points</bold> to <bold>{scandicPoints, number} Scandic Friends points</bold>": "<bold>{sasPoints, number} EuroBonus points</bold> to <bold>{scandicPoints, number} Scandic Friends points</bold>",
"<sasMark>SAS {sasLevelName}</sasMark> and <scandicMark>{scandicLevelName}</scandicMark> are equally matched tiers. Level up one of your memberships for a chance of an upgrade!": "<sasMark>SAS {sasLevelName}</sasMark> and <scandicMark>{scandicLevelName}</scandicMark> are equally matched tiers. Level up one of your memberships for a chance of an upgrade!",
"<sasMark>SAS {sasLevelName}</sasMark> has upgraded your Scandic Friends level to <scandicMark>{scandicLevelName}</scandicMark>.": "<sasMark>SAS {sasLevelName}</sasMark> has upgraded your Scandic Friends level to <scandicMark>{scandicLevelName}</scandicMark>.",
"<scandicMark>Scandic {scandicLevelName}</scandicMark> has upgraded you to <sasMark>{sasLevelName}</sasMark>.": "<scandicMark>Scandic {scandicLevelName}</scandicMark> has upgraded you to <sasMark>{sasLevelName}</sasMark>.",
@@ -80,6 +82,7 @@
"Back to scandichotels.com": "Tilbage til scandichotels.com",
"Back to select room": "Tilbage til at vælge værelse",
"Back to top": "Tilbage til top",
"Balance": "Balance",
"Bar": "Bar",
"Based on availability": "Baseret på tilgængelighed",
"Bed": "Seng type",
@@ -91,11 +94,13 @@
"Birth date is missing": "Birth date is missing",
"Birth date: {dateOfBirth, date, ::MMMM d yyyy}": "Birth date: {dateOfBirth, date, ::MMMM d yyyy}",
"Boardroom": "Boardroom",
"Bonus Nights range from 10 000 - 80 000 points. Book your next stay with us today!": "Bonus Nights range from 10 000 - 80 000 points. Book your next stay with us today!",
"Book": "Book",
"Book Reward Night": "Book bonusnat",
"Book a meeting": "Book et møde",
"Book a table online": "Book et bord online",
"Book another stay": "Book another stay",
"Book now": "Book now",
"Book parking": "Book parkering",
"Book your next stay": "Book your next stay",
"Book {type} parking": "Book {type} parkering",
@@ -228,6 +233,7 @@
"Download invoice": "Download faktura",
"Download the Scandic app": "Download Scandic-appen",
"Driving directions": "Kørselsanvisning",
"EB points to transfer": "EB points to transfer",
"Earn & spend points": "Få medlemsfordele og tilbud",
"Earn bonus nights & points": "Optjen bonusnætter og point",
"Edit": "Redigere",
@@ -295,6 +301,7 @@
"Get member benefits & offers": "Få medlemsfordele og tilbud",
"Get the member price: {amount}": "Betal kun {amount}",
"Go back": "Go back",
"Go back to My Pages": "Go back to My Pages",
"Go back to edit": "Gå tilbage til redigering",
"Go back to overview": "Gå tilbage til oversigten",
"Go to My Benefits": "Gå til 'Mine fordele'",
@@ -548,7 +555,9 @@
"Please enter the code sent to <maskedContactInfo></maskedContactInfo> in order to unlink your accounts.": "Please enter the code sent to <maskedContactInfo></maskedContactInfo> in order to unlink your accounts.",
"Please note that this is mandatory, and that your card will only be charged in the event of a no-show.": "Vær opmærksom på, at dette er påkrævet, og at dit kort kun vil blive opkrævet i tilfælde af en no-show.",
"Please try and change your search for this destination or see alternative hotels.": "Please try and change your search for this destination or see alternative hotels.",
"Point transfer completed!": "Point transfer completed!",
"Points": "Point",
"Points added": "Points added",
"Points being calculated": "Point udregnes",
"Points earned prior to May 1, 2021": "Point optjent inden 1. maj 2021",
"Points may take up to 10 days to be displayed.": "Det kan tage op til 10 dage at få vist point.",
@@ -575,6 +584,7 @@
"Proceed to login": "Fortsæt til login",
"Proceed to payment": "Fortsæt til betalingsmetode",
"Proceed to payment method": "Gå videre til betalingsmetode",
"Proceed with point transfer?": "Proceed with point transfer?",
"Promo code": "Promo code",
"Provide a payment card in the next step": "Giv os dine betalingsoplysninger i næste skridt",
"Public price from": "Offentlig pris fra",
@@ -614,6 +624,8 @@
"Room {roomIndex}": "Værelse {roomIndex}",
"Rooms": "Værelser",
"Rooms & Guests": "Værelser & gæster",
"SAS EuroBonus": "SAS EuroBonus",
"SF points to receive": "SF points to receive",
"Saturday": "Lørdag",
"SatSun: Always open": "LørSøn: Altid åben",
"SatSun: {openingTime}{closingTime}": "LørSøn: {openingTime}{closingTime}",
@@ -622,8 +634,10 @@
"Save": "Gemme",
"Save card to profile": "Save card to profile",
"Save updates": "Gem ændringer",
"Scandic Friends": "Scandic Friends",
"Scandic Friends Mastercard": "Scandic Friends Mastercard",
"Scandic Friends Point Shop": "Scandic Friends Point Shop",
"Scandic Friends points": "{points, number} Scandic Friends points",
"Scandic ♥ SAS": "Scandic ♥ SAS",
"Search": "Søge",
"See all": "Se alle",
@@ -719,6 +733,10 @@
"Tourist": "Turist",
"Transaction date": "Overførselsdato",
"Transactions": "Transaktioner",
"Transfer from": "Transfer from",
"Transfer points": "Transfer points",
"Transfer to": "Transfer to",
"Transferred points will not be level qualifying": "Transferred points will not be level qualifying",
"Transportations": "Transport",
"TripAdvisor rating": "TripAdvisor vurdering",
"Try again": "Try again",
@@ -789,14 +807,18 @@
"Year": "År",
"Yes": "Ja",
"Yes, I accept the general <termsAndConditionsLink>Terms & Conditions</termsAndConditionsLink>, and understand that Scandic will process my personal data in accordance with <privacyPolicyLink>Scandic's Privacy policy</privacyPolicyLink>. There you can learn more about what data we process, your rights and where to turn if you have questions.": "Yes, I accept the general <termsAndConditionsLink>Terms & Conditions</termsAndConditionsLink>, and understand that Scandic will process my personal data in accordance with <privacyPolicyLink>Scandic's Privacy policy</privacyPolicyLink>. There you can learn more about what data we process, your rights and where to turn if you have questions.",
"Yes, I want to transfer my points": "Yes, I want to transfer my points",
"Yes, close and remove benefit": "Ja, luk og fjern fordel",
"Yes, discard changes": "Ja, kasser ændringer",
"Yes, redeem": "Yes, redeem",
"Yes, remove my card": "Ja, fjern mit kort",
"You are about to exchange:": "You are about to exchange:",
"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 still book the room but you need to confirm that you accept the new price": "Du kan stadig booke værelset, men du skal bekræfte, at du accepterer den nye pris",
"You canceled adding a new credit card.": "Du har annulleret tilføjelsen af et nyt kreditkort.",
"You have <b>{amount}</b> gifts waiting for you!": "Du har <b>{amount}</b> gaver, der venter på dig!",
"You have enough points for a bonus night!": "You have enough points for a bonus night!",
"You have no points to transfer.": "You have no points to transfer.",
"You have no previous stays.": "Du har ingen tidligere ophold.",
"You have no upcoming stays.": "Du har ingen kommende ophold.",
"You have now cancelled your payment.": "Du har nu annulleret din betaling.",
@@ -813,15 +835,18 @@
"Your card will only be used for authorisation": "Dit kort vil kun blive brugt til autorisation",
"Your current level": "Dit nuværende niveau",
"Your details": "Dine oplysninger",
"Your exchanged points will retain their original expiry date with a maximum validity of 12 months.": "Your exchanged points will retain their original expiry date with a maximum validity of 12 months.",
"Your hotel": "Your hotel",
"Your level": "Dit niveau",
"Your member tier": "Dit medlemskabsniveau",
"Your new total": "Your new total",
"Your points to spend": "Dine brugbare point",
"Your room": "Dit værelse",
"Your room will remain available for check-in even after 18:00.": "Dit værelse vil forblive tilgængeligt til check-in selv efter kl. 18.00.",
"Your selected bed type will be provided based on availability": "Din valgte sengtype vil blive stillet til rådighed baseret på tilgængelighed",
"Your stay was cancelled. Cancellation cost: 0 {currency}. We're sorry to see that the plans didn't work out": "Dit ophold blev annulleret. Annullereringspris: 0 {currency}. Vi beklager, at planerne ikke fungerede ud",
"Your stay was cancelled. Cancellation cost: 0 {currency}. Were sorry to see that the plans didnt work out": "Dit ophold blev annulleret. Annullereringspris: 0 {currency}. Vi beklager, at planerne ikke fungerede ud",
"Your transaction": "Your transaction",
"Zip code": "Postnummer",
"Zoo": "Zoo",
"Zoom in": "Zoom ind",
@@ -879,6 +904,10 @@
"{number} km to city center": "{number} km til centrum",
"{number} people": "{number} people",
"{points, number} Bonus points": "{points, number} Bonus points",
"{points, number} EuroBonus points": "{points, number} EuroBonus points",
"{points, number} Scandic Friends points": "{points, number} Scandic Friends points",
"{points, number} p": "{points, number} p",
"{points, number} points": "{points, number} points",
"{pointsAmount, number} points": "{pointsAmount, number} point",
"{points} spendable points expiring by {date}": "{points} Brugbare point udløber den {date}",
"{price} {currency}": "{price} {currency}",

View File

@@ -1,8 +1,10 @@
{
"+46 8 517 517 00": "+46 8 517 517 00",
"/night per adult": "/Nacht pro Erwachsenem",
"1 EuroBonus point = 2 Scandic Friends points": "1 EuroBonus point = 2 Scandic Friends points",
"<b>Included</b> (based on availability)": "<b>Inbegriffen</b> (je nach Verfügbarkeit)",
"<b>Total price</b> (incl VAT)": "<b>Gesamtpreis</b> (inkl. MwSt.)",
"<bold>{sasPoints, number} EuroBonus points</bold> to <bold>{scandicPoints, number} Scandic Friends points</bold>": "<bold>{sasPoints, number} EuroBonus points</bold> to <bold>{scandicPoints, number} Scandic Friends points</bold>",
"<sasMark>SAS {sasLevelName}</sasMark> and <scandicMark>{scandicLevelName}</scandicMark> are equally matched tiers. Level up one of your memberships for a chance of an upgrade!": "<sasMark>SAS {sasLevelName}</sasMark> and <scandicMark>{scandicLevelName}</scandicMark> are equally matched tiers. Level up one of your memberships for a chance of an upgrade!",
"<sasMark>SAS {sasLevelName}</sasMark> has upgraded your Scandic Friends level to <scandicMark>{scandicLevelName}</scandicMark>.": "<sasMark>SAS {sasLevelName}</sasMark> has upgraded your Scandic Friends level to <scandicMark>{scandicLevelName}</scandicMark>.",
"<scandicMark>Scandic {scandicLevelName}</scandicMark> has upgraded you to <sasMark>{sasLevelName}</sasMark>.": "<scandicMark>Scandic {scandicLevelName}</scandicMark> has upgraded you to <sasMark>{sasLevelName}</sasMark>.",
@@ -81,6 +83,7 @@
"Back to scandichotels.com": "Zurück zu scandichotels.com",
"Back to select room": "Zurück zur Zimmerauswahl",
"Back to top": "Zurück zur Spitze",
"Balance": "Balance",
"Bar": "Bar",
"Based on availability": "Je nach Verfügbarkeit",
"Bed": "Bettentyp",
@@ -92,11 +95,13 @@
"Birth date is missing": "Birth date is missing",
"Birth date: {dateOfBirth, date, ::MMMM d yyyy}": "Birth date: {dateOfBirth, date, ::MMMM d yyyy}",
"Boardroom": "Boardroom",
"Bonus Nights range from 10 000 - 80 000 points. Book your next stay with us today!": "Bonus Nights range from 10 000 - 80 000 points. Book your next stay with us today!",
"Book": "Buchen",
"Book Reward Night": "Bonusnacht buchen",
"Book a meeting": "Buchen Sie ein Meeting",
"Book a table online": "Tisch online buchen",
"Book another stay": "Book another stay",
"Book now": "Book now",
"Book parking": "Parkplatz buchen",
"Book your next stay": "Book your next stay",
"Book {type} parking": "Buchen Sie {type} Parkplatz",
@@ -229,6 +234,7 @@
"Download invoice": "Rechnung herunterladen",
"Download the Scandic app": "Laden Sie die Scandic-App herunter",
"Driving directions": "Anfahrtsbeschreibung",
"EB points to transfer": "EB points to transfer",
"Earn & spend points": "Holen Sie sich Vorteile und Angebote für Mitglieder",
"Earn bonus nights & points": "Sammeln Sie Bonusnächte und -punkte",
"Edit": "Bearbeiten",
@@ -296,6 +302,7 @@
"Get member benefits & offers": "Holen Sie sich Vorteile und Angebote für Mitglieder",
"Get the member price: {amount}": "Nur bezahlen {amount}",
"Go back": "Go back",
"Go back to My Pages": "Go back to My Pages",
"Go back to edit": "Zurück zum Bearbeiten",
"Go back to overview": "Zurück zur Übersicht",
"Go to My Benefits": "Gehen Sie zu „Meine Vorteile“",
@@ -547,7 +554,9 @@
"Please enter the code sent to <maskedContactInfo></maskedContactInfo> in order to unlink your accounts.": "Please enter the code sent to <maskedContactInfo></maskedContactInfo> in order to unlink your accounts.",
"Please note that this is mandatory, and that your card will only be charged in the event of a no-show.": "Bitte beachten Sie, dass dies erforderlich ist und dass Ihr Kreditkartenkonto nur in einem No-Show-Fall belastet wird.",
"Please try and change your search for this destination or see alternative hotels.": "Please try and change your search for this destination or see alternative hotels.",
"Point transfer completed!": "Point transfer completed!",
"Points": "Punkte",
"Points added": "Points added",
"Points being calculated": "Punkte werden berechnet",
"Points earned prior to May 1, 2021": "Zusammengeführte Punkte vor dem 1. Mai 2021",
"Points may take up to 10 days to be displayed.": "Es kann bis zu 10 Tage dauern, bis Punkte angezeigt werden.",
@@ -574,6 +583,7 @@
"Proceed to login": "Weiter zum Login",
"Proceed to payment": "Weiter zur Zahlungsmethode",
"Proceed to payment method": "Zum Zahlungsmethode wechseln",
"Proceed with point transfer?": "Proceed with point transfer?",
"Promo code": "Promo code",
"Provide a payment card in the next step": "Geben Sie Ihre Zahlungskarteninformationen im nächsten Schritt an",
"Public price from": "Öffentlicher Preis ab",
@@ -613,6 +623,8 @@
"Room {roomIndex}": "Zimmer {roomIndex}",
"Rooms": "Räume",
"Rooms & Guests": "Zimmer & Gäste",
"SAS EuroBonus": "SAS EuroBonus",
"SF points to receive": "SF points to receive",
"Saturday": "Samstag",
"SatSun: Always open": "SaSo: Immer geöffnet",
"SatSun: {openingTime}{closingTime}": "SaSo: {openingTime}{closingTime}",
@@ -621,8 +633,10 @@
"Save": "Speichern",
"Save card to profile": "Save card to profile",
"Save updates": "Updates speichern",
"Scandic Friends": "Scandic Friends",
"Scandic Friends Mastercard": "Scandic Friends Mastercard",
"Scandic Friends Point Shop": "Scandic Friends Point Shop",
"Scandic Friends points": "{points, number} Scandic Friends points",
"Scandic ♥ SAS": "Scandic ♥ SAS",
"Search": "Suchen",
"See all": "Alle anzeigen",
@@ -717,6 +731,10 @@
"Tourist": "Tourist",
"Transaction date": "Transaktionsdatum",
"Transactions": "Transaktionen",
"Transfer from": "Transfer from",
"Transfer points": "Transfer points",
"Transfer to": "Transfer to",
"Transferred points will not be level qualifying": "Transferred points will not be level qualifying",
"Transportations": "Transportmittel",
"TripAdvisor rating": "TripAdvisor-Bewertung",
"Try again": "Try again",
@@ -787,14 +805,18 @@
"Year": "Jahr",
"Yes": "Ja",
"Yes, I accept the general <termsAndConditionsLink>Terms & Conditions</termsAndConditionsLink>, and understand that Scandic will process my personal data in accordance with <privacyPolicyLink>Scandic's Privacy policy</privacyPolicyLink>. There you can learn more about what data we process, your rights and where to turn if you have questions.": "Yes, I accept the general <termsAndConditionsLink>Terms & Conditions</termsAndConditionsLink>, and understand that Scandic will process my personal data in accordance with <privacyPolicyLink>Scandic's Privacy policy</privacyPolicyLink>. There you can learn more about what data we process, your rights and where to turn if you have questions.",
"Yes, I want to transfer my points": "Yes, I want to transfer my points",
"Yes, close and remove benefit": "Ja, Vorteil schließen und entfernen",
"Yes, discard changes": "Ja, Änderungen verwerfen",
"Yes, redeem": "Yes, redeem",
"Yes, remove my card": "Ja, meine Karte entfernen",
"You are about to exchange:": "You are about to exchange:",
"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 still book the room but you need to confirm that you accept the new price": "Sie können das Zimmer noch buchen, aber Sie müssen bestätigen, dass Sie die neue Preis akzeptieren",
"You canceled adding a new credit card.": "Sie haben das Hinzufügen einer neuen Kreditkarte abgebrochen.",
"You have <b>{amount}</b> gifts waiting for you!": "Es warten <b>{amount}</b> Geschenke auf Sie!",
"You have enough points for a bonus night!": "You have enough points for a bonus night!",
"You have no points to transfer.": "You have no points to transfer.",
"You have no previous stays.": "Sie haben keine vorherigen Aufenthalte.",
"You have no upcoming stays.": "Sie haben keine bevorstehenden Aufenthalte.",
"You have now cancelled your payment.": "Sie haben jetzt Ihre Zahlung abgebrochen.",
@@ -811,15 +833,18 @@
"Your card will only be used for authorisation": "Ihre Karte wird nur zur Autorisierung verwendet",
"Your current level": "Ihr aktuelles Level",
"Your details": "Ihre Angaben",
"Your exchanged points will retain their original expiry date with a maximum validity of 12 months.": "Your exchanged points will retain their original expiry date with a maximum validity of 12 months.",
"Your hotel": "Your hotel",
"Your level": "Dein level",
"Your member tier": "Ihr Mitgliedsniveau",
"Your new total": "Your new total",
"Your points to spend": "Meine Punkte",
"Your room": "Ihr Zimmer",
"Your room will remain available for check-in even after 18:00.": "Ihr Zimmer bleibt auch nach 18:00 Uhr zum Check-in verfügbar.",
"Your selected bed type will be provided based on availability": "Ihre ausgewählte Bettart wird basierend auf der Verfügbarkeit bereitgestellt",
"Your stay was cancelled. Cancellation cost: 0 {currency}. We're sorry to see that the plans didn't work out": "Ihr Aufenthalt wurde storniert. Stornierungskosten: 0 {currency}. Es tut uns leid, dass die Pläne nicht funktionierten",
"Your stay was cancelled. Cancellation cost: 0 {currency}. Were sorry to see that the plans didnt work out": "Ihr Aufenthalt wurde storniert. Stornierungskosten: 0 {currency}. Es tut uns leid, dass die Pläne nicht funktionierten",
"Your transaction": "Your transaction",
"Zip code": "PLZ",
"Zoo": "Zoo",
"Zoom in": "Vergrößern",
@@ -877,6 +902,10 @@
"{number} km to city center": "{number} km zum Stadtzentrum",
"{number} people": "{number} people",
"{points, number} Bonus points": "{points, number} Bonus points",
"{points, number} EuroBonus points": "{points, number} EuroBonus points",
"{points, number} Scandic Friends points": "{points, number} Scandic Friends points",
"{points, number} p": "{points, number} p",
"{points, number} points": "{points, number} points",
"{pointsAmount, number} points": "{pointsAmount, number} punkte",
"{points} spendable points expiring by {date}": "{points} Einlösbare punkte verfallen bis zum {date}",
"{price} {currency}": "{price} {currency}",

View File

@@ -1,8 +1,10 @@
{
"+46 8 517 517 00": "+46 8 517 517 00",
"/night per adult": "/night per adult",
"1 EuroBonus point = 2 Scandic Friends points": "1 EuroBonus point = 2 Scandic Friends points",
"<b>Included</b> (based on availability)": "<b>Included</b> (based on availability)",
"<b>Total price</b> (incl VAT)": "<b>Total price</b> (incl VAT)",
"<bold>{sasPoints, number} EuroBonus points</bold> to <bold>{scandicPoints, number} Scandic Friends points</bold>": "<bold>{sasPoints, number} EuroBonus points</bold> to <bold>{scandicPoints, number} Scandic Friends points</bold>",
"<sasMark>SAS {sasLevelName}</sasMark> and <scandicMark>{scandicLevelName}</scandicMark> are equally matched tiers. Level up one of your memberships for a chance of an upgrade!": "<sasMark>SAS {sasLevelName}</sasMark> and <scandicMark>{scandicLevelName}</scandicMark> are equally matched tiers. Level up one of your memberships for a chance of an upgrade!",
"<sasMark>SAS {sasLevelName}</sasMark> has upgraded your Scandic Friends level to <scandicMark>{scandicLevelName}</scandicMark>.": "<sasMark>SAS {sasLevelName}</sasMark> has upgraded your Scandic Friends level to <scandicMark>{scandicLevelName}</scandicMark>.",
"<scandicMark>Scandic {scandicLevelName}</scandicMark> has upgraded you to <sasMark>{sasLevelName}</sasMark>.": "<scandicMark>Scandic {scandicLevelName}</scandicMark> has upgraded you to <sasMark>{sasLevelName}</sasMark>.",
@@ -79,6 +81,7 @@
"Back to scandichotels.com": "Back to scandichotels.com",
"Back to select room": "Back to select room",
"Back to top": "Back to top",
"Balance": "Balance",
"Bar": "Bar",
"Based on availability": "Based on availability",
"Bed": "Bed",
@@ -90,11 +93,13 @@
"Birth date is missing": "Birth date is missing",
"Birth date: {dateOfBirth, date, ::MMMM d yyyy}": "Birth date: {dateOfBirth, date, ::MMMM d yyyy}",
"Boardroom": "Boardroom",
"Bonus Nights range from 10 000 - 80 000 points. Book your next stay with us today!": "Bonus Nights range from 10 000 - 80 000 points. Book your next stay with us today!",
"Book": "Book",
"Book Reward Night": "Book Reward Night",
"Book a meeting": "Book a meeting",
"Book a table online": "Book a table online",
"Book another stay": "Book another stay",
"Book now": "Book now",
"Book parking": "Book parking",
"Book your next stay": "Book your next stay",
"Book {type} parking": "Book {type} parking",
@@ -227,6 +232,7 @@
"Download invoice": "Download invoice",
"Download the Scandic app": "Download the Scandic app",
"Driving directions": "Driving directions",
"EB points to transfer": "EB points to transfer",
"Earn & spend points": "Earn & spend points",
"Earn bonus nights & points": "Earn bonus nights & points",
"Edit": "Edit",
@@ -294,6 +300,7 @@
"Get member benefits & offers": "Get member benefits & offers",
"Get the member price: {amount}": "Get the member price: {amount}",
"Go back": "Go back",
"Go back to My Pages": "Go back to My Pages",
"Go back to edit": "Go back to edit",
"Go back to overview": "Go back to overview",
"Go to My Benefits": "Go to My Benefits",
@@ -546,7 +553,9 @@
"Please enter the code sent to <maskedContactInfo></maskedContactInfo> in order to unlink your accounts.": "Please enter the code sent to <maskedContactInfo></maskedContactInfo> in order to unlink your accounts.",
"Please note that this is mandatory, and that your card will only be charged in the event of a no-show.": "Please note that this is mandatory, and that your card will only be charged in the event of a no-show.",
"Please try and change your search for this destination or see alternative hotels.": "Please try and change your search for this destination or see alternative hotels.",
"Point transfer completed!": "Point transfer completed!",
"Points": "Points",
"Points added": "Points added",
"Points being calculated": "Points being calculated",
"Points earned prior to May 1, 2021": "Points earned prior to May 1, 2021",
"Points may take up to 10 days to be displayed.": "Points may take up to 10 days to be displayed.",
@@ -573,6 +582,7 @@
"Proceed to login": "Proceed to login",
"Proceed to payment": "Proceed to payment",
"Proceed to payment method": "Proceed to payment method",
"Proceed with point transfer?": "Proceed with point transfer?",
"Promo code": "Promo code",
"Provide a payment card in the next step": "Provide a payment card in the next step",
"Public price from": "Public price from",
@@ -612,6 +622,8 @@
"Room {roomIndex}": "Room {roomIndex}",
"Rooms": "Rooms",
"Rooms & Guests": "Rooms & Guests",
"SAS EuroBonus": "SAS EuroBonus",
"SF points to receive": "SF points to receive",
"Saturday": "Saturday",
"SatSun: Always open": "SatSun: Always open",
"SatSun: {openingTime}{closingTime}": "SatSun: {openingTime}{closingTime}",
@@ -620,8 +632,10 @@
"Save": "Save",
"Save card to profile": "Save card to profile",
"Save updates": "Save updates",
"Scandic Friends": "Scandic Friends",
"Scandic Friends Mastercard": "Scandic Friends Mastercard",
"Scandic Friends Point Shop": "Scandic Friends Point Shop",
"Scandic Friends points": "{points, number} Scandic Friends points",
"Scandic ♥ SAS": "Scandic ♥ SAS",
"Search": "Search",
"See all": "See all",
@@ -715,6 +729,10 @@
"Tourist": "Tourist",
"Transaction date": "Transaction date",
"Transactions": "Transactions",
"Transfer from": "Transfer from",
"Transfer points": "Transfer points",
"Transfer to": "Transfer to",
"Transferred points will not be level qualifying": "Transferred points will not be level qualifying",
"Transportations": "Transportations",
"TripAdvisor rating": "TripAdvisor rating",
"Try again": "Try again",
@@ -785,14 +803,18 @@
"Year": "Year",
"Yes": "Yes",
"Yes, I accept the general <termsAndConditionsLink>Terms & Conditions</termsAndConditionsLink>, and understand that Scandic will process my personal data in accordance with <privacyPolicyLink>Scandic's Privacy policy</privacyPolicyLink>. There you can learn more about what data we process, your rights and where to turn if you have questions.": "Yes, I accept the general <termsAndConditionsLink>Terms & Conditions</termsAndConditionsLink>, and understand that Scandic will process my personal data in accordance with <privacyPolicyLink>Scandic's Privacy policy</privacyPolicyLink>. There you can learn more about what data we process, your rights and where to turn if you have questions.",
"Yes, I want to transfer my points": "Yes, I want to transfer my points",
"Yes, close and remove benefit": "Yes, close and remove benefit",
"Yes, discard changes": "Yes, discard changes",
"Yes, redeem": "Yes, redeem",
"Yes, remove my card": "Yes, remove my card",
"You are about to exchange:": "You are about to exchange:",
"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 still book the room but you need to confirm that you accept the new price": "You can still book the room but you need to confirm that you accept the new price",
"You canceled adding a new credit card.": "You canceled adding a new credit card.",
"You have <b>{amount}</b> gifts waiting for you!": "You have <b>{amount}</b> gifts waiting for you!",
"You have enough points for a bonus night!": "You have enough points for a bonus night!",
"You have no points to transfer.": "You have no points to transfer.",
"You have no previous stays.": "You have no previous stays.",
"You have no upcoming stays.": "You have no upcoming stays.",
"You have now cancelled your payment.": "You have now cancelled your payment.",
@@ -809,15 +831,18 @@
"Your card will only be used for authorisation": "Your card will only be used for authorisation",
"Your current level": "Your current level",
"Your details": "Your details",
"Your exchanged points will retain their original expiry date with a maximum validity of 12 months.": "Your exchanged points will retain their original expiry date with a maximum validity of 12 months.",
"Your hotel": "Your hotel",
"Your level": "Your level",
"Your member tier": "Your member tier",
"Your new total": "Your new total",
"Your points to spend": "Your points to spend",
"Your room": "Your room",
"Your room will remain available for check-in even after 18:00.": "Your room will remain available for check-in even after 18:00.",
"Your selected bed type will be provided based on availability": "Your selected bed type will be provided based on availability",
"Your stay was cancelled. Cancellation cost: 0 {currency}. We're sorry to see that the plans didn't work out": "Your stay was cancelled. Cancellation cost: 0 {currency}. We're sorry to see that the plans didn't work out",
"Your stay was cancelled. Cancellation cost: 0 {currency}. Were sorry to see that the plans didnt work out": "Your stay was cancelled. Cancellation cost: 0 {currency}. Were sorry to see that the plans didnt work out",
"Your transaction": "Your transaction",
"Zip code": "Zip code",
"Zoo": "Zoo",
"Zoom in": "Zoom in",
@@ -872,6 +897,10 @@
"{number} km to city center": "{number} km to city center",
"{number} people": "{number} people",
"{points, number} Bonus points": "{points, number} Bonus points",
"{points, number} EuroBonus points": "{points, number} EuroBonus points",
"{points, number} Scandic Friends points": "{points, number} Scandic Friends points",
"{points, number} p": "{points, number} p",
"{points, number} points": "{points, number} points",
"{pointsAmount, number} points": "{pointsAmount, number} points",
"{points} spendable points expiring by {date}": "{points} spendable points expiring by {date}",
"{price} {currency}": "{price} {currency}",

View File

@@ -1,8 +1,10 @@
{
"+46 8 517 517 00": "+46 8 517 517 00",
"/night per adult": "/yötä aikuista kohti",
"1 EuroBonus point = 2 Scandic Friends points": "1 EuroBonus point = 2 Scandic Friends points",
"<b>Included</b> (based on availability)": "<b>Sisältyy</b> (saatavuuden mukaan)",
"<b>Total price</b> (incl VAT)": "<b>Kokonaishinta</b> (sis. ALV)",
"<bold>{sasPoints, number} EuroBonus points</bold> to <bold>{scandicPoints, number} Scandic Friends points</bold>": "<bold>{sasPoints, number} EuroBonus points</bold> to <bold>{scandicPoints, number} Scandic Friends points</bold>",
"<sasMark>SAS {sasLevelName}</sasMark> and <scandicMark>{scandicLevelName}</scandicMark> are equally matched tiers. Level up one of your memberships for a chance of an upgrade!": "<sasMark>SAS {sasLevelName}</sasMark> and <scandicMark>{scandicLevelName}</scandicMark> are equally matched tiers. Level up one of your memberships for a chance of an upgrade!",
"<sasMark>SAS {sasLevelName}</sasMark> has upgraded your Scandic Friends level to <scandicMark>{scandicLevelName}</scandicMark>.": "<sasMark>SAS {sasLevelName}</sasMark> has upgraded your Scandic Friends level to <scandicMark>{scandicLevelName}</scandicMark>.",
"<scandicMark>Scandic {scandicLevelName}</scandicMark> has upgraded you to <sasMark>{sasLevelName}</sasMark>.": "<scandicMark>Scandic {scandicLevelName}</scandicMark> has upgraded you to <sasMark>{sasLevelName}</sasMark>.",
@@ -79,6 +81,7 @@
"Back to scandichotels.com": "Takaisin scandichotels.com",
"Back to select room": "Palaa huoneen valintaan",
"Back to top": "Takaisin ylös",
"Balance": "Balance",
"Bar": "Bar",
"Based on availability": "Saatavuuden mukaan",
"Bed": "Vuodetyyppi",
@@ -90,11 +93,13 @@
"Birth date is missing": "Birth date is missing",
"Birth date: {dateOfBirth, date, ::MMMM d yyyy}": "Birth date: {dateOfBirth, date, ::MMMM d yyyy}",
"Boardroom": "Boardroom",
"Bonus Nights range from 10 000 - 80 000 points. Book your next stay with us today!": "Bonus Nights range from 10 000 - 80 000 points. Book your next stay with us today!",
"Book": "Varaa",
"Book Reward Night": "Kirjapalkinto-ilta",
"Book a meeting": "Varaa kokous",
"Book a table online": "Varaa pöytä verkossa",
"Book another stay": "Book another stay",
"Book now": "Book now",
"Book parking": "Varaa pysäköinti",
"Book your next stay": "Book your next stay",
"Book {type} parking": "Varaa {type} pysäköinti",
@@ -228,6 +233,7 @@
"Download invoice": "Lataa lasku",
"Download the Scandic app": "Lataa Scandic-sovellus",
"Driving directions": "Ajo-ohjeet",
"EB points to transfer": "EB points to transfer",
"Earn & spend points": "Hanki jäsenetuja ja -tarjouksia",
"Earn bonus nights & points": "Ansaitse bonusöitä ja pisteitä",
"Edit": "Muokata",
@@ -295,6 +301,7 @@
"Get member benefits & offers": "Hanki jäsenetuja ja -tarjouksia",
"Get the member price: {amount}": "Vain maksaa {amount}",
"Go back": "Go back",
"Go back to My Pages": "Go back to My Pages",
"Go back to edit": "Palaa muokkaamaan",
"Go back to overview": "Palaa yleiskatsaukseen",
"Go to My Benefits": "Siirry kohtaan 'Omat edut'",
@@ -546,7 +553,9 @@
"Please enter the code sent to <maskedContactInfo></maskedContactInfo> in order to unlink your accounts.": "Please enter the code sent to <maskedContactInfo></maskedContactInfo> in order to unlink your accounts.",
"Please note that this is mandatory, and that your card will only be charged in the event of a no-show.": "Huomaa, että tämä on pakollinen, ja että maksukorttiisi kirjataan vain, jos varausmyyntiä ei tapahtu.",
"Please try and change your search for this destination or see alternative hotels.": "Please try and change your search for this destination or see alternative hotels.",
"Point transfer completed!": "Point transfer completed!",
"Points": "Pisteet",
"Points added": "Points added",
"Points being calculated": "Pisteitä lasketaan",
"Points earned prior to May 1, 2021": "Pisteet, jotka ansaittu ennen 1.5.2021",
"Points may take up to 10 days to be displayed.": "Pisteiden näyttäminen voi kestää jopa 10 päivää.",
@@ -573,6 +582,7 @@
"Proceed to login": "Jatka kirjautumiseen",
"Proceed to payment": "Siirry maksutavalle",
"Proceed to payment method": "Siirry maksutapaan",
"Proceed with point transfer?": "Proceed with point transfer?",
"Promo code": "Promo code",
"Provide a payment card in the next step": "Anna maksukortin tiedot seuraavassa vaiheessa",
"Public price from": "Julkinen hinta alkaen",
@@ -613,6 +623,8 @@
"Rooms": "Huoneet",
"Rooms & Guests": "Huoneet & Vieraat",
"Rooms & Guestss": "Huoneet & Vieraat",
"SAS EuroBonus": "SAS EuroBonus",
"SF points to receive": "SF points to receive",
"Saturday": "Lauantai",
"SatSun: Always open": "LaSu: Aina auki",
"SatSun: {openingTime}{closingTime}": "LaSu: {openingTime}{closingTime}",
@@ -621,8 +633,10 @@
"Save": "Tallenna",
"Save card to profile": "Save card to profile",
"Save updates": "Tallenna muutokset",
"Scandic Friends": "Scandic Friends",
"Scandic Friends Mastercard": "Scandic Friends Mastercard",
"Scandic Friends Point Shop": "Scandic Friends Point Shop",
"Scandic Friends points": "{points, number} Scandic Friends points",
"Scandic ♥ SAS": "Scandic ♥ SAS",
"Search": "Haku",
"See all": "Katso kaikki",
@@ -717,6 +731,10 @@
"Tourist": "Turisti",
"Transaction date": "Tapahtuman päivämäärä",
"Transactions": "Tapahtumat",
"Transfer from": "Transfer from",
"Transfer points": "Transfer points",
"Transfer to": "Transfer to",
"Transferred points will not be level qualifying": "Transferred points will not be level qualifying",
"Transportations": "Kuljetukset",
"TripAdvisor rating": "TripAdvisor-luokitus",
"Try again": "Try again",
@@ -787,14 +805,18 @@
"Year": "Vuosi",
"Yes": "Kyllä",
"Yes, I accept the general <termsAndConditionsLink>Terms & Conditions</termsAndConditionsLink>, and understand that Scandic will process my personal data in accordance with <privacyPolicyLink>Scandic's Privacy policy</privacyPolicyLink>. There you can learn more about what data we process, your rights and where to turn if you have questions.": "Yes, I accept the general <termsAndConditionsLink>Terms & Conditions</termsAndConditionsLink>, and understand that Scandic will process my personal data in accordance with <privacyPolicyLink>Scandic's Privacy policy</privacyPolicyLink>. There you can learn more about what data we process, your rights and where to turn if you have questions.",
"Yes, I want to transfer my points": "Yes, I want to transfer my points",
"Yes, close and remove benefit": "Kyllä, sulje ja poista etu",
"Yes, discard changes": "Kyllä, hylkää muutokset",
"Yes, redeem": "Yes, redeem",
"Yes, remove my card": "Kyllä, poista korttini",
"You are about to exchange:": "You are about to exchange:",
"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 still book the room but you need to confirm that you accept the new price": "Voit vielä bookea huoneen, mutta sinun on vahvistettava, että hyväksyt uuden hinnan",
"You canceled adding a new credit card.": "Peruutit uuden luottokortin lisäämisen.",
"You have <b>{amount}</b> gifts waiting for you!": "Sinulla on <b>{amount}</b> lahjaa odottamassa sinua!",
"You have enough points for a bonus night!": "You have enough points for a bonus night!",
"You have no points to transfer.": "You have no points to transfer.",
"You have no previous stays.": "Sinulla ei ole aiempia majoituksia.",
"You have no upcoming stays.": "Sinulla ei ole tulevia majoituksia.",
"You have now cancelled your payment.": "Sinut nyt peruutit maksun.",
@@ -811,15 +833,18 @@
"Your card will only be used for authorisation": "Korttiasi käytetään vain valtuutukseen",
"Your current level": "Nykyinen tasosi",
"Your details": "Tietosi",
"Your exchanged points will retain their original expiry date with a maximum validity of 12 months.": "Your exchanged points will retain their original expiry date with a maximum validity of 12 months.",
"Your hotel": "Your hotel",
"Your level": "Tasosi",
"Your member tier": "Sinun jäsenyysluokkasi",
"Your new total": "Your new total",
"Your points to spend": "Käytettävissä olevat pisteesi",
"Your room": "Sinun huoneesi",
"Your room will remain available for check-in even after 18:00.": "Huoneesi on käytettävissä sisäänkirjautumista varten myös klo 18.00 jälkeen.",
"Your selected bed type will be provided based on availability": "Valitun vuodetyypin toimitetaan saatavuuden mukaan",
"Your stay was cancelled. Cancellation cost: 0 {currency}. We're sorry to see that the plans didn't work out": "Majoituksesi peruutettiin. Peruutusmaksu: 0 {currency}. Emme voi käyttää sitä, että suunnitellut majoitukset eivät toiminneet",
"Your stay was cancelled. Cancellation cost: 0 {currency}. Were sorry to see that the plans didnt work out": "Majoituksesi peruutettiin. Peruutusmaksu: 0 {currency}. Emme voi käyttää sitä, että suunnitellut majoitukset eivät toiminneet",
"Your transaction": "Your transaction",
"Zip code": "Postinumero",
"Zoo": "Eläintarha",
"Zoom in": "Lähennä",
@@ -877,6 +902,10 @@
"{number} km to city center": "{number} km Etäisyys kaupunkiin",
"{number} people": "{number} people",
"{points, number} Bonus points": "{points, number} Bonus points",
"{points, number} EuroBonus points": "{points, number} EuroBonus points",
"{points, number} Scandic Friends points": "{points, number} Scandic Friends points",
"{points, number} p": "{points, number} p",
"{points, number} points": "{points, number} points",
"{pointsAmount, number} points": "{pointsAmount, number} pistettä",
"{points} spendable points expiring by {date}": "{points} pistettä vanhenee {date} mennessä",
"{price} {currency}": "{price} {currency}",

View File

@@ -1,8 +1,10 @@
{
"+46 8 517 517 00": "+46 8 517 517 00",
"/night per adult": "/natt per voksen",
"1 EuroBonus point = 2 Scandic Friends points": "1 EuroBonus point = 2 Scandic Friends points",
"<b>Included</b> (based on availability)": "<b>Inkludert</b> (basert på tilgjengelighet)",
"<b>Total price</b> (incl VAT)": "<b>Totalpris</b> (inkl. mva)",
"<bold>{sasPoints, number} EuroBonus points</bold> to <bold>{scandicPoints, number} Scandic Friends points</bold>": "<bold>{sasPoints, number} EuroBonus points</bold> to <bold>{scandicPoints, number} Scandic Friends points</bold>",
"<sasMark>SAS {sasLevelName}</sasMark> and <scandicMark>{scandicLevelName}</scandicMark> are equally matched tiers. Level up one of your memberships for a chance of an upgrade!": "<sasMark>SAS {sasLevelName}</sasMark> and <scandicMark>{scandicLevelName}</scandicMark> are equally matched tiers. Level up one of your memberships for a chance of an upgrade!",
"<sasMark>SAS {sasLevelName}</sasMark> has upgraded your Scandic Friends level to <scandicMark>{scandicLevelName}</scandicMark>.": "<sasMark>SAS {sasLevelName}</sasMark> has upgraded your Scandic Friends level to <scandicMark>{scandicLevelName}</scandicMark>.",
"<scandicMark>Scandic {scandicLevelName}</scandicMark> has upgraded you to <sasMark>{sasLevelName}</sasMark>.": "<scandicMark>Scandic {scandicLevelName}</scandicMark> has upgraded you to <sasMark>{sasLevelName}</sasMark>.",
@@ -79,6 +81,7 @@
"Back to scandichotels.com": "Tilbake til scandichotels.com",
"Back to select room": "Tilbake til å velge rom",
"Back to top": "Tilbake til toppen",
"Balance": "Balance",
"Bar": "Bar",
"Based on availability": "Basert på tilgjengelighet",
"Bed": "Seng type",
@@ -90,11 +93,13 @@
"Birth date is missing": "Birth date is missing",
"Birth date: {dateOfBirth, date, ::MMMM d yyyy}": "Birth date: {dateOfBirth, date, ::MMMM d yyyy}",
"Boardroom": "Boardroom",
"Bonus Nights range from 10 000 - 80 000 points. Book your next stay with us today!": "Bonus Nights range from 10 000 - 80 000 points. Book your next stay with us today!",
"Book": "Bestill",
"Book Reward Night": "Bestill belønningskveld",
"Book a meeting": "Bestill et møte",
"Book a table online": "Bestill bord online",
"Book another stay": "Book another stay",
"Book now": "Book now",
"Book parking": "Bestill parkering",
"Book your next stay": "Book your next stay",
"Book {type} parking": "Book {type} parkering",
@@ -227,6 +232,7 @@
"Download invoice": "Last ned faktura",
"Download the Scandic app": "Last ned Scandic-appen",
"Driving directions": "Veibeskrivelser",
"EB points to transfer": "EB points to transfer",
"Earn & spend points": "Få medlemsfordeler og tilbud",
"Earn bonus nights & points": "Tjen bonusnetter og poeng",
"Edit": "Redigere",
@@ -294,6 +300,7 @@
"Get member benefits & offers": "Få medlemsfordeler og tilbud",
"Get the member price: {amount}": "Bare betal {amount}",
"Go back": "Go back",
"Go back to My Pages": "Go back to My Pages",
"Go back to edit": "Gå tilbake til redigering",
"Go back to overview": "Gå tilbake til oversikten",
"Go to My Benefits": "Gå til 'Mine fordeler'",
@@ -545,7 +552,9 @@
"Please enter the code sent to <maskedContactInfo></maskedContactInfo> in order to unlink your accounts.": "Please enter the code sent to <maskedContactInfo></maskedContactInfo> in order to unlink your accounts.",
"Please note that this is mandatory, and that your card will only be charged in the event of a no-show.": "Vær oppmerksom på at dette er påkrevd, og at ditt kredittkort kun vil bli belastet i tilfelle av en no-show.",
"Please try and change your search for this destination or see alternative hotels.": "Please try and change your search for this destination or see alternative hotels.",
"Point transfer completed!": "Point transfer completed!",
"Points": "Poeng",
"Points added": "Points added",
"Points being calculated": "Poeng beregnes",
"Points earned prior to May 1, 2021": "Opptjente poeng før 1. mai 2021",
"Points may take up to 10 days to be displayed.": "Det kan ta opptil 10 dager før poeng vises.",
@@ -572,6 +581,7 @@
"Proceed to login": "Fortsett til innlogging",
"Proceed to payment": "Fortsett til betalingsmetode",
"Proceed to payment method": "Gå videre til betalingsmetode",
"Proceed with point transfer?": "Proceed with point transfer?",
"Promo code": "Promo code",
"Provide a payment card in the next step": "Gi oss dine betalingskortdetaljer i neste steg",
"Public price from": "Offentlig pris fra",
@@ -610,6 +620,8 @@
"Room {roomIndex}": "Rom {roomIndex}",
"Rooms": "Rom",
"Rooms & Guests": "Rom og gjester",
"SAS EuroBonus": "SAS EuroBonus",
"SF points to receive": "SF points to receive",
"Saturday": "Lørdag",
"SatSun: Always open": "LørSøn: Alltid åpen",
"SatSun: {openingTime}{closingTime}": "LørSøn: {openingTime}{closingTime}",
@@ -618,8 +630,10 @@
"Save": "Lagre",
"Save card to profile": "Save card to profile",
"Save updates": "Lagre endringer",
"Scandic Friends": "Scandic Friends",
"Scandic Friends Mastercard": "Scandic Friends Mastercard",
"Scandic Friends Point Shop": "Scandic Friends Point Shop",
"Scandic Friends points": "{points, number} Scandic Friends points",
"Scandic ♥ SAS": "Scandic ♥ SAS",
"Search": "Søk",
"See all": "Se alle",
@@ -714,6 +728,10 @@
"Tourist": "Turist",
"Transaction date": "Transaksjonsdato",
"Transactions": "Transaksjoner",
"Transfer from": "Transfer from",
"Transfer points": "Transfer points",
"Transfer to": "Transfer to",
"Transferred points will not be level qualifying": "Transferred points will not be level qualifying",
"Transportations": "Transport",
"TripAdvisor rating": "TripAdvisor vurdering",
"Try again": "Try again",
@@ -783,14 +801,18 @@
"Year": "År",
"Yes": "Ja",
"Yes, I accept the general <termsAndConditionsLink>Terms & Conditions</termsAndConditionsLink>, and understand that Scandic will process my personal data in accordance with <privacyPolicyLink>Scandic's Privacy policy</privacyPolicyLink>. There you can learn more about what data we process, your rights and where to turn if you have questions.": "Yes, I accept the general <termsAndConditionsLink>Terms & Conditions</termsAndConditionsLink>, and understand that Scandic will process my personal data in accordance with <privacyPolicyLink>Scandic's Privacy policy</privacyPolicyLink>. There you can learn more about what data we process, your rights and where to turn if you have questions.",
"Yes, I want to transfer my points": "Yes, I want to transfer my points",
"Yes, close and remove benefit": "Ja, lukk og fjern fordel",
"Yes, discard changes": "Ja, forkast endringer",
"Yes, redeem": "Yes, redeem",
"Yes, remove my card": "Ja, fjern kortet mitt",
"You are about to exchange:": "You are about to exchange:",
"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 still book the room but you need to confirm that you accept the new price": "Du kan fortsatt booke rommet, men du må bekrefte at du aksepterer den nye prisen",
"You canceled adding a new credit card.": "Du kansellerte å legge til et nytt kredittkort.",
"You have <b>{amount}</b> gifts waiting for you!": "Du har <b>{amount}</b> gaver som venter på deg!",
"You have enough points for a bonus night!": "You have enough points for a bonus night!",
"You have no points to transfer.": "You have no points to transfer.",
"You have no previous stays.": "Du har ingen tidligere opphold.",
"You have no upcoming stays.": "Du har ingen kommende opphold.",
"You have now cancelled your payment.": "Du har nå annullerer din betaling.",
@@ -807,15 +829,18 @@
"Your card will only be used for authorisation": "Kortet ditt vil kun bli brukt til autorisasjon",
"Your current level": "Ditt nåværende nivå",
"Your details": "Dine detaljer",
"Your exchanged points will retain their original expiry date with a maximum validity of 12 months.": "Your exchanged points will retain their original expiry date with a maximum validity of 12 months.",
"Your hotel": "Your hotel",
"Your level": "Ditt nivå",
"Your member tier": "Ditt medlemskapsnivå",
"Your new total": "Your new total",
"Your points to spend": "Dine brukbare poeng",
"Your room": "Rommet ditt",
"Your room will remain available for check-in even after 18:00.": "Rommet ditt vil være tilgjengelig for innsjekking selv etter kl. 18.00.",
"Your selected bed type will be provided based on availability": "Din valgte sengtype vil blive stillet til rådighed baseret på tilgængelighed",
"Your stay was cancelled. Cancellation cost: 0 {currency}. We're sorry to see that the plans didn't work out": "Ditt ophold ble annulleret. Annullereringspris: 0 {currency}. Vi beklager at planene ikke fungerte ut",
"Your stay was cancelled. Cancellation cost: 0 {currency}. Were sorry to see that the plans didnt work out": "Dit ophold blev annulleret. Annullereringspris: 0 {currency}. Vi beklager, at planerne ikke fungerede ud",
"Your transaction": "Your transaction",
"Zip code": "Post kode",
"Zoo": "Dyrehage",
"Zoom in": "Zoom inn",
@@ -873,6 +898,10 @@
"{number} km to city center": "{number} km til sentrum",
"{number} people": "{number} people",
"{points, number} Bonus points": "{points, number} Bonus points",
"{points, number} EuroBonus points": "{points, number} EuroBonus points",
"{points, number} Scandic Friends points": "{points, number} Scandic Friends points",
"{points, number} p": "{points, number} p",
"{points, number} points": "{points, number} points",
"{pointsAmount, number} points": "{pointsAmount, number} poeng",
"{points} spendable points expiring by {date}": "{points} Brukbare poeng utløper innen {date}",
"{price} {currency}": "{price} {currency}",

View File

@@ -1,8 +1,10 @@
{
"+46 8 517 517 00": "+46 8 517 517 00",
"/night per adult": "/natt per vuxen",
"1 EuroBonus point = 2 Scandic Friends points": "1 EuroBonus point = 2 Scandic Friends points",
"<b>Included</b> (based on availability)": "<b>Ingår</b> (baserat på tillgänglighet)",
"<b>Total price</b> (incl VAT)": "<b>Totalpris</b> (inkl moms)",
"<bold>{sasPoints, number} EuroBonus points</bold> to <bold>{scandicPoints, number} Scandic Friends points</bold>": "<bold>{sasPoints, number} EuroBonus points</bold> to <bold>{scandicPoints, number} Scandic Friends points</bold>",
"<sasMark>SAS {sasLevelName}</sasMark> and <scandicMark>{scandicLevelName}</scandicMark> are equally matched tiers. Level up one of your memberships for a chance of an upgrade!": "<sasMark>SAS {sasLevelName}</sasMark> and <scandicMark>{scandicLevelName}</scandicMark> are equally matched tiers. Level up one of your memberships for a chance of an upgrade!",
"<sasMark>SAS {sasLevelName}</sasMark> has upgraded your Scandic Friends level to <scandicMark>{scandicLevelName}</scandicMark>.": "<sasMark>SAS {sasLevelName}</sasMark> has upgraded your Scandic Friends level to <scandicMark>{scandicLevelName}</scandicMark>.",
"<scandicMark>Scandic {scandicLevelName}</scandicMark> has upgraded you to <sasMark>{sasLevelName}</sasMark>.": "<scandicMark>Scandic {scandicLevelName}</scandicMark> has upgraded you to <sasMark>{sasLevelName}</sasMark>.",
@@ -79,6 +81,7 @@
"Back to scandichotels.com": "Tillbaka till scandichotels.com",
"Back to select room": "Tillbaka till välj rum",
"Back to top": "Tillbaka till toppen",
"Balance": "Balance",
"Bar": "Bar",
"Based on availability": "Baserat på tillgänglighet",
"Bed": "Sängtyp",
@@ -90,11 +93,13 @@
"Birth date is missing": "Birth date is missing",
"Birth date: {dateOfBirth, date, ::MMMM d yyyy}": "Birth date: {dateOfBirth, date, ::MMMM d yyyy}",
"Boardroom": "Boardroom",
"Bonus Nights range from 10 000 - 80 000 points. Book your next stay with us today!": "Bonus Nights range from 10 000 - 80 000 points. Book your next stay with us today!",
"Book": "Boka",
"Book Reward Night": "Boka frinatt",
"Book a meeting": "Boka ett möte",
"Book a table online": "Boka ett bord online",
"Book another stay": "Book another stay",
"Book now": "Book now",
"Book parking": "Boka parkering",
"Book your next stay": "Book your next stay",
"Book {type} parking": "Boka {type} parkering",
@@ -227,6 +232,7 @@
"Download invoice": "Ladda ner faktura",
"Download the Scandic app": "Ladda ner Scandic-appen",
"Driving directions": "Vägbeskrivningar",
"EB points to transfer": "EB points to transfer",
"Earn & spend points": "Ta del av medlemsförmåner och erbjudanden",
"Earn bonus nights & points": "Tjäna bonusnätter och poäng",
"Edit": "Redigera",
@@ -294,6 +300,7 @@
"Get member benefits & offers": "Ta del av medlemsförmåner och erbjudanden",
"Get the member price: {amount}": "Betala endast {amount}",
"Go back": "Go back",
"Go back to My Pages": "Go back to My Pages",
"Go back to edit": "Gå tillbaka till redigeringen",
"Go back to overview": "Gå tillbaka till översikten",
"Go to My Benefits": "Gå till 'Mina förmåner'",
@@ -545,7 +552,9 @@
"Please enter the code sent to <maskedContactInfo></maskedContactInfo> in order to unlink your accounts.": "Please enter the code sent to <maskedContactInfo></maskedContactInfo> in order to unlink your accounts.",
"Please note that this is mandatory, and that your card will only be charged in the event of a no-show.": "Vänligen notera att detta är obligatoriskt, och att ditt kreditkort endast debiteras i händelse av en no-show.",
"Please try and change your search for this destination or see alternative hotels.": "Please try and change your search for this destination or see alternative hotels.",
"Point transfer completed!": "Point transfer completed!",
"Points": "Poäng",
"Points added": "Points added",
"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 may take up to 10 days to be displayed.": "Det kan ta upp till 10 dagar innan poäng visas.",
@@ -572,6 +581,7 @@
"Proceed to login": "Fortsätt till inloggning",
"Proceed to payment": "Gå vidare till betalningsmetod",
"Proceed to payment method": "Gå vidare till betalningsmetod",
"Proceed with point transfer?": "Proceed with point transfer?",
"Promo code": "Promo code",
"Provide a payment card in the next step": "Ge oss dina betalkortdetaljer i nästa steg",
"Public price from": "Offentligt pris från",
@@ -611,6 +621,8 @@
"Room {roomIndex}": "Rum {roomIndex}",
"Rooms": "Rum",
"Rooms & Guests": "Rum och gäster",
"SAS EuroBonus": "SAS EuroBonus",
"SF points to receive": "SF points to receive",
"Saturday": "Lördag",
"SatSun: Always open": "LörSön: Alltid öppet",
"SatSun: {openingTime}{closingTime}": "LörSön: {openingTime}{closingTime}",
@@ -619,8 +631,10 @@
"Save": "Spara",
"Save card to profile": "Save card to profile",
"Save updates": "Spara uppdateringar",
"Scandic Friends": "Scandic Friends",
"Scandic Friends Mastercard": "Scandic Friends Mastercard",
"Scandic Friends Point Shop": "Scandic Friends Point Shop",
"Scandic Friends points": "{points, number} Scandic Friends points",
"Scandic ♥ SAS": "Scandic ♥ SAS",
"Search": "Sök",
"See all": "Se alla",
@@ -715,6 +729,10 @@
"Tourist": "Turist",
"Transaction date": "Transaktionsdatum",
"Transactions": "Transaktioner",
"Transfer from": "Transfer from",
"Transfer points": "Transfer points",
"Transfer to": "Transfer to",
"Transferred points will not be level qualifying": "Transferred points will not be level qualifying",
"Transportations": "Transport",
"TripAdvisor rating": "TripAdvisor-betyg",
"Try again": "Try again",
@@ -785,14 +803,18 @@
"Year": "År",
"Yes": "Ja",
"Yes, I accept the general <termsAndConditionsLink>Terms & Conditions</termsAndConditionsLink>, and understand that Scandic will process my personal data in accordance with <privacyPolicyLink>Scandic's Privacy policy</privacyPolicyLink>. There you can learn more about what data we process, your rights and where to turn if you have questions.": "Yes, I accept the general <termsAndConditionsLink>Terms & Conditions</termsAndConditionsLink>, and understand that Scandic will process my personal data in accordance with <privacyPolicyLink>Scandic's Privacy policy</privacyPolicyLink>. There you can learn more about what data we process, your rights and where to turn if you have questions.",
"Yes, I want to transfer my points": "Yes, I want to transfer my points",
"Yes, close and remove benefit": "Ja, stäng och ta bort förmån",
"Yes, discard changes": "Ja, ignorera ändringar",
"Yes, redeem": "Yes, redeem",
"Yes, remove my card": "Ja, ta bort mitt kort",
"You are about to exchange:": "You are about to exchange:",
"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 still book the room but you need to confirm that you accept the new price": "Du kan fortsatt boka rummet men du måste bekräfta att du accepterar det nya priset",
"You canceled adding a new credit card.": "Du avbröt att lägga till ett nytt kreditkort.",
"You have <b>{amount}</b> gifts waiting for you!": "Du har <b>{amount}</b> presenter som väntar på dig!",
"You have enough points for a bonus night!": "You have enough points for a bonus night!",
"You have no points to transfer.": "You have no points to transfer.",
"You have no previous stays.": "Du har inga tidigare vistelser.",
"You have no upcoming stays.": "Du har inga planerade resor.",
"You have now cancelled your payment.": "Du har nu avbrutit din betalning.",
@@ -809,15 +831,18 @@
"Your card will only be used for authorisation": "Ditt kort kommer endast att användas för auktorisering",
"Your current level": "Din nuvarande nivå",
"Your details": "Dina uppgifter",
"Your exchanged points will retain their original expiry date with a maximum validity of 12 months.": "Your exchanged points will retain their original expiry date with a maximum validity of 12 months.",
"Your hotel": "Your hotel",
"Your level": "Din nivå",
"Your member tier": "Din medlemskapsnivå",
"Your new total": "Your new total",
"Your points to spend": "Dina spenderbara poäng",
"Your room": "Ditt rum",
"Your room will remain available for check-in even after 18:00.": "Ditt rum kommer att förbli tillgängligt för incheckning även efter kl. 18.00.",
"Your selected bed type will be provided based on availability": "Din valda sängtyp kommer att tillhandahållas baserat på tillgänglighet",
"Your stay was cancelled. Cancellation cost: 0 {currency}. We're sorry to see that the plans didn't work out": "Din vistelse blev avbokad. Avbokningskostnad: 0 {currency}. Vi beklagar att planerna inte fungerade.",
"Your stay was cancelled. Cancellation cost: 0 {currency}. Were sorry to see that the plans didnt work out": "Din vistelse blev avbokad. Avbokningskostnad: 0 {currency}. Vi beklagar att planerna inte fungerade ut",
"Your transaction": "Your transaction",
"Zip code": "Postnummer",
"Zoo": "Djurpark",
"Zoom in": "Zooma in",
@@ -877,6 +902,10 @@
"{number} km to city center": "{number} km till centrum",
"{number} people": "{number} personer",
"{points, number} Bonus points": "{points, number} Bonus points",
"{points, number} EuroBonus points": "{points, number} EuroBonus points",
"{points, number} Scandic Friends points": "{points, number} Scandic Friends points",
"{points, number} p": "{points, number} p",
"{points, number} points": "{points, number} points",
"{pointsAmount, number} points": "{pointsAmount, number} poäng",
"{points} spendable points expiring by {date}": "{points} poäng förfaller {date}",
"{price} {currency}": "{price} {currency}",

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 226 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 52 KiB

View File

@@ -5,6 +5,7 @@ import { verifyOtp } from "./otp/verify/verifyOtp"
import { linkAccount } from "./linkAccount"
import { performLevelUpgrade } from "./performLevelUpgrade"
import { unlinkAccount } from "./unlinkAccount"
import { transferPoints } from "./transferPoints"
export const sasRouter = router({
verifyOtp,
@@ -12,4 +13,5 @@ export const sasRouter = router({
linkAccount,
unlinkAccount,
performLevelUpgrade,
transferPoints,
})

View File

@@ -0,0 +1,41 @@
import { z } from "zod"
// import * as api from "@/lib/api"
import { protectedProcedure } from "@/server/trpc"
import { getSasToken } from "./getSasToken"
const outputSchema = z.object({
transferState: z.enum(["success"]),
})
const transferPointsInputSchema = z.object({
points: z.number(),
})
export const transferPoints = protectedProcedure
.output(outputSchema)
.input(transferPointsInputSchema)
.mutation(async function ({ ctx, input }) {
const sasAuthToken = getSasToken()
console.log("[SAS] transfer points")
console.log({ sasAuthToken })
console.log({ points: input.points })
// const apiResponse = await api.post(api.endpoints.v1.Profile.link, {
// headers: {
// Authorization: `Bearer ${ctx.session.token.access_token}`,
// },
// body: {
// partner: "sas_eb",
// tocDate: getCurrentDateWithoutTime(),
// partnerSpecific: {
// eurobonusAccessToken: sasAuthToken,
// },
// },
// })
console.log(`[SAS] transfer points success`)
return { transferState: "success" }
})

View File

@@ -12,7 +12,9 @@ export enum IconName {
AccountCircle = "AccountCircle",
Air = "Air",
Airplane = "Airplane",
ArrowFrom = "ArrowFrom",
ArrowRight = "ArrowRight",
ArrowTo = "ArrowTo",
Bar = "Bar",
Bed = "Bed",
Biking = "Biking",
@@ -115,6 +117,7 @@ export enum IconName {
StarFilled = "StarFilled",
Street = "Street",
Swim = "Swim",
Swipe = "Swipe",
Thermostat = "Thermostat",
Train = "Train",
Tripadvisor = "Tripadvisor",

View File

@@ -13,12 +13,13 @@ export namespace DynamicContentEnum {
overview_table = "overview_table",
points_overview = "points_overview",
previous_stays = "previous_stays",
sas_linked_account = "sas_linked_account",
sas_tier_comparison = "sas_tier_comparison",
sign_up_form = "sign_up_form",
sign_up_verification = "sign_up_verification",
soonest_stays = "soonest_stays",
upcoming_stays = "upcoming_stays",
sas_linked_account = "sas_linked_account",
sas_transfer_points = "sas_transfer_points",
sas_tier_comparison = "sas_tier_comparison",
}
/** Type needed to satisfy zod enum type */
@@ -35,12 +36,13 @@ export namespace DynamicContentEnum {
components.overview_table,
components.points_overview,
components.previous_stays,
components.sas_linked_account,
components.sas_tier_comparison,
components.sign_up_form,
components.sign_up_verification,
components.soonest_stays,
components.upcoming_stays,
components.sas_linked_account,
components.sas_transfer_points,
components.sas_tier_comparison,
]
}