feat(SW-186): implemented queries and typings for card inside header query
This commit is contained in:
@@ -2,6 +2,10 @@ import { z } from "zod"
|
||||
|
||||
import { Lang } from "@/constants/languages"
|
||||
|
||||
import { removeMultipleSlashes } from "@/utils/url"
|
||||
|
||||
import { imageVaultAssetTransformedSchema } from "../schemas/imageVault"
|
||||
|
||||
import { Image } from "@/types/image"
|
||||
|
||||
// Help me write this zod schema based on the type ContactConfig
|
||||
@@ -262,120 +266,176 @@ const validateFooterRefConfigSchema = z.object({
|
||||
|
||||
export type FooterRefDataRaw = z.infer<typeof validateFooterRefConfigSchema>
|
||||
|
||||
const linkConnectionNodeSchema = z.object({
|
||||
edges: z.array(
|
||||
z.object({
|
||||
node: z.object({
|
||||
system: z.object({
|
||||
uid: z.string(),
|
||||
locale: z.nativeEnum(Lang),
|
||||
}),
|
||||
url: z.string(),
|
||||
title: z.string(),
|
||||
web: z.object({
|
||||
original_url: z.string().nullable().optional(),
|
||||
}),
|
||||
}),
|
||||
})
|
||||
),
|
||||
})
|
||||
|
||||
const internalExternalLinkSchema = z.object({
|
||||
external_link: z.object({
|
||||
href: z.string(),
|
||||
title: z.string(),
|
||||
}),
|
||||
is_external_link: z.boolean(),
|
||||
open_in_new_tab: z.boolean(),
|
||||
page_link: z.object({
|
||||
link_title: z.string(),
|
||||
linkConnection: linkConnectionNodeSchema,
|
||||
}),
|
||||
})
|
||||
|
||||
export type InternalExternalLinkData = z.infer<
|
||||
typeof internalExternalLinkSchema
|
||||
>
|
||||
|
||||
const cardButtonSchema = z.object({
|
||||
cta_text: z.string(),
|
||||
external_link: z.object({
|
||||
href: z.string(),
|
||||
title: z.string(),
|
||||
}),
|
||||
is_contentstack_link: z.boolean(),
|
||||
linkConnection: linkConnectionNodeSchema,
|
||||
open_in_new_tab: z.boolean(),
|
||||
})
|
||||
|
||||
const menuItemSchema = z.object({
|
||||
title: z.string(),
|
||||
link: internalExternalLinkSchema,
|
||||
submenu: z.array(
|
||||
z.object({
|
||||
title: z.string(),
|
||||
links: z.array(internalExternalLinkSchema),
|
||||
})
|
||||
),
|
||||
see_all_link: internalExternalLinkSchema,
|
||||
// cardConnection: z.array(
|
||||
// z.object({
|
||||
// node: z.object({
|
||||
// title: z.string(),
|
||||
// heading: z.string(),
|
||||
// body_text: z.string(),
|
||||
// background_image: z.any(), // TODO: Any for now, should be Image
|
||||
// has_primary_button: z.boolean(),
|
||||
// has_secondary_button: z.boolean(),
|
||||
// scripted_top_title: z.string(),
|
||||
// primary_button: cardButtonSchema,
|
||||
// secondary_button: cardButtonSchema,
|
||||
// }),
|
||||
// })
|
||||
// ),
|
||||
})
|
||||
|
||||
export const validateHeaderSchema = z.object({
|
||||
all_header: z.object({
|
||||
items: z.array(
|
||||
const linkConnectionNodeSchema = z
|
||||
.object({
|
||||
edges: z.array(
|
||||
z.object({
|
||||
top_link: internalExternalLinkSchema.optional(),
|
||||
menu_items: z.array(menuItemSchema),
|
||||
node: z.object({
|
||||
system: z.object({
|
||||
uid: z.string(),
|
||||
locale: z.nativeEnum(Lang),
|
||||
}),
|
||||
url: z.string(),
|
||||
title: z.string(),
|
||||
web: z.object({
|
||||
original_url: z.string().nullable().optional(),
|
||||
}),
|
||||
}),
|
||||
})
|
||||
),
|
||||
}),
|
||||
})
|
||||
})
|
||||
.transform((rawData) => {
|
||||
const node = rawData.edges[0]?.node
|
||||
if (!node) {
|
||||
return null
|
||||
}
|
||||
const url = node.url
|
||||
const originalUrl = node.web?.original_url
|
||||
const lang = node.system.locale
|
||||
return { originalUrl, url: removeMultipleSlashes(`/${lang}/${url}`) }
|
||||
})
|
||||
|
||||
export type HeaderDataRaw = z.infer<typeof validateHeaderSchema>
|
||||
const internalExternalLinkSchema = z
|
||||
.object({
|
||||
external_link: z.object({
|
||||
href: z.string(),
|
||||
title: z.string(),
|
||||
}),
|
||||
is_external_link: z.boolean(),
|
||||
open_in_new_tab: z.boolean(),
|
||||
page_link: z.object({
|
||||
link_title: z.string(),
|
||||
linkConnection: linkConnectionNodeSchema,
|
||||
}),
|
||||
})
|
||||
.transform((rawData) => {
|
||||
if (!rawData) {
|
||||
return null
|
||||
}
|
||||
|
||||
export type InternalExternalLink = {
|
||||
href: string
|
||||
title: string
|
||||
isExternal: boolean
|
||||
openInNewTab: boolean
|
||||
}
|
||||
const linkConnectionData = rawData.page_link.linkConnection
|
||||
const isExternalLink =
|
||||
rawData.is_external_link && rawData.external_link.href
|
||||
const isOriginalLink = linkConnectionData?.originalUrl
|
||||
const externalLink = rawData.external_link
|
||||
const href =
|
||||
isExternalLink || !linkConnectionData
|
||||
? externalLink.href
|
||||
: linkConnectionData.originalUrl || linkConnectionData.url
|
||||
const title = isExternalLink
|
||||
? externalLink.title
|
||||
: rawData.page_link.link_title
|
||||
|
||||
export type SubmenuItem = {
|
||||
title: string
|
||||
links: InternalExternalLink[]
|
||||
}
|
||||
return {
|
||||
openInNewTab: rawData.open_in_new_tab,
|
||||
title,
|
||||
href,
|
||||
isExternal: !!(isExternalLink || isOriginalLink),
|
||||
}
|
||||
})
|
||||
|
||||
export type MenuItem = {
|
||||
title: string
|
||||
link: InternalExternalLink | null
|
||||
seeAllLink: InternalExternalLink | null
|
||||
submenu: SubmenuItem[]
|
||||
}
|
||||
const cardButtonSchema = z
|
||||
.object({
|
||||
cta_text: z.string(),
|
||||
external_link: z.object({
|
||||
href: z.string(),
|
||||
title: z.string(),
|
||||
}),
|
||||
is_contentstack_link: z.boolean(),
|
||||
linkConnection: linkConnectionNodeSchema,
|
||||
open_in_new_tab: z.boolean(),
|
||||
})
|
||||
.transform((rawData) => {
|
||||
if (!rawData) {
|
||||
return null
|
||||
}
|
||||
|
||||
export type HeaderData = Omit<
|
||||
HeaderDataRaw["all_header"]["items"][0],
|
||||
"top_link" | "menu_items"
|
||||
> & {
|
||||
topLink: InternalExternalLink | null
|
||||
menuItems: MenuItem[]
|
||||
}
|
||||
const linkConnectionData = rawData.linkConnection
|
||||
const isExternalLink = !rawData.is_contentstack_link
|
||||
const externalLink = rawData.external_link
|
||||
const href =
|
||||
isExternalLink || !linkConnectionData
|
||||
? externalLink.href
|
||||
: linkConnectionData.originalUrl || linkConnectionData.url
|
||||
const title = isExternalLink ? externalLink.title : rawData.cta_text
|
||||
|
||||
const validateHeaderRefSchema = z.object({
|
||||
return {
|
||||
openInNewTab: rawData.open_in_new_tab,
|
||||
title,
|
||||
href,
|
||||
isExternal: !!(isExternalLink || linkConnectionData?.originalUrl),
|
||||
}
|
||||
})
|
||||
|
||||
const cardSchema = z
|
||||
.object({
|
||||
heading: z.string(),
|
||||
body_text: z.string(),
|
||||
background_image: imageVaultAssetTransformedSchema,
|
||||
has_primary_button: z.boolean(),
|
||||
has_secondary_button: z.boolean(),
|
||||
scripted_top_title: z.string(),
|
||||
primary_button: cardButtonSchema,
|
||||
secondary_button: cardButtonSchema,
|
||||
})
|
||||
.transform((rawData) => {
|
||||
return {
|
||||
scriptedTopTitle: rawData.scripted_top_title,
|
||||
heading: rawData.heading,
|
||||
bodyText: rawData.body_text,
|
||||
backgroundImage: rawData.background_image,
|
||||
primaryButton: rawData.has_primary_button ? rawData.primary_button : null,
|
||||
secondaryButton: rawData.has_secondary_button
|
||||
? rawData.secondary_button
|
||||
: null,
|
||||
}
|
||||
})
|
||||
|
||||
const menuItemSchema = z
|
||||
.object({
|
||||
title: z.string(),
|
||||
link: internalExternalLinkSchema,
|
||||
submenu: z.array(
|
||||
z.object({
|
||||
title: z.string(),
|
||||
links: z.array(internalExternalLinkSchema),
|
||||
})
|
||||
),
|
||||
see_all_link: internalExternalLinkSchema,
|
||||
cardConnection: z.object({
|
||||
edges: z.array(z.object({ node: cardSchema })),
|
||||
}),
|
||||
})
|
||||
.transform((rawData) => {
|
||||
return {
|
||||
link: rawData.submenu.length ? null : rawData.link,
|
||||
seeAllLink: rawData.submenu.length ? rawData.see_all_link : null,
|
||||
submenu: rawData.submenu,
|
||||
card: rawData.cardConnection.edges[0]?.node,
|
||||
}
|
||||
})
|
||||
|
||||
export const getHeaderSchema = z
|
||||
.object({
|
||||
all_header: z.object({
|
||||
items: z.array(
|
||||
z.object({
|
||||
top_link: internalExternalLinkSchema.optional(),
|
||||
menu_items: z.array(menuItemSchema),
|
||||
})
|
||||
),
|
||||
}),
|
||||
})
|
||||
.transform((rawData) => {
|
||||
const { top_link, menu_items } = rawData.all_header.items[0]
|
||||
|
||||
return {
|
||||
topLink: top_link,
|
||||
menuItems: menu_items,
|
||||
}
|
||||
})
|
||||
|
||||
export const getHeaderRefSchema = z.object({
|
||||
all_header: z.object({
|
||||
items: z.array(
|
||||
z.object({
|
||||
@@ -387,5 +447,3 @@ const validateHeaderRefSchema = z.object({
|
||||
),
|
||||
}),
|
||||
})
|
||||
|
||||
export type HeaderRefDataRaw = z.infer<typeof validateHeaderRefSchema>
|
||||
|
||||
Reference in New Issue
Block a user