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 => 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 => 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(), }), })