feat(SW-186): Added refs and some extra querys
This commit is contained in:
@@ -13,16 +13,12 @@ import type { NavigationMenuItemProps } from "@/types/components/header/navigati
|
||||
|
||||
export default function MenuItem({ item, isMobile }: NavigationMenuItemProps) {
|
||||
const { submenu, title, link, seeAllLink, card } = item
|
||||
const [isExpanded, setIsExpanded] = useState(false)
|
||||
const [isExpanded, setIsExpanded] = useState(false) // TODO: Use store to manage this state when adding the menu itself.
|
||||
|
||||
function handleButtonClick() {
|
||||
setIsExpanded((prev) => !prev)
|
||||
}
|
||||
|
||||
if (!submenu.length && !link) {
|
||||
return null
|
||||
}
|
||||
|
||||
return submenu.length ? (
|
||||
<MainMenuButton
|
||||
onClick={handleButtonClick}
|
||||
|
||||
@@ -46,7 +46,7 @@ export default async function MainMenu({
|
||||
/>
|
||||
</NextLink>
|
||||
<div className={styles.menus}>
|
||||
{menuItems ? (
|
||||
{menuItems?.length ? (
|
||||
<NavigationMenu items={menuItems} isMobile={false} />
|
||||
) : null}
|
||||
{user ? (
|
||||
@@ -74,7 +74,7 @@ export default async function MainMenu({
|
||||
</span>
|
||||
</Link>
|
||||
)}
|
||||
{menuItems ? (
|
||||
{menuItems?.length ? (
|
||||
<MobileMenu languageUrls={languageUrls} menuItems={menuItems} />
|
||||
) : null}
|
||||
</div>
|
||||
@@ -82,26 +82,3 @@ export default async function MainMenu({
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
const error = {
|
||||
query: { lang: "sv" },
|
||||
error: {
|
||||
issues: [
|
||||
{
|
||||
code: "invalid_type",
|
||||
expected: "string",
|
||||
received: "null",
|
||||
path: ["all_header", "items", 0, "top_link", "title"],
|
||||
message: "Expected string, received null",
|
||||
},
|
||||
{
|
||||
code: "invalid_type",
|
||||
expected: "array",
|
||||
received: "null",
|
||||
path: ["all_header", "items", 0, "menu_items"],
|
||||
message: "Expected array, received null",
|
||||
},
|
||||
],
|
||||
name: "ZodError",
|
||||
},
|
||||
}
|
||||
|
||||
@@ -1,16 +1,13 @@
|
||||
.topMenu {
|
||||
display: none;
|
||||
background-color: var(--Base-Surface-Subtle-Normal);
|
||||
padding: var(--Spacing-x2) var(--Spacing-x-one-and-half);
|
||||
padding: var(--Spacing-x2);
|
||||
border-bottom: 1px solid var(--Base-Border-Subtle);
|
||||
}
|
||||
|
||||
.content {
|
||||
max-width: var(--max-width-navigation);
|
||||
margin: 0 auto;
|
||||
display: grid;
|
||||
justify-content: space-between;
|
||||
gap: var(--Spacing-x3);
|
||||
}
|
||||
|
||||
.options {
|
||||
@@ -24,7 +21,10 @@
|
||||
display: block;
|
||||
}
|
||||
.content {
|
||||
display: grid;
|
||||
grid-template-areas: "topLink options";
|
||||
justify-content: space-between;
|
||||
gap: var(--Spacing-x3);
|
||||
}
|
||||
|
||||
.topLink {
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
#import "../PageLink/ContentPageLink.graphql"
|
||||
#import "../PageLink/LoyaltyPageLink.graphql"
|
||||
|
||||
fragment InternalOrExternalLink on InternalOrExternalLink {
|
||||
is_external_link
|
||||
open_in_new_tab
|
||||
external_link {
|
||||
href
|
||||
title
|
||||
}
|
||||
page_link {
|
||||
linkConnection {
|
||||
edges {
|
||||
node {
|
||||
...ContentPageLink
|
||||
...LoyaltyPageLink
|
||||
}
|
||||
}
|
||||
}
|
||||
link_title
|
||||
}
|
||||
}
|
||||
@@ -5,4 +5,8 @@ fragment HotelPageLink on HotelPage {
|
||||
}
|
||||
title
|
||||
url
|
||||
# TODO: Might need to add this if this is needed for hotel pages.
|
||||
# web {
|
||||
# original_url
|
||||
# }
|
||||
}
|
||||
|
||||
48
lib/graphql/Fragments/Refs/HotelPage/Breadcrumbs.graphql
Normal file
48
lib/graphql/Fragments/Refs/HotelPage/Breadcrumbs.graphql
Normal file
@@ -0,0 +1,48 @@
|
||||
#import "../System.graphql"
|
||||
|
||||
fragment HotelPageBreadcrumbsRefs on HotelPage {
|
||||
web {
|
||||
breadcrumbs {
|
||||
title
|
||||
parentsConnection {
|
||||
edges {
|
||||
node {
|
||||
... on ContentPage {
|
||||
web {
|
||||
breadcrumbs {
|
||||
title
|
||||
}
|
||||
}
|
||||
system {
|
||||
...System
|
||||
}
|
||||
}
|
||||
... on HotelPage {
|
||||
web {
|
||||
breadcrumbs {
|
||||
title
|
||||
}
|
||||
}
|
||||
system {
|
||||
...System
|
||||
}
|
||||
}
|
||||
... on LoyaltyPage {
|
||||
web {
|
||||
breadcrumbs {
|
||||
title
|
||||
}
|
||||
}
|
||||
system {
|
||||
...System
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
system {
|
||||
...System
|
||||
}
|
||||
}
|
||||
7
lib/graphql/Fragments/Refs/HotelPage/HotelPage.graphql
Normal file
7
lib/graphql/Fragments/Refs/HotelPage/HotelPage.graphql
Normal file
@@ -0,0 +1,7 @@
|
||||
#import "../System.graphql"
|
||||
|
||||
fragment HotelPageRef on HotelPage {
|
||||
system {
|
||||
...System
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,17 @@
|
||||
#import "../Fragments/Refs/System.graphql"
|
||||
|
||||
#import "../Fragments/Header/InternalOrExternalLink.graphql"
|
||||
#import "../Fragments/PageLink/ContentPageLink.graphql"
|
||||
#import "../Fragments/PageLink/LoyaltyPageLink.graphql"
|
||||
#import "../Fragments/PageLink/AccountPageLink.graphql"
|
||||
#import "../Fragments/PageLink/ContentPageLink.graphql"
|
||||
#import "../Fragments/PageLink/HotelPageLink.graphql"
|
||||
#import "../Fragments/PageLink/LoyaltyPageLink.graphql"
|
||||
#import "../Fragments/Blocks/Card.graphql"
|
||||
|
||||
#import "../Fragments/Blocks/Refs/Card.graphql"
|
||||
#import "../Fragments/Refs/ContentPage/ContentPage.graphql"
|
||||
#import "../Fragments/Refs/HotelPage/HotelPage.graphql"
|
||||
#import "../Fragments/Refs/LoyaltyPage/LoyaltyPage.graphql"
|
||||
#import "../Fragments/Refs/MyPages/AccountPage.graphql"
|
||||
|
||||
query GetHeader($locale: String!) {
|
||||
all_header(limit: 1, locale: $locale) {
|
||||
items {
|
||||
@@ -15,6 +21,7 @@ query GetHeader($locale: String!) {
|
||||
edges {
|
||||
node {
|
||||
...ContentPageLink
|
||||
...HotelPageLink
|
||||
...LoyaltyPageLink
|
||||
}
|
||||
}
|
||||
@@ -26,6 +33,7 @@ query GetHeader($locale: String!) {
|
||||
edges {
|
||||
node {
|
||||
...ContentPageLink
|
||||
...HotelPageLink
|
||||
...LoyaltyPageLink
|
||||
}
|
||||
}
|
||||
@@ -36,6 +44,7 @@ query GetHeader($locale: String!) {
|
||||
edges {
|
||||
node {
|
||||
...ContentPageLink
|
||||
...HotelPageLink
|
||||
...LoyaltyPageLink
|
||||
}
|
||||
}
|
||||
@@ -49,6 +58,7 @@ query GetHeader($locale: String!) {
|
||||
edges {
|
||||
node {
|
||||
...ContentPageLink
|
||||
...HotelPageLink
|
||||
...LoyaltyPageLink
|
||||
}
|
||||
}
|
||||
@@ -70,6 +80,59 @@ query GetHeader($locale: String!) {
|
||||
query GetHeaderRef($locale: String!) {
|
||||
all_header(limit: 1, locale: $locale) {
|
||||
items {
|
||||
top_link {
|
||||
linkConnection {
|
||||
edges {
|
||||
node {
|
||||
...ContentPageRef
|
||||
...HotelPageRef
|
||||
...LoyaltyPageRef
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
menu_items {
|
||||
linkConnection {
|
||||
edges {
|
||||
node {
|
||||
...ContentPageRef
|
||||
...HotelPageRef
|
||||
...LoyaltyPageRef
|
||||
}
|
||||
}
|
||||
}
|
||||
see_all_link {
|
||||
linkConnection {
|
||||
edges {
|
||||
node {
|
||||
...ContentPageRef
|
||||
...HotelPageRef
|
||||
...LoyaltyPageRef
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
submenu {
|
||||
links {
|
||||
linkConnection {
|
||||
edges {
|
||||
node {
|
||||
...ContentPageRef
|
||||
...HotelPageRef
|
||||
...LoyaltyPageRef
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
cardConnection {
|
||||
edges {
|
||||
node {
|
||||
...CardBlockRef
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
system {
|
||||
...System
|
||||
}
|
||||
|
||||
@@ -268,24 +268,26 @@ 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),
|
||||
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(),
|
||||
}),
|
||||
}),
|
||||
url: z.string(),
|
||||
title: z.string(),
|
||||
web: z.object({
|
||||
original_url: z.string().nullable().optional(),
|
||||
}),
|
||||
}),
|
||||
})
|
||||
),
|
||||
})
|
||||
)
|
||||
.max(1),
|
||||
})
|
||||
.transform((rawData) => {
|
||||
const node = rawData.edges[0]?.node
|
||||
.transform((data) => {
|
||||
const node = data.edges[0]?.node
|
||||
if (!node) {
|
||||
return null
|
||||
}
|
||||
@@ -301,15 +303,14 @@ const linkConnectionNodeSchema = z
|
||||
|
||||
const linkWithTitleSchema = z
|
||||
.object({
|
||||
title: z.string().nullable(),
|
||||
title: z.string(),
|
||||
linkConnection: linkConnectionNodeSchema,
|
||||
})
|
||||
.transform((rawData) => {
|
||||
return rawData.linkConnection && rawData.title
|
||||
? {
|
||||
...rawData.linkConnection,
|
||||
title: rawData.title,
|
||||
href: rawData.linkConnection.href,
|
||||
isExternal: rawData.linkConnection.isExternal,
|
||||
}
|
||||
: null
|
||||
})
|
||||
@@ -325,21 +326,18 @@ const cardButtonSchema = z
|
||||
linkConnection: linkConnectionNodeSchema,
|
||||
open_in_new_tab: z.boolean(),
|
||||
})
|
||||
.transform((rawData) => {
|
||||
if (!rawData) {
|
||||
return null
|
||||
}
|
||||
const linkConnectionData = rawData.linkConnection
|
||||
const isContentstackLink = rawData.is_contentstack_link
|
||||
const externalLink = rawData.external_link
|
||||
.transform((data) => {
|
||||
const linkConnectionData = data.linkConnection
|
||||
const isContentstackLink = data.is_contentstack_link
|
||||
const externalLink = data.external_link
|
||||
const href =
|
||||
isContentstackLink && externalLink.href
|
||||
? externalLink.href
|
||||
: linkConnectionData?.href || ""
|
||||
|
||||
return {
|
||||
openInNewTab: rawData.open_in_new_tab,
|
||||
title: rawData.cta_text,
|
||||
openInNewTab: data.open_in_new_tab,
|
||||
title: data.cta_text,
|
||||
href,
|
||||
isExternal: !isContentstackLink || linkConnectionData?.isExternal,
|
||||
}
|
||||
@@ -347,23 +345,25 @@ const cardButtonSchema = z
|
||||
|
||||
const cardConnectionSchema = z
|
||||
.object({
|
||||
edges: z.array(
|
||||
z.object({
|
||||
node: 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,
|
||||
}),
|
||||
})
|
||||
),
|
||||
edges: z
|
||||
.array(
|
||||
z.object({
|
||||
node: 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.nullable(),
|
||||
secondary_button: cardButtonSchema.nullable(),
|
||||
}),
|
||||
})
|
||||
)
|
||||
.max(1),
|
||||
})
|
||||
.transform((rawData) => {
|
||||
const node = rawData.edges[0]?.node
|
||||
.transform((data) => {
|
||||
const node = data.edges[0]?.node
|
||||
if (!node) {
|
||||
return null
|
||||
}
|
||||
@@ -391,31 +391,33 @@ export const menuItemSchema = z
|
||||
see_all_link: linkWithTitleSchema,
|
||||
cardConnection: cardConnectionSchema,
|
||||
})
|
||||
.transform(
|
||||
({ submenu, linkConnection, cardConnection, see_all_link, title }) => {
|
||||
return {
|
||||
title,
|
||||
link: submenu.length ? null : linkConnection,
|
||||
seeAllLink: submenu.length ? see_all_link : null,
|
||||
submenu,
|
||||
card: cardConnection,
|
||||
}
|
||||
.transform((data) => {
|
||||
const { submenu, linkConnection, cardConnection, see_all_link, title } =
|
||||
data
|
||||
return {
|
||||
title,
|
||||
link: submenu.length ? null : linkConnection,
|
||||
seeAllLink: submenu.length ? see_all_link : null,
|
||||
submenu,
|
||||
card: cardConnection,
|
||||
}
|
||||
)
|
||||
})
|
||||
|
||||
export const getHeaderSchema = z
|
||||
.object({
|
||||
all_header: z.object({
|
||||
items: z.array(
|
||||
z.object({
|
||||
top_link: linkWithTitleSchema.nullable(),
|
||||
menu_items: z.array(menuItemSchema).nullable(),
|
||||
})
|
||||
),
|
||||
items: z
|
||||
.array(
|
||||
z.object({
|
||||
top_link: linkWithTitleSchema,
|
||||
menu_items: z.array(menuItemSchema),
|
||||
})
|
||||
)
|
||||
.length(1),
|
||||
}),
|
||||
})
|
||||
.transform((rawData) => {
|
||||
const { top_link, menu_items } = rawData.all_header.items[0]
|
||||
.transform((data) => {
|
||||
const { top_link, menu_items } = data.all_header.items[0]
|
||||
|
||||
return {
|
||||
topLink: top_link,
|
||||
@@ -423,15 +425,78 @@ export const getHeaderSchema = z
|
||||
}
|
||||
})
|
||||
|
||||
export const getHeaderRefSchema = z.object({
|
||||
all_header: z.object({
|
||||
items: z.array(
|
||||
const linkConnectionRefs = z.object({
|
||||
edges: z
|
||||
.array(
|
||||
z.object({
|
||||
system: z.object({
|
||||
content_type_uid: z.string(),
|
||||
uid: z.string(),
|
||||
node: z.object({
|
||||
system: z.object({
|
||||
content_type_uid: z.string(),
|
||||
uid: z.string(),
|
||||
}),
|
||||
}),
|
||||
})
|
||||
),
|
||||
)
|
||||
.max(1),
|
||||
})
|
||||
|
||||
const cardConnectionRefs = z.object({
|
||||
primary_button: z
|
||||
.object({
|
||||
linkConnection: linkConnectionRefs,
|
||||
})
|
||||
.nullable(),
|
||||
secondary_button: z
|
||||
.object({
|
||||
linkConnection: linkConnectionRefs,
|
||||
})
|
||||
.nullable(),
|
||||
system: z.object({
|
||||
content_type_uid: z.string(),
|
||||
uid: z.string(),
|
||||
}),
|
||||
})
|
||||
|
||||
export const getHeaderRefSchema = z.object({
|
||||
all_header: z.object({
|
||||
items: z
|
||||
.array(
|
||||
z.object({
|
||||
top_link: z
|
||||
.object({
|
||||
linkConnection: linkConnectionRefs,
|
||||
})
|
||||
.nullable(),
|
||||
menu_items: z.array(
|
||||
z.object({
|
||||
linkConnection: linkConnectionRefs,
|
||||
see_all_link: z.object({
|
||||
linkConnection: linkConnectionRefs,
|
||||
}),
|
||||
cardConnection: z.object({
|
||||
edges: z
|
||||
.array(
|
||||
z.object({
|
||||
node: cardConnectionRefs,
|
||||
})
|
||||
)
|
||||
.max(1),
|
||||
}),
|
||||
submenu: z.array(
|
||||
z.object({
|
||||
links: z.array(
|
||||
z.object({ linkConnection: linkConnectionRefs })
|
||||
),
|
||||
})
|
||||
),
|
||||
})
|
||||
),
|
||||
system: z.object({
|
||||
content_type_uid: z.string(),
|
||||
uid: z.string(),
|
||||
}),
|
||||
})
|
||||
)
|
||||
.length(1),
|
||||
}),
|
||||
})
|
||||
|
||||
@@ -14,7 +14,11 @@ import { request } from "@/lib/graphql/request"
|
||||
import { notFound } from "@/server/errors/trpc"
|
||||
import { contentstackBaseProcedure, router } from "@/server/trpc"
|
||||
|
||||
import { generateRefsResponseTag, generateTag } from "@/utils/generateTag"
|
||||
import {
|
||||
generateRefsResponseTag,
|
||||
generateTag,
|
||||
generateTags,
|
||||
} from "@/utils/generateTag"
|
||||
|
||||
import { langInput } from "./input"
|
||||
import {
|
||||
@@ -24,11 +28,13 @@ import {
|
||||
CurrentHeaderRefDataRaw,
|
||||
FooterDataRaw,
|
||||
FooterRefDataRaw,
|
||||
getHeaderRefSchema,
|
||||
getHeaderSchema,
|
||||
validateContactConfigSchema,
|
||||
validateCurrentHeaderConfigSchema,
|
||||
validateFooterConfigSchema,
|
||||
} from "./output"
|
||||
import { getConnections } from "./utils"
|
||||
|
||||
import { HeaderRefResponse, HeaderResponse } from "@/types/header"
|
||||
|
||||
@@ -64,13 +70,13 @@ const getCurrentHeaderFailCounter = meter.createCounter(
|
||||
)
|
||||
|
||||
// OpenTelemetry metrics: Header
|
||||
const getHeaderRefCounter = meter.createCounter(
|
||||
const getHeaderRefsCounter = meter.createCounter(
|
||||
"trpc.contentstack.header.ref.get"
|
||||
)
|
||||
const getHeaderRefSuccessCounter = meter.createCounter(
|
||||
const getHeaderRefsSuccessCounter = meter.createCounter(
|
||||
"trpc.contentstack.header.ref.get-success"
|
||||
)
|
||||
const getHeaderRefFailCounter = meter.createCounter(
|
||||
const getHeaderRefsFailCounter = meter.createCounter(
|
||||
"trpc.contentstack.header.ref.get-fail"
|
||||
)
|
||||
const getHeaderCounter = meter.createCounter("trpc.contentstack.header.get")
|
||||
@@ -164,31 +170,90 @@ export const baseQueryRouter = router({
|
||||
}),
|
||||
header: contentstackBaseProcedure.query(async ({ ctx }) => {
|
||||
const { lang } = ctx
|
||||
getHeaderRefCounter.add(1, { lang })
|
||||
getHeaderRefsCounter.add(1, { lang })
|
||||
console.info(
|
||||
"contentstack.header.ref start",
|
||||
"contentstack.header.refs start",
|
||||
JSON.stringify({ query: { lang } })
|
||||
)
|
||||
|
||||
// TODO: Add better ref types and error handling for responseRef
|
||||
const responseRef = await request<HeaderRefResponse>(GetHeaderRef, {
|
||||
locale: lang,
|
||||
})
|
||||
const responseRef = await request<HeaderRefResponse>(
|
||||
GetHeaderRef,
|
||||
{
|
||||
locale: lang,
|
||||
},
|
||||
{
|
||||
cache: "force-cache",
|
||||
next: {
|
||||
tags: [generateRefsResponseTag(lang, "header")],
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
getCurrentHeaderCounter.add(1, { lang })
|
||||
if (!responseRef.data) {
|
||||
const notFoundError = notFound(responseRef)
|
||||
getHeaderRefsFailCounter.add(1, {
|
||||
lang,
|
||||
error_type: "not_found",
|
||||
error: JSON.stringify({ code: notFoundError.code }),
|
||||
})
|
||||
console.error(
|
||||
"contentstack.header.refs not found error",
|
||||
JSON.stringify({
|
||||
query: {
|
||||
lang,
|
||||
},
|
||||
error: { code: notFoundError.code },
|
||||
})
|
||||
)
|
||||
throw notFoundError
|
||||
}
|
||||
|
||||
const validatedHeaderRefs = getHeaderRefSchema.safeParse(responseRef.data)
|
||||
|
||||
if (!validatedHeaderRefs.success) {
|
||||
getHeaderRefsFailCounter.add(1, {
|
||||
lang,
|
||||
error_type: "validation_error",
|
||||
error: JSON.stringify(validatedHeaderRefs.error),
|
||||
})
|
||||
console.error(
|
||||
"contentstack.header.refs validation error",
|
||||
JSON.stringify({
|
||||
query: {
|
||||
lang,
|
||||
},
|
||||
error: validatedHeaderRefs.error,
|
||||
})
|
||||
)
|
||||
return null
|
||||
}
|
||||
|
||||
getHeaderRefsSuccessCounter.add(1, { lang })
|
||||
console.info(
|
||||
"contentstack.header.refs success",
|
||||
JSON.stringify({ query: { lang } })
|
||||
)
|
||||
|
||||
const connections = getConnections(validatedHeaderRefs.data)
|
||||
|
||||
getHeaderCounter.add(1, { lang })
|
||||
console.info(
|
||||
"contentstack.header start",
|
||||
JSON.stringify({ query: { lang } })
|
||||
)
|
||||
|
||||
const tags = [
|
||||
generateTags(lang, connections),
|
||||
generateTag(
|
||||
lang,
|
||||
validatedHeaderRefs.data.all_header.items[0].system.uid
|
||||
),
|
||||
].flat()
|
||||
|
||||
const response = await request<HeaderResponse>(
|
||||
GetHeader,
|
||||
{ locale: lang }
|
||||
// {
|
||||
// tags: [
|
||||
// generateTag(lang, responseRef.data.all_header.items[0].system.uid),
|
||||
// ],
|
||||
// }
|
||||
{ locale: lang },
|
||||
{ cache: "force-cache", next: { tags } }
|
||||
)
|
||||
|
||||
if (!response.data) {
|
||||
@@ -422,161 +487,3 @@ export const baseQueryRouter = router({
|
||||
return validatedFooterConfig.data.all_current_footer.items[0]
|
||||
}),
|
||||
})
|
||||
|
||||
const json = {
|
||||
query: { lang: "en" },
|
||||
error: {
|
||||
issues: [
|
||||
{
|
||||
code: "invalid_type",
|
||||
expected: "object",
|
||||
received: "undefined",
|
||||
path: ["all_header", "items", 0, "top_link", "link"],
|
||||
message: "Required",
|
||||
},
|
||||
{
|
||||
code: "invalid_type",
|
||||
expected: "object",
|
||||
received: "undefined",
|
||||
path: ["all_header", "items", 0, "menu_items", 0, "link"],
|
||||
message: "Required",
|
||||
},
|
||||
{
|
||||
code: "invalid_type",
|
||||
expected: "object",
|
||||
received: "undefined",
|
||||
path: [
|
||||
"all_header",
|
||||
"items",
|
||||
0,
|
||||
"menu_items",
|
||||
0,
|
||||
"submenu",
|
||||
0,
|
||||
"links",
|
||||
0,
|
||||
"link",
|
||||
],
|
||||
message: "Required",
|
||||
},
|
||||
{
|
||||
code: "invalid_type",
|
||||
expected: "object",
|
||||
received: "undefined",
|
||||
path: [
|
||||
"all_header",
|
||||
"items",
|
||||
0,
|
||||
"menu_items",
|
||||
0,
|
||||
"submenu",
|
||||
0,
|
||||
"links",
|
||||
1,
|
||||
"link",
|
||||
],
|
||||
message: "Required",
|
||||
},
|
||||
{
|
||||
code: "invalid_type",
|
||||
expected: "object",
|
||||
received: "undefined",
|
||||
path: [
|
||||
"all_header",
|
||||
"items",
|
||||
0,
|
||||
"menu_items",
|
||||
0,
|
||||
"submenu",
|
||||
1,
|
||||
"links",
|
||||
0,
|
||||
"link",
|
||||
],
|
||||
message: "Required",
|
||||
},
|
||||
{
|
||||
code: "invalid_type",
|
||||
expected: "object",
|
||||
received: "undefined",
|
||||
path: [
|
||||
"all_header",
|
||||
"items",
|
||||
0,
|
||||
"menu_items",
|
||||
0,
|
||||
"see_all_link",
|
||||
"link",
|
||||
],
|
||||
message: "Required",
|
||||
},
|
||||
{
|
||||
code: "invalid_type",
|
||||
expected: "object",
|
||||
received: "undefined",
|
||||
path: ["all_header", "items", 0, "menu_items", 1, "link"],
|
||||
message: "Required",
|
||||
},
|
||||
{
|
||||
code: "invalid_type",
|
||||
expected: "object",
|
||||
received: "undefined",
|
||||
path: [
|
||||
"all_header",
|
||||
"items",
|
||||
0,
|
||||
"menu_items",
|
||||
1,
|
||||
"see_all_link",
|
||||
"link",
|
||||
],
|
||||
message: "Required",
|
||||
},
|
||||
{
|
||||
code: "invalid_type",
|
||||
expected: "object",
|
||||
received: "undefined",
|
||||
path: ["all_header", "items", 0, "menu_items", 2, "link"],
|
||||
message: "Required",
|
||||
},
|
||||
{
|
||||
code: "invalid_type",
|
||||
expected: "object",
|
||||
received: "undefined",
|
||||
path: [
|
||||
"all_header",
|
||||
"items",
|
||||
0,
|
||||
"menu_items",
|
||||
2,
|
||||
"see_all_link",
|
||||
"link",
|
||||
],
|
||||
message: "Required",
|
||||
},
|
||||
{
|
||||
code: "invalid_type",
|
||||
expected: "object",
|
||||
received: "undefined",
|
||||
path: ["all_header", "items", 0, "menu_items", 3, "link"],
|
||||
message: "Required",
|
||||
},
|
||||
{
|
||||
code: "invalid_type",
|
||||
expected: "object",
|
||||
received: "undefined",
|
||||
path: [
|
||||
"all_header",
|
||||
"items",
|
||||
0,
|
||||
"menu_items",
|
||||
3,
|
||||
"see_all_link",
|
||||
"link",
|
||||
],
|
||||
message: "Required",
|
||||
},
|
||||
],
|
||||
name: "ZodError",
|
||||
},
|
||||
}
|
||||
|
||||
40
server/routers/contentstack/base/utils.ts
Normal file
40
server/routers/contentstack/base/utils.ts
Normal file
@@ -0,0 +1,40 @@
|
||||
import { HeaderRefResponse } from "@/types/header"
|
||||
import { Edges } from "@/types/requests/utils/edges"
|
||||
import { NodeRefs } from "@/types/requests/utils/refs"
|
||||
|
||||
export function getConnections(refs: HeaderRefResponse) {
|
||||
const connections: Edges<NodeRefs>[] = []
|
||||
const headerData = refs.all_header.items[0]
|
||||
const topLink = headerData.top_link
|
||||
if (topLink) {
|
||||
connections.push(topLink.linkConnection)
|
||||
}
|
||||
|
||||
headerData.menu_items.forEach(
|
||||
({ linkConnection, see_all_link, cardConnection, submenu }) => {
|
||||
const card = cardConnection.edges[0]?.node
|
||||
connections.push(linkConnection)
|
||||
|
||||
if (see_all_link) {
|
||||
connections.push(see_all_link.linkConnection)
|
||||
}
|
||||
|
||||
if (card) {
|
||||
if (card.primary_button) {
|
||||
connections.push(card.primary_button.linkConnection)
|
||||
}
|
||||
if (card.secondary_button) {
|
||||
connections.push(card.secondary_button.linkConnection)
|
||||
}
|
||||
}
|
||||
|
||||
submenu.forEach(({ links }) => {
|
||||
links.forEach(({ linkConnection }) => {
|
||||
connections.push(linkConnection)
|
||||
})
|
||||
})
|
||||
}
|
||||
)
|
||||
|
||||
return connections
|
||||
}
|
||||
Reference in New Issue
Block a user