Merged in feat/SW-1488-unlink-sas-account (pull request #1349)
Implement unlink SAS flow Approved-by: Joakim Jäderberg
This commit is contained in:
@@ -78,7 +78,10 @@ export async function GET(
|
|||||||
httpOnly: true,
|
httpOnly: true,
|
||||||
})
|
})
|
||||||
|
|
||||||
if (stateResult.data.intent === "link") {
|
if (
|
||||||
|
stateResult.data.intent === "link" ||
|
||||||
|
stateResult.data.intent === "unlink"
|
||||||
|
) {
|
||||||
const [data, error] = await safeTry(
|
const [data, error] = await safeTry(
|
||||||
serverClient().partner.sas.requestOtp({})
|
serverClient().partner.sas.requestOtp({})
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ export default async function SasXScandicLayout({
|
|||||||
<Link className={styles.backLink} href={profileOverview[params.lang]}>
|
<Link className={styles.backLink} href={profileOverview[params.lang]}>
|
||||||
<ArrowLeft height={20} width={20} />
|
<ArrowLeft height={20} width={20} />
|
||||||
<span className={styles.long}>
|
<span className={styles.long}>
|
||||||
{intl.formatMessage({ id: "Back to Scandichotels.com" })}
|
{intl.formatMessage({ id: "Back to scandichotels.com" })}
|
||||||
</span>
|
</span>
|
||||||
<span className={styles.short}>
|
<span className={styles.short}>
|
||||||
{intl.formatMessage({ id: "Back" })}
|
{intl.formatMessage({ id: "Back" })}
|
||||||
|
|||||||
@@ -18,8 +18,11 @@ import type { LangParams, PageArgs, SearchParams } from "@/types/params"
|
|||||||
import type { State } from "../sasUtils"
|
import type { State } from "../sasUtils"
|
||||||
|
|
||||||
const searchParamsSchema = z.object({
|
const searchParamsSchema = z.object({
|
||||||
intent: z.enum(["link"]),
|
intent: z.enum(["link", "unlink"]),
|
||||||
})
|
})
|
||||||
|
|
||||||
|
type Intent = z.infer<typeof searchParamsSchema>["intent"]
|
||||||
|
|
||||||
export default async function SASxScandicLoginPage({
|
export default async function SASxScandicLoginPage({
|
||||||
searchParams,
|
searchParams,
|
||||||
params,
|
params,
|
||||||
@@ -42,11 +45,19 @@ export default async function SASxScandicLoginPage({
|
|||||||
const clientId = env.SAS_AUTH_CLIENTID
|
const clientId = env.SAS_AUTH_CLIENTID
|
||||||
const sasLoginHostname = env.SAS_AUTH_ENDPOINT
|
const sasLoginHostname = env.SAS_AUTH_ENDPOINT
|
||||||
const audience = "eb-partner-api"
|
const audience = "eb-partner-api"
|
||||||
// TODO check if this is correct scopes
|
|
||||||
const scope = encodeURIComponent("openid profile email")
|
const scope = encodeURIComponent("openid profile email")
|
||||||
|
|
||||||
const loginLink = `${sasLoginHostname}/oauth/authorize?response_type=code&client_id=${clientId}&redirect_uri=${redirectUri}&scope=${scope}&state=${urlState}&audience=${audience}`
|
const loginLink = `${sasLoginHostname}/oauth/authorize?response_type=code&client_id=${clientId}&redirect_uri=${redirectUri}&scope=${scope}&state=${urlState}&audience=${audience}`
|
||||||
|
|
||||||
|
const intentDescriptions: Record<Intent, string> = {
|
||||||
|
link: intl.formatMessage({
|
||||||
|
id: "In order to verify your account linking we will ask you to sign in to your SAS EuroBonus account.",
|
||||||
|
}),
|
||||||
|
unlink: intl.formatMessage({
|
||||||
|
id: "Log in to your SAS Eurobonus account to confirm account unlinking.",
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SASModal>
|
<SASModal>
|
||||||
<Redirect url={loginLink} timeout={3000} />
|
<Redirect url={loginLink} timeout={3000} />
|
||||||
@@ -60,11 +71,7 @@ export default async function SASxScandicLoginPage({
|
|||||||
<Title as="h2" level="h1" textTransform="regular">
|
<Title as="h2" level="h1" textTransform="regular">
|
||||||
{intl.formatMessage({ id: "Redirecting you to SAS" })}
|
{intl.formatMessage({ id: "Redirecting you to SAS" })}
|
||||||
</Title>
|
</Title>
|
||||||
<Body textAlign="center">
|
<Body textAlign="center">{intentDescriptions[parsedParams.intent]}</Body>
|
||||||
{intl.formatMessage({
|
|
||||||
id: "In order to verify your account linking we will ask you to sign in to your SAS EuroBonus account.",
|
|
||||||
})}
|
|
||||||
</Body>
|
|
||||||
<Footnote textAlign="center">
|
<Footnote textAlign="center">
|
||||||
{intl.formatMessage<React.ReactNode>(
|
{intl.formatMessage<React.ReactNode>(
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import { cookies } from "next/headers"
|
|||||||
import { redirect } from "next/navigation"
|
import { redirect } from "next/navigation"
|
||||||
import { z } from "zod"
|
import { z } from "zod"
|
||||||
|
|
||||||
|
import { myPages } from "@/constants/routes/myPages"
|
||||||
import { serverClient } from "@/lib/trpc/server"
|
import { serverClient } from "@/lib/trpc/server"
|
||||||
|
|
||||||
import { getIntl } from "@/i18n"
|
import { getIntl } from "@/i18n"
|
||||||
@@ -12,17 +13,21 @@ import OneTimePasswordForm, {
|
|||||||
type OnSubmitHandler,
|
type OnSubmitHandler,
|
||||||
} from "./OneTimePasswordForm"
|
} from "./OneTimePasswordForm"
|
||||||
|
|
||||||
|
import type { ReactNode } from "react"
|
||||||
|
|
||||||
import type { LangParams, PageArgs, SearchParams } from "@/types/params"
|
import type { LangParams, PageArgs, SearchParams } from "@/types/params"
|
||||||
import type { Lang } from "@/constants/languages"
|
import type { Lang } from "@/constants/languages"
|
||||||
|
|
||||||
const otpError = z.enum(["invalidCode", "expiredCode"])
|
const otpError = z.enum(["invalidCode", "expiredCode"])
|
||||||
|
const intent = z.enum(["link", "unlink"])
|
||||||
const searchParamsSchema = z.object({
|
const searchParamsSchema = z.object({
|
||||||
intent: z.enum(["link"]),
|
intent: intent,
|
||||||
to: z.string(),
|
to: z.string(),
|
||||||
error: otpError.optional(),
|
error: otpError.optional(),
|
||||||
})
|
})
|
||||||
|
|
||||||
export type OtpError = z.infer<typeof otpError>
|
export type OtpError = z.infer<typeof otpError>
|
||||||
|
type Intent = z.infer<typeof intent>
|
||||||
|
|
||||||
export default async function SASxScandicOneTimePasswordPage({
|
export default async function SASxScandicOneTimePasswordPage({
|
||||||
searchParams,
|
searchParams,
|
||||||
@@ -88,26 +93,37 @@ export default async function SASxScandicOneTimePasswordPage({
|
|||||||
switch (intent) {
|
switch (intent) {
|
||||||
case "link":
|
case "link":
|
||||||
return handleLinkAccount({ lang: params.lang })
|
return handleLinkAccount({ lang: params.lang })
|
||||||
|
case "unlink":
|
||||||
|
return handleUnlinkAccount({ lang: params.lang })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const maskedContactInfo = () => (
|
||||||
|
<>
|
||||||
|
<br />
|
||||||
|
<strong>{to}</strong>
|
||||||
|
<br />
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
const intentDescriptions: Record<Intent, ReactNode> = {
|
||||||
|
link: intl.formatMessage<React.ReactNode>(
|
||||||
|
{
|
||||||
|
id: "Please enter the code sent to <maskedContactInfo></maskedContactInfo> in order to confirm your account linking.",
|
||||||
|
},
|
||||||
|
{ maskedContactInfo }
|
||||||
|
),
|
||||||
|
unlink: intl.formatMessage<React.ReactNode>(
|
||||||
|
{
|
||||||
|
id: "Please enter the code sent to <maskedContactInfo></maskedContactInfo> in order to unlink your accounts.",
|
||||||
|
},
|
||||||
|
{ maskedContactInfo }
|
||||||
|
),
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<OneTimePasswordForm
|
<OneTimePasswordForm
|
||||||
heading={intl.formatMessage({ id: "Verification code" })}
|
heading={intl.formatMessage({ id: "Verification code" })}
|
||||||
ingress={intl.formatMessage<React.ReactNode>(
|
ingress={intentDescriptions[intent]}
|
||||||
{
|
|
||||||
id: "Please enter the code sent to <maskedContactInfo></maskedContactInfo> in order to confirm your account linking.",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
maskedContactInfo: () => (
|
|
||||||
<>
|
|
||||||
<br />
|
|
||||||
<strong>{to}</strong>
|
|
||||||
<br />
|
|
||||||
</>
|
|
||||||
),
|
|
||||||
}
|
|
||||||
)}
|
|
||||||
footnote={intl.formatMessage({
|
footnote={intl.formatMessage({
|
||||||
id: "This verifcation is needed for additional security.",
|
id: "This verifcation is needed for additional security.",
|
||||||
})}
|
})}
|
||||||
@@ -168,3 +184,34 @@ async function handleLinkAccount({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function handleUnlinkAccount({
|
||||||
|
lang,
|
||||||
|
}: {
|
||||||
|
lang: Lang
|
||||||
|
}): ReturnType<OnSubmitHandler> {
|
||||||
|
const [res, error] = await safeTry(serverClient().partner.sas.unlinkAccount())
|
||||||
|
if (!res || error) {
|
||||||
|
console.error("[SAS] unlink account error", error)
|
||||||
|
return {
|
||||||
|
url: `/${lang}/sas-x-scandic/error`,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (res.linkingState) {
|
||||||
|
case "unlinked":
|
||||||
|
return {
|
||||||
|
url: `/${lang}/sas-x-scandic/unlink/success`,
|
||||||
|
type: "replace",
|
||||||
|
}
|
||||||
|
case "notLinked":
|
||||||
|
return {
|
||||||
|
url: myPages[lang],
|
||||||
|
}
|
||||||
|
case "error":
|
||||||
|
return {
|
||||||
|
url: `/${lang}/sas-x-scandic/error`,
|
||||||
|
type: "replace",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -2,8 +2,7 @@ import { z } from "zod"
|
|||||||
|
|
||||||
export const SAS_TOKEN_STORAGE_KEY = "sas-x-scandic-token"
|
export const SAS_TOKEN_STORAGE_KEY = "sas-x-scandic-token"
|
||||||
|
|
||||||
// TODO nonce??
|
|
||||||
export const stateSchema = z.object({
|
export const stateSchema = z.object({
|
||||||
intent: z.literal("link"),
|
intent: z.enum(["link", "unlink"]),
|
||||||
})
|
})
|
||||||
export type State = z.infer<typeof stateSchema>
|
export type State = z.infer<typeof stateSchema>
|
||||||
|
|||||||
@@ -0,0 +1,36 @@
|
|||||||
|
import React from "react"
|
||||||
|
|
||||||
|
import { overview } from "@/constants/routes/myPages"
|
||||||
|
|
||||||
|
import CheckCircle from "@/components/Icons/CheckCircle"
|
||||||
|
import { Redirect } from "@/components/Redirect"
|
||||||
|
import Body from "@/components/TempDesignSystem/Text/Body"
|
||||||
|
import Title from "@/components/TempDesignSystem/Text/Title"
|
||||||
|
import { getIntl } from "@/i18n"
|
||||||
|
|
||||||
|
import { SASModal } from "../../components/SASModal"
|
||||||
|
|
||||||
|
import type { LangParams, PageArgs } from "@/types/params"
|
||||||
|
|
||||||
|
export default async function SASxScandicUnlinkSuccessPage({
|
||||||
|
params,
|
||||||
|
}: PageArgs<LangParams>) {
|
||||||
|
const intl = await getIntl()
|
||||||
|
|
||||||
|
return (
|
||||||
|
<SASModal>
|
||||||
|
<Redirect url={overview[params.lang]} timeout={3000} />
|
||||||
|
<CheckCircle height={64} width={64} color="uiSemanticSuccess" />
|
||||||
|
<Title as="h2" level="h1" textAlign="center">
|
||||||
|
{intl.formatMessage({ id: "Your accounts are now unlinked" })}
|
||||||
|
</Title>
|
||||||
|
<div>
|
||||||
|
<Body textAlign="center">
|
||||||
|
{intl.formatMessage({
|
||||||
|
id: "Redirecting you to My Pages.",
|
||||||
|
})}
|
||||||
|
</Body>
|
||||||
|
</div>
|
||||||
|
</SASModal>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -1,47 +1,34 @@
|
|||||||
"use client"
|
"use client"
|
||||||
|
|
||||||
import { useRouter } from "next/navigation"
|
import { useParams } from "next/navigation"
|
||||||
import { useIntl } from "react-intl"
|
import { useIntl } from "react-intl"
|
||||||
|
|
||||||
import { trpc } from "@/lib/trpc/client"
|
import Dialog from "@/components/Dialog"
|
||||||
|
import Button from "@/components/TempDesignSystem/Button"
|
||||||
|
|
||||||
import { Loading } from "@/components/Loading"
|
import type { LangParams } from "@/types/params"
|
||||||
import Link from "@/components/TempDesignSystem/Link"
|
|
||||||
import { toast } from "@/components/TempDesignSystem/Toasts"
|
|
||||||
|
|
||||||
export function UnlinkSAS() {
|
export function UnlinkSAS() {
|
||||||
const intl = useIntl()
|
const intl = useIntl()
|
||||||
const router = useRouter()
|
const params = useParams<LangParams>()
|
||||||
|
|
||||||
const { mutate, isPending } = trpc.partner.sas.unlinkAccount.useMutation({
|
|
||||||
onSuccess() {
|
|
||||||
toast.success(intl.formatMessage({ id: "Account unlinked, reloading" }))
|
|
||||||
// TODO: reload page
|
|
||||||
router.push("/en/scandic-friends/my-pages")
|
|
||||||
},
|
|
||||||
onError() {
|
|
||||||
toast.error(intl.formatMessage({ id: "Failed to unlink account" }))
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
const handleClick = (event: React.MouseEvent<HTMLAnchorElement>) => {
|
|
||||||
event.preventDefault()
|
|
||||||
mutate()
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isPending) {
|
|
||||||
return <Loading color="burgundy" />
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Link
|
<Dialog
|
||||||
href="#"
|
titleText={intl.formatMessage({
|
||||||
onClick={handleClick}
|
id: "Are you sure you want to unlink your account?",
|
||||||
color="burgundy"
|
})}
|
||||||
variant="default"
|
// TODO update copy
|
||||||
weight="bold"
|
bodyText={intl.formatMessage({
|
||||||
>
|
id: "We could not connect your accounts to give you access. Please contact us and we’ll help you resolve this issue.",
|
||||||
{intl.formatMessage({ id: "Unlink accounts" })}
|
})}
|
||||||
</Link>
|
cancelButtonText={intl.formatMessage({ id: "Go back" })}
|
||||||
|
proceedText={intl.formatMessage({ id: "Yes, unlink my accounts" })}
|
||||||
|
proceedHref={`/${params.lang}/sas-x-scandic/login?intent=unlink`}
|
||||||
|
trigger={
|
||||||
|
<Button intent="text" theme="base">
|
||||||
|
{intl.formatMessage({ id: "Unlink accounts" })}
|
||||||
|
</Button>
|
||||||
|
}
|
||||||
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,8 +42,8 @@ export default async function SASLinkedAccount({
|
|||||||
</section>
|
</section>
|
||||||
</SectionContainer>
|
</SectionContainer>
|
||||||
<div className={styles.mutationSection}>
|
<div className={styles.mutationSection}>
|
||||||
<LevelUpgradeButton />
|
|
||||||
<UnlinkSAS />
|
<UnlinkSAS />
|
||||||
|
<LevelUpgradeButton />
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
& .textContainer {
|
& .textContainer {
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -10,6 +11,10 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
gap: var(--Spacing-x1);
|
gap: var(--Spacing-x1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media screen and (min-width: 768px) {
|
||||||
|
width: fit-content;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.loading {
|
.loading {
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
|
|
||||||
.mutationSection {
|
.mutationSection {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column-reverse;
|
||||||
gap: var(--Spacing-x2);
|
gap: var(--Spacing-x2);
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|
||||||
|
|||||||
@@ -24,13 +24,11 @@ export default function Dialog({
|
|||||||
proceedOnClick = () => {},
|
proceedOnClick = () => {},
|
||||||
proceedText,
|
proceedText,
|
||||||
titleText,
|
titleText,
|
||||||
triggerButtonText,
|
trigger,
|
||||||
}: DialogProps) {
|
}: DialogProps) {
|
||||||
return (
|
return (
|
||||||
<DialogTrigger>
|
<DialogTrigger>
|
||||||
<Button intent="secondary" size="small" theme="base">
|
{trigger}
|
||||||
{triggerButtonText}
|
|
||||||
</Button>
|
|
||||||
<ModalOverlay className={styles.overlay} isDismissable>
|
<ModalOverlay className={styles.overlay} isDismissable>
|
||||||
<Modal>
|
<Modal>
|
||||||
<AriaDialog role="alertdialog">
|
<AriaDialog role="alertdialog">
|
||||||
|
|||||||
@@ -133,7 +133,11 @@ export default function Form({ user }: EditFormProps) {
|
|||||||
proceedHref={profile[lang]}
|
proceedHref={profile[lang]}
|
||||||
proceedText={intl.formatMessage({ id: "Yes, discard changes" })}
|
proceedText={intl.formatMessage({ id: "Yes, discard changes" })}
|
||||||
titleText={intl.formatMessage({ id: "Discard unsaved changes?" })}
|
titleText={intl.formatMessage({ id: "Discard unsaved changes?" })}
|
||||||
triggerButtonText={intl.formatMessage({ id: "Discard changes" })}
|
trigger={
|
||||||
|
<Button intent="secondary" size="small" theme="base">
|
||||||
|
{intl.formatMessage({ id: "Discard changes" })}
|
||||||
|
</Button>
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
<Button
|
<Button
|
||||||
disabled={!isValid || methods.formState.isSubmitting}
|
disabled={!isValid || methods.formState.isSubmitting}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import { trpc } from "@/lib/trpc/client"
|
|||||||
|
|
||||||
import Dialog from "@/components/Dialog"
|
import Dialog from "@/components/Dialog"
|
||||||
import { DeleteIcon } from "@/components/Icons"
|
import { DeleteIcon } from "@/components/Icons"
|
||||||
|
import Button from "@/components/TempDesignSystem/Button"
|
||||||
import { toast } from "@/components/TempDesignSystem/Toasts"
|
import { toast } from "@/components/TempDesignSystem/Toasts"
|
||||||
|
|
||||||
import type { DeleteCreditCardConfirmationProps } from "@/types/components/myPages/myProfile/creditCards"
|
import type { DeleteCreditCardConfirmationProps } from "@/types/components/myPages/myProfile/creditCards"
|
||||||
@@ -52,7 +53,11 @@ export default function DeleteCreditCardConfirmation({
|
|||||||
proceedOnClick={handleProceedDeleteCard}
|
proceedOnClick={handleProceedDeleteCard}
|
||||||
proceedText={intl.formatMessage({ id: "Yes, remove my card" })}
|
proceedText={intl.formatMessage({ id: "Yes, remove my card" })}
|
||||||
titleText={intl.formatMessage({ id: "Remove card from member profile" })}
|
titleText={intl.formatMessage({ id: "Remove card from member profile" })}
|
||||||
triggerButtonText={<DeleteIcon color="burgundy" />}
|
trigger={
|
||||||
|
<Button intent="secondary" size="small" theme="base">
|
||||||
|
<DeleteIcon color="burgundy" />
|
||||||
|
</Button>
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -319,6 +319,7 @@
|
|||||||
"Locations": "Placeringer",
|
"Locations": "Placeringer",
|
||||||
"Log in": "Log på",
|
"Log in": "Log på",
|
||||||
"Log in here": "Log ind her",
|
"Log in here": "Log ind her",
|
||||||
|
"Log in to your SAS Eurobonus account to confirm account unlinking.": "Log in to your SAS Eurobonus account to confirm account unlinking.",
|
||||||
"Log in/Join": "Log på/Tilmeld dig",
|
"Log in/Join": "Log på/Tilmeld dig",
|
||||||
"Log out": "Log ud",
|
"Log out": "Log ud",
|
||||||
"Long {long} ∙ Lat {lat}": "Long {long} ∙ Lat {lat}",
|
"Long {long} ∙ Lat {lat}": "Long {long} ∙ Lat {lat}",
|
||||||
@@ -441,6 +442,7 @@
|
|||||||
"Phone number": "Telefonnummer",
|
"Phone number": "Telefonnummer",
|
||||||
"Please enter a valid phone number": "Indtast venligst et gyldigt telefonnummer",
|
"Please enter a valid phone number": "Indtast venligst et gyldigt telefonnummer",
|
||||||
"Please enter the code sent to <maskedContactInfo></maskedContactInfo> in order to confirm your account linking.": "Please enter the code sent to <maskedContactInfo></maskedContactInfo> in order to confirm your account linking.",
|
"Please enter the code sent to <maskedContactInfo></maskedContactInfo> in order to confirm your account linking.": "Please enter the code sent to <maskedContactInfo></maskedContactInfo> in order to confirm your account linking.",
|
||||||
|
"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 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.",
|
"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.",
|
||||||
"Points": "Point",
|
"Points": "Point",
|
||||||
@@ -674,6 +676,7 @@
|
|||||||
"Your Challenges Conquer & Earn!": "Dine udfordringer Overvind og tjen!",
|
"Your Challenges Conquer & Earn!": "Dine udfordringer Overvind og tjen!",
|
||||||
"Your SAS level has upgraded your friends level": "Your SAS level has upgraded your friends level",
|
"Your SAS level has upgraded your friends level": "Your SAS level has upgraded your friends level",
|
||||||
"Your accounts are connected": "Your accounts are connected",
|
"Your accounts are connected": "Your accounts are connected",
|
||||||
|
"Your accounts are now unlinked": "Your accounts are now unlinked",
|
||||||
"Your booking(s) is confirmed but we could not verify your membership. If you have booked with a member discount, you'll either need to present your existing membership number upon check-in, become a member or pay the price difference at the hotel. Signing up is preferably done online before the stay.": "Din booking er bekræftet, men vi kunne ikke verificere dit medlemskab. Hvis du har booket med et medlemstilbud, skal du enten vise dit eksisterende medlemskab ved check-in, blive medlem eller betale prisdifferencen ved check-in. Tilmelding er foretrukket online før opholdet.",
|
"Your booking(s) is confirmed but we could not verify your membership. If you have booked with a member discount, you'll either need to present your existing membership number upon check-in, become a member or pay the price difference at the hotel. Signing up is preferably done online before the stay.": "Din booking er bekræftet, men vi kunne ikke verificere dit medlemskab. Hvis du har booket med et medlemstilbud, skal du enten vise dit eksisterende medlemskab ved check-in, blive medlem eller betale prisdifferencen ved check-in. Tilmelding er foretrukket online før opholdet.",
|
||||||
"Your card was successfully removed!": "Dit kort blev fjernet!",
|
"Your card was successfully removed!": "Dit kort blev fjernet!",
|
||||||
"Your card was successfully saved!": "Dit kort blev gemt!",
|
"Your card was successfully saved!": "Dit kort blev gemt!",
|
||||||
|
|||||||
@@ -320,6 +320,7 @@
|
|||||||
"Locations": "Orte",
|
"Locations": "Orte",
|
||||||
"Log in": "Anmeldung",
|
"Log in": "Anmeldung",
|
||||||
"Log in here": "Hier einloggen",
|
"Log in here": "Hier einloggen",
|
||||||
|
"Log in to your SAS Eurobonus account to confirm account unlinking.": "Log in to your SAS Eurobonus account to confirm account unlinking.",
|
||||||
"Log in/Join": "Log in/Anmelden",
|
"Log in/Join": "Log in/Anmelden",
|
||||||
"Log out": "Ausloggen",
|
"Log out": "Ausloggen",
|
||||||
"Long {long} ∙ Lat {lat}": "Long {long} ∙ Lat {lat}",
|
"Long {long} ∙ Lat {lat}": "Long {long} ∙ Lat {lat}",
|
||||||
@@ -442,6 +443,7 @@
|
|||||||
"Phone number": "Telefonnummer",
|
"Phone number": "Telefonnummer",
|
||||||
"Please enter a valid phone number": "Bitte geben Sie eine gültige Telefonnummer ein",
|
"Please enter a valid phone number": "Bitte geben Sie eine gültige Telefonnummer ein",
|
||||||
"Please enter the code sent to <maskedContactInfo></maskedContactInfo> in order to confirm your account linking.": "Please enter the code sent to <maskedContactInfo></maskedContactInfo> in order to confirm your account linking.",
|
"Please enter the code sent to <maskedContactInfo></maskedContactInfo> in order to confirm your account linking.": "Please enter the code sent to <maskedContactInfo></maskedContactInfo> in order to confirm your account linking.",
|
||||||
|
"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 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.",
|
"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.",
|
||||||
"Points": "Punkte",
|
"Points": "Punkte",
|
||||||
@@ -674,6 +676,7 @@
|
|||||||
"Your Challenges Conquer & Earn!": "Meistern Sie Ihre Herausforderungen und verdienen Sie Geld!",
|
"Your Challenges Conquer & Earn!": "Meistern Sie Ihre Herausforderungen und verdienen Sie Geld!",
|
||||||
"Your SAS level has upgraded your friends level": "Your SAS level has upgraded your friends level",
|
"Your SAS level has upgraded your friends level": "Your SAS level has upgraded your friends level",
|
||||||
"Your accounts are connected": "Your accounts are connected",
|
"Your accounts are connected": "Your accounts are connected",
|
||||||
|
"Your accounts are now unlinked": "Your accounts are now unlinked",
|
||||||
"Your booking(s) is confirmed but we could not verify your membership. If you have booked with a member discount, you'll either need to present your existing membership number upon check-in, become a member or pay the price difference at the hotel. Signing up is preferably done online before the stay.": "Ihre Buchung ist bestätigt, aber wir konnten Ihr Mitglied nicht verifizieren. Wenn Sie mit einem Mitgliederrabatt gebucht haben, müssen Sie entweder Ihr vorhandenes Mitgliedschaftsnummer bei der Anreise präsentieren, ein Mitglied werden oder die Preisdifferenz bei der Anreise bezahlen. Die Anmeldung ist vorzugsweise online vor der Aufenthaltsdauer erfolgreich.",
|
"Your booking(s) is confirmed but we could not verify your membership. If you have booked with a member discount, you'll either need to present your existing membership number upon check-in, become a member or pay the price difference at the hotel. Signing up is preferably done online before the stay.": "Ihre Buchung ist bestätigt, aber wir konnten Ihr Mitglied nicht verifizieren. Wenn Sie mit einem Mitgliederrabatt gebucht haben, müssen Sie entweder Ihr vorhandenes Mitgliedschaftsnummer bei der Anreise präsentieren, ein Mitglied werden oder die Preisdifferenz bei der Anreise bezahlen. Die Anmeldung ist vorzugsweise online vor der Aufenthaltsdauer erfolgreich.",
|
||||||
"Your card was successfully removed!": "Ihre Karte wurde erfolgreich entfernt!",
|
"Your card was successfully removed!": "Ihre Karte wurde erfolgreich entfernt!",
|
||||||
"Your card was successfully saved!": "Ihre Karte wurde erfolgreich gespeichert!",
|
"Your card was successfully saved!": "Ihre Karte wurde erfolgreich gespeichert!",
|
||||||
|
|||||||
@@ -323,6 +323,7 @@
|
|||||||
"Locations": "Locations",
|
"Locations": "Locations",
|
||||||
"Log in": "Log in",
|
"Log in": "Log in",
|
||||||
"Log in here": "Log in here",
|
"Log in here": "Log in here",
|
||||||
|
"Log in to your SAS Eurobonus account to confirm account unlinking.": "Log in to your SAS Eurobonus account to confirm account unlinking.",
|
||||||
"Log in/Join": "Log in/Join",
|
"Log in/Join": "Log in/Join",
|
||||||
"Log out": "Log out",
|
"Log out": "Log out",
|
||||||
"Long {long} ∙ Lat {lat}": "Long {long} ∙ Lat {lat}",
|
"Long {long} ∙ Lat {lat}": "Long {long} ∙ Lat {lat}",
|
||||||
@@ -446,6 +447,7 @@
|
|||||||
"Phone number": "Phone number",
|
"Phone number": "Phone number",
|
||||||
"Please enter a valid phone number": "Please enter a valid phone number",
|
"Please enter a valid phone number": "Please enter a valid phone number",
|
||||||
"Please enter the code sent to <maskedContactInfo></maskedContactInfo> in order to confirm your account linking.": "Please enter the code sent to <maskedContactInfo></maskedContactInfo> in order to confirm your account linking.",
|
"Please enter the code sent to <maskedContactInfo></maskedContactInfo> in order to confirm your account linking.": "Please enter the code sent to <maskedContactInfo></maskedContactInfo> in order to confirm your account linking.",
|
||||||
|
"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 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.",
|
"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.",
|
||||||
"Points": "Points",
|
"Points": "Points",
|
||||||
@@ -680,6 +682,7 @@
|
|||||||
"Your Challenges Conquer & Earn!": "Your Challenges Conquer & Earn!",
|
"Your Challenges Conquer & Earn!": "Your Challenges Conquer & Earn!",
|
||||||
"Your SAS level has upgraded your friends level": "Your SAS level has upgraded your friends level",
|
"Your SAS level has upgraded your friends level": "Your SAS level has upgraded your friends level",
|
||||||
"Your accounts are connected": "Your accounts are connected",
|
"Your accounts are connected": "Your accounts are connected",
|
||||||
|
"Your accounts are now unlinked": "Your accounts are now unlinked",
|
||||||
"Your booking(s) is confirmed but we could not verify your membership. If you have booked with a member discount, you'll either need to present your existing membership number upon check-in, become a member or pay the price difference at the hotel. Signing up is preferably done online before the stay.": "Your booking(s) is confirmed but we could not verify your membership. If you have booked with a member discount, you'll either need to present your existing membership number upon check-in, become a member or pay the price difference at the hotel. Signing up is preferably done online before the stay.",
|
"Your booking(s) is confirmed but we could not verify your membership. If you have booked with a member discount, you'll either need to present your existing membership number upon check-in, become a member or pay the price difference at the hotel. Signing up is preferably done online before the stay.": "Your booking(s) is confirmed but we could not verify your membership. If you have booked with a member discount, you'll either need to present your existing membership number upon check-in, become a member or pay the price difference at the hotel. Signing up is preferably done online before the stay.",
|
||||||
"Your card was successfully removed!": "Your card was successfully removed!",
|
"Your card was successfully removed!": "Your card was successfully removed!",
|
||||||
"Your card was successfully saved!": "Your card was successfully saved!",
|
"Your card was successfully saved!": "Your card was successfully saved!",
|
||||||
|
|||||||
@@ -319,6 +319,7 @@
|
|||||||
"Locations": "Sijainnit",
|
"Locations": "Sijainnit",
|
||||||
"Log in": "Kirjaudu sisään",
|
"Log in": "Kirjaudu sisään",
|
||||||
"Log in here": "Kirjaudu sisään",
|
"Log in here": "Kirjaudu sisään",
|
||||||
|
"Log in to your SAS Eurobonus account to confirm account unlinking.": "Log in to your SAS Eurobonus account to confirm account unlinking.",
|
||||||
"Log in/Join": "Kirjaudu sisään/Liittyä",
|
"Log in/Join": "Kirjaudu sisään/Liittyä",
|
||||||
"Log out": "Kirjaudu ulos",
|
"Log out": "Kirjaudu ulos",
|
||||||
"Long {long} ∙ Lat {lat}": "Long {long} ∙ Lat {lat}",
|
"Long {long} ∙ Lat {lat}": "Long {long} ∙ Lat {lat}",
|
||||||
@@ -441,6 +442,7 @@
|
|||||||
"Phone number": "Puhelinnumero",
|
"Phone number": "Puhelinnumero",
|
||||||
"Please enter a valid phone number": "Ole hyvä ja näppäile voimassaoleva puhelinnumero",
|
"Please enter a valid phone number": "Ole hyvä ja näppäile voimassaoleva puhelinnumero",
|
||||||
"Please enter the code sent to <maskedContactInfo></maskedContactInfo> in order to confirm your account linking.": "Please enter the code sent to <maskedContactInfo></maskedContactInfo> in order to confirm your account linking.",
|
"Please enter the code sent to <maskedContactInfo></maskedContactInfo> in order to confirm your account linking.": "Please enter the code sent to <maskedContactInfo></maskedContactInfo> in order to confirm your account linking.",
|
||||||
|
"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 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.",
|
"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.",
|
||||||
"Points": "Pisteet",
|
"Points": "Pisteet",
|
||||||
@@ -674,6 +676,7 @@
|
|||||||
"Your Challenges Conquer & Earn!": "Your Challenges Conquer & Earn!",
|
"Your Challenges Conquer & Earn!": "Your Challenges Conquer & Earn!",
|
||||||
"Your SAS level has upgraded your friends level": "Your SAS level has upgraded your friends level",
|
"Your SAS level has upgraded your friends level": "Your SAS level has upgraded your friends level",
|
||||||
"Your accounts are connected": "Your accounts are connected",
|
"Your accounts are connected": "Your accounts are connected",
|
||||||
|
"Your accounts are now unlinked": "Your accounts are now unlinked",
|
||||||
"Your booking(s) is confirmed but we could not verify your membership. If you have booked with a member discount, you'll either need to present your existing membership number upon check-in, become a member or pay the price difference at the hotel. Signing up is preferably done online before the stay.": "Varauksesi on vahvistettu, mutta jäsenyytesi ei voitu vahvistaa. Jos olet bookeutunut jäsenyysalennoilla, sinun on joko esitettävä olemassa olevan jäsenyysnumero tarkistukseen, tulla jäseneksi tai maksamaan hinnan eron hotellissa. Jäsenyyden tilittäminen on suositeltavampaa tehdä verkkoon ennen majoittumista.",
|
"Your booking(s) is confirmed but we could not verify your membership. If you have booked with a member discount, you'll either need to present your existing membership number upon check-in, become a member or pay the price difference at the hotel. Signing up is preferably done online before the stay.": "Varauksesi on vahvistettu, mutta jäsenyytesi ei voitu vahvistaa. Jos olet bookeutunut jäsenyysalennoilla, sinun on joko esitettävä olemassa olevan jäsenyysnumero tarkistukseen, tulla jäseneksi tai maksamaan hinnan eron hotellissa. Jäsenyyden tilittäminen on suositeltavampaa tehdä verkkoon ennen majoittumista.",
|
||||||
"Your card was successfully removed!": "Korttisi poistettiin onnistuneesti!",
|
"Your card was successfully removed!": "Korttisi poistettiin onnistuneesti!",
|
||||||
"Your card was successfully saved!": "Korttisi tallennettu onnistuneesti!",
|
"Your card was successfully saved!": "Korttisi tallennettu onnistuneesti!",
|
||||||
|
|||||||
@@ -318,6 +318,7 @@
|
|||||||
"Locations": "Steder",
|
"Locations": "Steder",
|
||||||
"Log in": "Logg Inn",
|
"Log in": "Logg Inn",
|
||||||
"Log in here": "Logg inn her",
|
"Log in here": "Logg inn her",
|
||||||
|
"Log in to your SAS Eurobonus account to confirm account unlinking.": "Log in to your SAS Eurobonus account to confirm account unlinking.",
|
||||||
"Log in/Join": "Logg på/Bli med",
|
"Log in/Join": "Logg på/Bli med",
|
||||||
"Log out": "Logg ut",
|
"Log out": "Logg ut",
|
||||||
"Long {long} ∙ Lat {lat}": "Long {long} ∙ Lat {lat}",
|
"Long {long} ∙ Lat {lat}": "Long {long} ∙ Lat {lat}",
|
||||||
@@ -440,6 +441,7 @@
|
|||||||
"Phone number": "Telefonnummer",
|
"Phone number": "Telefonnummer",
|
||||||
"Please enter a valid phone number": "Vennligst oppgi et gyldig telefonnummer",
|
"Please enter a valid phone number": "Vennligst oppgi et gyldig telefonnummer",
|
||||||
"Please enter the code sent to <maskedContactInfo></maskedContactInfo> in order to confirm your account linking.": "Please enter the code sent to <maskedContactInfo></maskedContactInfo> in order to confirm your account linking.",
|
"Please enter the code sent to <maskedContactInfo></maskedContactInfo> in order to confirm your account linking.": "Please enter the code sent to <maskedContactInfo></maskedContactInfo> in order to confirm your account linking.",
|
||||||
|
"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 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.",
|
"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.",
|
||||||
"Points": "Poeng",
|
"Points": "Poeng",
|
||||||
@@ -672,6 +674,7 @@
|
|||||||
"Your Challenges Conquer & Earn!": "Dine utfordringer Erobre og tjen!",
|
"Your Challenges Conquer & Earn!": "Dine utfordringer Erobre og tjen!",
|
||||||
"Your SAS level has upgraded your friends level": "Your SAS level has upgraded your friends level",
|
"Your SAS level has upgraded your friends level": "Your SAS level has upgraded your friends level",
|
||||||
"Your accounts are connected": "Your accounts are connected",
|
"Your accounts are connected": "Your accounts are connected",
|
||||||
|
"Your accounts are now unlinked": "Your accounts are now unlinked",
|
||||||
"Your booking(s) is confirmed but we could not verify your membership. If you have booked with a member discount, you'll either need to present your existing membership number upon check-in, become a member or pay the price difference at the hotel. Signing up is preferably done online before the stay.": "Din bestilling er bekreftet, men vi kunne ikke verifisere medlemskapet ditt. Hvis du har booke ut med et medlemsrabatt, må du enten presentere eksisterende medlemsnummer ved check-in, bli medlem eller betale prisdifferansen ved hotellet. Registrering er foretrukket gjort online før oppholdet.",
|
"Your booking(s) is confirmed but we could not verify your membership. If you have booked with a member discount, you'll either need to present your existing membership number upon check-in, become a member or pay the price difference at the hotel. Signing up is preferably done online before the stay.": "Din bestilling er bekreftet, men vi kunne ikke verifisere medlemskapet ditt. Hvis du har booke ut med et medlemsrabatt, må du enten presentere eksisterende medlemsnummer ved check-in, bli medlem eller betale prisdifferansen ved hotellet. Registrering er foretrukket gjort online før oppholdet.",
|
||||||
"Your card was successfully removed!": "Kortet ditt ble fjernet!",
|
"Your card was successfully removed!": "Kortet ditt ble fjernet!",
|
||||||
"Your card was successfully saved!": "Kortet ditt ble lagret!",
|
"Your card was successfully saved!": "Kortet ditt ble lagret!",
|
||||||
|
|||||||
@@ -318,6 +318,7 @@
|
|||||||
"Locations": "Platser",
|
"Locations": "Platser",
|
||||||
"Log in": "Logga in",
|
"Log in": "Logga in",
|
||||||
"Log in here": "Logga in här",
|
"Log in here": "Logga in här",
|
||||||
|
"Log in to your SAS Eurobonus account to confirm account unlinking.": "Log in to your SAS Eurobonus account to confirm account unlinking.",
|
||||||
"Log in/Join": "Logga in/Gå med",
|
"Log in/Join": "Logga in/Gå med",
|
||||||
"Log out": "Logga ut",
|
"Log out": "Logga ut",
|
||||||
"Long {long} ∙ Lat {lat}": "Long {long} ∙ Lat {lat}",
|
"Long {long} ∙ Lat {lat}": "Long {long} ∙ Lat {lat}",
|
||||||
@@ -440,6 +441,7 @@
|
|||||||
"Phone number": "Telefonnummer",
|
"Phone number": "Telefonnummer",
|
||||||
"Please enter a valid phone number": "Var vänlig och ange ett giltigt telefonnummer",
|
"Please enter a valid phone number": "Var vänlig och ange ett giltigt telefonnummer",
|
||||||
"Please enter the code sent to <maskedContactInfo></maskedContactInfo> in order to confirm your account linking.": "Please enter the code sent to <maskedContactInfo></maskedContactInfo> in order to confirm your account linking.",
|
"Please enter the code sent to <maskedContactInfo></maskedContactInfo> in order to confirm your account linking.": "Please enter the code sent to <maskedContactInfo></maskedContactInfo> in order to confirm your account linking.",
|
||||||
|
"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 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.",
|
"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.",
|
||||||
"Points": "Poäng",
|
"Points": "Poäng",
|
||||||
@@ -672,6 +674,7 @@
|
|||||||
"Your Challenges Conquer & Earn!": "Dina utmaningar Erövra och tjäna!",
|
"Your Challenges Conquer & Earn!": "Dina utmaningar Erövra och tjäna!",
|
||||||
"Your SAS level has upgraded your friends level": "Your SAS level has upgraded your friends level",
|
"Your SAS level has upgraded your friends level": "Your SAS level has upgraded your friends level",
|
||||||
"Your accounts are connected": "Your accounts are connected",
|
"Your accounts are connected": "Your accounts are connected",
|
||||||
|
"Your accounts are now unlinked": "Your accounts are now unlinked",
|
||||||
"Your booking(s) is confirmed but we could not verify your membership. If you have booked with a member discount, you'll either need to present your existing membership number upon check-in, become a member or pay the price difference at the hotel. Signing up is preferably done online before the stay.": "Din bokning är bekräftad, men vi kunde inte verifiera ditt medlemskap. Om du har bokat med ett medlemsrabatt måste du antingen presentera ditt befintliga medlemsnummer vid check-in, bli medlem eller betala prisdifferensen vid hotell. Registrering är föredragen gjord online före vistelsen.",
|
"Your booking(s) is confirmed but we could not verify your membership. If you have booked with a member discount, you'll either need to present your existing membership number upon check-in, become a member or pay the price difference at the hotel. Signing up is preferably done online before the stay.": "Din bokning är bekräftad, men vi kunde inte verifiera ditt medlemskap. Om du har bokat med ett medlemsrabatt måste du antingen presentera ditt befintliga medlemsnummer vid check-in, bli medlem eller betala prisdifferensen vid hotell. Registrering är föredragen gjord online före vistelsen.",
|
||||||
"Your card was successfully removed!": "Ditt kort har tagits bort!",
|
"Your card was successfully removed!": "Ditt kort har tagits bort!",
|
||||||
"Your card was successfully saved!": "Ditt kort har sparats!",
|
"Your card was successfully saved!": "Ditt kort har sparats!",
|
||||||
|
|||||||
@@ -163,6 +163,8 @@ export namespace endpoints {
|
|||||||
export const subscriberId = `${base.path.profile}/${version}/${base.enitity.Profile}/SubscriberId`
|
export const subscriberId = `${base.path.profile}/${version}/${base.enitity.Profile}/SubscriberId`
|
||||||
export const link = `${base.path.profile}/${version}/${base.enitity.Profile}/link`
|
export const link = `${base.path.profile}/${version}/${base.enitity.Profile}/link`
|
||||||
|
|
||||||
|
export const unlink = `${base.path.profile}/${version}/${base.enitity.Profile}/Unlink`
|
||||||
|
|
||||||
// TODO: Remove once new endpoints are out in production.
|
// TODO: Remove once new endpoints are out in production.
|
||||||
export const reward = `${base.path.profile}/${version}/${base.enitity.Profile}/reward`
|
export const reward = `${base.path.profile}/${version}/${base.enitity.Profile}/reward`
|
||||||
export const tierRewards = `${base.path.profile}/${version}/${base.enitity.Profile}/tierRewards`
|
export const tierRewards = `${base.path.profile}/${version}/${base.enitity.Profile}/tierRewards`
|
||||||
|
|||||||
@@ -1,27 +1,50 @@
|
|||||||
import { TRPCError } from "@trpc/server"
|
|
||||||
import { z } from "zod"
|
import { z } from "zod"
|
||||||
|
|
||||||
|
import * as api from "@/lib/api"
|
||||||
import { protectedProcedure } from "@/server/trpc"
|
import { protectedProcedure } from "@/server/trpc"
|
||||||
|
|
||||||
import { timeout } from "@/utils/timeout"
|
import { getSasToken } from "./getSasToken"
|
||||||
|
|
||||||
const outputSchema = z.object({
|
const outputSchema = z.object({
|
||||||
// unlinked: z.boolean(),
|
linkingState: z.enum(["unlinked", "notLinked", "error"]),
|
||||||
})
|
})
|
||||||
|
|
||||||
export const unlinkAccount = protectedProcedure
|
export const unlinkAccount = protectedProcedure
|
||||||
.output(outputSchema)
|
.output(outputSchema)
|
||||||
.mutation(async function ({ ctx, input }) {
|
.mutation(async function ({ ctx }) {
|
||||||
console.log("[SAS] unlink account")
|
const sasAuthToken = getSasToken()
|
||||||
await timeout(1000)
|
|
||||||
//TODO: Call actual API here
|
|
||||||
|
|
||||||
throw new TRPCError({
|
const apiResponse = await api.post(api.endpoints.v1.Profile.unlink, {
|
||||||
message: "Unable to unlink account",
|
headers: {
|
||||||
code: "BAD_REQUEST",
|
Authorization: `Bearer ${ctx.session.token.access_token}`,
|
||||||
|
},
|
||||||
|
body: {
|
||||||
|
partner: "sas_eb",
|
||||||
|
partnerSpecific: {
|
||||||
|
eurobonusAccessToken: sasAuthToken,
|
||||||
|
},
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
return {
|
if (apiResponse.status === 204) {
|
||||||
unlinked: true,
|
console.log("[SAS] unlink account success")
|
||||||
|
return { linkingState: "unlinked" }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (apiResponse.status === 400) {
|
||||||
|
const result = await apiResponse.json()
|
||||||
|
|
||||||
|
console.log("[SAS] unlink account error with response", result)
|
||||||
|
return { linkingState: "error" }
|
||||||
|
}
|
||||||
|
|
||||||
|
if (apiResponse.status === 404) {
|
||||||
|
console.log("[SAS] tried unlinking an account that was not linked")
|
||||||
|
return { linkingState: "notLinked" }
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(
|
||||||
|
`[SAS] unlink account error with status code ${apiResponse.status} and response ${await apiResponse.text()}`
|
||||||
|
)
|
||||||
|
return { linkingState: "error" }
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -6,5 +6,5 @@ export interface DialogProps {
|
|||||||
proceedOnClick?: (close: () => void) => void
|
proceedOnClick?: (close: () => void) => void
|
||||||
proceedText: string
|
proceedText: string
|
||||||
titleText: string
|
titleText: string
|
||||||
triggerButtonText: React.ReactNode
|
trigger: React.ReactNode
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user