feat(SW-2264): Added campaign overview page
Approved-by: Matilda Landström
This commit is contained in:
@@ -9,6 +9,10 @@ import {
|
||||
GetMyPagesBreadcrumbs,
|
||||
GetMyPagesBreadcrumbsRefs,
|
||||
} from "@/lib/graphql/Query/Breadcrumbs/AccountPage.graphql"
|
||||
import {
|
||||
GetCampaignOverviewPageBreadcrumbs,
|
||||
GetCampaignOverviewPageBreadcrumbsRefs,
|
||||
} from "@/lib/graphql/Query/Breadcrumbs/CampaignOverviewPage.graphql"
|
||||
import {
|
||||
GetCampaignPageBreadcrumbs,
|
||||
GetCampaignPageBreadcrumbsRefs,
|
||||
@@ -158,6 +162,17 @@ export const breadcrumbsQueryRouter = router({
|
||||
},
|
||||
variables
|
||||
)
|
||||
case PageContentTypeEnum.campaignOverviewPage:
|
||||
return await getBreadcrumbs<{
|
||||
campaign_overview_page: RawBreadcrumbsSchema
|
||||
}>(
|
||||
{
|
||||
dataKey: "campaign_overview_page",
|
||||
refQuery: GetCampaignOverviewPageBreadcrumbsRefs,
|
||||
query: GetCampaignOverviewPageBreadcrumbs,
|
||||
},
|
||||
variables
|
||||
)
|
||||
case PageContentTypeEnum.campaignPage:
|
||||
return await getBreadcrumbs<{
|
||||
campaign_page: RawBreadcrumbsSchema
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
import { mergeRouters } from "@scandic-hotels/trpc"
|
||||
|
||||
import { campaignOverviewPageQueryRouter } from "./query"
|
||||
|
||||
export const campaignOverviewPageRouter = mergeRouters(
|
||||
campaignOverviewPageQueryRouter
|
||||
)
|
||||
@@ -0,0 +1,57 @@
|
||||
import { z } from "zod"
|
||||
|
||||
import {
|
||||
linkAndTitleSchema,
|
||||
linkConnectionRefs,
|
||||
} from "@/server/routers/contentstack/schemas/linkConnection"
|
||||
|
||||
import { systemSchema } from "../schemas/system"
|
||||
|
||||
const navigationLinksSchema = z
|
||||
.array(linkAndTitleSchema)
|
||||
.nullable()
|
||||
.transform((data) => {
|
||||
if (!data) {
|
||||
return null
|
||||
}
|
||||
|
||||
return data
|
||||
.filter((item) => !!item.link)
|
||||
.map((item) => ({
|
||||
url: item.link!.url,
|
||||
title: item.title || item.link!.title,
|
||||
}))
|
||||
})
|
||||
|
||||
export const campaignOverviewPageSchema = z.object({
|
||||
campaign_overview_page: z.object({
|
||||
title: z.string(),
|
||||
header: z.object({
|
||||
heading: z.string(),
|
||||
preamble: z.string(),
|
||||
navigation_links: navigationLinksSchema,
|
||||
}),
|
||||
system: systemSchema.merge(
|
||||
z.object({
|
||||
created_at: z.string(),
|
||||
updated_at: z.string(),
|
||||
})
|
||||
),
|
||||
}),
|
||||
trackingProps: z.object({
|
||||
url: z.string(),
|
||||
}),
|
||||
})
|
||||
|
||||
/** REFS */
|
||||
|
||||
const campaignOverviewPageHeaderRefs = z.object({
|
||||
navigation_links: z.array(linkConnectionRefs),
|
||||
})
|
||||
|
||||
export const campaignOverviewPageRefsSchema = z.object({
|
||||
campaign_overview_page: z.object({
|
||||
header: campaignOverviewPageHeaderRefs,
|
||||
system: systemSchema,
|
||||
}),
|
||||
})
|
||||
@@ -0,0 +1,135 @@
|
||||
import { createCounter } from "@scandic-hotels/common/telemetry"
|
||||
import { router } from "@scandic-hotels/trpc"
|
||||
import { notFound } from "@scandic-hotels/trpc/errors"
|
||||
import { contentStackUidWithServiceProcedure } from "@scandic-hotels/trpc/procedures"
|
||||
|
||||
import {
|
||||
GetCampaignOverviewPage,
|
||||
GetCampaignOverviewPageRefs,
|
||||
} from "@/lib/graphql/Query/CampaignOverviewPage/CampaignOverviewPage.graphql"
|
||||
import { request } from "@/lib/graphql/request"
|
||||
|
||||
import { generateRefsResponseTag } from "@/utils/generateTag"
|
||||
|
||||
import {
|
||||
campaignOverviewPageRefsSchema,
|
||||
campaignOverviewPageSchema,
|
||||
} from "./output"
|
||||
import { generatePageTags } from "./utils"
|
||||
|
||||
import {
|
||||
TrackingChannelEnum,
|
||||
type TrackingSDKPageData,
|
||||
} from "@/types/components/tracking"
|
||||
import type {
|
||||
GetCampaignOverviewPageData,
|
||||
GetCampaignOverviewPageRefsData,
|
||||
} from "@/types/trpc/routers/contentstack/campaignOverviewPage"
|
||||
|
||||
export const campaignOverviewPageQueryRouter = router({
|
||||
get: contentStackUidWithServiceProcedure.query(async ({ ctx }) => {
|
||||
const { lang, uid } = ctx
|
||||
|
||||
const getCampaignOverviewPageRefsCounter = createCounter(
|
||||
"trpc.contentstack",
|
||||
"campaignOverviewPage.get.refs"
|
||||
)
|
||||
const metricsGetCampaignOverviewPageRefs =
|
||||
getCampaignOverviewPageRefsCounter.init({
|
||||
lang,
|
||||
uid,
|
||||
})
|
||||
|
||||
metricsGetCampaignOverviewPageRefs.start()
|
||||
|
||||
const refsResponse = await request<GetCampaignOverviewPageRefsData>(
|
||||
GetCampaignOverviewPageRefs,
|
||||
{ locale: lang, uid },
|
||||
{
|
||||
key: generateRefsResponseTag(lang, uid),
|
||||
ttl: "max",
|
||||
}
|
||||
)
|
||||
|
||||
if (!refsResponse.data) {
|
||||
const notFoundError = notFound(refsResponse)
|
||||
metricsGetCampaignOverviewPageRefs.noDataError()
|
||||
throw notFoundError
|
||||
}
|
||||
|
||||
const validatedRefsData = campaignOverviewPageRefsSchema.safeParse(
|
||||
refsResponse.data
|
||||
)
|
||||
if (!validatedRefsData.success) {
|
||||
metricsGetCampaignOverviewPageRefs.validationError(
|
||||
validatedRefsData.error
|
||||
)
|
||||
return null
|
||||
}
|
||||
|
||||
metricsGetCampaignOverviewPageRefs.success()
|
||||
|
||||
const tags = generatePageTags(validatedRefsData.data, lang)
|
||||
|
||||
const getCampaignOverviewPageCounter = createCounter(
|
||||
"trpc.contentstack",
|
||||
"campaignOverviewPage.get"
|
||||
)
|
||||
const metricsGetCampaignOverviewPage = getCampaignOverviewPageCounter.init({
|
||||
lang,
|
||||
uid,
|
||||
})
|
||||
|
||||
metricsGetCampaignOverviewPage.start()
|
||||
|
||||
const response = await request<GetCampaignOverviewPageData>(
|
||||
GetCampaignOverviewPage,
|
||||
{
|
||||
locale: lang,
|
||||
uid,
|
||||
},
|
||||
{
|
||||
key: tags,
|
||||
ttl: "max",
|
||||
}
|
||||
)
|
||||
if (!response.data) {
|
||||
const notFoundError = notFound(response)
|
||||
metricsGetCampaignOverviewPage.noDataError()
|
||||
throw notFoundError
|
||||
}
|
||||
|
||||
const validatedResponse = campaignOverviewPageSchema.safeParse(
|
||||
response.data
|
||||
)
|
||||
|
||||
if (!validatedResponse.success) {
|
||||
metricsGetCampaignOverviewPage.validationError(validatedResponse.error)
|
||||
return null
|
||||
}
|
||||
|
||||
const campaignOverviewPage = validatedResponse.data.campaign_overview_page
|
||||
|
||||
metricsGetCampaignOverviewPage.success()
|
||||
|
||||
const system = campaignOverviewPage.system
|
||||
const pageName = `campaign-overview-page`
|
||||
|
||||
const tracking: TrackingSDKPageData = {
|
||||
pageId: system.uid,
|
||||
domainLanguage: system.locale,
|
||||
publishDate: system.updated_at,
|
||||
createDate: system.created_at,
|
||||
channel: TrackingChannelEnum["campaign-overview-page"],
|
||||
pageType: "campaign-overview-page",
|
||||
pageName,
|
||||
siteSections: pageName,
|
||||
siteVersion: "new-web",
|
||||
}
|
||||
|
||||
return {
|
||||
campaignOverviewPage,
|
||||
tracking,
|
||||
}
|
||||
}),
|
||||
})
|
||||
@@ -0,0 +1,33 @@
|
||||
import { generateTag, generateTagsFromSystem } from "@/utils/generateTag"
|
||||
|
||||
import type { Lang } from "@scandic-hotels/common/constants/language"
|
||||
|
||||
import type { System } from "@/types/requests/system"
|
||||
import type { CampaignOverviewPageRefs } from "@/types/trpc/routers/contentstack/campaignOverviewPage"
|
||||
|
||||
export function generatePageTags(
|
||||
validatedData: CampaignOverviewPageRefs,
|
||||
lang: Lang
|
||||
): string[] {
|
||||
const connections = getConnections(validatedData)
|
||||
return [
|
||||
generateTagsFromSystem(lang, connections),
|
||||
generateTag(lang, validatedData.campaign_overview_page.system.uid),
|
||||
].flat()
|
||||
}
|
||||
|
||||
export function getConnections({
|
||||
campaign_overview_page,
|
||||
}: CampaignOverviewPageRefs) {
|
||||
const connections: System["system"][] = [campaign_overview_page.system]
|
||||
|
||||
if (campaign_overview_page.header.navigation_links) {
|
||||
campaign_overview_page.header.navigation_links.forEach((link) => {
|
||||
if (link.link) {
|
||||
connections.push(link.link)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
return connections
|
||||
}
|
||||
@@ -3,6 +3,7 @@ import { router } from "@scandic-hotels/trpc"
|
||||
import { accountPageRouter } from "./accountPage"
|
||||
import { baseRouter } from "./base"
|
||||
import { breadcrumbsRouter } from "./breadcrumbs"
|
||||
import { campaignOverviewPageRouter } from "./campaignOverviewPage"
|
||||
import { campaignPageRouter } from "./campaignPage"
|
||||
import { collectionPageRouter } from "./collectionPage"
|
||||
import { contentPageRouter } from "./contentPage"
|
||||
@@ -26,6 +27,7 @@ export const contentstackRouter = router({
|
||||
hotelPage: hotelPageRouter,
|
||||
languageSwitcher: languageSwitcherRouter,
|
||||
loyaltyPage: loyaltyPageRouter,
|
||||
campaignOverviewPage: campaignOverviewPageRouter,
|
||||
campaignPage: campaignPageRouter,
|
||||
collectionPage: collectionPageRouter,
|
||||
contentPage: contentPageRouter,
|
||||
|
||||
@@ -7,6 +7,10 @@ import {
|
||||
GetDaDeEnUrlsAccountPage,
|
||||
GetFiNoSvUrlsAccountPage,
|
||||
} from "@/lib/graphql/Query/AccountPage/AccountPage.graphql"
|
||||
import {
|
||||
GetDaDeEnUrlsCampaignOverviewPage,
|
||||
GetFiNoSvUrlsCampaignOverviewPage,
|
||||
} from "@/lib/graphql/Query/CampaignOverviewPage/CampaignOverviewPage.graphql"
|
||||
import {
|
||||
GetDaDeEnUrlsCampaignPage,
|
||||
GetFiNoSvUrlsCampaignPage,
|
||||
@@ -100,6 +104,10 @@ export async function getUrlsOfAllLanguages(
|
||||
daDeEnDocument = GetDaDeEnUrlsCurrentBlocksPage
|
||||
fiNoSvDocument = GetFiNoSvUrlsCurrentBlocksPage
|
||||
break
|
||||
case PageContentTypeEnum.campaignOverviewPage:
|
||||
daDeEnDocument = GetDaDeEnUrlsCampaignOverviewPage
|
||||
fiNoSvDocument = GetFiNoSvUrlsCampaignOverviewPage
|
||||
break
|
||||
case PageContentTypeEnum.campaignPage:
|
||||
daDeEnDocument = GetDaDeEnUrlsCampaignPage
|
||||
fiNoSvDocument = GetFiNoSvUrlsCampaignPage
|
||||
|
||||
@@ -7,6 +7,7 @@ import { contentStackUidWithServiceProcedure } from "@scandic-hotels/trpc/proced
|
||||
|
||||
import { env } from "@/env/server"
|
||||
import { GetAccountPageMetadata } from "@/lib/graphql/Query/AccountPage/Metadata.graphql"
|
||||
import { GetCampaignOverviewPageMetadata } from "@/lib/graphql/Query/CampaignOverviewPage/Metadata.graphql"
|
||||
import { GetCampaignPageMetadata } from "@/lib/graphql/Query/CampaignPage/Metadata.graphql"
|
||||
import { GetCollectionPageMetadata } from "@/lib/graphql/Query/CollectionPage/Metadata.graphql"
|
||||
import { GetContentPageMetadata } from "@/lib/graphql/Query/ContentPage/Metadata.graphql"
|
||||
@@ -131,6 +132,14 @@ export const metadataQueryRouter = router({
|
||||
accountPageResponse.account_page
|
||||
)
|
||||
break
|
||||
case PageContentTypeEnum.campaignOverviewPage:
|
||||
const campaignOverviewPageResponse = await fetchMetadata<{
|
||||
campaign_overview_page: RawMetadataSchema
|
||||
}>(GetCampaignOverviewPageMetadata, variables)
|
||||
metadata = await getTransformedMetadata(
|
||||
campaignOverviewPageResponse.campaign_overview_page
|
||||
)
|
||||
break
|
||||
case PageContentTypeEnum.campaignPage:
|
||||
const campaignPageResponse = await fetchMetadata<{
|
||||
campaign_page: RawMetadataSchema
|
||||
|
||||
@@ -5,6 +5,7 @@ import { contentstackBaseProcedure } from "@scandic-hotels/trpc/procedures"
|
||||
|
||||
import {
|
||||
GetAccountPageSettings,
|
||||
GetCampaignOverviewPageSettings,
|
||||
GetCampaignPageSettings,
|
||||
GetCollectionPageSettings,
|
||||
GetContentPageSettings,
|
||||
@@ -77,6 +78,7 @@ export const pageSettingsQueryRouter = router({
|
||||
|
||||
const graphqlQueriesForContentType: Record<PageContentTypeEnum, any> = {
|
||||
[PageContentTypeEnum.accountPage]: GetAccountPageSettings,
|
||||
[PageContentTypeEnum.campaignOverviewPage]: GetCampaignOverviewPageSettings,
|
||||
[PageContentTypeEnum.campaignPage]: GetCampaignPageSettings,
|
||||
[PageContentTypeEnum.collectionPage]: GetCollectionPageSettings,
|
||||
[PageContentTypeEnum.contentPage]: GetContentPageSettings,
|
||||
|
||||
@@ -2,6 +2,8 @@ import { z } from "zod"
|
||||
|
||||
import {
|
||||
accountPageSchema,
|
||||
campaignOverviewPageSchema,
|
||||
campaignPageSchema,
|
||||
collectionPageSchema,
|
||||
contentPageSchema,
|
||||
destinationCityPageSchema,
|
||||
@@ -20,6 +22,8 @@ export const contentEmbedsSchema = z
|
||||
imageContainerSchema,
|
||||
sysAssetSchema,
|
||||
accountPageSchema,
|
||||
campaignOverviewPageSchema,
|
||||
campaignPageSchema,
|
||||
collectionPageSchema,
|
||||
contentPageSchema,
|
||||
destinationCityPageSchema,
|
||||
|
||||
@@ -32,6 +32,18 @@ export const extendedPageLinkSchema = pageLinkSchema.merge(
|
||||
.default({ original_url: "" }),
|
||||
})
|
||||
)
|
||||
|
||||
export const campaignOverviewPageSchema = z
|
||||
.object({
|
||||
__typename: z.literal(ContentEnum.blocks.CampaignOverviewPage),
|
||||
})
|
||||
.merge(extendedPageLinkSchema)
|
||||
|
||||
export const campaignOverviewPageRefSchema = z.object({
|
||||
__typename: z.literal(ContentEnum.blocks.CampaignOverviewPage),
|
||||
system: systemSchema,
|
||||
})
|
||||
|
||||
export const collectionPageSchema = z
|
||||
.object({
|
||||
__typename: z.literal(ContentEnum.blocks.CollectionPage),
|
||||
@@ -133,6 +145,7 @@ export const startPageRefSchema = z.object({
|
||||
|
||||
export const linkUnionSchema = z.discriminatedUnion("__typename", [
|
||||
accountPageSchema,
|
||||
campaignOverviewPageSchema,
|
||||
campaignPageSchema,
|
||||
collectionPageSchema,
|
||||
contentPageSchema,
|
||||
@@ -146,6 +159,7 @@ export const linkUnionSchema = z.discriminatedUnion("__typename", [
|
||||
|
||||
type Data =
|
||||
| z.output<typeof accountPageSchema>
|
||||
| z.output<typeof campaignOverviewPageSchema>
|
||||
| z.output<typeof campaignPageSchema>
|
||||
| z.output<typeof collectionPageSchema>
|
||||
| z.output<typeof contentPageSchema>
|
||||
@@ -161,6 +175,7 @@ export function transformPageLink(data: Data) {
|
||||
if (data && "__typename" in data) {
|
||||
switch (data.__typename) {
|
||||
case ContentEnum.blocks.AccountPage:
|
||||
case ContentEnum.blocks.CampaignOverviewPage:
|
||||
case ContentEnum.blocks.CampaignPage:
|
||||
case ContentEnum.blocks.DestinationCityPage:
|
||||
case ContentEnum.blocks.DestinationCountryPage:
|
||||
@@ -173,7 +188,6 @@ export function transformPageLink(data: Data) {
|
||||
title: data.title,
|
||||
url: removeMultipleSlashes(`/${data.system.locale}/${data.url}`),
|
||||
}
|
||||
|
||||
case ContentEnum.blocks.CollectionPage:
|
||||
case ContentEnum.blocks.ContentPage:
|
||||
case ContentEnum.blocks.LoyaltyPage:
|
||||
@@ -195,6 +209,7 @@ export function transformPageLink(data: Data) {
|
||||
|
||||
export const linkRefsUnionSchema = z.discriminatedUnion("__typename", [
|
||||
accountPageRefSchema,
|
||||
campaignOverviewPageRefSchema,
|
||||
campaignPageRefSchema,
|
||||
collectionPageRefSchema,
|
||||
contentPageRefSchema,
|
||||
@@ -208,6 +223,7 @@ export const linkRefsUnionSchema = z.discriminatedUnion("__typename", [
|
||||
|
||||
type RefData =
|
||||
| z.output<typeof accountPageRefSchema>
|
||||
| z.output<typeof campaignOverviewPageRefSchema>
|
||||
| z.output<typeof campaignPageRefSchema>
|
||||
| z.output<typeof collectionPageRefSchema>
|
||||
| z.output<typeof contentPageRefSchema>
|
||||
@@ -223,6 +239,7 @@ export function transformPageLinkRef(data: RefData) {
|
||||
if (data && "__typename" in data) {
|
||||
switch (data.__typename) {
|
||||
case ContentEnum.blocks.AccountPage:
|
||||
case ContentEnum.blocks.CampaignOverviewPage:
|
||||
case ContentEnum.blocks.CampaignPage:
|
||||
case ContentEnum.blocks.CollectionPage:
|
||||
case ContentEnum.blocks.ContentPage:
|
||||
|
||||
Reference in New Issue
Block a user