Merged in feat/SW-1584-destination-content-blocks (pull request #1278)

Feat/SW-1584 destination content blocks

* feat(SW-1584): Added accordion and content blocks to destination city pages

* feat(SW-1584): Added accordion and content blocks to destination country pages


Approved-by: Matilda Landström
This commit is contained in:
Erik Tiekstra
2025-02-10 09:28:32 +00:00
parent 918887a63f
commit eb0b88f8ea
18 changed files with 546 additions and 33 deletions

View File

@@ -1,7 +1,14 @@
import { z } from "zod"
import { discriminatedUnionArray } from "@/lib/discriminatedUnion"
import { removeMultipleSlashes } from "@/utils/url"
import {
accordionRefsSchema,
accordionSchema,
} from "../schemas/blocks/accordion"
import { contentRefsSchema, contentSchema } from "../schemas/blocks/content"
import { tempImageVaultAssetSchema } from "../schemas/imageVault"
import {
linkRefsUnionSchema,
@@ -15,6 +22,7 @@ import {
TrackingChannelEnum,
type TrackingSDKPageData,
} from "@/types/components/tracking"
import { DestinationCityPageEnum } from "@/types/enums/destinationCityPage"
export const destinationCityListDataSchema = z
.object({
@@ -54,6 +62,25 @@ export const destinationCityListDataSchema = z
({ all_destination_city_page }) => all_destination_city_page.items?.[0]
)
export const destinationCityPageContent = z
.object({
__typename: z.literal(DestinationCityPageEnum.ContentStack.blocks.Content),
})
.merge(contentSchema)
export const destinationCityPageAccordion = z
.object({
__typename: z.literal(
DestinationCityPageEnum.ContentStack.blocks.Accordion
),
})
.merge(accordionSchema)
export const blocksSchema = z.discriminatedUnion("__typename", [
destinationCityPageAccordion,
destinationCityPageContent,
])
export const destinationCityPageSchema = z
.object({
destination_city_page: z.object({
@@ -123,6 +150,7 @@ export const destinationCityPageSchema = z
}),
}),
}),
blocks: discriminatedUnionArray(blocksSchema.options).nullable(),
system: systemSchema.merge(
z.object({
created_at: z.string(),
@@ -158,6 +186,25 @@ export const destinationCityPageSchema = z
})
/** REFS */
const destinationCityPageContentRefs = z
.object({
__typename: z.literal(DestinationCityPageEnum.ContentStack.blocks.Content),
})
.merge(contentRefsSchema)
const destinationCityPageAccordionRefs = z
.object({
__typename: z.literal(
DestinationCityPageEnum.ContentStack.blocks.Accordion
),
})
.merge(accordionRefsSchema)
const blocksRefsSchema = z.discriminatedUnion("__typename", [
destinationCityPageAccordionRefs,
destinationCityPageContentRefs,
])
export const destinationCityPageRefsSchema = z.object({
destination_city_page: z.object({
sidepeek_content: z.object({
@@ -171,6 +218,7 @@ export const destinationCityPageRefsSchema = z.object({
}),
}),
}),
blocks: discriminatedUnionArray(blocksRefsSchema.options).nullable(),
system: systemSchema,
}),
})

View File

@@ -4,13 +4,14 @@ import { getHotel } from "../../hotels/query"
import { getHotelIdsByCityIdentifier } from "../../hotels/utils"
import { getHotelPageUrl } from "../hotelPage/utils"
import { DestinationCityPageEnum } from "@/types/enums/destinationCityPage"
import type { HotelData } from "@/types/hotel"
import type { System } from "@/types/requests/system"
import type { GetDestinationCityPageRefsSchema } from "@/types/trpc/routers/contentstack/destinationCityPage"
import type { DestinationCityPageRefs } from "@/types/trpc/routers/contentstack/destinationCityPage"
import type { Lang } from "@/constants/languages"
export function generatePageTags(
validatedData: GetDestinationCityPageRefsSchema,
validatedData: DestinationCityPageRefs,
lang: Lang
): string[] {
const connections = getConnections(validatedData)
@@ -22,8 +23,29 @@ export function generatePageTags(
export function getConnections({
destination_city_page,
}: GetDestinationCityPageRefsSchema) {
}: DestinationCityPageRefs) {
const connections: System["system"][] = [destination_city_page.system]
if (destination_city_page.blocks) {
destination_city_page.blocks.forEach((block) => {
switch (block.__typename) {
case DestinationCityPageEnum.ContentStack.blocks.Accordion: {
if (block.accordion.length) {
connections.push(...block.accordion)
}
break
}
case DestinationCityPageEnum.ContentStack.blocks.Content:
{
if (block.content.length) {
// TS has trouble infering the filtered types
// @ts-ignore
connections.push(...block.content)
}
}
break
}
})
}
if (destination_city_page.sidepeek_content) {
destination_city_page.sidepeek_content.content.embedded_itemsConnection.edges.forEach(
({ node }) => {

View File

@@ -1,5 +1,12 @@
import { z } from "zod"
import { discriminatedUnionArray } from "@/lib/discriminatedUnion"
import {
accordionRefsSchema,
accordionSchema,
} from "../schemas/blocks/accordion"
import { contentRefsSchema, contentSchema } from "../schemas/blocks/content"
import { tempImageVaultAssetSchema } from "../schemas/imageVault"
import {
linkRefsUnionSchema,
@@ -14,6 +21,28 @@ import {
type TrackingSDKPageData,
} from "@/types/components/tracking"
import { Country } from "@/types/enums/country"
import { DestinationCountryPageEnum } from "@/types/enums/destinationCountryPage"
export const destinationCountryPageContent = z
.object({
__typename: z.literal(
DestinationCountryPageEnum.ContentStack.blocks.Content
),
})
.merge(contentSchema)
export const destinationCountryPageAccordion = z
.object({
__typename: z.literal(
DestinationCountryPageEnum.ContentStack.blocks.Accordion
),
})
.merge(accordionSchema)
export const blocksSchema = z.discriminatedUnion("__typename", [
destinationCountryPageAccordion,
destinationCountryPageContent,
])
export const destinationCountryPageSchema = z
.object({
@@ -57,6 +86,7 @@ export const destinationCountryPageSchema = z
}),
}),
}),
blocks: discriminatedUnionArray(blocksSchema.options).nullable(),
system: systemSchema.merge(
z.object({
created_at: z.string(),
@@ -91,6 +121,26 @@ export const destinationCountryPageSchema = z
})
/** REFS */
const destinationCountryPageContentRefs = z
.object({
__typename: z.literal(
DestinationCountryPageEnum.ContentStack.blocks.Content
),
})
.merge(contentRefsSchema)
const destinationCountryPageAccordionRefs = z
.object({
__typename: z.literal(
DestinationCountryPageEnum.ContentStack.blocks.Accordion
),
})
.merge(accordionRefsSchema)
const blocksRefsSchema = z.discriminatedUnion("__typename", [
destinationCountryPageAccordionRefs,
destinationCountryPageContentRefs,
])
export const destinationCountryPageRefsSchema = z.object({
destination_country_page: z.object({
sidepeek_content: z.object({
@@ -104,6 +154,7 @@ export const destinationCountryPageRefsSchema = z.object({
}),
}),
}),
blocks: discriminatedUnionArray(blocksRefsSchema.options).nullable(),
system: systemSchema,
}),
})

View File

@@ -14,14 +14,15 @@ import {
} from "./telemetry"
import { ApiCountry, type Country } from "@/types/enums/country"
import { DestinationCountryPageEnum } from "@/types/enums/destinationCountryPage"
import type { RequestOptionsWithOutBody } from "@/types/fetch"
import type { System } from "@/types/requests/system"
import type { GetDestinationCityListDataResponse } from "@/types/trpc/routers/contentstack/destinationCityPage"
import type { GetDestinationCountryPageRefsSchema } from "@/types/trpc/routers/contentstack/destinationCountryPage"
import type { DestinationCountryPageRefs } from "@/types/trpc/routers/contentstack/destinationCountryPage"
import type { Lang } from "@/constants/languages"
export function generatePageTags(
validatedData: GetDestinationCountryPageRefsSchema,
validatedData: DestinationCountryPageRefs,
lang: Lang
): string[] {
const connections = getConnections(validatedData)
@@ -33,9 +34,29 @@ export function generatePageTags(
export function getConnections({
destination_country_page,
}: GetDestinationCountryPageRefsSchema) {
}: DestinationCountryPageRefs) {
const connections: System["system"][] = [destination_country_page.system]
if (destination_country_page.blocks) {
destination_country_page.blocks.forEach((block) => {
switch (block.__typename) {
case DestinationCountryPageEnum.ContentStack.blocks.Accordion: {
if (block.accordion.length) {
connections.push(...block.accordion)
}
break
}
case DestinationCountryPageEnum.ContentStack.blocks.Content:
{
if (block.content.length) {
// TS has trouble infering the filtered types
// @ts-ignore
connections.push(...block.content)
}
}
break
}
})
}
if (destination_country_page.sidepeek_content) {
destination_country_page.sidepeek_content.content.embedded_itemsConnection.edges.forEach(
({ node }) => {

View File

@@ -35,6 +35,10 @@ export type Accordion = z.infer<typeof accordionSchema>
enum AccordionEnum {
ContentPageBlocksAccordionBlockAccordionsGlobalAccordion = "ContentPageBlocksAccordionBlockAccordionsGlobalAccordion",
ContentPageBlocksAccordionBlockAccordionsSpecificAccordion = "ContentPageBlocksAccordionBlockAccordionsSpecificAccordion",
DestinationCityPageBlocksAccordionBlockAccordionsGlobalAccordion = "DestinationCityPageBlocksAccordionBlockAccordionsGlobalAccordion",
DestinationCityPageBlocksAccordionBlockAccordionsSpecificAccordion = "DestinationCityPageBlocksAccordionBlockAccordionsSpecificAccordion",
DestinationCountryPageBlocksAccordionBlockAccordionsGlobalAccordion = "DestinationCountryPageBlocksAccordionBlockAccordionsGlobalAccordion",
DestinationCountryPageBlocksAccordionBlockAccordionsSpecificAccordion = "DestinationCountryPageBlocksAccordionBlockAccordionsSpecificAccordion",
}
export const accordionSchema = z.object({
@@ -47,10 +51,7 @@ export const accordionSchema = z.object({
title: z.string().optional().default(""),
accordions: z.array(
z.object({
__typename: z.enum([
AccordionEnum.ContentPageBlocksAccordionBlockAccordionsGlobalAccordion,
AccordionEnum.ContentPageBlocksAccordionBlockAccordionsSpecificAccordion,
]),
__typename: z.nativeEnum(AccordionEnum),
global_accordion: z
.object({
global_accordionConnection: z.object({
@@ -78,6 +79,8 @@ export const accordionSchema = z.object({
accordions: data.accordions.flatMap((acc) => {
switch (acc.__typename) {
case AccordionEnum.ContentPageBlocksAccordionBlockAccordionsGlobalAccordion:
case AccordionEnum.DestinationCityPageBlocksAccordionBlockAccordionsGlobalAccordion:
case AccordionEnum.DestinationCountryPageBlocksAccordionBlockAccordionsGlobalAccordion:
return (
acc.global_accordion?.global_accordionConnection.edges.flatMap(
({ node: accordionConnection }) => {
@@ -86,6 +89,8 @@ export const accordionSchema = z.object({
) || []
)
case AccordionEnum.ContentPageBlocksAccordionBlockAccordionsSpecificAccordion:
case AccordionEnum.DestinationCityPageBlocksAccordionBlockAccordionsSpecificAccordion:
case AccordionEnum.DestinationCountryPageBlocksAccordionBlockAccordionsSpecificAccordion:
return acc.specific_accordion?.questions || []
}
}),
@@ -136,10 +141,7 @@ export const accordionRefsSchema = z.object({
.object({
accordions: z.array(
z.object({
__typename: z.enum([
AccordionEnum.ContentPageBlocksAccordionBlockAccordionsGlobalAccordion,
AccordionEnum.ContentPageBlocksAccordionBlockAccordionsSpecificAccordion,
]),
__typename: z.nativeEnum(AccordionEnum),
global_accordion: z
.object({
global_accordionConnection: globalAccordionConnectionRefs,
@@ -153,6 +155,8 @@ export const accordionRefsSchema = z.object({
return data.accordions.flatMap((accordion) => {
switch (accordion.__typename) {
case AccordionEnum.ContentPageBlocksAccordionBlockAccordionsGlobalAccordion:
case AccordionEnum.DestinationCityPageBlocksAccordionBlockAccordionsGlobalAccordion:
case AccordionEnum.DestinationCountryPageBlocksAccordionBlockAccordionsGlobalAccordion:
return (
accordion.global_accordion?.global_accordionConnection.edges.flatMap(
({ node: accordionConnection }) => {
@@ -165,6 +169,8 @@ export const accordionRefsSchema = z.object({
) || []
)
case AccordionEnum.ContentPageBlocksAccordionBlockAccordionsSpecificAccordion:
case AccordionEnum.DestinationCityPageBlocksAccordionBlockAccordionsSpecificAccordion:
case AccordionEnum.DestinationCountryPageBlocksAccordionBlockAccordionsSpecificAccordion:
return (
accordion.specific_accordion?.questions.flatMap((question) =>
question.answer.embedded_itemsConnection.edges.flatMap(