import { z } from "zod" import { Lang } from "@/constants/languages" import { Image } from "@/types/image" // Help me write this zod schema based on the type ContactConfig export const validateContactConfigSchema = z.object({ all_contact_config: z.object({ items: z.array( z.object({ email: z.object({ name: z.string().nullable(), address: z.string().nullable(), }), email_loyalty: z.object({ name: z.string().nullable(), address: z.string().nullable(), }), mailing_address: z.object({ zip: z.string().nullable(), street: z.string().nullable(), name: z.string().nullable(), city: z.string().nullable(), country: z.string().nullable(), }), phone: z.object({ number: z.string().nullable(), name: z.string().nullable(), }), phone_loyalty: z.object({ number: z.string().nullable(), name: z.string().nullable(), }), visiting_address: z.object({ zip: z.string().nullable(), country: z.string().nullable(), city: z.string().nullable(), street: z.string().nullable(), }), }) ), }), }) export enum ContactFieldGroupsEnum { email = "email", email_loyalty = "email_loyalty", mailing_address = "mailing_address", phone = "phone", phone_loyalty = "phone_loyalty", visiting_address = "visiting_address", } export type ContactFieldGroups = keyof typeof ContactFieldGroupsEnum export type ContactConfigData = z.infer export type ContactConfig = ContactConfigData["all_contact_config"]["items"][0] export type ContactFields = { display_text: string | null contact_field: string footnote: string | null } export const validateCurrentHeaderConfigSchema = z.object({ all_current_header: z.object({ items: z.array( z.object({ frontpage_link_text: z.string(), logoConnection: z.object({ edges: z.array( z.object({ node: z.object({ description: z.string().optional().nullable(), dimension: z.object({ height: z.number(), width: z.number(), }), metadata: z.any().nullable(), system: z.object({ uid: z.string(), }), title: z.string().nullable(), url: z.string().nullable(), }), }) ), }), menu: z.object({ links: z.array( z.object({ href: z.string(), title: z.string(), }) ), }), top_menu: z.object({ links: z.array( z.object({ link: z.object({ href: z.string(), title: z.string(), }), show_on_mobile: z.boolean(), sort_order_mobile: z.number(), }) ), }), }) ), }), }) export type CurrentHeaderDataRaw = z.infer< typeof validateCurrentHeaderConfigSchema > export type CurrentHeaderData = Omit< CurrentHeaderDataRaw["all_current_header"]["items"][0], "logoConnection" > & { logo: Image } const validateCurrentHeaderRefConfigSchema = z.object({ all_current_header: z.object({ items: z.array( z.object({ system: z.object({ content_type_uid: z.string(), uid: z.string(), }), }) ), }), }) export type CurrentHeaderRefDataRaw = z.infer< typeof validateCurrentHeaderRefConfigSchema > const validateAppDownload = z.object({ href: z.string(), imageConnection: z.object({ edges: z.array( z.object({ node: z.object({ description: z.string().optional().nullable(), dimension: z.object({ height: z.number(), width: z.number(), }), metadata: z.any().nullable(), system: z.object({ uid: z.string(), }), title: z.string(), url: z.string(), }), }) ), }), }) const validateNavigationItem = z.object({ links: z.array(z.object({ href: z.string(), title: z.string() })), title: z.string(), }) export type NavigationItem = z.infer export const validateFooterConfigSchema = z.object({ all_current_footer: z.object({ items: z.array( z.object({ title: z.string(), about: z.object({ title: z.string(), text: z.string(), }), app_downloads: z.object({ title: z.string(), app_store: validateAppDownload, google_play: validateAppDownload, }), logoConnection: z.object({ edges: z.array( z.object({ node: z.object({ description: z.string().optional().nullable(), dimension: z.object({ height: z.number(), width: z.number(), }), metadata: z.any().nullable(), system: z.object({ uid: z.string(), }), title: z.string(), url: z.string(), }), }) ), }), navigation: z.array(validateNavigationItem), social_media: z.object({ title: z.string(), facebook: z.object({ href: z.string(), title: z.string() }), instagram: z.object({ href: z.string(), title: z.string() }), twitter: z.object({ href: z.string(), title: z.string() }), }), trip_advisor: z.object({ title: z.string(), logoConnection: z.object({ edges: z.array( z.object({ node: z.object({ description: z.string().optional().nullable(), dimension: z.object({ height: z.number(), width: z.number(), }), metadata: z.any().nullable(), system: z.object({ uid: z.string(), }), title: z.string(), url: z.string(), }), }) ), }), }), }) ), }), }) export type FooterDataRaw = z.infer export type FooterData = Omit< FooterDataRaw["all_current_footer"]["items"][0], "logoConnection" > & { logo: Image } const validateFooterRefConfigSchema = z.object({ all_current_footer: z.object({ items: z.array( z.object({ system: z.object({ content_type_uid: z.string(), uid: z.string(), }), }) ), }), }) export type FooterRefDataRaw = z.infer 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( z.object({ top_link: internalExternalLinkSchema.optional(), menu_items: z.array(menuItemSchema), }) ), }), }) export type HeaderDataRaw = z.infer export type InternalExternalLink = { href: string title: string isExternal: boolean openInNewTab: boolean } export type SubmenuItem = { title: string links: InternalExternalLink[] } export type MenuItem = { title: string link: InternalExternalLink | null seeAllLink: InternalExternalLink | null submenu: SubmenuItem[] } export type HeaderData = Omit< HeaderDataRaw["all_header"]["items"][0], "top_link" | "menu_items" > & { topLink: InternalExternalLink | null menuItems: MenuItem[] } const validateHeaderRefSchema = z.object({ all_header: z.object({ items: z.array( z.object({ system: z.object({ content_type_uid: z.string(), uid: z.string(), }), }) ), }), }) export type HeaderRefDataRaw = z.infer