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 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({
|
export default function BenefitCard({
|
||||||
comparedValues,
|
comparedValues,
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import BenefitCard from "../BenefitCard"
|
|||||||
|
|
||||||
import styles from "./benefitList.module.css"
|
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) {
|
export default function BenefitList({ levels }: BenefitListProps) {
|
||||||
return getUnlockedBenefits(levels).map((benefit) => {
|
return getUnlockedBenefits(levels).map((benefit) => {
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import CheckCircle from "@/components/Icons/CheckCircle"
|
|||||||
|
|
||||||
import styles from "./benefitValue.module.css"
|
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) {
|
export default function BenefitValue({ benefit }: BenefitValueProps) {
|
||||||
if (!benefit.unlocked) {
|
if (!benefit.unlocked) {
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import styles from "./desktopHeader.module.css"
|
|||||||
import type {
|
import type {
|
||||||
DesktopSelectColumns,
|
DesktopSelectColumns,
|
||||||
LargeTableProps,
|
LargeTableProps,
|
||||||
} from "@/types/components/loyalty/blocks"
|
} from "@/types/components/content/blocks"
|
||||||
|
|
||||||
export default function DesktopHeader({
|
export default function DesktopHeader({
|
||||||
levels,
|
levels,
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import styles from "./largeTable.module.css"
|
|||||||
import type {
|
import type {
|
||||||
BenefitTableHeaderProps,
|
BenefitTableHeaderProps,
|
||||||
LargeTableProps,
|
LargeTableProps,
|
||||||
} from "@/types/components/loyalty/blocks"
|
} from "@/types/components/content/blocks"
|
||||||
|
|
||||||
export default function LargeTable({
|
export default function LargeTable({
|
||||||
levels,
|
levels,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import styles from "./levelSummary.module.css"
|
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({
|
export default function LevelSummary({
|
||||||
level,
|
level,
|
||||||
|
|||||||
@@ -1,3 +1,7 @@
|
|||||||
|
/*nav:has(+ .contentPage) {*/
|
||||||
|
/* background-color: var(--Base-Surface-Subtle-Normal);*/
|
||||||
|
/*}*/
|
||||||
|
|
||||||
.contentPage {
|
.contentPage {
|
||||||
padding-bottom: var(--Spacing-x9);
|
padding-bottom: var(--Spacing-x9);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
#import "../Fragments/Blocks/Card.graphql"
|
#import "../Fragments/Blocks/Card.graphql"
|
||||||
#import "../Fragments/Blocks/LoyaltyCard.graphql"
|
#import "../Fragments/Blocks/LoyaltyCard.graphql"
|
||||||
|
|
||||||
#import "../Fragments/Blocks/Refs/Card.graphql"
|
#import "../Fragments/Blocks/Refs/Card.graphql"
|
||||||
#import "../Fragments/Blocks/Refs/LoyaltyCard.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
|
title
|
||||||
header {
|
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 {
|
||||||
...System
|
...System
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import { imageVaultAssetSchema } from "../schemas/imageVault"
|
|||||||
import {
|
import {
|
||||||
CardsGridEnum,
|
CardsGridEnum,
|
||||||
ContentBlocksTypenameEnum,
|
ContentBlocksTypenameEnum,
|
||||||
|
DynamicContentComponentEnum,
|
||||||
} from "@/types/components/content/enums"
|
} from "@/types/components/content/enums"
|
||||||
import { ImageVaultAsset } from "@/types/components/imageVault"
|
import { ImageVaultAsset } from "@/types/components/imageVault"
|
||||||
import { Embeds } from "@/types/requests/embeds"
|
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({
|
const cardBlock = z.object({
|
||||||
__typename: z.literal(CardsGridEnum.Card),
|
__typename: z.literal(CardsGridEnum.Card),
|
||||||
heading: z.string().nullable(),
|
heading: z.string().nullable(),
|
||||||
@@ -111,10 +128,13 @@ const contentPageCards = z.object({
|
|||||||
|
|
||||||
const contentPageBlockItem = z.discriminatedUnion("__typename", [
|
const contentPageBlockItem = z.discriminatedUnion("__typename", [
|
||||||
contentPageBlockTextContent,
|
contentPageBlockTextContent,
|
||||||
contentPageShortcuts,
|
|
||||||
contentPageCards,
|
contentPageCards,
|
||||||
|
contentPageDynamicContent,
|
||||||
|
contentPageShortcuts,
|
||||||
])
|
])
|
||||||
|
|
||||||
|
export type DynamicContent = z.infer<typeof contentPageDynamicContent>
|
||||||
|
|
||||||
type BlockContentRaw = z.infer<typeof contentPageBlockTextContent>
|
type BlockContentRaw = z.infer<typeof contentPageBlockTextContent>
|
||||||
export interface RteBlockContent extends BlockContentRaw {
|
export interface RteBlockContent extends BlockContentRaw {
|
||||||
content: {
|
content: {
|
||||||
@@ -141,7 +161,7 @@ export type CardsGrid = Omit<CardsGridRaw, "cards"> & {
|
|||||||
}
|
}
|
||||||
export type CardsRaw = CardsGrid["cards_grid"]["cards"][number]
|
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
|
// Content Page Schema and types
|
||||||
export const validateContentPageSchema = z.object({
|
export const validateContentPageSchema = z.object({
|
||||||
@@ -246,7 +266,13 @@ const contentPageBlockTextContentRefs = z.object({
|
|||||||
const contentPageCardsRefs = z.object({
|
const contentPageCardsRefs = z.object({
|
||||||
__typename: z.literal(ContentBlocksTypenameEnum.ContentPageBlocksCardsGrid),
|
__typename: z.literal(ContentBlocksTypenameEnum.ContentPageBlocksCardsGrid),
|
||||||
cards_grid: z.object({
|
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", [
|
const contentPageBlockRefsItem = z.discriminatedUnion("__typename", [
|
||||||
contentPageBlockTextContentRefs,
|
contentPageBlockTextContentRefs,
|
||||||
contentPageShortcutsRefs,
|
contentPageShortcutsRefs,
|
||||||
contentPageCardsRefs,
|
contentPageCardsRefs,
|
||||||
|
contentPageDynamicContentRefs,
|
||||||
])
|
])
|
||||||
|
|
||||||
export const validateContentPageRefsSchema = z.object({
|
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:
|
default:
|
||||||
return block
|
return block
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,13 @@
|
|||||||
|
import { Lang } from "@/constants/languages"
|
||||||
|
import { membershipLevels } from "@/constants/membershipLevels"
|
||||||
import {
|
import {
|
||||||
Block,
|
Block,
|
||||||
CardsGrid,
|
CardsGrid,
|
||||||
|
DynamicContent,
|
||||||
} from "@/server/routers/contentstack/contentPage/output"
|
} from "@/server/routers/contentstack/contentPage/output"
|
||||||
|
|
||||||
|
import type { IntlFormatters } from "@formatjs/intl"
|
||||||
|
|
||||||
export type BlocksProps = {
|
export type BlocksProps = {
|
||||||
blocks: Block[]
|
blocks: Block[]
|
||||||
}
|
}
|
||||||
@@ -10,3 +15,89 @@ export type BlocksProps = {
|
|||||||
export type CardsGridProps = Pick<CardsGrid, "cards_grid"> & {
|
export type CardsGridProps = Pick<CardsGrid, "cards_grid"> & {
|
||||||
firstItem?: boolean
|
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",
|
ContentPageBlocksContent = "ContentPageBlocksContent",
|
||||||
ContentPageBlocksShortcuts = "ContentPageBlocksShortcuts",
|
ContentPageBlocksShortcuts = "ContentPageBlocksShortcuts",
|
||||||
ContentPageBlocksCardsGrid = "ContentPageBlocksCardsGrid",
|
ContentPageBlocksCardsGrid = "ContentPageBlocksCardsGrid",
|
||||||
|
ContentPageBlocksDynamicContent = "ContentPageBlocksDynamicContent",
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum CardsGridEnum {
|
export enum CardsGridEnum {
|
||||||
LoyaltyCard = "LoyaltyCard",
|
LoyaltyCard = "LoyaltyCard",
|
||||||
Card = "Card",
|
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