feat(SW-1452): Added filtering and sorting to destination city pages * feat(SW-1452): Added filtering and sorting to destination city pages * feat(SW-1452): Added temporary component for country pages to avoid Context issues Approved-by: Matilda Landström
117 lines
3.0 KiB
TypeScript
117 lines
3.0 KiB
TypeScript
import { z } from "zod"
|
|
|
|
import { attributesSchema as hotelAttributesSchema } from "../../hotels/schemas/hotel"
|
|
import { tempImageVaultAssetSchema } from "../schemas/imageVault"
|
|
import { systemSchema } from "../schemas/system"
|
|
import { getDescription, getImage, getTitle } from "./utils"
|
|
|
|
import type { Metadata } from "next"
|
|
|
|
import { RTETypeEnum } from "@/types/rte/enums"
|
|
|
|
const metaDataJsonSchema = z.object({
|
|
children: z.array(
|
|
z.object({
|
|
type: z.nativeEnum(RTETypeEnum),
|
|
children: z.array(
|
|
z.object({
|
|
text: z.string().optional(),
|
|
})
|
|
),
|
|
})
|
|
),
|
|
})
|
|
|
|
const metaDataBlocksSchema = z
|
|
.array(
|
|
z.object({
|
|
content: z
|
|
.object({
|
|
content: z
|
|
.object({
|
|
json: metaDataJsonSchema,
|
|
})
|
|
.optional()
|
|
.nullable(),
|
|
})
|
|
.optional()
|
|
.nullable(),
|
|
})
|
|
)
|
|
.optional()
|
|
.nullable()
|
|
|
|
export const rawMetadataSchema = z.object({
|
|
web: z
|
|
.object({
|
|
seo_metadata: z
|
|
.object({
|
|
title: z.string().optional().nullable(),
|
|
description: z.string().optional().nullable(),
|
|
noindex: z.boolean().optional().nullable(),
|
|
seo_image: tempImageVaultAssetSchema.nullable(),
|
|
})
|
|
.optional()
|
|
.nullable(),
|
|
breadcrumbs: z
|
|
.object({
|
|
title: z.string().optional().nullable(),
|
|
})
|
|
.optional()
|
|
.nullable(),
|
|
})
|
|
.optional()
|
|
.nullable(),
|
|
destination_settings: z
|
|
.object({
|
|
city_denmark: z.string().optional().nullable(),
|
|
city_finland: z.string().optional().nullable(),
|
|
city_germany: z.string().optional().nullable(),
|
|
city_poland: z.string().optional().nullable(),
|
|
city_norway: z.string().optional().nullable(),
|
|
city_sweden: z.string().optional().nullable(),
|
|
})
|
|
.optional()
|
|
.nullable(),
|
|
heading: z.string().optional().nullable(),
|
|
preamble: z.string().optional().nullable(),
|
|
header: z
|
|
.object({
|
|
heading: z.string().optional().nullable(),
|
|
preamble: z.string().optional().nullable(),
|
|
})
|
|
.optional()
|
|
.nullable(),
|
|
hero_image: tempImageVaultAssetSchema.nullable(),
|
|
blocks: metaDataBlocksSchema,
|
|
hotel_page_id: z.string().optional().nullable(),
|
|
hotelData: hotelAttributesSchema
|
|
.pick({ name: true, address: true, hotelContent: true, gallery: true })
|
|
.optional()
|
|
.nullable(),
|
|
cityName: z.string().optional().nullable(),
|
|
cityFilter: z.string().optional().nullable(),
|
|
cityFilterType: z.enum(["facility", "surroundings"]).optional().nullable(),
|
|
system: systemSchema,
|
|
})
|
|
|
|
export const metadataSchema = rawMetadataSchema.transform(async (data) => {
|
|
const noIndex = !!data.web?.seo_metadata?.noindex
|
|
|
|
const metadata: Metadata = {
|
|
title: await getTitle(data),
|
|
description: getDescription(data),
|
|
openGraph: {
|
|
images: getImage(data),
|
|
},
|
|
}
|
|
|
|
if (noIndex) {
|
|
metadata.robots = {
|
|
index: false,
|
|
follow: true,
|
|
}
|
|
}
|
|
return metadata
|
|
})
|