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) {
|
export default function MenuItem({ item, isMobile }: NavigationMenuItemProps) {
|
||||||
const { submenu, title, link, seeAllLink, card } = item
|
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() {
|
function handleButtonClick() {
|
||||||
setIsExpanded((prev) => !prev)
|
setIsExpanded((prev) => !prev)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!submenu.length && !link) {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
return submenu.length ? (
|
return submenu.length ? (
|
||||||
<MainMenuButton
|
<MainMenuButton
|
||||||
onClick={handleButtonClick}
|
onClick={handleButtonClick}
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ export default async function MainMenu({
|
|||||||
/>
|
/>
|
||||||
</NextLink>
|
</NextLink>
|
||||||
<div className={styles.menus}>
|
<div className={styles.menus}>
|
||||||
{menuItems ? (
|
{menuItems?.length ? (
|
||||||
<NavigationMenu items={menuItems} isMobile={false} />
|
<NavigationMenu items={menuItems} isMobile={false} />
|
||||||
) : null}
|
) : null}
|
||||||
{user ? (
|
{user ? (
|
||||||
@@ -74,7 +74,7 @@ export default async function MainMenu({
|
|||||||
</span>
|
</span>
|
||||||
</Link>
|
</Link>
|
||||||
)}
|
)}
|
||||||
{menuItems ? (
|
{menuItems?.length ? (
|
||||||
<MobileMenu languageUrls={languageUrls} menuItems={menuItems} />
|
<MobileMenu languageUrls={languageUrls} menuItems={menuItems} />
|
||||||
) : null}
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
@@ -82,26 +82,3 @@ export default async function MainMenu({
|
|||||||
</div>
|
</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 {
|
.topMenu {
|
||||||
display: none;
|
display: none;
|
||||||
background-color: var(--Base-Surface-Subtle-Normal);
|
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);
|
border-bottom: 1px solid var(--Base-Border-Subtle);
|
||||||
}
|
}
|
||||||
|
|
||||||
.content {
|
.content {
|
||||||
max-width: var(--max-width-navigation);
|
max-width: var(--max-width-navigation);
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
display: grid;
|
|
||||||
justify-content: space-between;
|
|
||||||
gap: var(--Spacing-x3);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.options {
|
.options {
|
||||||
@@ -24,7 +21,10 @@
|
|||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
.content {
|
.content {
|
||||||
|
display: grid;
|
||||||
grid-template-areas: "topLink options";
|
grid-template-areas: "topLink options";
|
||||||
|
justify-content: space-between;
|
||||||
|
gap: var(--Spacing-x3);
|
||||||
}
|
}
|
||||||
|
|
||||||
.topLink {
|
.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
|
title
|
||||||
url
|
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/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/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/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!) {
|
query GetHeader($locale: String!) {
|
||||||
all_header(limit: 1, locale: $locale) {
|
all_header(limit: 1, locale: $locale) {
|
||||||
items {
|
items {
|
||||||
@@ -15,6 +21,7 @@ query GetHeader($locale: String!) {
|
|||||||
edges {
|
edges {
|
||||||
node {
|
node {
|
||||||
...ContentPageLink
|
...ContentPageLink
|
||||||
|
...HotelPageLink
|
||||||
...LoyaltyPageLink
|
...LoyaltyPageLink
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -26,6 +33,7 @@ query GetHeader($locale: String!) {
|
|||||||
edges {
|
edges {
|
||||||
node {
|
node {
|
||||||
...ContentPageLink
|
...ContentPageLink
|
||||||
|
...HotelPageLink
|
||||||
...LoyaltyPageLink
|
...LoyaltyPageLink
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -36,6 +44,7 @@ query GetHeader($locale: String!) {
|
|||||||
edges {
|
edges {
|
||||||
node {
|
node {
|
||||||
...ContentPageLink
|
...ContentPageLink
|
||||||
|
...HotelPageLink
|
||||||
...LoyaltyPageLink
|
...LoyaltyPageLink
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -49,6 +58,7 @@ query GetHeader($locale: String!) {
|
|||||||
edges {
|
edges {
|
||||||
node {
|
node {
|
||||||
...ContentPageLink
|
...ContentPageLink
|
||||||
|
...HotelPageLink
|
||||||
...LoyaltyPageLink
|
...LoyaltyPageLink
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -70,6 +80,59 @@ query GetHeader($locale: String!) {
|
|||||||
query GetHeaderRef($locale: String!) {
|
query GetHeaderRef($locale: String!) {
|
||||||
all_header(limit: 1, locale: $locale) {
|
all_header(limit: 1, locale: $locale) {
|
||||||
items {
|
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 {
|
||||||
...System
|
...System
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -268,24 +268,26 @@ export type FooterRefDataRaw = z.infer<typeof validateFooterRefConfigSchema>
|
|||||||
|
|
||||||
const linkConnectionNodeSchema = z
|
const linkConnectionNodeSchema = z
|
||||||
.object({
|
.object({
|
||||||
edges: z.array(
|
edges: z
|
||||||
z.object({
|
.array(
|
||||||
node: z.object({
|
z.object({
|
||||||
system: z.object({
|
node: z.object({
|
||||||
uid: z.string(),
|
system: z.object({
|
||||||
locale: z.nativeEnum(Lang),
|
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({
|
.max(1),
|
||||||
original_url: z.string().nullable().optional(),
|
|
||||||
}),
|
|
||||||
}),
|
|
||||||
})
|
|
||||||
),
|
|
||||||
})
|
})
|
||||||
.transform((rawData) => {
|
.transform((data) => {
|
||||||
const node = rawData.edges[0]?.node
|
const node = data.edges[0]?.node
|
||||||
if (!node) {
|
if (!node) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
@@ -301,15 +303,14 @@ const linkConnectionNodeSchema = z
|
|||||||
|
|
||||||
const linkWithTitleSchema = z
|
const linkWithTitleSchema = z
|
||||||
.object({
|
.object({
|
||||||
title: z.string().nullable(),
|
title: z.string(),
|
||||||
linkConnection: linkConnectionNodeSchema,
|
linkConnection: linkConnectionNodeSchema,
|
||||||
})
|
})
|
||||||
.transform((rawData) => {
|
.transform((rawData) => {
|
||||||
return rawData.linkConnection && rawData.title
|
return rawData.linkConnection && rawData.title
|
||||||
? {
|
? {
|
||||||
|
...rawData.linkConnection,
|
||||||
title: rawData.title,
|
title: rawData.title,
|
||||||
href: rawData.linkConnection.href,
|
|
||||||
isExternal: rawData.linkConnection.isExternal,
|
|
||||||
}
|
}
|
||||||
: null
|
: null
|
||||||
})
|
})
|
||||||
@@ -325,21 +326,18 @@ const cardButtonSchema = z
|
|||||||
linkConnection: linkConnectionNodeSchema,
|
linkConnection: linkConnectionNodeSchema,
|
||||||
open_in_new_tab: z.boolean(),
|
open_in_new_tab: z.boolean(),
|
||||||
})
|
})
|
||||||
.transform((rawData) => {
|
.transform((data) => {
|
||||||
if (!rawData) {
|
const linkConnectionData = data.linkConnection
|
||||||
return null
|
const isContentstackLink = data.is_contentstack_link
|
||||||
}
|
const externalLink = data.external_link
|
||||||
const linkConnectionData = rawData.linkConnection
|
|
||||||
const isContentstackLink = rawData.is_contentstack_link
|
|
||||||
const externalLink = rawData.external_link
|
|
||||||
const href =
|
const href =
|
||||||
isContentstackLink && externalLink.href
|
isContentstackLink && externalLink.href
|
||||||
? externalLink.href
|
? externalLink.href
|
||||||
: linkConnectionData?.href || ""
|
: linkConnectionData?.href || ""
|
||||||
|
|
||||||
return {
|
return {
|
||||||
openInNewTab: rawData.open_in_new_tab,
|
openInNewTab: data.open_in_new_tab,
|
||||||
title: rawData.cta_text,
|
title: data.cta_text,
|
||||||
href,
|
href,
|
||||||
isExternal: !isContentstackLink || linkConnectionData?.isExternal,
|
isExternal: !isContentstackLink || linkConnectionData?.isExternal,
|
||||||
}
|
}
|
||||||
@@ -347,23 +345,25 @@ const cardButtonSchema = z
|
|||||||
|
|
||||||
const cardConnectionSchema = z
|
const cardConnectionSchema = z
|
||||||
.object({
|
.object({
|
||||||
edges: z.array(
|
edges: z
|
||||||
z.object({
|
.array(
|
||||||
node: z.object({
|
z.object({
|
||||||
heading: z.string(),
|
node: z.object({
|
||||||
body_text: z.string(),
|
heading: z.string(),
|
||||||
background_image: imageVaultAssetTransformedSchema,
|
body_text: z.string(),
|
||||||
has_primary_button: z.boolean(),
|
background_image: imageVaultAssetTransformedSchema,
|
||||||
has_secondary_button: z.boolean(),
|
has_primary_button: z.boolean(),
|
||||||
scripted_top_title: z.string(),
|
has_secondary_button: z.boolean(),
|
||||||
primary_button: cardButtonSchema,
|
scripted_top_title: z.string(),
|
||||||
secondary_button: cardButtonSchema,
|
primary_button: cardButtonSchema.nullable(),
|
||||||
}),
|
secondary_button: cardButtonSchema.nullable(),
|
||||||
})
|
}),
|
||||||
),
|
})
|
||||||
|
)
|
||||||
|
.max(1),
|
||||||
})
|
})
|
||||||
.transform((rawData) => {
|
.transform((data) => {
|
||||||
const node = rawData.edges[0]?.node
|
const node = data.edges[0]?.node
|
||||||
if (!node) {
|
if (!node) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
@@ -391,31 +391,33 @@ export const menuItemSchema = z
|
|||||||
see_all_link: linkWithTitleSchema,
|
see_all_link: linkWithTitleSchema,
|
||||||
cardConnection: cardConnectionSchema,
|
cardConnection: cardConnectionSchema,
|
||||||
})
|
})
|
||||||
.transform(
|
.transform((data) => {
|
||||||
({ submenu, linkConnection, cardConnection, see_all_link, title }) => {
|
const { submenu, linkConnection, cardConnection, see_all_link, title } =
|
||||||
return {
|
data
|
||||||
title,
|
return {
|
||||||
link: submenu.length ? null : linkConnection,
|
title,
|
||||||
seeAllLink: submenu.length ? see_all_link : null,
|
link: submenu.length ? null : linkConnection,
|
||||||
submenu,
|
seeAllLink: submenu.length ? see_all_link : null,
|
||||||
card: cardConnection,
|
submenu,
|
||||||
}
|
card: cardConnection,
|
||||||
}
|
}
|
||||||
)
|
})
|
||||||
|
|
||||||
export const getHeaderSchema = z
|
export const getHeaderSchema = z
|
||||||
.object({
|
.object({
|
||||||
all_header: z.object({
|
all_header: z.object({
|
||||||
items: z.array(
|
items: z
|
||||||
z.object({
|
.array(
|
||||||
top_link: linkWithTitleSchema.nullable(),
|
z.object({
|
||||||
menu_items: z.array(menuItemSchema).nullable(),
|
top_link: linkWithTitleSchema,
|
||||||
})
|
menu_items: z.array(menuItemSchema),
|
||||||
),
|
})
|
||||||
|
)
|
||||||
|
.length(1),
|
||||||
}),
|
}),
|
||||||
})
|
})
|
||||||
.transform((rawData) => {
|
.transform((data) => {
|
||||||
const { top_link, menu_items } = rawData.all_header.items[0]
|
const { top_link, menu_items } = data.all_header.items[0]
|
||||||
|
|
||||||
return {
|
return {
|
||||||
topLink: top_link,
|
topLink: top_link,
|
||||||
@@ -423,15 +425,78 @@ export const getHeaderSchema = z
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
export const getHeaderRefSchema = z.object({
|
const linkConnectionRefs = z.object({
|
||||||
all_header: z.object({
|
edges: z
|
||||||
items: z.array(
|
.array(
|
||||||
z.object({
|
z.object({
|
||||||
system: z.object({
|
node: z.object({
|
||||||
content_type_uid: z.string(),
|
system: z.object({
|
||||||
uid: z.string(),
|
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 { notFound } from "@/server/errors/trpc"
|
||||||
import { contentstackBaseProcedure, router } from "@/server/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 { langInput } from "./input"
|
||||||
import {
|
import {
|
||||||
@@ -24,11 +28,13 @@ import {
|
|||||||
CurrentHeaderRefDataRaw,
|
CurrentHeaderRefDataRaw,
|
||||||
FooterDataRaw,
|
FooterDataRaw,
|
||||||
FooterRefDataRaw,
|
FooterRefDataRaw,
|
||||||
|
getHeaderRefSchema,
|
||||||
getHeaderSchema,
|
getHeaderSchema,
|
||||||
validateContactConfigSchema,
|
validateContactConfigSchema,
|
||||||
validateCurrentHeaderConfigSchema,
|
validateCurrentHeaderConfigSchema,
|
||||||
validateFooterConfigSchema,
|
validateFooterConfigSchema,
|
||||||
} from "./output"
|
} from "./output"
|
||||||
|
import { getConnections } from "./utils"
|
||||||
|
|
||||||
import { HeaderRefResponse, HeaderResponse } from "@/types/header"
|
import { HeaderRefResponse, HeaderResponse } from "@/types/header"
|
||||||
|
|
||||||
@@ -64,13 +70,13 @@ const getCurrentHeaderFailCounter = meter.createCounter(
|
|||||||
)
|
)
|
||||||
|
|
||||||
// OpenTelemetry metrics: Header
|
// OpenTelemetry metrics: Header
|
||||||
const getHeaderRefCounter = meter.createCounter(
|
const getHeaderRefsCounter = meter.createCounter(
|
||||||
"trpc.contentstack.header.ref.get"
|
"trpc.contentstack.header.ref.get"
|
||||||
)
|
)
|
||||||
const getHeaderRefSuccessCounter = meter.createCounter(
|
const getHeaderRefsSuccessCounter = meter.createCounter(
|
||||||
"trpc.contentstack.header.ref.get-success"
|
"trpc.contentstack.header.ref.get-success"
|
||||||
)
|
)
|
||||||
const getHeaderRefFailCounter = meter.createCounter(
|
const getHeaderRefsFailCounter = meter.createCounter(
|
||||||
"trpc.contentstack.header.ref.get-fail"
|
"trpc.contentstack.header.ref.get-fail"
|
||||||
)
|
)
|
||||||
const getHeaderCounter = meter.createCounter("trpc.contentstack.header.get")
|
const getHeaderCounter = meter.createCounter("trpc.contentstack.header.get")
|
||||||
@@ -164,31 +170,90 @@ export const baseQueryRouter = router({
|
|||||||
}),
|
}),
|
||||||
header: contentstackBaseProcedure.query(async ({ ctx }) => {
|
header: contentstackBaseProcedure.query(async ({ ctx }) => {
|
||||||
const { lang } = ctx
|
const { lang } = ctx
|
||||||
getHeaderRefCounter.add(1, { lang })
|
getHeaderRefsCounter.add(1, { lang })
|
||||||
console.info(
|
console.info(
|
||||||
"contentstack.header.ref start",
|
"contentstack.header.refs start",
|
||||||
JSON.stringify({ query: { lang } })
|
JSON.stringify({ query: { lang } })
|
||||||
)
|
)
|
||||||
|
|
||||||
// TODO: Add better ref types and error handling for responseRef
|
const responseRef = await request<HeaderRefResponse>(
|
||||||
const responseRef = await request<HeaderRefResponse>(GetHeaderRef, {
|
GetHeaderRef,
|
||||||
locale: lang,
|
{
|
||||||
})
|
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(
|
console.info(
|
||||||
"contentstack.header start",
|
"contentstack.header start",
|
||||||
JSON.stringify({ query: { lang } })
|
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>(
|
const response = await request<HeaderResponse>(
|
||||||
GetHeader,
|
GetHeader,
|
||||||
{ locale: lang }
|
{ locale: lang },
|
||||||
// {
|
{ cache: "force-cache", next: { tags } }
|
||||||
// tags: [
|
|
||||||
// generateTag(lang, responseRef.data.all_header.items[0].system.uid),
|
|
||||||
// ],
|
|
||||||
// }
|
|
||||||
)
|
)
|
||||||
|
|
||||||
if (!response.data) {
|
if (!response.data) {
|
||||||
@@ -422,161 +487,3 @@ export const baseQueryRouter = router({
|
|||||||
return validatedFooterConfig.data.all_current_footer.items[0]
|
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