Files
web/server/routers/contentstack/schemas/blocks/carouselCards.ts
Chuma Mcphoy (We Ahead) b2add701e5 Merged in fix/LOY-143-hide-see-all-link (pull request #1341)
fix(LOY-143): properly hide see all link for carosel cards

* fix(LOY-143): Improve link handling in CarouselCards schema


Approved-by: Christian Andolf
2025-02-14 12:19:46 +00:00

140 lines
3.7 KiB
TypeScript

import { z } from "zod"
import {
contentCardRefSchema,
contentCardSchema,
transformContentCard,
} from "./cards/contentCard"
import { buttonSchema } from "./utils/buttonLinkSchema"
import { linkConnectionRefsSchema } from "./utils/linkConnection"
import { BlocksEnums } from "@/types/enums/blocks"
import {
type CarouselCardFilter,
CarouselCardFilterEnum,
} from "@/types/enums/carouselCards"
const commonFields = {
heading: z.string().optional(),
link: buttonSchema.optional(),
} as const
const carouselCardsWithFilters = z.object({
...commonFields,
enable_filters: z.literal(true),
card_groups: z.array(
z.object({
filter_identifier: z.nativeEnum(CarouselCardFilterEnum),
filter_label: z.string(),
cardConnection: z.object({
edges: z.array(z.object({ node: contentCardSchema })),
}),
})
),
})
const carouselCardsWithoutFilters = z.object({
...commonFields,
enable_filters: z.literal(false),
card_groups: z.array(
z.object({
filter_identifier: z.null(),
filter_label: z.string(),
cardConnection: z.object({
edges: z.array(z.object({ node: contentCardSchema })),
}),
})
),
})
export const carouselCardsSchema = z.object({
typename: z
.literal(BlocksEnums.block.CarouselCards)
.optional()
.default(BlocksEnums.block.CarouselCards),
carousel_cards: z
.discriminatedUnion("enable_filters", [
carouselCardsWithFilters,
carouselCardsWithoutFilters,
])
.transform((data) => {
if (!data.enable_filters) {
return {
heading: data.heading,
enableFilters: false,
filterCategories: [],
cards: data.card_groups
.flatMap((group) =>
group.cardConnection.edges.map((edge) =>
transformContentCard(edge.node)
)
)
.filter((card): card is NonNullable<typeof card> => card !== null),
link:
data.link?.href && data.link.title
? { href: data.link.href, text: data.link.title }
: undefined,
}
}
const filterCategories = data.card_groups.reduce<
Array<{
identifier: CarouselCardFilter
label: string
}>
>((acc, group) => {
const identifier = group.filter_identifier
if (!acc.some((category) => category.identifier === identifier)) {
acc.push({
identifier,
label: group.filter_label,
})
}
return acc
}, [])
return {
heading: data.heading,
enableFilters: true,
filterCategories,
cards: data.card_groups.flatMap((group) =>
group.cardConnection.edges
.map((edge) => transformContentCard(edge.node))
.filter((card): card is NonNullable<typeof card> => card !== null)
.map((card) => ({
...card,
filterId: group.filter_identifier,
}))
),
defaultFilter:
data.card_groups[0]?.filter_identifier ??
filterCategories[0]?.identifier,
link:
data.link?.href && data.link.title
? { href: data.link.href, text: data.link.title }
: undefined,
}
}),
})
export const carouselCardsRefsSchema = z.object({
typename: z
.literal(BlocksEnums.block.CarouselCards)
.optional()
.default(BlocksEnums.block.CarouselCards),
carousel_cards: z.object({
card_groups: z.array(
z.object({
cardConnection: z.object({
edges: z.array(
z.object({
node: contentCardRefSchema,
})
),
}),
})
),
link: linkConnectionRefsSchema.optional(),
}),
})