feat(SW-285): add missing code for dynamic content

This commit is contained in:
Chuma McPhoy
2024-09-02 20:04:58 +02:00
parent 1c2a34591b
commit 60636d8cbe
12 changed files with 206 additions and 10 deletions

View File

@@ -6,7 +6,7 @@ import BenefitValue from "../BenefitValue"
import styles from "./benefitCard.module.css"
import type { BenefitCardProps } from "@/types/components/loyalty/blocks"
import type { BenefitCardProps } from "@/types/components/content/blocks"
export default function BenefitCard({
comparedValues,

View File

@@ -4,7 +4,7 @@ import BenefitCard from "../BenefitCard"
import styles from "./benefitList.module.css"
import type { BenefitListProps } from "@/types/components/loyalty/blocks"
import type { BenefitListProps } from "@/types/components/content/blocks"
export default function BenefitList({ levels }: BenefitListProps) {
return getUnlockedBenefits(levels).map((benefit) => {

View File

@@ -4,7 +4,7 @@ import CheckCircle from "@/components/Icons/CheckCircle"
import styles from "./benefitValue.module.css"
import type { BenefitValueProps } from "@/types/components/loyalty/blocks"
import type { BenefitValueProps } from "@/types/components/content/blocks"
export default function BenefitValue({ benefit }: BenefitValueProps) {
if (!benefit.unlocked) {

View File

@@ -8,7 +8,7 @@ import styles from "./desktopHeader.module.css"
import type {
DesktopSelectColumns,
LargeTableProps,
} from "@/types/components/loyalty/blocks"
} from "@/types/components/content/blocks"
export default function DesktopHeader({
levels,

View File

@@ -11,7 +11,7 @@ import styles from "./largeTable.module.css"
import type {
BenefitTableHeaderProps,
LargeTableProps,
} from "@/types/components/loyalty/blocks"
} from "@/types/components/content/blocks"
export default function LargeTable({
levels,

View File

@@ -1,6 +1,6 @@
import styles from "./levelSummary.module.css"
import type { LevelSummaryProps } from "@/types/components/loyalty/blocks"
import type { LevelSummaryProps } from "@/types/components/content/blocks"
export default function LevelSummary({
level,

View File

@@ -1,3 +1,7 @@
/*nav:has(+ .contentPage) {*/
/* background-color: var(--Base-Surface-Subtle-Normal);*/
/*}*/
.contentPage {
padding-bottom: var(--Spacing-x9);
}

View File

@@ -1,5 +1,6 @@
#import "../Fragments/Blocks/Card.graphql"
#import "../Fragments/Blocks/LoyaltyCard.graphql"
#import "../Fragments/Blocks/Refs/Card.graphql"
#import "../Fragments/Blocks/Refs/LoyaltyCard.graphql"
@@ -83,6 +84,27 @@ query GetContentPage($locale: String!, $uid: String!) {
}
}
}
... on ContentPageBlocksDynamicContent {
__typename
dynamic_content {
title
subtitle
component
link {
text
pageConnection {
edges {
node {
# TODO: Link HotelPage
...ContentPageLink
...LoyaltyPageLink
}
}
totalCount
}
}
}
}
}
title
header {
@@ -164,6 +186,22 @@ query GetContentPageRefs($locale: String!, $uid: String!) {
}
}
}
... on ContentPageBlocksDynamicContent {
__typename
dynamic_content {
link {
pageConnection {
edges {
node {
__typename
...ContentPageRef
...LoyaltyPageRef
}
}
}
}
}
}
}
system {
...System

View File

@@ -7,6 +7,7 @@ import { imageVaultAssetSchema } from "../schemas/imageVault"
import {
CardsGridEnum,
ContentBlocksTypenameEnum,
DynamicContentComponentEnum,
} from "@/types/components/content/enums"
import { ImageVaultAsset } from "@/types/components/imageVault"
import { Embeds } from "@/types/requests/embeds"
@@ -45,7 +46,23 @@ const contentPageShortcuts = z.object({
}),
})
// TODO: this is a separate entity, should be in a separate file.
const contentPageDynamicContent = z.object({
__typename: z.literal(
ContentBlocksTypenameEnum.ContentPageBlocksDynamicContent
),
dynamic_content: z.object({
title: z.string().nullable(),
subtitle: z.string().nullable(),
component: z.nativeEnum(DynamicContentComponentEnum),
link: z
.object({
text: z.string(),
href: z.string(),
})
.optional(),
}),
})
const cardBlock = z.object({
__typename: z.literal(CardsGridEnum.Card),
heading: z.string().nullable(),
@@ -111,10 +128,13 @@ const contentPageCards = z.object({
const contentPageBlockItem = z.discriminatedUnion("__typename", [
contentPageBlockTextContent,
contentPageShortcuts,
contentPageCards,
contentPageDynamicContent,
contentPageShortcuts,
])
export type DynamicContent = z.infer<typeof contentPageDynamicContent>
type BlockContentRaw = z.infer<typeof contentPageBlockTextContent>
export interface RteBlockContent extends BlockContentRaw {
content: {
@@ -141,7 +161,7 @@ export type CardsGrid = Omit<CardsGridRaw, "cards"> & {
}
export type CardsRaw = CardsGrid["cards_grid"]["cards"][number]
export type Block = RteBlockContent | Shortcuts | CardsGrid
export type Block = RteBlockContent | Shortcuts | CardsGrid | DynamicContent
// Content Page Schema and types
export const validateContentPageSchema = z.object({
@@ -246,7 +266,13 @@ const contentPageBlockTextContentRefs = z.object({
const contentPageCardsRefs = z.object({
__typename: z.literal(ContentBlocksTypenameEnum.ContentPageBlocksCardsGrid),
cards_grid: z.object({
cardConnection: cardGridCardsRef,
cardConnection: z.object({
edges: z.array(
z.object({
node: cardGridCardsRef,
})
),
}),
}),
})
@@ -261,10 +287,22 @@ const contentPageShortcutsRefs = z.object({
}),
})
const contentPageDynamicContentRefs = z.object({
__typename: z.literal(
ContentBlocksTypenameEnum.ContentPageBlocksDynamicContent
),
dynamic_content: z.object({
link: z.object({
pageConnection: pageConnectionRefs,
}),
}),
})
const contentPageBlockRefsItem = z.discriminatedUnion("__typename", [
contentPageBlockTextContentRefs,
contentPageShortcutsRefs,
contentPageCardsRefs,
contentPageDynamicContentRefs,
])
export const validateContentPageRefsSchema = z.object({

View File

@@ -121,6 +121,24 @@ export const contentPageQueryRouter = router({
),
},
}
case ContentBlocksTypenameEnum.ContentPageBlocksDynamicContent:
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,
},
}
default:
return block
}

View File

@@ -1,8 +1,13 @@
import { Lang } from "@/constants/languages"
import { membershipLevels } from "@/constants/membershipLevels"
import {
Block,
CardsGrid,
DynamicContent,
} from "@/server/routers/contentstack/contentPage/output"
import type { IntlFormatters } from "@formatjs/intl"
export type BlocksProps = {
blocks: Block[]
}
@@ -10,3 +15,89 @@ export type BlocksProps = {
export type CardsGridProps = Pick<CardsGrid, "cards_grid"> & {
firstItem?: boolean
}
export type DynamicContentProps = {
dynamicContent: DynamicContent["dynamic_content"]
firstItem: boolean
}
export type DynamicComponentProps = {
component: DynamicContent["dynamic_content"]["component"]
}
type BenefitTitle = { title: string }
export type Level = {
level: membershipLevels
name: string
requiredPoints: number
requiredNights?: number
benefits: BenefitTitle[]
}
export type LevelCardProps = {
formatMessage: IntlFormatters["formatMessage"]
lang: Lang
level: Level
}
export type BenefitCardProps = {
comparedValues: BenefitValueInformation[]
title: string
description: string
}
type BenefitValueInformation = {
unlocked: boolean
value?: string
valueDetails?: string
}
export type Benefit = {
name: string
description: string
unlocked: boolean
value?: string
valueDetails?: string
}
export type ComparisonLevel = {
level: membershipLevels
name: string
description: string
requirement: string
icon: string
benefits: Benefit[]
}
export type BenefitListProps = {
levels: ComparisonLevel[]
}
export type BenefitValueProps = {
benefit: BenefitValueInformation
}
export type MobileColumnHeaderProps = {
column: "A" | "B"
}
export type DesktopSelectColumns = {
column: MobileColumnHeaderProps["column"] | "C"
}
export type LargeTableProps = {
levels: ComparisonLevel[]
activeLevel: membershipLevels | null
Select?: (column: DesktopSelectColumns) => JSX.Element | null
}
export type BenefitTableHeaderProps = {
name: string
description: string
}
export type LevelSummaryProps = {
level: ComparisonLevel
showDescription?: boolean
}

View File

@@ -2,9 +2,16 @@ export enum ContentBlocksTypenameEnum {
ContentPageBlocksContent = "ContentPageBlocksContent",
ContentPageBlocksShortcuts = "ContentPageBlocksShortcuts",
ContentPageBlocksCardsGrid = "ContentPageBlocksCardsGrid",
ContentPageBlocksDynamicContent = "ContentPageBlocksDynamicContent",
}
export enum CardsGridEnum {
LoyaltyCard = "LoyaltyCard",
Card = "Card",
}
export enum DynamicContentComponentEnum {
loyalty_levels = "loyalty_levels",
how_it_works = "how_it_works",
overview_table = "overview_table",
}