Merged in feature/sas-login (pull request #1256)
First steps towards the SAS partnership * otp flow now pretends to do the linking * Update LinkAccountForm header * Update redirect times * Clean up comments * Set maxAge on sas cookies * make all SAS routes protected * Merge remote-tracking branch 'refs/remotes/origin/feature/sas-login' into feature/sas-login * Require auth for sas link flow * Fix resend otp * Add error support to OneTimePasswordForm * Add Sentry to SAS error boundary * Move SAS_REQUEST_OTP_STATE_STORAGE_COOKIE_NAME * Add missing translations * Merge branch 'master' of bitbucket.org:scandic-swap/web into feature/sas-login * Merge branch 'feature/sas-login' of bitbucket.org:scandic-swap/web into feature/sas-login * Add TooManyCodesError component * Refactor GenericError to support new errors * Add FailedAttemptsError * remove removed component <VWOScript/> * Merge branch 'feature/sas-login' of bitbucket.org:scandic-swap/web into feature/sas-login * remove local cookie-bot reference * Fix sas campaign logo scaling * feature toggle the SAS stuff * Merge branch 'feature/sas-login' of bitbucket.org:scandic-swap/web into feature/sas-login * fix: use env vars for SAS endpoints Approved-by: Linus Flood
This commit is contained in:
@@ -0,0 +1,35 @@
|
||||
"use client"
|
||||
import Link from "next/link"
|
||||
import { useIntl } from "react-intl"
|
||||
|
||||
import ErrorCircleFilledIcon from "@/components/Icons/ErrorCircleFilled"
|
||||
import Button from "@/components/TempDesignSystem/Button"
|
||||
import Body from "@/components/TempDesignSystem/Text/Body"
|
||||
import Title from "@/components/TempDesignSystem/Text/Title"
|
||||
|
||||
import { SASModal, SASModalContactBlock, SASModalDivider } from "./SASModal"
|
||||
|
||||
export function AlreadyLinkedError() {
|
||||
const intl = useIntl()
|
||||
|
||||
return (
|
||||
<SASModal>
|
||||
<ErrorCircleFilledIcon height={64} width={64} color="red" />
|
||||
<Title as="h2" level="h1" textAlign="center" textTransform="regular">
|
||||
{intl.formatMessage({ id: "Accounts are already linked" })}
|
||||
</Title>
|
||||
<Body textAlign="center">
|
||||
{/* TODO copy */}
|
||||
{intl.formatMessage({
|
||||
id: "We could not connect your accounts to give you access. Please contact us and we’ll help you resolve this issue.",
|
||||
})}
|
||||
</Body>
|
||||
{/* TODO link to SASxScandic page on My Pages */}
|
||||
<Button theme="base" asChild>
|
||||
<Link href="#">{intl.formatMessage({ id: "View your account" })}</Link>
|
||||
</Button>
|
||||
<SASModalDivider />
|
||||
<SASModalContactBlock />
|
||||
</SASModal>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
"use client"
|
||||
import { useIntl } from "react-intl"
|
||||
|
||||
import ErrorCircleFilledIcon from "@/components/Icons/ErrorCircleFilled"
|
||||
import Button from "@/components/TempDesignSystem/Button"
|
||||
import Body from "@/components/TempDesignSystem/Text/Body"
|
||||
import Title from "@/components/TempDesignSystem/Text/Title"
|
||||
|
||||
import { SASModal, SASModalContactBlock, SASModalDivider } from "./SASModal"
|
||||
|
||||
export function DateOfBirthError() {
|
||||
const intl = useIntl()
|
||||
|
||||
return (
|
||||
<SASModal>
|
||||
<ErrorCircleFilledIcon height={64} width={64} color="red" />
|
||||
<Title as="h2" level="h1" textAlign="center" textTransform="regular">
|
||||
{intl.formatMessage({ id: "Date of birth not matching" })}
|
||||
</Title>
|
||||
<Body textAlign="center">
|
||||
{/* TODO copy */}
|
||||
{intl.formatMessage({
|
||||
id: "We could not connect your accounts to give you access. Please contact us and we’ll help you resolve this issue.",
|
||||
})}
|
||||
</Body>
|
||||
{/* TODO link to where? */}
|
||||
<Button theme="base">
|
||||
{intl.formatMessage({ id: "View your account" })}
|
||||
</Button>
|
||||
<SASModalDivider />
|
||||
<SASModalContactBlock />
|
||||
</SASModal>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
"use client"
|
||||
|
||||
import { useIntl } from "react-intl"
|
||||
|
||||
import Button from "@/components/TempDesignSystem/Button"
|
||||
import Body from "@/components/TempDesignSystem/Text/Body"
|
||||
|
||||
import { GenericError } from "./GenericError"
|
||||
|
||||
export function FailedAttemptsError() {
|
||||
const intl = useIntl()
|
||||
|
||||
return (
|
||||
<GenericError
|
||||
title={intl.formatMessage({ id: "Too many failed attempts" })}
|
||||
variant="info"
|
||||
>
|
||||
<Body textAlign="center">
|
||||
{intl.formatMessage({
|
||||
id: "Please wait 1 hour before trying again.",
|
||||
})}
|
||||
</Body>
|
||||
<Button theme="base" disabled>
|
||||
{intl.formatMessage({ id: "Send new code" })}
|
||||
</Button>
|
||||
</GenericError>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
"use client"
|
||||
import Image from "next/image"
|
||||
|
||||
import ErrorCircleFilledIcon from "@/components/Icons/ErrorCircleFilled"
|
||||
import Title from "@/components/TempDesignSystem/Text/Title"
|
||||
|
||||
import { SASModal } from "./SASModal"
|
||||
|
||||
import type { ReactNode } from "react"
|
||||
|
||||
export function GenericError({
|
||||
title,
|
||||
variant = "error",
|
||||
children,
|
||||
}: {
|
||||
title: ReactNode
|
||||
variant?: "error" | "info"
|
||||
children: ReactNode
|
||||
}) {
|
||||
return (
|
||||
<SASModal>
|
||||
{variant === "error" ? (
|
||||
<ErrorCircleFilledIcon height={64} width={64} color="red" />
|
||||
) : (
|
||||
<Image
|
||||
src="/_static/img/scandic-loyalty-time.svg"
|
||||
alt=""
|
||||
width={140}
|
||||
height={110}
|
||||
style={{ marginTop: 16 }}
|
||||
/>
|
||||
)}
|
||||
<Title as="h3" level="h1" textAlign="center" textTransform="regular">
|
||||
{title}
|
||||
</Title>
|
||||
{children}
|
||||
</SASModal>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
.container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: var(--Spacing-x3);
|
||||
background-color: white;
|
||||
width: 100%;
|
||||
padding: var(--Spacing-x3) var(--Spacing-x3) var(--Spacing-x4);
|
||||
text-align: center;
|
||||
border-radius: var(--Corner-radius-Medium) var(--Corner-radius-Medium) 0 0;
|
||||
margin-top: auto;
|
||||
|
||||
@media screen and (min-width: 768px) {
|
||||
& {
|
||||
border-radius: var(--Corner-radius-Medium);
|
||||
margin-top: initial;
|
||||
width: 560px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.divider {
|
||||
width: 100%;
|
||||
position: relative;
|
||||
|
||||
& > span {
|
||||
position: relative;
|
||||
padding: 0 var(--Spacing-x2);
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
&::before {
|
||||
position: absolute;
|
||||
bottom: calc(50% - 1px);
|
||||
content: "";
|
||||
display: block;
|
||||
height: 1px;
|
||||
width: 100%;
|
||||
background-color: var(--Base-Border-Subtle);
|
||||
}
|
||||
}
|
||||
|
||||
.contactBlockTitle {
|
||||
margin-bottom: var(--Spacing-x1);
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
"use client"
|
||||
|
||||
import { useIntl } from "react-intl"
|
||||
|
||||
import Link from "@/components/TempDesignSystem/Link"
|
||||
import Body from "@/components/TempDesignSystem/Text/Body"
|
||||
import Title from "@/components/TempDesignSystem/Text/Title"
|
||||
|
||||
import styles from "./SASModal.module.css"
|
||||
|
||||
export function SASModal({ children }: { children: React.ReactNode }) {
|
||||
return <section className={styles.container}>{children}</section>
|
||||
}
|
||||
|
||||
export function SASModalDivider() {
|
||||
const intl = useIntl()
|
||||
|
||||
return (
|
||||
<div className={styles.divider}>
|
||||
<Body asChild color="uiTextPlaceholder">
|
||||
<span>{intl.formatMessage({ id: "or" })}</span>
|
||||
</Body>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export function SASModalContactBlock() {
|
||||
const intl = useIntl()
|
||||
|
||||
const phone = intl.formatMessage({ id: "+46 8 517 517 00" })
|
||||
|
||||
return (
|
||||
<div style={{ display: "flex", flexDirection: "column" }}>
|
||||
<Title
|
||||
level="h4"
|
||||
as="h3"
|
||||
textTransform="regular"
|
||||
className={styles.contactBlockTitle}
|
||||
>
|
||||
{intl.formatMessage({ id: "Contact our memberservice" })}
|
||||
</Title>
|
||||
<Link
|
||||
href={`tel:${phone.replaceAll(" ", "")}`}
|
||||
textDecoration="underline"
|
||||
>
|
||||
{phone}
|
||||
</Link>
|
||||
<Link href="mailto:member@scandichotels.com" textDecoration="underline">
|
||||
member@scandichotels.com
|
||||
</Link>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
"use client"
|
||||
|
||||
import { useIntl } from "react-intl"
|
||||
|
||||
import Button from "@/components/TempDesignSystem/Button"
|
||||
import Body from "@/components/TempDesignSystem/Text/Body"
|
||||
|
||||
import { GenericError } from "./GenericError"
|
||||
|
||||
export function TooManyCodesError() {
|
||||
const intl = useIntl()
|
||||
|
||||
return (
|
||||
<GenericError
|
||||
title={intl.formatMessage({ id: "You’ve requested too many codes" })}
|
||||
variant="info"
|
||||
>
|
||||
<Body textAlign="center">
|
||||
{intl.formatMessage({
|
||||
id: "Please wait 1 hour before trying again.",
|
||||
})}
|
||||
</Body>
|
||||
<Button theme="base" disabled>
|
||||
{intl.formatMessage({ id: "Send new code" })}
|
||||
</Button>
|
||||
</GenericError>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user