feat(SW-285): add missing code for dynamic content
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -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) => {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
/*nav:has(+ .contentPage) {*/
|
||||
/* background-color: var(--Base-Surface-Subtle-Normal);*/
|
||||
/*}*/
|
||||
|
||||
.contentPage {
|
||||
padding-bottom: var(--Spacing-x9);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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({
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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",
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user