fix: trpc endpoint for footer data

This commit is contained in:
Christel Westerberg
2024-05-30 14:25:11 +02:00
parent fbb29c93c9
commit 2c102c62e0
16 changed files with 154 additions and 90 deletions

View File

@@ -53,7 +53,7 @@ export default async function RootLayout({
<TrpcProvider lang={params.lang}> <TrpcProvider lang={params.lang}>
<Header lang={params.lang} languageSwitcher={languageSwitcher} /> <Header lang={params.lang} languageSwitcher={languageSwitcher} />
{children} {children}
<Footer lang={params.lang} /> <Footer />
</TrpcProvider> </TrpcProvider>
<Script id="page-tracking">{` <Script id="page-tracking">{`
typeof _satellite !== "undefined" && _satellite.pageBottom(); typeof _satellite !== "undefined" && _satellite.pageBottom();

View File

@@ -81,7 +81,7 @@ export default function RootLayout({
<SkipToMainContent lang={params.lang} /> <SkipToMainContent lang={params.lang} />
<Header lang={params.lang} languageSwitcher={languageSwitcher} /> <Header lang={params.lang} languageSwitcher={languageSwitcher} />
{children} {children}
<Footer lang={params.lang} /> <Footer />
<Script id="page-tracking">{` <Script id="page-tracking">{`
typeof _satellite !== "undefined" && _satellite.pageBottom(); typeof _satellite !== "undefined" && _satellite.pageBottom();
`}</Script> `}</Script>

View File

@@ -53,7 +53,7 @@ export default function RootLayout({
<LangPopup lang={params.lang} /> <LangPopup lang={params.lang} />
<SkipToMainContent lang={params.lang} /> <SkipToMainContent lang={params.lang} />
{children} {children}
<Footer lang={params.lang} /> <Footer />
</body> </body>
</html> </html>
) )

View File

@@ -34,19 +34,19 @@
text-align: center; text-align: center;
color: #fff; color: #fff;
font-family: BrandonText-Bold, Arial, Helvetica, sans-serif; font-family: BrandonText-Bold, Arial, Helvetica, sans-serif;
font-size: 1.375rem; font-size: 22px;
line-height: 1.1em; line-height: 17.6px;
text-transform: uppercase; text-transform: uppercase;
font-weight: 400; font-weight: 400;
color: #483729; color: #483729;
margin-bottom: 1rem; margin-bottom: 16px;
margin-top: 0; margin-top: 0;
} }
.hiddenAccessible { .hiddenAccessible {
display: block; display: block;
position: absolute; position: absolute;
left: -100000em; left: -100000px;
top: auto; top: auto;
width: 1px; width: 1px;
height: 1px; height: 1px;
@@ -81,7 +81,7 @@
} }
.contentBottomTitle { .contentBottomTitle {
margin-bottom: 16px; margin: 16px 0;
font-weight: 700; font-weight: 700;
font-size: 16px; font-size: 16px;
line-height: 22.4px; line-height: 22.4px;
@@ -109,6 +109,7 @@
.tableData { .tableData {
width: 50px; width: 50px;
height: 62px; height: 62px;
padding: 1px;
} }
.sectionContainer { .sectionContainer {
@@ -124,7 +125,8 @@
line-height: normal; line-height: normal;
font-size: 16px; font-size: 16px;
font-weight: 700; font-weight: 700;
margin-bottom: 16px; margin: 16px 0;
color: #fff;
} }
.socialMediaIconsContainer { .socialMediaIconsContainer {

View File

@@ -1,7 +1,4 @@
import Script from "next/script" import { serverClient } from "@/lib/trpc/server"
import { GetFooter } from "@/lib/graphql/Query/Footer.graphql"
import { request } from "@/lib/graphql/request"
import Image from "@/components/Image" import Image from "@/components/Image"
@@ -10,24 +7,9 @@ import Navigation from "./Navigation"
import styles from "./footer.module.css" import styles from "./footer.module.css"
import type { LangParams } from "@/types/params" import type { LangParams } from "@/types/params"
import type { GetFooterData } from "@/types/requests/footer"
export default async function Footer({ lang }: LangParams) { export default async function Footer() {
const { data } = await request<GetFooterData>( const footerData = await serverClient().contentstack.config.footer()
GetFooter,
{
locale: lang,
},
{
next: { tags: [`footer-${lang}`] },
}
)
if (!data.all_footer.items.length) {
return null
}
const footerData = data.all_footer.items[0]
return ( return (
<footer className={styles.container}> <footer className={styles.container}>
<div className={styles.content}> <div className={styles.content}>

View File

@@ -19,6 +19,7 @@
} }
.linkListTitle { .linkListTitle {
color: #fff;
font-family: font-family:
Helvetica Neue, Helvetica Neue,
Roboto, Roboto,

View File

@@ -1,6 +1,6 @@
#import "../Image.graphql" #import "../Image.graphql"
fragment AppDownloads on Footer { fragment AppDownloads on CurrentFooter {
app_downloads { app_downloads {
title title
app_store { app_store {

View File

@@ -1,6 +1,6 @@
#import "../Image.graphql" #import "../Image.graphql"
fragment Logo on Footer { fragment Logo on CurrentFooter {
logoConnection { logoConnection {
edges { edges {
node { node {

View File

@@ -1,4 +1,4 @@
fragment Navigation on Footer { fragment Navigation on CurrentFooter {
navigation { navigation {
links { links {
href href

View File

@@ -1,4 +1,4 @@
fragment SocialMedia on Footer { fragment SocialMedia on CurrentFooter {
social_media { social_media {
title title
facebook { facebook {

View File

@@ -1,6 +1,6 @@
#import "../Image.graphql" #import "../Image.graphql"
fragment TripAdvisor on Footer { fragment TripAdvisor on CurrentFooter {
trip_advisor { trip_advisor {
logoConnection { logoConnection {
edges { edges {

View File

@@ -4,8 +4,8 @@
#import "../Fragments/Footer/SocialMedia.graphql" #import "../Fragments/Footer/SocialMedia.graphql"
#import "../Fragments/Footer/TripAdvisor.graphql" #import "../Fragments/Footer/TripAdvisor.graphql"
query GetFooter($locale: String!) { query GetCurrentFooter($locale: String!) {
all_footer(limit: 1, locale: $locale) { all_current_footer(limit: 1, locale: $locale) {
items { items {
title title
system { system {

View File

@@ -132,4 +132,111 @@ const validateHeaderRefConfigSchema = z.object({
}), }),
}) })
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(),
}),
})
),
}),
})
export type HeaderRefDataRaw = z.infer<typeof validateHeaderRefConfigSchema> export type HeaderRefDataRaw = z.infer<typeof validateHeaderRefConfigSchema>
const validateNavigationItem = z.object({
links: z.array(z.object({ href: z.string(), title: z.string() })),
title: z.string(),
})
export type NavigationItem = z.infer<typeof validateNavigationItem>
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<typeof validateFooterConfigSchema>
export type FooterData = Omit<
FooterDataRaw["all_current_footer"]["items"][0],
"logoConnection"
> & {
logo: Image
}

View File

@@ -1,4 +1,5 @@
import { GetContactConfig } from "@/lib/graphql/Query/ContactConfig.graphql" import { GetContactConfig } from "@/lib/graphql/Query/ContactConfig.graphql"
import { GetCurrentFooter } from "@/lib/graphql/Query/CurrentFooter.graphql"
import { import {
GetCurrentHeader, GetCurrentHeader,
GetCurrentHeaderRef, GetCurrentHeaderRef,
@@ -11,10 +12,12 @@ import { generateTag } from "@/utils/generateTag"
import { import {
type ContactConfigData, type ContactConfigData,
FooterDataRaw,
HeaderData, HeaderData,
HeaderDataRaw, HeaderDataRaw,
HeaderRefDataRaw, HeaderRefDataRaw,
validateContactConfigSchema, validateContactConfigSchema,
validateFooterConfigSchema,
validateHeaderConfigSchema, validateHeaderConfigSchema,
} from "./output" } from "./output"
@@ -81,4 +84,25 @@ export const configQueryRouter = router({
logo, logo,
} as HeaderData } as HeaderData
}), }),
footer: contentstackProcedure.query(async ({ ctx }) => {
const response = await request<FooterDataRaw>(
GetCurrentFooter,
{
locale: ctx.lang,
},
{
next: { tags: [`footer-${ctx.lang}`] },
}
)
const validatedFooterConfig = validateFooterConfigSchema.safeParse(
response.data
)
if (!validatedFooterConfig.success) {
throw internalServerError(validatedFooterConfig.error)
}
return validatedFooterConfig.data.all_current_footer.items[0]
}),
}) })

View File

@@ -1,4 +1,4 @@
import type { NavigationItem } from "@/types/requests/footer" import { NavigationItem } from "@/server/routers/contentstack/config/output"
export type FooterNavigationProps = { export type FooterNavigationProps = {
linkGroups: NavigationItem[] linkGroups: NavigationItem[]

View File

@@ -1,52 +0,0 @@
import type { Image } from "../image"
import type { AllRequestResponse } from "./utils/all"
import type { EdgesWithTotalCount } from "./utils/edges"
type AppDownload = {
href: string
imageConnection: EdgesWithTotalCount<Image>
}
export type Link = {
href: string
title: string
}
export type NavigationItem = {
links: Link[]
title: string
}
type SocialMedium = {
href: string
title: string
}
export type Footer = {
title: string
about: {
title: string
text: string
}
app_downloads: {
title: string
app_store: AppDownload
google_play: AppDownload
}
logoConnection: EdgesWithTotalCount<Image>
navigation: NavigationItem[]
social_media: {
title: string
facebook: SocialMedium
instagram: SocialMedium
twitter: SocialMedium
}
trip_advisor: {
title: string
logoConnection: EdgesWithTotalCount<Image>
}
}
export type GetFooterData = {
all_footer: AllRequestResponse<Footer>
}