feat: add new cards grid block
This commit is contained in:
@@ -17,7 +17,8 @@ import type {
|
||||
import { RTEMarkType } from "@/types/rte/node"
|
||||
import type { RenderOptions } from "@/types/rte/option"
|
||||
|
||||
function extractPossibleAttributes(attrs: Attributes) {
|
||||
function extractPossibleAttributes(attrs: Attributes | undefined) {
|
||||
if (!attrs) return {}
|
||||
const props: Record<string, any> = {}
|
||||
if (attrs.id) {
|
||||
props.id = attrs.id
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
.container {
|
||||
display: grid;
|
||||
gap: 2.4rem;
|
||||
}
|
||||
|
||||
.subtitle {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.titleContainer {
|
||||
display: grid;
|
||||
gap: 0.8rem;
|
||||
}
|
||||
|
||||
.cardContainer {
|
||||
display: grid;
|
||||
gap: 1.6rem;
|
||||
}
|
||||
|
||||
@media screen and (min-width: 950px) {
|
||||
.cardContainer {
|
||||
grid-template-columns: 1fr 1fr;
|
||||
}
|
||||
|
||||
.cardWrapper:last-child {
|
||||
grid-column: span 2;
|
||||
}
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
import { _ } from "@/lib/translation"
|
||||
|
||||
import Card from "@/components/TempDesignSystem/Card"
|
||||
import Title from "@/components/Title"
|
||||
|
||||
import styles from "./cardGrid.module.css"
|
||||
|
||||
import { CardGridProps } from "@/types/components/loyalty/blocks"
|
||||
|
||||
export default function CardGrid({ card_grid }: CardGridProps) {
|
||||
return (
|
||||
<section className={styles.container}>
|
||||
<header className={styles.titleContainer}>
|
||||
<Title as="h3" level="h2" weight="semiBold" uppercase>
|
||||
{card_grid.title}
|
||||
</Title>
|
||||
{card_grid.subtitle ? (
|
||||
<Title
|
||||
as="h5"
|
||||
level="h3"
|
||||
weight="regular"
|
||||
className={styles.subtitle}
|
||||
>
|
||||
{card_grid.subtitle}
|
||||
</Title>
|
||||
) : null}
|
||||
</header>
|
||||
<div className={styles.cardContainer}>
|
||||
{card_grid.cards.map((card, i) => (
|
||||
<div className={styles.cardWrapper} key={`${card.title}+${i}`}>
|
||||
<Card
|
||||
subtitle={card.subtitle}
|
||||
title={card.title}
|
||||
link={card.link}
|
||||
/>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
)
|
||||
}
|
||||
4
components/Loyalty/Blocks/CardsGrid/cardsGrid.module.css
Normal file
4
components/Loyalty/Blocks/CardsGrid/cardsGrid.module.css
Normal file
@@ -0,0 +1,4 @@
|
||||
.section {
|
||||
display: grid;
|
||||
gap: 2.4rem;
|
||||
}
|
||||
44
components/Loyalty/Blocks/CardsGrid/index.tsx
Normal file
44
components/Loyalty/Blocks/CardsGrid/index.tsx
Normal file
@@ -0,0 +1,44 @@
|
||||
import { _ } from "@/lib/translation"
|
||||
|
||||
import Header from "@/components/MyPages/Blocks/Header"
|
||||
import Card from "@/components/TempDesignSystem/Card"
|
||||
import CardGrid from "@/components/TempDesignSystem/CardGrid"
|
||||
|
||||
import styles from "./cardsGrid.module.css"
|
||||
|
||||
import { CardsGridProps } from "@/types/components/loyalty/blocks"
|
||||
|
||||
export default function CardsGrid({ cards_grid }: CardsGridProps) {
|
||||
return (
|
||||
<section className={styles.section}>
|
||||
<Header title={cards_grid.title} subtitle={cards_grid.preamble} />
|
||||
<CardGrid variant={cards_grid.layout}>
|
||||
{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 && {
|
||||
href: card.secondaryButton.link.href,
|
||||
title: card.secondaryButton.link.title,
|
||||
openInNewTab: card.secondaryButton.open_in_new_tab,
|
||||
isExternal: card.secondaryButton.isExternal,
|
||||
}
|
||||
}
|
||||
primaryButton={
|
||||
card.primaryButton && {
|
||||
href: card.primaryButton.link.href,
|
||||
title: card.primaryButton.link.title,
|
||||
openInNewTab: card.primaryButton.open_in_new_tab,
|
||||
isExternal: card.primaryButton.isExternal,
|
||||
}
|
||||
}
|
||||
/>
|
||||
))}
|
||||
</CardGrid>
|
||||
</section>
|
||||
)
|
||||
}
|
||||
@@ -2,7 +2,7 @@ import JsonToHtml from "@/components/JsonToHtml"
|
||||
import DynamicContentBlock from "@/components/Loyalty/Blocks/DynamicContent"
|
||||
import Shortcuts from "@/components/MyPages/Blocks/Shortcuts"
|
||||
|
||||
import CardGrid from "./CardGrid"
|
||||
import CardsGrid from "./CardsGrid"
|
||||
|
||||
import type { BlocksProps } from "@/types/components/loyalty/blocks"
|
||||
import { LoyaltyBlocksTypenameEnum } from "@/types/components/loyalty/enums"
|
||||
@@ -10,8 +10,6 @@ import { LoyaltyBlocksTypenameEnum } from "@/types/components/loyalty/enums"
|
||||
export function Blocks({ blocks }: BlocksProps) {
|
||||
return blocks.map((block) => {
|
||||
switch (block.__typename) {
|
||||
case LoyaltyBlocksTypenameEnum.LoyaltyPageBlocksCardGrid:
|
||||
return <CardGrid card_grid={block.card_grid} />
|
||||
case LoyaltyBlocksTypenameEnum.LoyaltyPageBlocksContent:
|
||||
return (
|
||||
<section>
|
||||
@@ -31,6 +29,8 @@ export function Blocks({ blocks }: BlocksProps) {
|
||||
subtitle={block.shortcuts.preamble}
|
||||
/>
|
||||
)
|
||||
case LoyaltyBlocksTypenameEnum.LoyaltyPageBlocksCardsGrid:
|
||||
return <CardsGrid cards_grid={block.cards_grid} />
|
||||
default:
|
||||
return null
|
||||
}
|
||||
|
||||
16
components/TempDesignSystem/Card/variants.ts
Normal file
16
components/TempDesignSystem/Card/variants.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import { cva } from "class-variance-authority"
|
||||
|
||||
import styles from "./card.module.css"
|
||||
|
||||
export const cardVariants = cva(styles.container, {
|
||||
variants: {
|
||||
theme: {
|
||||
one: styles.themeOne,
|
||||
two: styles.themeTwo,
|
||||
three: styles.themeThree,
|
||||
},
|
||||
},
|
||||
defaultVariants: {
|
||||
theme: "one",
|
||||
},
|
||||
})
|
||||
@@ -37,14 +37,19 @@
|
||||
}
|
||||
|
||||
@media screen and (min-width: 950px) {
|
||||
.twoColumnGrid {
|
||||
.twoColumnGrid,
|
||||
.twoPlusOne {
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
}
|
||||
|
||||
.treeColumnGrid {
|
||||
.threeColumnGrid {
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
}
|
||||
|
||||
.twoPlusOne > *:last-child {
|
||||
grid-column: span 2;
|
||||
}
|
||||
|
||||
.carousel {
|
||||
grid-auto-flow: unset;
|
||||
margin: 0;
|
||||
|
||||
49
lib/graphql/Fragments/Blocks/Card.graphql
Normal file
49
lib/graphql/Fragments/Blocks/Card.graphql
Normal file
@@ -0,0 +1,49 @@
|
||||
fragment CardBlock on Card {
|
||||
heading
|
||||
body_text
|
||||
background_image
|
||||
scripted_top_title
|
||||
title
|
||||
secondary_button {
|
||||
is_contentstack_link
|
||||
cta_text
|
||||
open_in_new_tab
|
||||
external_link {
|
||||
title
|
||||
href
|
||||
}
|
||||
linkConnection {
|
||||
edges {
|
||||
node {
|
||||
__typename
|
||||
...LoyaltyPageLink
|
||||
...ContentPageLink
|
||||
...AccountPageLink
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
primary_button {
|
||||
is_contentstack_link
|
||||
cta_text
|
||||
open_in_new_tab
|
||||
external_link {
|
||||
title
|
||||
href
|
||||
}
|
||||
linkConnection {
|
||||
edges {
|
||||
node {
|
||||
__typename
|
||||
...LoyaltyPageLink
|
||||
...ContentPageLink
|
||||
...AccountPageLink
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
system {
|
||||
locale
|
||||
uid
|
||||
}
|
||||
}
|
||||
29
lib/graphql/Fragments/Blocks/Refs/Card.graphql
Normal file
29
lib/graphql/Fragments/Blocks/Refs/Card.graphql
Normal file
@@ -0,0 +1,29 @@
|
||||
fragment CardBlockRef on Card {
|
||||
secondary_button {
|
||||
linkConnection {
|
||||
edges {
|
||||
node {
|
||||
__typename
|
||||
...LoyaltyPageRef
|
||||
...ContentPageRef
|
||||
...AccountPageRef
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
primary_button {
|
||||
linkConnection {
|
||||
edges {
|
||||
node {
|
||||
__typename
|
||||
...LoyaltyPageRef
|
||||
...ContentPageRef
|
||||
...AccountPageRef
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
system {
|
||||
...System
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,6 @@
|
||||
#import "../Fragments/Image.graphql"
|
||||
#import "../Fragments/Blocks/Card.graphql"
|
||||
#import "../Fragments/Blocks/Refs/Card.graphql"
|
||||
#import "../Fragments/PageLink/AccountPageLink.graphql"
|
||||
#import "../Fragments/PageLink/ContentPageLink.graphql"
|
||||
#import "../Fragments/PageLink/LoyaltyPageLink.graphql"
|
||||
@@ -11,8 +13,8 @@
|
||||
query GetLoyaltyPage($locale: String!, $uid: String!) {
|
||||
loyalty_page(uid: $uid, locale: $locale) {
|
||||
blocks {
|
||||
__typename
|
||||
... on LoyaltyPageBlocksShortcuts {
|
||||
__typename
|
||||
shortcuts {
|
||||
title
|
||||
preamble
|
||||
@@ -22,10 +24,9 @@ query GetLoyaltyPage($locale: String!, $uid: String!) {
|
||||
linkConnection {
|
||||
edges {
|
||||
node {
|
||||
__typename
|
||||
...AccountPageLink
|
||||
...LoyaltyPageLink
|
||||
...ContentPageLink
|
||||
...AccountPageLink
|
||||
}
|
||||
}
|
||||
totalCount
|
||||
@@ -34,6 +35,7 @@ query GetLoyaltyPage($locale: String!, $uid: String!) {
|
||||
}
|
||||
}
|
||||
... on LoyaltyPageBlocksDynamicContent {
|
||||
__typename
|
||||
dynamic_content {
|
||||
title
|
||||
subtitle
|
||||
@@ -52,30 +54,8 @@ query GetLoyaltyPage($locale: String!, $uid: String!) {
|
||||
}
|
||||
}
|
||||
}
|
||||
... on LoyaltyPageBlocksCardGrid {
|
||||
card_grid {
|
||||
title
|
||||
subtitle
|
||||
cards {
|
||||
referenceConnection {
|
||||
edges {
|
||||
node {
|
||||
__typename
|
||||
...LoyaltyPageLink
|
||||
...ContentPageLink
|
||||
...AccountPageLink
|
||||
}
|
||||
}
|
||||
totalCount
|
||||
}
|
||||
title
|
||||
subtitle
|
||||
open_in_new_tab
|
||||
cta_text
|
||||
}
|
||||
}
|
||||
}
|
||||
... on LoyaltyPageBlocksContent {
|
||||
__typename
|
||||
content {
|
||||
content {
|
||||
json
|
||||
@@ -83,7 +63,6 @@ query GetLoyaltyPage($locale: String!, $uid: String!) {
|
||||
edges {
|
||||
node {
|
||||
__typename
|
||||
...Image
|
||||
...LoyaltyPageLink
|
||||
...ContentPageLink
|
||||
}
|
||||
@@ -93,6 +72,22 @@ query GetLoyaltyPage($locale: String!, $uid: String!) {
|
||||
}
|
||||
}
|
||||
}
|
||||
... on LoyaltyPageBlocksCardsGrid {
|
||||
__typename
|
||||
cards_grid {
|
||||
title
|
||||
preamble
|
||||
layout
|
||||
theme
|
||||
cardConnection(limit: 10) {
|
||||
edges {
|
||||
node {
|
||||
...CardBlock
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
title
|
||||
heading
|
||||
@@ -185,23 +180,6 @@ query GetLoyaltyPageRefs($locale: String!, $uid: String!) {
|
||||
}
|
||||
}
|
||||
}
|
||||
... on LoyaltyPageBlocksCardGrid {
|
||||
__typename
|
||||
card_grid {
|
||||
cards {
|
||||
referenceConnection {
|
||||
edges {
|
||||
node {
|
||||
__typename
|
||||
...AccountPageRef
|
||||
...ContentPageRef
|
||||
...LoyaltyPageRef
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
... on LoyaltyPageBlocksContent {
|
||||
__typename
|
||||
content {
|
||||
@@ -228,6 +206,18 @@ query GetLoyaltyPageRefs($locale: String!, $uid: String!) {
|
||||
}
|
||||
}
|
||||
}
|
||||
... on LoyaltyPageBlocksCardsGrid {
|
||||
__typename
|
||||
cards_grid {
|
||||
cardConnection(limit: 10) {
|
||||
edges {
|
||||
node {
|
||||
...CardBlockRef
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
sidebar {
|
||||
... on LoyaltyPageSidebarContent {
|
||||
|
||||
@@ -13,37 +13,22 @@ import { PageLinkEnum } from "@/types/requests/pageLinks"
|
||||
import { EdgesWithTotalCount } from "@/types/requests/utils/edges"
|
||||
import { RTEDocument } from "@/types/rte/node"
|
||||
|
||||
const loyaltyPageBlockCardGrid = z.object({
|
||||
__typename: z.literal(LoyaltyBlocksTypenameEnum.LoyaltyPageBlocksCardGrid),
|
||||
card_grid: z.object({
|
||||
title: z.string().nullable(),
|
||||
subtitle: z.string().nullable(),
|
||||
cards: z.array(
|
||||
z.object({
|
||||
title: z.string().nullable(),
|
||||
subtitle: z.string().nullable(),
|
||||
referenceConnection: z.object({
|
||||
edges: z.array(
|
||||
z.object({
|
||||
node: z.object({
|
||||
system: z.object({
|
||||
uid: z.string(),
|
||||
locale: z.nativeEnum(Lang),
|
||||
}),
|
||||
url: z.string(),
|
||||
title: z.string(),
|
||||
__typename: z.string(),
|
||||
}),
|
||||
})
|
||||
),
|
||||
totalCount: z.number(),
|
||||
const pageLink = z.object({
|
||||
edges: z.array(
|
||||
z.object({
|
||||
node: z.object({
|
||||
system: z.object({
|
||||
uid: z.string(),
|
||||
locale: z.nativeEnum(Lang),
|
||||
}),
|
||||
open_in_new_tab: z.boolean(),
|
||||
cta_text: z.string().nullable(),
|
||||
})
|
||||
),
|
||||
}),
|
||||
url: z.string(),
|
||||
title: z.string(),
|
||||
__typename: z.string(),
|
||||
}),
|
||||
})
|
||||
),
|
||||
})
|
||||
|
||||
const loyaltyPageDynamicContent = z.object({
|
||||
__typename: z.literal(
|
||||
LoyaltyBlocksTypenameEnum.LoyaltyPageBlocksDynamicContent
|
||||
@@ -93,7 +78,8 @@ const loyaltyPageShortcuts = z.object({
|
||||
.object({
|
||||
original_url: z.string().nullable(),
|
||||
})
|
||||
.nullable(),
|
||||
.nullable()
|
||||
.optional(),
|
||||
title: z.string(),
|
||||
}),
|
||||
})
|
||||
@@ -107,6 +93,59 @@ const loyaltyPageShortcuts = z.object({
|
||||
}),
|
||||
})
|
||||
|
||||
const cardBlock = z.object({
|
||||
heading: z.string().nullable(),
|
||||
body_text: z.string().nullable(),
|
||||
background_image: z.any(),
|
||||
scripted_top_title: z.string().nullable(),
|
||||
primary_button: z
|
||||
.object({
|
||||
is_contentstack_link: z.boolean(),
|
||||
cta_text: z.string().nullable(),
|
||||
open_in_new_tab: z.boolean(),
|
||||
external_link: z.object({
|
||||
title: z.string().nullable(),
|
||||
href: z.string().nullable(),
|
||||
}),
|
||||
linkConnection: pageLink,
|
||||
})
|
||||
.nullable(),
|
||||
secondary_button: z
|
||||
.object({
|
||||
is_contentstack_link: z.boolean(),
|
||||
cta_text: z.string().nullable(),
|
||||
open_in_new_tab: z.boolean().nullable(),
|
||||
external_link: z.object({
|
||||
title: z.string().nullable(),
|
||||
href: z.string().nullable(),
|
||||
}),
|
||||
linkConnection: pageLink,
|
||||
})
|
||||
.nullable(),
|
||||
|
||||
system: z.object({
|
||||
locale: z.nativeEnum(Lang),
|
||||
uid: z.string(),
|
||||
}),
|
||||
})
|
||||
|
||||
const loyaltyPageCards = z.object({
|
||||
__typename: z.literal(LoyaltyBlocksTypenameEnum.LoyaltyPageBlocksCardsGrid),
|
||||
cards_grid: z.object({
|
||||
title: z.string().nullable(),
|
||||
preamble: z.string().nullable(),
|
||||
layout: z.enum(["twoColumnGrid", "threeColumnGrid", "twoPlusOne"]),
|
||||
theme: z.enum(["one", "two", "three"]).nullable(),
|
||||
cardConnection: z.object({
|
||||
edges: z.array(
|
||||
z.object({
|
||||
node: cardBlock,
|
||||
})
|
||||
),
|
||||
}),
|
||||
}),
|
||||
})
|
||||
|
||||
const loyaltyPageBlockTextContent = z.object({
|
||||
__typename: z.literal(LoyaltyBlocksTypenameEnum.LoyaltyPageBlocksContent),
|
||||
content: z.object({
|
||||
@@ -121,10 +160,10 @@ const loyaltyPageBlockTextContent = z.object({
|
||||
})
|
||||
|
||||
const loyaltyPageBlockItem = z.discriminatedUnion("__typename", [
|
||||
loyaltyPageBlockCardGrid,
|
||||
loyaltyPageDynamicContent,
|
||||
loyaltyPageBlockTextContent,
|
||||
loyaltyPageShortcuts,
|
||||
loyaltyPageCards,
|
||||
])
|
||||
|
||||
const loyaltyPageSidebarTextContent = z.object({
|
||||
@@ -178,26 +217,6 @@ export const validateLoyaltyPageSchema = z.object({
|
||||
})
|
||||
|
||||
// Block types
|
||||
type CardGridRaw = z.infer<typeof loyaltyPageBlockCardGrid>
|
||||
|
||||
export type CardGridCard = Omit<
|
||||
CardGridRaw["card_grid"]["cards"][number],
|
||||
"referenceConnection"
|
||||
> & {
|
||||
link:
|
||||
| {
|
||||
href: string
|
||||
title: string
|
||||
}
|
||||
| undefined
|
||||
}
|
||||
|
||||
export type CardGrid = Omit<CardGridRaw, "card_grid"> & {
|
||||
card_grid: Omit<CardGridRaw["card_grid"], "cards"> & {
|
||||
cards: CardGridCard[]
|
||||
}
|
||||
}
|
||||
|
||||
type DynamicContentRaw = z.infer<typeof loyaltyPageDynamicContent>
|
||||
|
||||
export type DynamicContent = Omit<DynamicContentRaw, "dynamic_content"> & {
|
||||
@@ -222,6 +241,43 @@ export interface RteBlockContent extends BlockContentRaw {
|
||||
}
|
||||
}
|
||||
|
||||
type CardsGridRaw = z.infer<typeof loyaltyPageCards>
|
||||
|
||||
export type CardsGrid = Omit<CardsGridRaw, "cards_grid"> & {
|
||||
cards_grid: Omit<CardsGridRaw["cards_grid"], "cardConnection"> & {
|
||||
cards: {
|
||||
system: {
|
||||
locale: Lang
|
||||
uid: string
|
||||
}
|
||||
heading: string | null
|
||||
body_text: string | null
|
||||
scripted_top_title: string | null
|
||||
primaryButton:
|
||||
| {
|
||||
open_in_new_tab: boolean
|
||||
link: {
|
||||
title: string
|
||||
href: string
|
||||
}
|
||||
isExternal: boolean
|
||||
}
|
||||
| undefined
|
||||
secondaryButton:
|
||||
| {
|
||||
open_in_new_tab: boolean
|
||||
link: {
|
||||
title: string
|
||||
href: string
|
||||
}
|
||||
isExternal: boolean
|
||||
}
|
||||
| undefined
|
||||
background_image?: any
|
||||
}[]
|
||||
}
|
||||
}
|
||||
|
||||
type ShortcutsRaw = z.infer<typeof loyaltyPageShortcuts>
|
||||
|
||||
export type Shortcuts = Omit<ShortcutsRaw, "shortcuts"> & {
|
||||
@@ -235,7 +291,7 @@ export type Shortcuts = Omit<ShortcutsRaw, "shortcuts"> & {
|
||||
}
|
||||
}
|
||||
|
||||
export type Block = CardGrid | RteBlockContent | DynamicContent | Shortcuts
|
||||
export type Block = RteBlockContent | DynamicContent | Shortcuts | CardsGrid
|
||||
|
||||
// Sidebar block types
|
||||
type SidebarContentRaw = z.infer<typeof loyaltyPageSidebarTextContent>
|
||||
@@ -275,14 +331,34 @@ const pageConnectionRefs = z.object({
|
||||
),
|
||||
})
|
||||
|
||||
const loyaltyPageBlockCardGridRefs = z.object({
|
||||
__typename: z.literal(LoyaltyBlocksTypenameEnum.LoyaltyPageBlocksCardGrid),
|
||||
card_grid: z.object({
|
||||
cards: z.array(
|
||||
z.object({
|
||||
referenceConnection: pageConnectionRefs,
|
||||
})
|
||||
),
|
||||
const cardBlockRefs = z.object({
|
||||
primary_button: z
|
||||
.object({
|
||||
linkConnection: pageConnectionRefs,
|
||||
})
|
||||
.nullable(),
|
||||
secondary_button: z
|
||||
.object({
|
||||
linkConnection: pageConnectionRefs,
|
||||
})
|
||||
.nullable(),
|
||||
|
||||
system: z.object({
|
||||
content_type_uid: z.string(),
|
||||
uid: z.string(),
|
||||
}),
|
||||
})
|
||||
|
||||
const loyaltyPageCardsRefs = z.object({
|
||||
__typename: z.literal(LoyaltyBlocksTypenameEnum.LoyaltyPageBlocksCardsGrid),
|
||||
cards_grid: z.object({
|
||||
cardConnection: z.object({
|
||||
edges: z.array(
|
||||
z.object({
|
||||
node: cardBlockRefs,
|
||||
})
|
||||
),
|
||||
}),
|
||||
}),
|
||||
})
|
||||
|
||||
@@ -318,10 +394,10 @@ const loyaltyPageBlockTextContentRefs = z.object({
|
||||
})
|
||||
|
||||
const loyaltyPageBlocRefsItem = z.discriminatedUnion("__typename", [
|
||||
loyaltyPageBlockCardGridRefs,
|
||||
loyaltyPageDynamicContentRefs,
|
||||
loyaltyPageBlockTextContentRefs,
|
||||
loyaltyPageShortcutsRefs,
|
||||
loyaltyPageCardsRefs,
|
||||
])
|
||||
|
||||
const loyaltyPageSidebarTextContentRef = z.object({
|
||||
|
||||
@@ -60,6 +60,8 @@ export const loyaltyPageQueryRouter = router({
|
||||
const validatedLoyaltyPageRefs =
|
||||
validateLoyaltyPageRefsSchema.safeParse(cleanedData)
|
||||
if (!validatedLoyaltyPageRefs.success) {
|
||||
console.error("Bad validation for `GetLoyaltyPageRefs`")
|
||||
console.error(validatedLoyaltyPageRefs.error)
|
||||
throw internalServerError(validatedLoyaltyPageRefs.error)
|
||||
}
|
||||
|
||||
@@ -114,24 +116,6 @@ export const loyaltyPageQueryRouter = router({
|
||||
const blocks = validatedLoyaltyPage.data.loyalty_page.blocks
|
||||
? validatedLoyaltyPage.data.loyalty_page.blocks.map((block) => {
|
||||
switch (block.__typename) {
|
||||
case LoyaltyBlocksTypenameEnum.LoyaltyPageBlocksCardGrid:
|
||||
return {
|
||||
...block,
|
||||
card_grid: {
|
||||
...block.card_grid,
|
||||
cards: block.card_grid.cards.map((card) => {
|
||||
return {
|
||||
...card,
|
||||
link: card.referenceConnection.totalCount
|
||||
? {
|
||||
href: `/${card.referenceConnection.edges[0].node.system.locale}${card.referenceConnection.edges[0].node.url}`,
|
||||
title: card.cta_text || _("Read more"),
|
||||
}
|
||||
: undefined,
|
||||
}
|
||||
}),
|
||||
},
|
||||
}
|
||||
case LoyaltyBlocksTypenameEnum.LoyaltyPageBlocksDynamicContent:
|
||||
return {
|
||||
...block,
|
||||
@@ -174,6 +158,70 @@ export const loyaltyPageQueryRouter = router({
|
||||
})),
|
||||
},
|
||||
}
|
||||
case LoyaltyBlocksTypenameEnum.LoyaltyPageBlocksCardsGrid:
|
||||
return {
|
||||
...block,
|
||||
cards_grid: {
|
||||
...block.cards_grid,
|
||||
cards: block.cards_grid.cardConnection.edges.map(
|
||||
({ node: card }) => {
|
||||
const primaryButton = card.primary_button
|
||||
? {
|
||||
open_in_new_tab:
|
||||
card.primary_button.open_in_new_tab,
|
||||
link: {
|
||||
title:
|
||||
card.primary_button.cta_text ||
|
||||
(card.primary_button.is_contentstack_link &&
|
||||
card.primary_button.linkConnection.edges.length
|
||||
? card.primary_button.linkConnection.edges[0]
|
||||
.node.title
|
||||
: card.primary_button.external_link.title),
|
||||
href:
|
||||
card.primary_button.is_contentstack_link &&
|
||||
card.primary_button.linkConnection.edges.length
|
||||
? `/${card.primary_button.linkConnection.edges[0].node.system.locale}${card.primary_button.linkConnection.edges[0].node.url}`
|
||||
: card.primary_button.external_link.href,
|
||||
},
|
||||
isExternal:
|
||||
!card.primary_button.is_contentstack_link,
|
||||
}
|
||||
: undefined
|
||||
|
||||
const secondaryButton = card.secondary_button
|
||||
? {
|
||||
open_in_new_tab:
|
||||
card.secondary_button.open_in_new_tab,
|
||||
link: {
|
||||
title:
|
||||
card.secondary_button.cta_text ||
|
||||
(card.secondary_button.is_contentstack_link &&
|
||||
card.secondary_button.linkConnection.edges
|
||||
.length
|
||||
? card.secondary_button.linkConnection
|
||||
.edges[0].node.title
|
||||
: card.secondary_button.external_link.title),
|
||||
href:
|
||||
card.secondary_button.is_contentstack_link &&
|
||||
card.secondary_button.linkConnection.edges
|
||||
.length
|
||||
? `/${card.secondary_button.linkConnection.edges[0].node.system.locale}${card.secondary_button.linkConnection.edges[0].node.url}`
|
||||
: card.secondary_button.external_link.title,
|
||||
},
|
||||
isExternal:
|
||||
!card.secondary_button.is_contentstack_link,
|
||||
}
|
||||
: undefined
|
||||
|
||||
return {
|
||||
...card,
|
||||
primaryButton,
|
||||
secondaryButton,
|
||||
}
|
||||
}
|
||||
),
|
||||
},
|
||||
}
|
||||
default:
|
||||
return block
|
||||
}
|
||||
|
||||
@@ -15,12 +15,16 @@ export function getConnections(refs: LoyaltyPageRefsDataRaw) {
|
||||
}
|
||||
break
|
||||
}
|
||||
case LoyaltyBlocksTypenameEnum.LoyaltyPageBlocksCardGrid: {
|
||||
item.card_grid.cards.forEach((card) => {
|
||||
if (card.referenceConnection.edges.length) {
|
||||
connections.push(card.referenceConnection)
|
||||
case LoyaltyBlocksTypenameEnum.LoyaltyPageBlocksCardsGrid: {
|
||||
connections.push(item.cards_grid.cardConnection)
|
||||
item.cards_grid.cardConnection.edges.forEach((card) => {
|
||||
if (card.node.primary_button) {
|
||||
connections.push(card.node.primary_button?.linkConnection)
|
||||
} else if (card.node.secondary_button) {
|
||||
connections.push(card.node.secondary_button?.linkConnection)
|
||||
}
|
||||
})
|
||||
|
||||
break
|
||||
}
|
||||
case LoyaltyBlocksTypenameEnum.LoyaltyPageBlocksShortcuts: {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import {
|
||||
Block,
|
||||
CardGrid,
|
||||
CardsGrid,
|
||||
DynamicContent,
|
||||
RteBlockContent,
|
||||
} from "@/server/routers/contentstack/loyaltyPage/output"
|
||||
@@ -17,7 +17,7 @@ export type DynamicComponentProps = {
|
||||
component: DynamicContent["dynamic_content"]["component"]
|
||||
}
|
||||
|
||||
export type CardGridProps = Pick<CardGrid, "card_grid">
|
||||
export type CardsGridProps = Pick<CardsGrid, "cards_grid">
|
||||
|
||||
export type Content = { content: RteBlockContent["content"]["content"] }
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ export type LoyaltyComponent = keyof typeof LoyaltyComponentEnum
|
||||
|
||||
export enum LoyaltyBlocksTypenameEnum {
|
||||
LoyaltyPageBlocksDynamicContent = "LoyaltyPageBlocksDynamicContent",
|
||||
LoyaltyPageBlocksCardGrid = "LoyaltyPageBlocksCardGrid",
|
||||
LoyaltyPageBlocksContent = "LoyaltyPageBlocksContent",
|
||||
LoyaltyPageBlocksShortcuts = "LoyaltyPageBlocksShortcuts",
|
||||
LoyaltyPageBlocksCardsGrid = "LoyaltyPageBlocksCardsGrid",
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user