From 323df671d8415e79da43b80df9b209bd1000c1c0 Mon Sep 17 00:00:00 2001 From: Christel Westerberg Date: Fri, 28 Jun 2024 11:21:09 +0200 Subject: [PATCH] fix: add loyaltyCard --- .../LoyaltyPage/loyaltyPage.module.css | 3 +- components/Loyalty/Blocks/CardsGrid/index.tsx | 51 ++++-- .../DynamicContent/LoyaltyLevels/index.tsx | 7 +- .../LoyaltyLevels/loyaltyLevels.module.css | 6 +- components/Loyalty/Blocks/index.tsx | 1 + components/Loyalty/Sidebar/sidebar.module.css | 16 +- .../TempDesignSystem/LoyaltyCard/index.tsx | 65 ++++++++ .../LoyaltyCard/loyaltyCard.module.css | 43 +++++ .../LoyaltyCard/loyaltyCard.ts | 20 +++ .../TempDesignSystem/LoyaltyCard/variants.ts | 14 ++ .../Text/Caption/caption.module.css | 12 ++ .../TempDesignSystem/Text/Caption/index.tsx | 16 +- .../TempDesignSystem/Text/Caption/variants.ts | 5 + .../Fragments/Blocks/LoyaltyCard.graphql | 28 ++++ .../Fragments/Blocks/Refs/Card.graphql | 1 + .../Fragments/Blocks/Refs/LoyaltyCard.graphql | 18 +++ lib/graphql/Query/LoyaltyPage.graphql | 8 + server/routers/contentstack/base/output.ts | 1 + .../contentstack/loyaltyPage/output.ts | 71 +++++++- .../routers/contentstack/loyaltyPage/query.ts | 153 ++++++++++-------- .../routers/contentstack/loyaltyPage/utils.ts | 25 ++- types/components/loyalty/blocks.ts | 4 +- types/components/loyalty/enums.ts | 5 + 23 files changed, 467 insertions(+), 106 deletions(-) create mode 100644 components/TempDesignSystem/LoyaltyCard/index.tsx create mode 100644 components/TempDesignSystem/LoyaltyCard/loyaltyCard.module.css create mode 100644 components/TempDesignSystem/LoyaltyCard/loyaltyCard.ts create mode 100644 components/TempDesignSystem/LoyaltyCard/variants.ts create mode 100644 lib/graphql/Fragments/Blocks/LoyaltyCard.graphql create mode 100644 lib/graphql/Fragments/Blocks/Refs/LoyaltyCard.graphql diff --git a/components/ContentType/LoyaltyPage/loyaltyPage.module.css b/components/ContentType/LoyaltyPage/loyaltyPage.module.css index 11d33bce4..b2bffc7b8 100644 --- a/components/ContentType/LoyaltyPage/loyaltyPage.module.css +++ b/components/ContentType/LoyaltyPage/loyaltyPage.module.css @@ -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); } diff --git a/components/Loyalty/Blocks/CardsGrid/index.tsx b/components/Loyalty/Blocks/CardsGrid/index.tsx index da47d46d1..359b0b809 100644 --- a/components/Loyalty/Blocks/CardsGrid/index.tsx +++ b/components/Loyalty/Blocks/CardsGrid/index.tsx @@ -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 ( -
+
- {cards_grid.cards.map((card) => ( - - ))} + {cards_grid.cards.map((card) => { + switch (card.__typename) { + case LoyaltyCardsGridEnum.LoyaltyCard: + return ( + + ) + case LoyaltyCardsGridEnum.Card: { + return ( + + ) + } + } + })} ) diff --git a/components/Loyalty/Blocks/DynamicContent/LoyaltyLevels/index.tsx b/components/Loyalty/Blocks/DynamicContent/LoyaltyLevels/index.tsx index 200114143..b0140b2f7 100644 --- a/components/Loyalty/Blocks/DynamicContent/LoyaltyLevels/index.tsx +++ b/components/Loyalty/Blocks/DynamicContent/LoyaltyLevels/index.tsx @@ -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) {
{level.benefits.map((benefit) => ( - {benefit.title} - + ))}
diff --git a/components/Loyalty/Blocks/DynamicContent/LoyaltyLevels/loyaltyLevels.module.css b/components/Loyalty/Blocks/DynamicContent/LoyaltyLevels/loyaltyLevels.module.css index 4289e5b83..7e0ce8408 100644 --- a/components/Loyalty/Blocks/DynamicContent/LoyaltyLevels/loyaltyLevels.module.css +++ b/components/Loyalty/Blocks/DynamicContent/LoyaltyLevels/loyaltyLevels.module.css @@ -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; } diff --git a/components/Loyalty/Blocks/index.tsx b/components/Loyalty/Blocks/index.tsx index 643fe73b0..c272026fa 100644 --- a/components/Loyalty/Blocks/index.tsx +++ b/components/Loyalty/Blocks/index.tsx @@ -43,6 +43,7 @@ export function Blocks({ blocks }: BlocksProps) { ) default: diff --git a/components/Loyalty/Sidebar/sidebar.module.css b/components/Loyalty/Sidebar/sidebar.module.css index 5a6dee03f..c4b8627a0 100644 --- a/components/Loyalty/Sidebar/sidebar.module.css +++ b/components/Loyalty/Sidebar/sidebar.module.css @@ -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); } } diff --git a/components/TempDesignSystem/LoyaltyCard/index.tsx b/components/TempDesignSystem/LoyaltyCard/index.tsx new file mode 100644 index 000000000..afafd6e7c --- /dev/null +++ b/components/TempDesignSystem/LoyaltyCard/index.tsx @@ -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 ( +
+ {image ? ( +
+ {image.meta.alt +
+ ) : null} + + {heading} + + {bodyText ? ( + + {bodyText} + + ) : null} +
+ {link ? ( + + + + {link.title} + + + ) : null} +
+
+ ) +} diff --git a/components/TempDesignSystem/LoyaltyCard/loyaltyCard.module.css b/components/TempDesignSystem/LoyaltyCard/loyaltyCard.module.css new file mode 100644 index 000000000..c6c1f59dc --- /dev/null +++ b/components/TempDesignSystem/LoyaltyCard/loyaltyCard.module.css @@ -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; +} diff --git a/components/TempDesignSystem/LoyaltyCard/loyaltyCard.ts b/components/TempDesignSystem/LoyaltyCard/loyaltyCard.ts new file mode 100644 index 000000000..784d643ad --- /dev/null +++ b/components/TempDesignSystem/LoyaltyCard/loyaltyCard.ts @@ -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, + VariantProps { + link?: { + href: string + title: string + openInNewTab?: boolean + isExternal: boolean + } + image?: ImageVaultAsset + heading?: string | null + bodyText?: string | null + backgroundImage?: { url: string } +} diff --git a/components/TempDesignSystem/LoyaltyCard/variants.ts b/components/TempDesignSystem/LoyaltyCard/variants.ts new file mode 100644 index 000000000..7fb16df0a --- /dev/null +++ b/components/TempDesignSystem/LoyaltyCard/variants.ts @@ -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", + }, +}) diff --git a/components/TempDesignSystem/Text/Caption/caption.module.css b/components/TempDesignSystem/Text/Caption/caption.module.css index 21e846236..09361d5bf 100644 --- a/components/TempDesignSystem/Text/Caption/caption.module.css +++ b/components/TempDesignSystem/Text/Caption/caption.module.css @@ -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; +} diff --git a/components/TempDesignSystem/Text/Caption/index.tsx b/components/TempDesignSystem/Text/Caption/index.tsx index a63680d98..0e43263c6 100644 --- a/components/TempDesignSystem/Text/Caption/index.tsx +++ b/components/TempDesignSystem/Text/Caption/index.tsx @@ -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 } diff --git a/components/TempDesignSystem/Text/Caption/variants.ts b/components/TempDesignSystem/Text/Caption/variants.ts index d4a4f14b0..a0188ffee 100644 --- a/components/TempDesignSystem/Text/Caption/variants.ts +++ b/components/TempDesignSystem/Text/Caption/variants.ts @@ -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", diff --git a/lib/graphql/Fragments/Blocks/LoyaltyCard.graphql b/lib/graphql/Fragments/Blocks/LoyaltyCard.graphql new file mode 100644 index 000000000..fcd19ea65 --- /dev/null +++ b/lib/graphql/Fragments/Blocks/LoyaltyCard.graphql @@ -0,0 +1,28 @@ +fragment LoyaltyCardBlock on LoyaltyCard { + heading + body_text + image + title + link { + cta_text + open_in_new_tab + external_link { + title + href + } + linkConnection { + edges { + node { + __typename + ...LoyaltyPageLink + ...ContentPageLink + ...AccountPageLink + } + } + } + } + system { + locale + uid + } +} diff --git a/lib/graphql/Fragments/Blocks/Refs/Card.graphql b/lib/graphql/Fragments/Blocks/Refs/Card.graphql index 3b3c33a9a..138a45b5e 100644 --- a/lib/graphql/Fragments/Blocks/Refs/Card.graphql +++ b/lib/graphql/Fragments/Blocks/Refs/Card.graphql @@ -1,4 +1,5 @@ fragment CardBlockRef on Card { + __typename secondary_button { linkConnection { edges { diff --git a/lib/graphql/Fragments/Blocks/Refs/LoyaltyCard.graphql b/lib/graphql/Fragments/Blocks/Refs/LoyaltyCard.graphql new file mode 100644 index 000000000..2bb847c8c --- /dev/null +++ b/lib/graphql/Fragments/Blocks/Refs/LoyaltyCard.graphql @@ -0,0 +1,18 @@ +fragment LoyaltyCardBlockRef on LoyaltyCard { + __typename + link { + linkConnection { + edges { + node { + __typename + ...LoyaltyPageRef + ...ContentPageRef + ...AccountPageRef + } + } + } + } + system { + ...System + } +} diff --git a/lib/graphql/Query/LoyaltyPage.graphql b/lib/graphql/Query/LoyaltyPage.graphql index 668640ae0..4fbc38a7b 100644 --- a/lib/graphql/Query/LoyaltyPage.graphql +++ b/lib/graphql/Query/LoyaltyPage.graphql @@ -1,6 +1,10 @@ #import "../Fragments/Image.graphql" #import "../Fragments/Blocks/Card.graphql" +#import "../Fragments/Blocks/LoyaltyCard.graphql" + #import "../Fragments/Blocks/Refs/Card.graphql" +#import "../Fragments/Blocks/Refs/LoyaltyCard.graphql" + #import "../Fragments/LoyaltyPage/Breadcrumbs.graphql" #import "../Fragments/PageLink/AccountPageLink.graphql" #import "../Fragments/PageLink/ContentPageLink.graphql" @@ -83,7 +87,9 @@ query GetLoyaltyPage($locale: String!, $uid: String!) { cardConnection(limit: 10) { edges { node { + __typename ...CardBlock + ...LoyaltyCardBlock } } } @@ -104,6 +110,7 @@ query GetLoyaltyPage($locale: String!, $uid: String!) { contact { display_text contact_field + footnote } } } @@ -206,6 +213,7 @@ query GetLoyaltyPageRefs($locale: String!, $uid: String!) { edges { node { ...CardBlockRef + ...LoyaltyCardBlockRef } } } diff --git a/server/routers/contentstack/base/output.ts b/server/routers/contentstack/base/output.ts index ce217f241..3c81aae88 100644 --- a/server/routers/contentstack/base/output.ts +++ b/server/routers/contentstack/base/output.ts @@ -59,6 +59,7 @@ export type ContactConfig = ContactConfigData["all_contact_config"]["items"][0] export type ContactFields = { display_text: string | null contact_field: string + footnote: string | null } export const validateHeaderConfigSchema = z.object({ diff --git a/server/routers/contentstack/loyaltyPage/output.ts b/server/routers/contentstack/loyaltyPage/output.ts index 2cd7dd427..f17e4fbdc 100644 --- a/server/routers/contentstack/loyaltyPage/output.ts +++ b/server/routers/contentstack/loyaltyPage/output.ts @@ -2,9 +2,11 @@ import { z } from "zod" import { Lang } from "@/constants/languages" +import { ImageVaultAsset } from "@/types/components/imageVaultImage" import { JoinLoyaltyContactTypenameEnum, LoyaltyBlocksTypenameEnum, + LoyaltyCardsGridEnum, LoyaltyComponentEnum, SidebarTypenameEnum, } from "@/types/components/loyalty/enums" @@ -47,6 +49,7 @@ const loyaltyPageShortcuts = z.object({ }) const cardBlock = z.object({ + __typename: z.literal(LoyaltyCardsGridEnum.Card), heading: z.string().nullable(), body_text: z.string().nullable(), background_image: z.any(), @@ -73,6 +76,30 @@ const cardBlock = z.object({ }), }) +const loyaltyCardBlock = z.object({ + __typename: z.literal(LoyaltyCardsGridEnum.LoyaltyCard), + heading: z.string().nullable(), + body_text: z.string().nullable(), + image: z.any(), + link: z + .object({ + openInNewTab: z.boolean(), + title: z.string(), + href: z.string(), + isExternal: z.boolean(), + }) + .optional(), + system: z.object({ + locale: z.nativeEnum(Lang), + uid: z.string(), + }), +}) + +const loyaltyPageCardsItems = z.discriminatedUnion("__typename", [ + loyaltyCardBlock, + cardBlock, +]) + const loyaltyPageCards = z.object({ __typename: z.literal(LoyaltyBlocksTypenameEnum.LoyaltyPageBlocksCardsGrid), cards_grid: z.object({ @@ -80,7 +107,7 @@ const loyaltyPageCards = z.object({ preamble: z.string().nullable(), layout: z.enum(["twoColumnGrid", "threeColumnGrid", "twoPlusOne"]), theme: z.enum(["one", "two", "three"]).nullable(), - cards: z.array(cardBlock), + cards: z.array(loyaltyPageCardsItems), }), }) @@ -132,6 +159,7 @@ const loyaltyPageJoinLoyaltyContact = z.object({ contact: z.object({ display_text: z.string().nullable(), contact_field: z.string(), + footnote: z.string().nullable(), }), }) ), @@ -151,7 +179,6 @@ export const validateLoyaltyPageSchema = z.object({ }) // Block types - export type DynamicContent = z.infer type BlockContentRaw = z.infer @@ -164,11 +191,25 @@ export interface RteBlockContent extends BlockContentRaw { } } +type LoyaltyCardRaw = z.infer + +type LoyaltyCard = Omit & { + image?: ImageVaultAsset +} + +type CardRaw = z.infer + +type Card = Omit & { + backgroundImage?: ImageVaultAsset +} + type CardsGridRaw = z.infer -export type CardsRaw = CardsGridRaw["cards_grid"]["cards"][number] +export type CardsGrid = Omit & { + cards: (LoyaltyCard | Card)[] +} -export type CardsGrid = z.infer +export type CardsRaw = CardsGrid["cards_grid"]["cards"][number] export type Shortcuts = z.infer @@ -210,6 +251,7 @@ const pageConnectionRefs = z.object({ }) const cardBlockRefs = z.object({ + __typename: z.literal(LoyaltyCardsGridEnum.Card), primary_button: z .object({ linkConnection: pageConnectionRefs, @@ -227,13 +269,32 @@ const cardBlockRefs = z.object({ }), }) +const loyaltyCardBlockRefs = z.object({ + __typename: z.literal(LoyaltyCardsGridEnum.LoyaltyCard), + link: z + .object({ + linkConnection: pageConnectionRefs, + }) + .nullable(), + + system: z.object({ + content_type_uid: z.string(), + uid: z.string(), + }), +}) + +const cardGridCardsRef = z.discriminatedUnion("__typename", [ + loyaltyCardBlockRefs, + cardBlockRefs, +]) + const loyaltyPageCardsRefs = z.object({ __typename: z.literal(LoyaltyBlocksTypenameEnum.LoyaltyPageBlocksCardsGrid), cards_grid: z.object({ cardConnection: z.object({ edges: z.array( z.object({ - node: cardBlockRefs, + node: cardGridCardsRef, }) ), }), diff --git a/server/routers/contentstack/loyaltyPage/query.ts b/server/routers/contentstack/loyaltyPage/query.ts index dcd711b65..c4d3c0bff 100644 --- a/server/routers/contentstack/loyaltyPage/query.ts +++ b/server/routers/contentstack/loyaltyPage/query.ts @@ -11,6 +11,7 @@ import { generateTag, generateTags, } from "@/utils/generateTag" +import { insertResponseToImageVaultAsset } from "@/utils/imageVault" import { removeMultipleSlashes } from "@/utils/url" import { removeEmptyObjects } from "../../utils" @@ -22,7 +23,17 @@ import { } from "./output" import { getConnections } from "./utils" -import { LoyaltyBlocksTypenameEnum } from "@/types/components/loyalty/enums" +import { InsertResponse } from "@/types/components/imageVaultImage" +import { + LoyaltyBlocksTypenameEnum, + LoyaltyCardsGridEnum, +} from "@/types/components/loyalty/enums" + +function makeImageVaultImage(image: any) { + return image && !!Object.keys(image).length + ? insertResponseToImageVaultAsset(image as InsertResponse) + : undefined +} function makeButtonObject(button: any) { return { @@ -35,9 +46,9 @@ function makeButtonObject(button: any) { href: button.is_contentstack_link && button.linkConnection.edges.length ? button.linkConnection.edges[0].node.web?.original_url || - removeMultipleSlashes( - `/${button.linkConnection.edges[0].node.system.locale}/${button.linkConnection.edges[0].node.url}` - ) + removeMultipleSlashes( + `/${button.linkConnection.edges[0].node.system.locale}/${button.linkConnection.edges[0].node.url}` + ) : button.external_link.href, isExternal: !button.is_contentstack_link, } @@ -96,66 +107,82 @@ export const loyaltyPageQueryRouter = router({ const blocks = response.data.loyalty_page.blocks ? response.data.loyalty_page.blocks.map((block: any) => { - switch (block.__typename) { - case LoyaltyBlocksTypenameEnum.LoyaltyPageBlocksDynamicContent: - return { - ...block, - dynamic_content: { - ...block.dynamic_content, - link: block.dynamic_content.link.pageConnection.edges.length - ? { - text: block.dynamic_content.link.text, - href: removeMultipleSlashes( - `/${block.dynamic_content.link.pageConnection.edges[0].node.system.locale}/${block.dynamic_content.link.pageConnection.edges[0].node.url}` - ), - title: - block.dynamic_content.link.pageConnection.edges[0] - .node.title, - } - : undefined, - }, - } - case LoyaltyBlocksTypenameEnum.LoyaltyPageBlocksShortcuts: - return { - ...block, - shortcuts: { - ...block.shortcuts, - shortcuts: block.shortcuts.shortcuts.map((shortcut: any) => ({ - text: shortcut.text, - openInNewTab: shortcut.open_in_new_tab, - ...shortcut.linkConnection.edges[0].node, - url: - shortcut.linkConnection.edges[0].node.web?.original_url || - removeMultipleSlashes( - `/${shortcut.linkConnection.edges[0].node.system.locale}/${shortcut.linkConnection.edges[0].node.url}` - ), - })), - }, - } - case LoyaltyBlocksTypenameEnum.LoyaltyPageBlocksCardsGrid: - return { - ...block, - cards_grid: { - ...block.cards_grid, - cards: block.cards_grid.cardConnection.edges.map( - ({ node: card }: { node: any }) => { - return { - ...card, - primaryButton: card.has_primary_button - ? makeButtonObject(card.primary_button) - : undefined, - secondaryButton: card.has_secondary_button - ? makeButtonObject(card.secondary_button) - : undefined, + switch (block.__typename) { + case LoyaltyBlocksTypenameEnum.LoyaltyPageBlocksDynamicContent: + return { + ...block, + dynamic_content: { + ...block.dynamic_content, + link: block.dynamic_content.link.pageConnection.edges.length + ? { + text: block.dynamic_content.link.text, + href: removeMultipleSlashes( + `/${block.dynamic_content.link.pageConnection.edges[0].node.system.locale}/${block.dynamic_content.link.pageConnection.edges[0].node.url}` + ), + title: + block.dynamic_content.link.pageConnection.edges[0] + .node.title, + } + : undefined, + }, + } + case LoyaltyBlocksTypenameEnum.LoyaltyPageBlocksShortcuts: + return { + ...block, + shortcuts: { + ...block.shortcuts, + shortcuts: block.shortcuts.shortcuts.map((shortcut: any) => ({ + text: shortcut.text, + openInNewTab: shortcut.open_in_new_tab, + ...shortcut.linkConnection.edges[0].node, + url: + shortcut.linkConnection.edges[0].node.web?.original_url || + removeMultipleSlashes( + `/${shortcut.linkConnection.edges[0].node.system.locale}/${shortcut.linkConnection.edges[0].node.url}` + ), + })), + }, + } + case LoyaltyBlocksTypenameEnum.LoyaltyPageBlocksCardsGrid: + return { + ...block, + cards_grid: { + ...block.cards_grid, + cards: block.cards_grid.cardConnection.edges.map( + ({ node: card }: { node: any }) => { + switch (card.__typename) { + case LoyaltyCardsGridEnum.LoyaltyCard: + return { + ...card, + image: makeImageVaultImage(card.image), + link: makeButtonObject({ + ...card.link, + is_contentstack_link: + !!card.link.linkConnection.edges.length, + }), + } + case LoyaltyCardsGridEnum.Card: + return { + ...card, + backgroundImage: makeImageVaultImage( + card.background_image + ), + primaryButton: card.has_primary_button + ? makeButtonObject(card.primary_button) + : undefined, + secondaryButton: card.has_secondary_button + ? makeButtonObject(card.secondary_button) + : undefined, + } + } } - } - ), - }, - } - default: - return block - } - }) + ), + }, + } + default: + return block + } + }) : null const loyaltyPage = { diff --git a/server/routers/contentstack/loyaltyPage/utils.ts b/server/routers/contentstack/loyaltyPage/utils.ts index e56207061..409ebadef 100644 --- a/server/routers/contentstack/loyaltyPage/utils.ts +++ b/server/routers/contentstack/loyaltyPage/utils.ts @@ -1,6 +1,9 @@ import { LoyaltyPageRefsDataRaw } from "./output" -import { LoyaltyBlocksTypenameEnum } from "@/types/components/loyalty/enums" +import { + LoyaltyBlocksTypenameEnum, + LoyaltyCardsGridEnum, +} from "@/types/components/loyalty/enums" import type { Edges } from "@/types/requests/utils/edges" import type { NodeRefs } from "@/types/requests/utils/refs" @@ -18,13 +21,23 @@ export function getConnections(refs: LoyaltyPageRefsDataRaw) { 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) + switch (card.node.__typename) { + case LoyaltyCardsGridEnum.LoyaltyCard: { + if (card.node.link) { + connections.push(card.node.link?.linkConnection) + } + break + } + case LoyaltyCardsGridEnum.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 + } } }) - break } case LoyaltyBlocksTypenameEnum.LoyaltyPageBlocksShortcuts: { diff --git a/types/components/loyalty/blocks.ts b/types/components/loyalty/blocks.ts index c06475cb1..f9f337344 100644 --- a/types/components/loyalty/blocks.ts +++ b/types/components/loyalty/blocks.ts @@ -24,7 +24,9 @@ export type DynamicComponentProps = { component: DynamicContent["dynamic_content"]["component"] } -export type CardsGridProps = Pick +export type CardsGridProps = Pick & { + firstItem?: boolean +} export type Content = { content: RteBlockContent["content"]["content"] } diff --git a/types/components/loyalty/enums.ts b/types/components/loyalty/enums.ts index 077c439cb..a27e15b57 100644 --- a/types/components/loyalty/enums.ts +++ b/types/components/loyalty/enums.ts @@ -31,3 +31,8 @@ export enum LoyaltyBlocksTypenameEnum { LoyaltyPageBlocksShortcuts = "LoyaltyPageBlocksShortcuts", LoyaltyPageBlocksCardsGrid = "LoyaltyPageBlocksCardsGrid", } + +export enum LoyaltyCardsGridEnum { + LoyaltyCard = "LoyaltyCard", + Card = "Card", +}