fix: add loyaltyCard

This commit is contained in:
Christel Westerberg
2024-06-28 11:21:09 +02:00
parent 5be118d9e5
commit 323df671d8
23 changed files with 467 additions and 106 deletions

View File

@@ -8,7 +8,7 @@
.blocks {
display: grid;
gap: var(--Spacing-x5);
gap: var(--Spacing-x7);
padding-left: var(--Spacing-x2);
padding-right: var(--Spacing-x2);
}
@@ -29,6 +29,7 @@
}
.blocks {
gap: var(--Spacing-x9);
padding-left: var(--Spacing-x0);
padding-right: var(--Spacing-x0);
}

View File

@@ -2,25 +2,50 @@ import SectionContainer from "@/components/Section/Container"
import Header from "@/components/Section/Header"
import Card from "@/components/TempDesignSystem/Card"
import Grids from "@/components/TempDesignSystem/Grids"
import LoyaltyCard from "@/components/TempDesignSystem/LoyaltyCard"
import { CardsGridProps } from "@/types/components/loyalty/blocks"
import { LoyaltyCardsGridEnum } from "@/types/components/loyalty/enums"
export default function CardsGrid({ cards_grid }: CardsGridProps) {
export default function CardsGrid({
cards_grid,
firstItem = false,
}: CardsGridProps) {
return (
<SectionContainer>
<Header title={cards_grid.title} subtitle={cards_grid.preamble} />
<Header
title={cards_grid.title}
subtitle={cards_grid.preamble}
topTitle={firstItem}
/>
<Grids.Stackable>
{cards_grid.cards.map((card) => (
<Card
theme={cards_grid.theme || "one"}
key={card.system.uid}
scriptedTopTitle={card.scripted_top_title}
heading={card.heading}
bodyText={card.body_text}
secondaryButton={card.secondaryButton}
primaryButton={card.primaryButton}
/>
))}
{cards_grid.cards.map((card) => {
switch (card.__typename) {
case LoyaltyCardsGridEnum.LoyaltyCard:
return (
<LoyaltyCard
key={card.system.uid}
image={card.image}
heading={card.heading}
bodyText={card.body_text}
link={card.link}
/>
)
case LoyaltyCardsGridEnum.Card: {
return (
<Card
theme={cards_grid.theme || "one"}
key={card.system.uid}
scriptedTopTitle={card.scripted_top_title}
heading={card.heading}
bodyText={card.body_text}
secondaryButton={card.secondaryButton}
primaryButton={card.primaryButton}
/>
)
}
}
})}
</Grids.Stackable>
</SectionContainer>
)

View File

@@ -16,7 +16,7 @@ import {
TrueFriend,
} from "@/components/Levels"
import BiroScript from "@/components/TempDesignSystem/Text/BiroScript"
import Footnote from "@/components/TempDesignSystem/Text/Footnote"
import Caption from "@/components/TempDesignSystem/Text/Caption"
import Title from "@/components/TempDesignSystem/Text/Title"
import levelsData from "./data"
@@ -97,7 +97,8 @@ function LevelCard({ formatMessage, lang, level }: LevelCardProps) {
</Title>
<div className={styles.textContainer}>
{level.benefits.map((benefit) => (
<Footnote
<Caption
className={styles.levelText}
key={benefit.title}
textAlign="center"
color="textMediumContrast"
@@ -107,7 +108,7 @@ function LevelCard({ formatMessage, lang, level }: LevelCardProps) {
color="primaryLightOnSurfaceAccent"
/>
{benefit.title}
</Footnote>
</Caption>
))}
</div>
</article>

View File

@@ -20,9 +20,9 @@
display: grid;
gap: var(--Spacing-x2);
min-height: 280px;
justify-content: center;
justify-items: center;
padding: var(--Spacing-x5) var(--Spacing-x1);
grid-template-rows: auto auto 1fr;
}
.textContainer {
@@ -34,6 +34,10 @@
justify-content: center;
}
.levelText {
margin: 0;
}
.checkIcon {
vertical-align: middle;
}

View File

@@ -43,6 +43,7 @@ export function Blocks({ blocks }: BlocksProps) {
<CardsGrid
cards_grid={block.cards_grid}
key={`${block.cards_grid.title}-${idx}`}
firstItem={firstItem}
/>
)
default:

View File

@@ -1,11 +1,15 @@
.aside {
align-content: flex-start;
display: grid;
gap: var(--Spacing-x4);
display: none;
}
@media screen and (max-width: 1366px) {
.content {
padding: var(--Spacing-x0) var(--Spacing-x2);
.content {
padding: var(--Spacing-x0) var(--Spacing-x2);
}
@media screen and (min-width: 1366px) {
.aside {
align-content: flex-start;
display: grid;
gap: var(--Spacing-x4);
}
}

View File

@@ -0,0 +1,65 @@
import ArrowRight from "@/components/Icons/ArrowRight"
import Image from "@/components/Image"
import Link from "@/components/TempDesignSystem/Link"
import Body from "@/components/TempDesignSystem/Text/Body"
import Title from "@/components/TempDesignSystem/Text/Title"
import { loyaltyCardVariants } from "./variants"
import styles from "./loyaltyCard.module.css"
import type { LoyaltyCardProps } from "./loyaltyCard"
export default function LoyaltyCard({
link,
image,
heading,
bodyText,
theme = "white",
className,
}: LoyaltyCardProps) {
return (
<article
className={loyaltyCardVariants({
className,
theme,
})}
>
{image ? (
<section>
<Image
src={image.url}
width={180}
height={160}
className={styles.image}
alt={image.meta.alt || image.title}
/>
</section>
) : null}
<Title as="h5" level="h3" textAlign="center">
{heading}
</Title>
{bodyText ? (
<Body textAlign="center" color="red">
{bodyText}
</Body>
) : null}
<div className={styles.buttonContainer}>
{link ? (
<span className={styles.linkWrapper}>
<ArrowRight color="burgundy" className={styles.icon} />
<Link
className={styles.link}
color="burgundy"
href={link.href}
target={link.openInNewTab ? "_blank" : undefined}
variant="myPage"
>
{link.title}
</Link>
</span>
) : null}
</div>
</article>
)
}

View File

@@ -0,0 +1,43 @@
.container {
align-items: center;
display: grid;
border-radius: var(--Corner-radius-xLarge);
gap: var(--Spacing-x2);
height: 480px;
justify-content: space-between;
margin-right: var(--Spacing-x2);
padding: var(--Spacing-x4) var(--Spacing-x3);
text-align: center;
width: 100%;
}
.image {
object-fit: contain;
height: 160px;
width: auto;
}
.white {
background-color: var(--Main-Grey-White);
}
.buttonContainer {
display: flex;
gap: var(--Spacing-x1);
justify-content: center;
}
.linkWrapper {
display: flex;
align-items: baseline;
gap: var(--Spacing-x-half);
}
.link {
display: flex;
align-items: center;
}
.icon {
align-self: center;
}

View File

@@ -0,0 +1,20 @@
import { loyaltyCardVariants } from "./variants"
import type { VariantProps } from "class-variance-authority"
import { ImageVaultAsset } from "@/types/components/imageVaultImage"
export interface LoyaltyCardProps
extends React.HTMLAttributes<HTMLDivElement>,
VariantProps<typeof loyaltyCardVariants> {
link?: {
href: string
title: string
openInNewTab?: boolean
isExternal: boolean
}
image?: ImageVaultAsset
heading?: string | null
bodyText?: string | null
backgroundImage?: { url: string }
}

View File

@@ -0,0 +1,14 @@
import { cva } from "class-variance-authority"
import styles from "./loyaltyCard.module.css"
export const loyaltyCardVariants = cva(styles.container, {
variants: {
theme: {
white: styles.white,
},
},
defaultVariants: {
theme: "white",
},
})

View File

@@ -36,3 +36,15 @@
.pale {
color: var(--Scandic-Brand-Pale-Peach);
}
.textMediumContrast {
color: var(--Base-Text-UI-Medium-contrast);
}
.center {
text-align: center;
}
.left {
text-align: left;
}

View File

@@ -9,19 +9,21 @@ export default function Caption({
className = "",
color,
fontOnly = false,
textAlign,
textTransform,
...props
}: CaptionProps) {
const Comp = asChild ? Slot : "p"
const classNames = fontOnly
? fontOnlycaptionVariants({
className,
textTransform,
})
className,
textTransform,
})
: captionVariants({
className,
color,
textTransform,
})
className,
color,
textTransform,
textAlign,
})
return <Comp className={classNames} {...props} />
}

View File

@@ -8,11 +8,16 @@ const config = {
black: styles.black,
burgundy: styles.burgundy,
pale: styles.pale,
textMediumContrast: styles.textMediumContrast,
},
textTransform: {
bold: styles.bold,
regular: styles.regular,
},
textAlign: {
center: styles.center,
left: styles.left,
},
},
defaultVariants: {
color: "black",