diff --git a/apps/scandic-web/components/TabFilters/index.tsx b/apps/scandic-web/components/TabFilters/index.tsx index cbb22132d..8e70f74d1 100644 --- a/apps/scandic-web/components/TabFilters/index.tsx +++ b/apps/scandic-web/components/TabFilters/index.tsx @@ -13,6 +13,7 @@ import styles from "./tabFilters.module.css" interface Filter { identifier: string label: string + iconIdentifier: string } interface TabFiltersProps { @@ -50,7 +51,7 @@ export default function TabFilters({ })} type="button" > - + {category.label} diff --git a/apps/scandic-web/server/routers/contentstack/schemas/blocks/cardGallery.ts b/apps/scandic-web/server/routers/contentstack/schemas/blocks/cardGallery.ts index 0f5ce6672..0c476f9aa 100644 --- a/apps/scandic-web/server/routers/contentstack/schemas/blocks/cardGallery.ts +++ b/apps/scandic-web/server/routers/contentstack/schemas/blocks/cardGallery.ts @@ -19,45 +19,58 @@ export const cardGallerySchema = z.object({ .object({ heading: z.string().optional(), link: buttonSchema.optional(), - card_groups: z.array( - z.object({ - filter_identifier: z.string(), - filter_label: z.string(), - cardsConnection: z.object({ - edges: z.array(z.object({ node: contentCardSchema })), - }), - }) - ), + card_groups: z + .array( + z + .object({ + filter_identifier: z.string().nullish(), + filter_label: z.string().nullish(), + cardsConnection: z.object({ + edges: z.array(z.object({ node: contentCardSchema })), + }), + }) + .transform((group) => { + if (!group.filter_label || !group.cardsConnection.edges.length) { + return null + } + + const iconIdentifier = group.filter_identifier ?? "favorite" + const identifier = `${group.filter_label.toLowerCase()}-${iconIdentifier}` + const cards = group.cardsConnection.edges + .map((edge) => transformContentCard(edge.node)) + .filter( + (card): card is NonNullable => card !== null + ) + .map((card) => ({ + ...card, + filterId: identifier, + })) + return { + label: group.filter_label, + iconIdentifier, + identifier, + cards, + } + }) + ) + .transform((groups) => + groups.filter( + (group): group is NonNullable => group !== null + ) + ), }) .transform((data) => { - const filterCategories = data.card_groups.reduce< - Array<{ identifier: string; 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 - }, []) + const filterCategories = data.card_groups.map((group) => ({ + identifier: group.identifier, + iconIdentifier: group.iconIdentifier, + label: group.label, + })) return { heading: data.heading, filterCategories, - cards: data.card_groups.flatMap((group) => - group.cardsConnection.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, + cards: data.card_groups.map((group) => group.cards).flat(), + defaultFilter: filterCategories[0]?.identifier, link: data.link?.href && data.link.title ? { href: data.link.href, text: data.link.title } diff --git a/apps/scandic-web/server/routers/contentstack/schemas/blocks/carouselCards.ts b/apps/scandic-web/server/routers/contentstack/schemas/blocks/carouselCards.ts index c7c195ebe..bee907d9d 100644 --- a/apps/scandic-web/server/routers/contentstack/schemas/blocks/carouselCards.ts +++ b/apps/scandic-web/server/routers/contentstack/schemas/blocks/carouselCards.ts @@ -15,32 +15,52 @@ const commonFields = { link: buttonSchema.optional(), } as const +const carouselCardGroupsSchema = z + .array( + z + .object({ + filter_identifier: z.string().nullish(), + filter_label: z.string().nullish(), + cardConnection: z.object({ + edges: z.array(z.object({ node: contentCardSchema })), + }), + }) + .transform((group) => { + if (!group.filter_label || !group.cardConnection.edges.length) { + return null + } + + const iconIdentifier = group.filter_identifier ?? "favorite" + const identifier = `${group.filter_label.toLowerCase()}-${iconIdentifier}` + const cards = group.cardConnection.edges + .map((edge) => transformContentCard(edge.node)) + .filter((card): card is NonNullable => card !== null) + .map((card) => ({ + ...card, + filterId: identifier, + })) + return { + label: group.filter_label, + iconIdentifier, + identifier, + cards, + } + }) + ) + .transform((groups) => + groups.filter((group): group is NonNullable => group !== null) + ) + const carouselCardsWithFilters = z.object({ ...commonFields, enable_filters: z.literal(true), - card_groups: z.array( - z.object({ - filter_identifier: z.string(), - filter_label: z.string(), - cardConnection: z.object({ - edges: z.array(z.object({ node: contentCardSchema })), - }), - }) - ), + card_groups: carouselCardGroupsSchema, }) 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 })), - }), - }) - ), + card_groups: carouselCardGroupsSchema, }) export const carouselCardsSchema = z.object({ @@ -59,13 +79,7 @@ export const carouselCardsSchema = z.object({ 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), + cards: data.card_groups.map((group) => group.cards).flat(), link: data.link?.href && data.link.title ? { href: data.link.href, text: data.link.title } @@ -73,35 +87,18 @@ export const carouselCardsSchema = z.object({ } } - const filterCategories = data.card_groups.reduce< - Array<{ identifier: string; 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 - }, []) + const filterCategories = data.card_groups.map((group) => ({ + identifier: group.identifier, + iconIdentifier: group.iconIdentifier, + label: group.label, + })) 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, + cards: data.card_groups.map((group) => group.cards).flat(), + defaultFilter: filterCategories[0]?.identifier, link: data.link?.href && data.link.title ? { href: data.link.href, text: data.link.title }