Merged in feature/sas-mypages (pull request #1302)
Feature/sas mypages * feat: Add SAS partner page under my pages * fix: feature toggle SAS Partner page in my pages * add translations for SAS account page * use 'flex-start' instead of 'start' * fix: flatten css * fix: don't use <SectionContainer /> on linkedAccounts page
This commit is contained in:
@@ -0,0 +1,207 @@
|
||||
import { cva, type VariantProps } from "class-variance-authority"
|
||||
import Image from "next/image"
|
||||
|
||||
import RocketLaunch from "@/components/Icons/RocketLaunch"
|
||||
import SkeletonShimmer from "@/components/SkeletonShimmer"
|
||||
import Caption from "@/components/TempDesignSystem/Text/Caption"
|
||||
import Footnote from "@/components/TempDesignSystem/Text/Footnote"
|
||||
import Subtitle from "@/components/TempDesignSystem/Text/Subtitle"
|
||||
import { getIntl } from "@/i18n"
|
||||
|
||||
import styles from "./tierLevelCard.module.css"
|
||||
|
||||
import type { ComponentProps, ReactNode } from "react"
|
||||
|
||||
type BoostState = "boostedInOtherSystem" | "boostedInThisSystem" | "notBoosted"
|
||||
|
||||
type BaseProps = {
|
||||
points: number
|
||||
tier: string
|
||||
boostState: BoostState
|
||||
}
|
||||
|
||||
type BoostedInOther = BaseProps & {
|
||||
boostState: "boostedInOtherSystem"
|
||||
boostedTier: string
|
||||
boostExpiration: Date
|
||||
}
|
||||
|
||||
type BoostedInThis = BaseProps & {
|
||||
boostState: "boostedInThisSystem"
|
||||
}
|
||||
|
||||
type NotBoosted = BaseProps & {
|
||||
boostState: "notBoosted"
|
||||
}
|
||||
|
||||
const variants = cva(styles.tierlevelcard, {
|
||||
variants: {
|
||||
bonusSystem: {
|
||||
scandic: styles.scandic,
|
||||
sas: styles.sas,
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
type Props = VariantProps<typeof variants> &
|
||||
(BoostedInOther | BoostedInThis | NotBoosted)
|
||||
export async function TierLevelCard({
|
||||
points,
|
||||
tier,
|
||||
bonusSystem,
|
||||
...boosted
|
||||
}: Props) {
|
||||
const intl = await getIntl()
|
||||
|
||||
const className = variants({ bonusSystem })
|
||||
|
||||
return (
|
||||
<article className={className}>
|
||||
{boosted.boostState === "boostedInOtherSystem" && (
|
||||
<section className={styles.boostedInfo}>
|
||||
<div className={styles.boostedTier}>
|
||||
<Caption
|
||||
uppercase
|
||||
type="bold"
|
||||
color={bonusSystemSpecifics[bonusSystem!].color}
|
||||
>
|
||||
{boosted.boostedTier}
|
||||
</Caption>
|
||||
<Caption
|
||||
type="bold"
|
||||
color={bonusSystemSpecifics[bonusSystem!].color}
|
||||
>
|
||||
{intl.formatMessage({ id: "Level upgrade" })}
|
||||
</Caption>
|
||||
</div>
|
||||
<Caption color={bonusSystemSpecifics[bonusSystem!].color}>
|
||||
{intl.formatMessage(
|
||||
{
|
||||
id: "Upgrade expires {upgradeExpires, date, short}",
|
||||
},
|
||||
{ upgradeExpires: boosted.boostExpiration }
|
||||
)}
|
||||
</Caption>
|
||||
</section>
|
||||
)}
|
||||
<section className={styles.baseInfo}>
|
||||
<div className={styles.header}>
|
||||
<div className={styles.tierInfo}>
|
||||
<span>
|
||||
<Caption
|
||||
uppercase
|
||||
type="bold"
|
||||
color={bonusSystemSpecifics[bonusSystem!].color}
|
||||
>
|
||||
{tier}
|
||||
</Caption>
|
||||
</span>
|
||||
<div className={styles.logoContainer}>
|
||||
{bonusSystemSpecifics[bonusSystem!].logo}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{boosted.boostState === "boostedInThisSystem" && (
|
||||
<Footnote className={styles.footnote}>
|
||||
<RocketLaunch
|
||||
color={bonusSystemSpecifics[bonusSystem!].rocketLaunchColor}
|
||||
/>
|
||||
<span>
|
||||
{intl.formatMessage({
|
||||
id: bonusSystemSpecifics[bonusSystem!].boostTextId,
|
||||
})}
|
||||
</span>
|
||||
</Footnote>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<Subtitle>
|
||||
{intl.formatMessage(
|
||||
{ id: "{points, number} Bonus points" },
|
||||
{ points }
|
||||
)}
|
||||
</Subtitle>
|
||||
</section>
|
||||
</article>
|
||||
)
|
||||
}
|
||||
|
||||
export function TierLevelCardSkeleton({
|
||||
bonusSystem,
|
||||
}: {
|
||||
bonusSystem?: NonNullable<Props["bonusSystem"]>
|
||||
}) {
|
||||
const className = variants({ bonusSystem })
|
||||
|
||||
return (
|
||||
<article className={className}>
|
||||
<section className={styles.baseInfo}>
|
||||
<div className={styles.header}>
|
||||
<div className={styles.tierInfo}>
|
||||
<span>
|
||||
<SkeletonShimmer width={"50px"} height={"16px"} />
|
||||
</span>
|
||||
|
||||
{bonusSystem && (
|
||||
<div className={styles.eurobonusLogo}>
|
||||
{bonusSystemSpecifics[bonusSystem!].logo}
|
||||
</div>
|
||||
)}
|
||||
{!bonusSystem && <SkeletonShimmer width={"74px"} height={"16px"} />}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Subtitle>
|
||||
<SkeletonShimmer width={"240px"} height={"26px"} />
|
||||
</Subtitle>
|
||||
</section>
|
||||
</article>
|
||||
)
|
||||
}
|
||||
|
||||
type BonusSystemSpecifics = {
|
||||
boostTextId: string
|
||||
logo: ReactNode
|
||||
rocketLaunchColor: ComponentProps<typeof RocketLaunch>["color"]
|
||||
color: ComponentProps<typeof Caption>["color"]
|
||||
}
|
||||
|
||||
type BonusSystemMapping = {
|
||||
[bonusSystem in NonNullable<
|
||||
VariantProps<typeof variants>["bonusSystem"]
|
||||
>]: BonusSystemSpecifics
|
||||
}
|
||||
|
||||
const bonusSystemSpecifics: BonusSystemMapping = {
|
||||
scandic: {
|
||||
boostTextId: "Your Friends level has upgraded your Eurobonus level",
|
||||
rocketLaunchColor: "red",
|
||||
color: "burgundy",
|
||||
logo: (
|
||||
<Image
|
||||
alt="Scandic logo"
|
||||
height={16}
|
||||
src="/_static/img/scandic-logotype.svg"
|
||||
width={74}
|
||||
/>
|
||||
),
|
||||
},
|
||||
sas: {
|
||||
boostTextId: "Your Eurobonus level has upgraded your friends level",
|
||||
rocketLaunchColor: "blue",
|
||||
color: "uiTextActive",
|
||||
logo: (
|
||||
<>
|
||||
<Image
|
||||
alt="SAS logo"
|
||||
height={16}
|
||||
src="/_static/img/sas/sas-logotype.svg"
|
||||
width={44}
|
||||
/>
|
||||
<Caption uppercase type="bold">
|
||||
Eurobonus
|
||||
</Caption>
|
||||
</>
|
||||
),
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
.tierlevelcard {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
justify-content: space-between;
|
||||
|
||||
border-radius: var(--Corner-radius-Medium);
|
||||
background: white;
|
||||
box-shadow: 0px 0px 8px 3px #0000001a;
|
||||
|
||||
overflow: hidden;
|
||||
|
||||
width: 100%;
|
||||
min-height: 176px;
|
||||
|
||||
@media screen and (min-width: 768px) {
|
||||
max-width: 335px;
|
||||
}
|
||||
|
||||
&.scandic {
|
||||
background: white;
|
||||
color: var(--Main-Brand-Burgundy);
|
||||
|
||||
.boostedInfo {
|
||||
background: linear-gradient(86.64deg, #faf6f2 0%, #f4d5c8 100.91%);
|
||||
border-radius: var(--Corner-radius-Medium);
|
||||
}
|
||||
}
|
||||
|
||||
&.sas {
|
||||
background: #f0f4ff;
|
||||
color: var(--Main-Brand-DarkBlue);
|
||||
|
||||
.boostedInfo {
|
||||
background: linear-gradient(90deg, #f0f4ff 0%, #bdcdff 100%);
|
||||
border-radius: var(--Corner-radius-Medium);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.boostedInfo {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--Spacing-x-half);
|
||||
box-shadow: 0px 0px 4px 2px #0000001a;
|
||||
|
||||
flex: 0;
|
||||
padding: var(--Spacing-x2) var(--Spacing-x-one-and-half);
|
||||
}
|
||||
|
||||
.boostedTier {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
gap: var(--Spacing-x-one-and-half);
|
||||
}
|
||||
|
||||
.baseInfo {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--Spacing-x-one-and-half);
|
||||
|
||||
padding: var(--Spacing-x2) var(--Spacing-x-one-and-half);
|
||||
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.header {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--Spacing-x2);
|
||||
}
|
||||
|
||||
.tierInfo {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
text-transform: uppercase;
|
||||
gap: var(--Spacing-x1);
|
||||
}
|
||||
|
||||
.logoContainer {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
gap: var(--Spacing-x1);
|
||||
}
|
||||
|
||||
.footnote {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
gap: var(--Spacing-x1);
|
||||
}
|
||||
Reference in New Issue
Block a user