diff --git a/components/Blocks/FullWidthCampaign/fullWidthCampaign.module.css b/components/Blocks/FullWidthCampaign/fullWidthCampaign.module.css
new file mode 100644
index 000000000..e2672cc5a
--- /dev/null
+++ b/components/Blocks/FullWidthCampaign/fullWidthCampaign.module.css
@@ -0,0 +1,41 @@
+.container {
+ position: relative;
+ height: 640px;
+ overflow: hidden;
+}
+
+.content {
+ position: absolute;
+ inset: 0;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ max-width: 800px;
+ margin: 0 auto;
+ gap: var(--Spacing-x1);
+ padding: var(--Spacing-x4) var(--Spacing-x3);
+}
+
+.mainContent {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: var(--Spacing-x2);
+}
+
+.buttons {
+ display: flex;
+ gap: var(--Spacing-x1);
+}
+
+.image {
+ max-width: 100%;
+ height: 600px;
+}
+
+@media screen and (min-width: 768px) {
+ .image {
+ height: 880px;
+ }
+}
diff --git a/components/Blocks/FullWidthCampaign/index.tsx b/components/Blocks/FullWidthCampaign/index.tsx
new file mode 100644
index 000000000..d1f84f5b5
--- /dev/null
+++ b/components/Blocks/FullWidthCampaign/index.tsx
@@ -0,0 +1,57 @@
+import Image from "@/components/Image"
+import Button from "@/components/TempDesignSystem/Button"
+import BiroScript from "@/components/TempDesignSystem/Text/BiroScript"
+import Body from "@/components/TempDesignSystem/Text/Body"
+import Title from "@/components/TempDesignSystem/Text/Title"
+
+import styles from "./fullWidthCampaign.module.css"
+
+import type { FullWidthCampaign } from "@/types/trpc/routers/contentstack/startPage"
+
+interface FullWidthCampaignProps {
+ content: FullWidthCampaign
+}
+
+export default function FullWidthCampaign({ content }: FullWidthCampaignProps) {
+ return content.full_width_campaignConnection.edges.map(({ node }) => (
+
+ {node.background_image ? (
+
+ ) : null}
+
+
{node.scripted_top_title}
+
+
+ {node.heading}
+
+
+ {node.body_text}
+
+
+ {node.has_primary_button ? (
+
+ ) : null}
+ {node.has_secondary_button ? (
+
+ ) : null}
+
+
+
+
+ ))
+}
diff --git a/components/Blocks/index.tsx b/components/Blocks/index.tsx
index a67a3880e..87283a5a9 100644
--- a/components/Blocks/index.tsx
+++ b/components/Blocks/index.tsx
@@ -7,6 +7,7 @@ import JsonToHtml from "@/components/JsonToHtml"
import { SasTierComparison } from "@/components/SasTierComparison"
import AccordionSection from "./Accordion"
+import FullWidthCampaign from "./FullWidthCampaign"
import HotelListing from "./HotelListing"
import Table from "./Table"
@@ -98,6 +99,8 @@ export default function Blocks({ blocks }: BlocksProps) {
firstItem={firstItem}
/>
)
+ case BlocksEnums.block.FullWidthCampaign:
+ return
default:
return null
}
diff --git a/components/ContentType/StartPage/index.tsx b/components/ContentType/StartPage/index.tsx
index 33972541f..9ecf0e007 100644
--- a/components/ContentType/StartPage/index.tsx
+++ b/components/ContentType/StartPage/index.tsx
@@ -43,13 +43,13 @@ export default async function StartPage() {
) : null}
+ {blocks ? : null}
JSON data
{JSON.stringify(content, null, 2)}
- {blocks ? : null}
diff --git a/lib/graphql/Fragments/Blocks/FullWidthCampaign.graphql b/lib/graphql/Fragments/Blocks/FullWidthCampaign.graphql
new file mode 100644
index 000000000..14d98cec1
--- /dev/null
+++ b/lib/graphql/Fragments/Blocks/FullWidthCampaign.graphql
@@ -0,0 +1,99 @@
+#import "../PageLink/AccountPageLink.graphql"
+#import "../PageLink/ContentPageLink.graphql"
+#import "../PageLink/LoyaltyPageLink.graphql"
+#import "../PageLink/HotelPageLink.graphql"
+#import "../PageLink/CollectionPageLink.graphql"
+
+#import "../AccountPage/Ref.graphql"
+#import "../ContentPage/Ref.graphql"
+#import "../HotelPage/Ref.graphql"
+#import "../LoyaltyPage/Ref.graphql"
+#import "../CollectionPage/Ref.graphql"
+
+fragment FullWidthCampaign on FullWidthCampaign {
+ background_image
+ scripted_top_title
+ heading
+ body_text
+ has_primary_button
+ primary_button {
+ cta_text
+ open_in_new_tab
+ is_contentstack_link
+ external_link {
+ href
+ title
+ }
+ linkConnection {
+ edges {
+ node {
+ __typename
+ ...AccountPageLink
+ ...ContentPageLink
+ ...LoyaltyPageLink
+ ...HotelPageLink
+ ...CollectionPageLink
+ }
+ }
+ }
+ }
+ has_secondary_button
+ secondary_button {
+ cta_text
+ open_in_new_tab
+ is_contentstack_link
+ external_link {
+ href
+ title
+ }
+ linkConnection {
+ edges {
+ node {
+ __typename
+ ...AccountPageLink
+ ...ContentPageLink
+ ...LoyaltyPageLink
+ ...HotelPageLink
+ ...CollectionPageLink
+ }
+ }
+ }
+ }
+ system {
+ ...System
+ }
+}
+
+fragment FullWidthCampaignRefs on FullWidthCampaign {
+ primary_button {
+ linkConnection {
+ edges {
+ node {
+ __typename
+ ...AccountPageRef
+ ...ContentPageRef
+ ...HotelPageRef
+ ...LoyaltyPageRef
+ ...CollectionPageRef
+ }
+ }
+ }
+ }
+ secondary_button {
+ linkConnection {
+ edges {
+ node {
+ __typename
+ ...AccountPageRef
+ ...ContentPageRef
+ ...HotelPageRef
+ ...LoyaltyPageRef
+ ...CollectionPageRef
+ }
+ }
+ }
+ }
+ system {
+ ...System
+ }
+}
diff --git a/lib/graphql/Query/StartPage/StartPage.graphql b/lib/graphql/Query/StartPage/StartPage.graphql
index a3bcfea4e..4e118ceba 100644
--- a/lib/graphql/Query/StartPage/StartPage.graphql
+++ b/lib/graphql/Query/StartPage/StartPage.graphql
@@ -1,14 +1,30 @@
#import "../../Fragments/System.graphql"
#import "../../Fragments/Blocks/CardsGrid.graphql"
+#import "../../Fragments/Blocks/FullWidthCampaign.graphql"
query GetStartPage($locale: String!, $uid: String!) {
- start_page(uid: $uid, locale: $locale) {
+ start_page(locale: $locale, uid: $uid) {
title
url
header {
heading
hero_image
}
+ blocks {
+ __typename
+ ... on StartPageBlocksFullWidthCampaign {
+ __typename
+ full_width_campaign {
+ full_width_campaignConnection {
+ edges {
+ node {
+ ...FullWidthCampaign
+ }
+ }
+ }
+ }
+ }
+ }
system {
...System
created_at
@@ -29,6 +45,17 @@ query GetStartPageRefs($locale: String!, $uid: String!) {
blocks {
__typename
...CardsGrid_StartPageRefs
+ ... on StartPageBlocksFullWidthCampaign {
+ full_width_campaign {
+ full_width_campaignConnection {
+ edges {
+ node {
+ ...FullWidthCampaignRefs
+ }
+ }
+ }
+ }
+ }
}
system {
...System
diff --git a/server/routers/contentstack/schemas/blocks/fullWidthCampaign.ts b/server/routers/contentstack/schemas/blocks/fullWidthCampaign.ts
new file mode 100644
index 000000000..f75f7d304
--- /dev/null
+++ b/server/routers/contentstack/schemas/blocks/fullWidthCampaign.ts
@@ -0,0 +1,58 @@
+import { z } from "zod"
+
+import * as pageLinks from "@/server/routers/contentstack/schemas/pageLinks"
+
+import { tempImageVaultAssetSchema } from "../imageVault"
+import { systemSchema } from "../system"
+import { buttonSchema } from "./utils/buttonLinkSchema"
+
+import { BlocksEnums } from "@/types/enums/blocks"
+
+export const fullWidthCampaignSchema = z.object({
+ full_width_campaign: z.object({
+ full_width_campaignConnection: z.object({
+ edges: z.array(
+ z.object({
+ node: z.object({
+ background_image: tempImageVaultAssetSchema,
+ heading: z.string().optional(),
+ body_text: z.string().optional(),
+ scripted_top_title: z.string().optional(),
+ has_primary_button: z.boolean().default(false),
+ primary_button: buttonSchema,
+ has_secondary_button: z.boolean().default(false),
+ secondary_button: buttonSchema,
+ system: systemSchema,
+ }),
+ })
+ ),
+ }),
+ }),
+})
+
+export const fullWidthCampaignBlockSchema = z
+ .object({
+ typename: z
+ .literal(BlocksEnums.block.FullWidthCampaign)
+ .optional()
+ .default(BlocksEnums.block.FullWidthCampaign),
+ })
+ .merge(fullWidthCampaignSchema)
+
+export const fullWidthCampaignBlockRefsSchema = z.object({
+ full_width_campaign: z.object({
+ full_width_campaignConnection: z.object({
+ edges: z.array(
+ z.object({
+ node: z.discriminatedUnion("__typename", [
+ pageLinks.accountPageRefSchema,
+ pageLinks.contentPageRefSchema,
+ pageLinks.loyaltyPageRefSchema,
+ pageLinks.collectionPageRefSchema,
+ pageLinks.hotelPageRefSchema,
+ ]),
+ })
+ ),
+ }),
+ }),
+})
diff --git a/server/routers/contentstack/startPage/output.ts b/server/routers/contentstack/startPage/output.ts
index f52c911eb..69c6dc02b 100644
--- a/server/routers/contentstack/startPage/output.ts
+++ b/server/routers/contentstack/startPage/output.ts
@@ -6,27 +6,40 @@ import {
cardGridRefsSchema,
cardsGridSchema,
} from "../schemas/blocks/cardsGrid"
+import {
+ fullWidthCampaignBlockRefsSchema,
+ fullWidthCampaignBlockSchema,
+} from "../schemas/blocks/fullWidthCampaign"
import { tempImageVaultAssetSchema } from "../schemas/imageVault"
import { systemSchema } from "../schemas/system"
import { StartPageEnum } from "@/types/enums/startPage"
-export const startPageCards = z
+const startPageCards = z
.object({
__typename: z.literal(StartPageEnum.ContentStack.blocks.CardsGrid),
})
.merge(cardsGridSchema)
-export const blocksSchema = z.discriminatedUnion("__typename", [startPageCards])
+const startPageFullWidthCampaign = z
+ .object({
+ __typename: z.literal(StartPageEnum.ContentStack.blocks.FullWidthCampaign),
+ })
+ .merge(fullWidthCampaignBlockSchema)
+
+export const blocksSchema = z.discriminatedUnion("__typename", [
+ startPageCards,
+ startPageFullWidthCampaign,
+])
export const startPageSchema = z.object({
start_page: z.object({
- blocks: discriminatedUnionArray(blocksSchema.options).nullable(),
title: z.string(),
header: z.object({
heading: z.string(),
hero_image: tempImageVaultAssetSchema,
}),
+ blocks: discriminatedUnionArray(blocksSchema.options).nullable(),
system: systemSchema.merge(
z.object({
created_at: z.string(),
@@ -46,8 +59,15 @@ const startPageCardsRefs = z
})
.merge(cardGridRefsSchema)
+const startPageFullWidthCampaignRef = z
+ .object({
+ __typename: z.literal(StartPageEnum.ContentStack.blocks.FullWidthCampaign),
+ })
+ .merge(fullWidthCampaignBlockRefsSchema)
+
const startPageBlockRefsItem = z.discriminatedUnion("__typename", [
startPageCardsRefs,
+ startPageFullWidthCampaignRef,
])
export const startPageRefsSchema = z.object({
diff --git a/server/routers/contentstack/startPage/query.ts b/server/routers/contentstack/startPage/query.ts
index d6cdf1986..5ce2c5ace 100644
--- a/server/routers/contentstack/startPage/query.ts
+++ b/server/routers/contentstack/startPage/query.ts
@@ -6,7 +6,7 @@ import { request } from "@/lib/graphql/request"
import { notFound } from "@/server/errors/trpc"
import { contentstackExtendedProcedureUID, router } from "@/server/trpc"
-import { generateTag } from "@/utils/generateTag"
+import { generateTag, generateTagsFromSystem } from "@/utils/generateTag"
import { startPageRefsSchema, startPageSchema } from "./output"
import {
@@ -17,6 +17,7 @@ import {
getStartPageRefsSuccessCounter,
getStartPageSuccessCounter,
} from "./telemetry"
+import { getConnections } from "./utils"
import {
TrackingChannelEnum,
@@ -103,6 +104,13 @@ export const startPageQueryRouter = router({
query: { lang, uid },
})
)
+
+ const connections = getConnections(validatedRefsData.data)
+
+ const tags = [
+ generateTagsFromSystem(lang, connections),
+ generateTag(lang, validatedRefsData.data.start_page.system.uid),
+ ].flat()
const response = await request(
GetStartPage,
{
@@ -112,10 +120,11 @@ export const startPageQueryRouter = router({
{
cache: "force-cache",
next: {
- tags: [generateTag(lang, uid)],
+ tags,
},
}
)
+
if (!response.data) {
const notFoundError = notFound(response)
getStartPageFailCounter.add(1, {
diff --git a/server/routers/contentstack/startPage/utils.ts b/server/routers/contentstack/startPage/utils.ts
new file mode 100644
index 000000000..9edb0720e
--- /dev/null
+++ b/server/routers/contentstack/startPage/utils.ts
@@ -0,0 +1,24 @@
+import { StartPageEnum } from "@/types/enums/startPage"
+import type { System } from "@/types/requests/system"
+import type { StartPageRefs } from "@/types/trpc/routers/contentstack/startPage"
+
+export function getConnections({ start_page }: StartPageRefs) {
+ const connections: System["system"][] = [start_page.system]
+
+ if (start_page.blocks) {
+ start_page.blocks.forEach((block) => {
+ switch (block.__typename) {
+ case StartPageEnum.ContentStack.blocks.FullWidthCampaign: {
+ block.full_width_campaign.full_width_campaignConnection.edges.forEach(
+ ({ node }) => {
+ connections.push(node.system)
+ }
+ )
+ break
+ }
+ }
+ })
+ }
+
+ return connections
+}
diff --git a/types/enums/blocks.ts b/types/enums/blocks.ts
index baf9a4a9c..4fd753abf 100644
--- a/types/enums/blocks.ts
+++ b/types/enums/blocks.ts
@@ -11,5 +11,6 @@ export namespace BlocksEnums {
UspGrid = "UspGrid",
SasTierComparison = "SasTierComparison",
HotelListing = "HotelListing",
+ FullWidthCampaign = "FullWidthCampaign",
}
}
diff --git a/types/enums/startPage.ts b/types/enums/startPage.ts
index fff235db4..339e5f26e 100644
--- a/types/enums/startPage.ts
+++ b/types/enums/startPage.ts
@@ -2,6 +2,7 @@ export namespace StartPageEnum {
export namespace ContentStack {
export const enum blocks {
CardsGrid = "StartPageBlocksCardsGrid",
+ FullWidthCampaign = "StartPageBlocksFullWidthCampaign",
}
}
}
diff --git a/types/trpc/routers/contentstack/startPage.ts b/types/trpc/routers/contentstack/startPage.ts
index 61219679e..c204c04c5 100644
--- a/types/trpc/routers/contentstack/startPage.ts
+++ b/types/trpc/routers/contentstack/startPage.ts
@@ -15,3 +15,5 @@ export interface GetStartPageRefsSchema
export interface StartPageRefs extends z.output {}
export type Block = z.output
+
+export type FullWidthCampaign = Block["full_width_campaign"]