feat(SW-217): Split up Card to two (Card and TeaserCard)
This commit is contained in:
@@ -1,10 +1,11 @@
|
||||
import SectionContainer from "@/components/Section/Container"
|
||||
import SectionHeader from "@/components/Section/Header"
|
||||
import Card from "@/components/TempDesignSystem/Card"
|
||||
import ContentCard from "@/components/TempDesignSystem/ContentCard"
|
||||
import Grids from "@/components/TempDesignSystem/Grids"
|
||||
import LoyaltyCard from "@/components/TempDesignSystem/LoyaltyCard"
|
||||
|
||||
import TeaserCard from "../TempDesignSystem/TeaserCard"
|
||||
|
||||
import type { CardsGridProps } from "@/types/components/blocks/cardsGrid"
|
||||
import { CardsGridEnum } from "@/types/enums/cardsGrid"
|
||||
|
||||
@@ -22,37 +23,38 @@ export default function CardsGrid({
|
||||
<Grids.Stackable>
|
||||
{cards_grid.cards.map((card) => {
|
||||
switch (card.__typename) {
|
||||
case CardsGridEnum.cards.Card: {
|
||||
return card.isContentCard ? (
|
||||
<ContentCard
|
||||
case CardsGridEnum.cards.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}
|
||||
/>
|
||||
)
|
||||
case CardsGridEnum.cards.TeaserCard:
|
||||
return (
|
||||
<TeaserCard
|
||||
key={card.system.uid}
|
||||
title={card.heading}
|
||||
description={card.body_text}
|
||||
backgroundImage={card.backgroundImage}
|
||||
primaryButton={card.primaryButton}
|
||||
secondaryButton={card.secondaryButton}
|
||||
sidePeekButton={card.sidePeekButton}
|
||||
image={card.image}
|
||||
style="default"
|
||||
title={card.heading}
|
||||
/>
|
||||
) : (
|
||||
<Card
|
||||
key={card.system.uid}
|
||||
bodyText={card.body_text}
|
||||
heading={card.heading}
|
||||
primaryButton={card.primaryButton}
|
||||
secondaryButton={card.secondaryButton}
|
||||
scriptedTopTitle={card.scripted_top_title}
|
||||
theme={cards_grid.theme || "one"}
|
||||
/>
|
||||
)
|
||||
}
|
||||
case CardsGridEnum.cards.LoyaltyCard:
|
||||
return (
|
||||
<LoyaltyCard
|
||||
key={card.system.uid}
|
||||
bodyText={card.body_text}
|
||||
heading={card.heading}
|
||||
image={card.image}
|
||||
heading={card.heading}
|
||||
bodyText={card.body_text}
|
||||
link={card.link}
|
||||
/>
|
||||
)
|
||||
|
||||
@@ -7,32 +7,32 @@ import Link from "@/components/TempDesignSystem/Link"
|
||||
import Body from "@/components/TempDesignSystem/Text/Body"
|
||||
|
||||
import Subtitle from "../Text/Subtitle"
|
||||
import { contentCardVariants } from "./variants"
|
||||
import { teaserCardVariants } from "./variants"
|
||||
|
||||
import styles from "./contentCard.module.css"
|
||||
import styles from "./teaserCard.module.css"
|
||||
|
||||
import type { ContentCardProps } from "@/types/components/contentCard"
|
||||
import type { TeaserCardProps } from "@/types/components/teaserCard"
|
||||
|
||||
export default function ContentCard({
|
||||
export default function TeaserCard({
|
||||
title,
|
||||
description,
|
||||
primaryButton,
|
||||
secondaryButton,
|
||||
sidePeekButton,
|
||||
backgroundImage,
|
||||
image,
|
||||
style = "default",
|
||||
alwaysStack = false,
|
||||
className,
|
||||
}: ContentCardProps) {
|
||||
const cardClasses = contentCardVariants({ style, alwaysStack, className })
|
||||
}: TeaserCardProps) {
|
||||
const cardClasses = teaserCardVariants({ style, alwaysStack, className })
|
||||
|
||||
return (
|
||||
<div className={cardClasses}>
|
||||
{backgroundImage && (
|
||||
<article className={cardClasses}>
|
||||
{image && (
|
||||
<div className={styles.imageContainer}>
|
||||
<Image
|
||||
src={backgroundImage.url}
|
||||
alt={backgroundImage.meta?.alt || ""}
|
||||
src={image.url}
|
||||
alt={image.meta?.alt || ""}
|
||||
className={styles.backgroundImage}
|
||||
width={399}
|
||||
height={201}
|
||||
@@ -70,6 +70,7 @@ export default function ContentCard({
|
||||
<Link
|
||||
href={primaryButton.href}
|
||||
target={primaryButton.openInNewTab ? "_blank" : undefined}
|
||||
color="none"
|
||||
>
|
||||
{primaryButton.title}
|
||||
</Link>
|
||||
@@ -93,6 +94,6 @@ export default function ContentCard({
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
)
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
import { cva } from "class-variance-authority"
|
||||
|
||||
import styles from "./contentCard.module.css"
|
||||
import styles from "./teaserCard.module.css"
|
||||
|
||||
export const contentCardVariants = cva(styles.card, {
|
||||
export const teaserCardVariants = cva(styles.card, {
|
||||
variants: {
|
||||
style: {
|
||||
default: styles.default,
|
||||
@@ -9,9 +9,7 @@ fragment CardBlock on Card {
|
||||
body_text
|
||||
has_primary_button
|
||||
has_secondary_button
|
||||
has_sidepeek_button
|
||||
heading
|
||||
is_content_card
|
||||
scripted_top_title
|
||||
title
|
||||
primary_button {
|
||||
@@ -52,9 +50,6 @@ fragment CardBlock on Card {
|
||||
}
|
||||
}
|
||||
}
|
||||
sidepeek_button {
|
||||
call_to_action_text
|
||||
}
|
||||
system {
|
||||
...System
|
||||
}
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
#import "./Card.graphql"
|
||||
#import "./LoyaltyCard.graphql"
|
||||
#import "./TeaserCard.graphql"
|
||||
|
||||
#import "./Refs/Card.graphql"
|
||||
#import "./Refs/LoyaltyCard.graphql"
|
||||
|
||||
#import "./Refs/TeaserCard.graphql"
|
||||
fragment CardsGrid_ContentPage on ContentPageBlocksCardsGrid {
|
||||
cards_grid {
|
||||
layout
|
||||
@@ -15,6 +17,7 @@ fragment CardsGrid_ContentPage on ContentPageBlocksCardsGrid {
|
||||
__typename
|
||||
...CardBlock
|
||||
...LoyaltyCardBlock
|
||||
...TeaserCardBlock
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -29,6 +32,7 @@ fragment CardsGrid_ContentPageRefs on ContentPageBlocksCardsGrid {
|
||||
__typename
|
||||
...CardBlockRef
|
||||
...LoyaltyCardBlockRef
|
||||
...TeaserCardBlockRef
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
36
lib/graphql/Fragments/Blocks/Refs/TeaserCard.graphql
Normal file
36
lib/graphql/Fragments/Blocks/Refs/TeaserCard.graphql
Normal file
@@ -0,0 +1,36 @@
|
||||
#import "../../AccountPage/Ref.graphql"
|
||||
#import "../../ContentPage/Ref.graphql"
|
||||
#import "../../LoyaltyPage/Ref.graphql"
|
||||
#import "../../HotelPage/Ref.graphql"
|
||||
|
||||
fragment TeaserCardBlockRef on TeaserCard {
|
||||
secondary_button {
|
||||
linkConnection {
|
||||
edges {
|
||||
node {
|
||||
__typename
|
||||
...AccountPageRef
|
||||
...ContentPageRef
|
||||
...LoyaltyPageRef
|
||||
...HotelPageRef
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
primary_button {
|
||||
linkConnection {
|
||||
edges {
|
||||
node {
|
||||
__typename
|
||||
...AccountPageRef
|
||||
...ContentPageRef
|
||||
...LoyaltyPageRef
|
||||
...HotelPageRef
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
system {
|
||||
...System
|
||||
}
|
||||
}
|
||||
61
lib/graphql/Fragments/Blocks/TeaserCard.graphql
Normal file
61
lib/graphql/Fragments/Blocks/TeaserCard.graphql
Normal file
@@ -0,0 +1,61 @@
|
||||
#import "../System.graphql"
|
||||
|
||||
#import "../PageLink/AccountPageLink.graphql"
|
||||
#import "../PageLink/ContentPageLink.graphql"
|
||||
#import "../PageLink/LoyaltyPageLink.graphql"
|
||||
#import "../PageLink/HotelPageLink.graphql"
|
||||
|
||||
fragment TeaserCardBlock on TeaserCard {
|
||||
heading
|
||||
body_text
|
||||
image
|
||||
title
|
||||
has_primary_button
|
||||
has_secondary_button
|
||||
has_sidepeek_button
|
||||
primary_button {
|
||||
is_contentstack_link
|
||||
cta_text
|
||||
open_in_new_tab
|
||||
external_link {
|
||||
title
|
||||
href
|
||||
}
|
||||
linkConnection {
|
||||
edges {
|
||||
node {
|
||||
__typename
|
||||
...LoyaltyPageLink
|
||||
...ContentPageLink
|
||||
...AccountPageLink
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
secondary_button {
|
||||
is_contentstack_link
|
||||
cta_text
|
||||
open_in_new_tab
|
||||
external_link {
|
||||
title
|
||||
href
|
||||
}
|
||||
linkConnection {
|
||||
edges {
|
||||
node {
|
||||
__typename
|
||||
...LoyaltyPageLink
|
||||
...ContentPageLink
|
||||
...AccountPageLink
|
||||
...HotelPageLink
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
sidepeek_button {
|
||||
call_to_action_text
|
||||
}
|
||||
system {
|
||||
...System
|
||||
}
|
||||
}
|
||||
@@ -15,17 +15,10 @@ export const cardBlockSchema = z.object({
|
||||
body_text: z.string().optional().default(""),
|
||||
has_primary_button: z.boolean().default(false),
|
||||
has_secondary_button: z.boolean().default(false),
|
||||
has_sidepeek_button: z.boolean().optional().default(false),
|
||||
heading: z.string().optional().default(""),
|
||||
is_content_card: z.boolean().optional().default(false),
|
||||
primary_button: buttonSchema,
|
||||
scripted_top_title: z.string().optional(),
|
||||
secondary_button: buttonSchema,
|
||||
sidepeek_button: z
|
||||
.object({
|
||||
call_to_action_text: z.string().optional(),
|
||||
})
|
||||
.optional(),
|
||||
system: systemSchema,
|
||||
title: z.string().optional(),
|
||||
})
|
||||
@@ -36,23 +29,53 @@ export function transformCardBlock(card: typeof cardBlockSchema._type) {
|
||||
backgroundImage: card.background_image,
|
||||
body_text: card.body_text,
|
||||
heading: card.heading,
|
||||
isContentCard: card.is_content_card,
|
||||
primaryButton: card.has_primary_button ? card.primary_button : undefined,
|
||||
scripted_top_title: card.scripted_top_title,
|
||||
secondaryButton: card.has_secondary_button
|
||||
? card.secondary_button
|
||||
: undefined,
|
||||
sidePeekButton:
|
||||
card.has_sidepeek_button && card.sidepeek_button?.call_to_action_text
|
||||
? {
|
||||
title: card.sidepeek_button.call_to_action_text,
|
||||
}
|
||||
: undefined,
|
||||
system: card.system,
|
||||
title: card.title,
|
||||
}
|
||||
}
|
||||
|
||||
export const teaserCardBlockSchema = z.object({
|
||||
__typename: z.literal(CardsGridEnum.cards.TeaserCard),
|
||||
heading: z.string().default(""),
|
||||
body_text: z.string().default(""),
|
||||
image: tempImageVaultAssetSchema,
|
||||
primary_button: buttonSchema,
|
||||
secondary_button: buttonSchema,
|
||||
has_primary_button: z.boolean().default(false),
|
||||
has_secondary_button: z.boolean().default(false),
|
||||
has_sidepeek_button: z.boolean().optional().default(false),
|
||||
side_peek_button: z
|
||||
.object({
|
||||
title: z.string().optional().default(""),
|
||||
})
|
||||
.optional(),
|
||||
system: systemSchema,
|
||||
})
|
||||
|
||||
export function transformTeaserCardBlock(
|
||||
card: typeof teaserCardBlockSchema._type
|
||||
) {
|
||||
return {
|
||||
__typename: card.__typename,
|
||||
body_text: card.body_text,
|
||||
heading: card.heading,
|
||||
primaryButton: card.has_primary_button ? card.primary_button : undefined,
|
||||
secondaryButton: card.has_secondary_button
|
||||
? card.secondary_button
|
||||
: undefined,
|
||||
sidePeekButton: card.has_sidepeek_button
|
||||
? card.side_peek_button
|
||||
: undefined,
|
||||
image: card.image,
|
||||
system: card.system,
|
||||
}
|
||||
}
|
||||
|
||||
const loyaltyCardBlockSchema = z.object({
|
||||
__typename: z.literal(CardsGridEnum.cards.LoyaltyCard),
|
||||
body_text: z.string().optional(),
|
||||
@@ -77,6 +100,7 @@ export const cardsGridSchema = z.object({
|
||||
node: z.discriminatedUnion("__typename", [
|
||||
cardBlockSchema,
|
||||
loyaltyCardBlockSchema,
|
||||
teaserCardBlockSchema,
|
||||
]),
|
||||
})
|
||||
),
|
||||
@@ -95,6 +119,8 @@ export const cardsGridSchema = z.object({
|
||||
cards: data.cardConnection.edges.map((card) => {
|
||||
if (card.node.__typename === CardsGridEnum.cards.Card) {
|
||||
return transformCardBlock(card.node)
|
||||
} else if (card.node.__typename === CardsGridEnum.cards.TeaserCard) {
|
||||
return transformTeaserCardBlock(card.node)
|
||||
} else {
|
||||
return {
|
||||
__typename: card.node.__typename,
|
||||
@@ -118,7 +144,11 @@ export const cardBlockRefsSchema = z.object({
|
||||
system: systemSchema,
|
||||
})
|
||||
|
||||
export function transformCardBlockRefs(card: typeof cardBlockRefsSchema._type) {
|
||||
export function transformCardBlockRefs(
|
||||
card:
|
||||
| typeof cardBlockRefsSchema._type
|
||||
| typeof teaserCardBlockRefsSchema._type
|
||||
) {
|
||||
const cards = [card.system]
|
||||
if (card.primary_button) {
|
||||
cards.push(card.primary_button)
|
||||
@@ -135,6 +165,13 @@ const loyaltyCardBlockRefsSchema = z.object({
|
||||
system: systemSchema,
|
||||
})
|
||||
|
||||
export const teaserCardBlockRefsSchema = z.object({
|
||||
__typename: z.literal(CardsGridEnum.cards.TeaserCard),
|
||||
primary_button: linkConnectionRefsSchema,
|
||||
secondary_button: linkConnectionRefsSchema,
|
||||
system: systemSchema,
|
||||
})
|
||||
|
||||
export const cardGridRefsSchema = z.object({
|
||||
cards_grid: z
|
||||
.object({
|
||||
@@ -144,6 +181,7 @@ export const cardGridRefsSchema = z.object({
|
||||
node: z.discriminatedUnion("__typename", [
|
||||
cardBlockRefsSchema,
|
||||
loyaltyCardBlockRefsSchema,
|
||||
teaserCardBlockRefsSchema,
|
||||
]),
|
||||
})
|
||||
),
|
||||
@@ -152,7 +190,10 @@ export const cardGridRefsSchema = z.object({
|
||||
.transform((data) => {
|
||||
return data.cardConnection.edges
|
||||
.map(({ node }) => {
|
||||
if (node.__typename === CardsGridEnum.cards.Card) {
|
||||
if (
|
||||
node.__typename === CardsGridEnum.cards.Card ||
|
||||
node.__typename === CardsGridEnum.cards.TeaserCard
|
||||
) {
|
||||
return transformCardBlockRefs(node)
|
||||
} else {
|
||||
const loyaltyCards = [node.system]
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { VariantProps } from "class-variance-authority"
|
||||
|
||||
import { contentCardVariants } from "@/components/TempDesignSystem/ContentCard/variants"
|
||||
import { teaserCardVariants } from "@/components/TempDesignSystem/TeaserCard/variants"
|
||||
|
||||
import { ImageVaultAsset } from "@/types/components/imageVault"
|
||||
import type { CardProps } from "@/components/TempDesignSystem/Card/card"
|
||||
@@ -9,13 +9,13 @@ interface SidePeekButton {
|
||||
title: string
|
||||
}
|
||||
|
||||
export interface ContentCardProps
|
||||
extends VariantProps<typeof contentCardVariants> {
|
||||
export interface TeaserCardProps
|
||||
extends VariantProps<typeof teaserCardVariants> {
|
||||
title: string
|
||||
description: string
|
||||
primaryButton?: CardProps["primaryButton"]
|
||||
secondaryButton?: CardProps["secondaryButton"]
|
||||
sidePeekButton?: SidePeekButton
|
||||
backgroundImage?: ImageVaultAsset
|
||||
image?: ImageVaultAsset
|
||||
className?: string
|
||||
}
|
||||
@@ -2,5 +2,6 @@ export namespace CardsGridEnum {
|
||||
export const enum cards {
|
||||
Card = "Card",
|
||||
LoyaltyCard = "LoyaltyCard",
|
||||
TeaserCard = "TeaserCard",
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user