diff --git a/apps/scandic-web/components/Blocks/AllCampaigns/allCampaigns.module.css b/apps/scandic-web/components/Blocks/AllCampaigns/allCampaigns.module.css
new file mode 100644
index 000000000..d676ec5b5
--- /dev/null
+++ b/apps/scandic-web/components/Blocks/AllCampaigns/allCampaigns.module.css
@@ -0,0 +1,35 @@
+.allCampaignsSection {
+ display: grid;
+ gap: var(--Space-x3);
+}
+
+.header {
+ display: grid;
+ gap: var(--Space-x15);
+}
+
+.heading {
+ color: var(--Text-Heading);
+}
+
+.cardsList {
+ list-style: none;
+ display: none;
+}
+
+@media screen and (min-width: 768px) {
+ .carousel {
+ display: none;
+ }
+ .cardsList {
+ display: grid;
+ grid-template-columns: repeat(2, 1fr);
+ gap: var(--Space-x4) var(--Space-x1);
+ }
+}
+
+@media screen and (min-width: 1024px) {
+ .cardsList {
+ grid-template-columns: repeat(3, 1fr);
+ }
+}
diff --git a/apps/scandic-web/components/Blocks/AllCampaigns/index.tsx b/apps/scandic-web/components/Blocks/AllCampaigns/index.tsx
new file mode 100644
index 000000000..ca2d4df8d
--- /dev/null
+++ b/apps/scandic-web/components/Blocks/AllCampaigns/index.tsx
@@ -0,0 +1,80 @@
+import { Typography } from "@scandic-hotels/design-system/Typography"
+
+import { Carousel } from "@/components/Carousel"
+import { CarouselContent } from "@/components/Carousel/CarouselContent"
+import { CarouselDots } from "@/components/Carousel/CarouselDots"
+import { CarouselItem } from "@/components/Carousel/CarouselItem"
+import {
+ CarouselNext,
+ CarouselPrevious,
+} from "@/components/Carousel/CarouselNavigation"
+import ContentCard from "@/components/ContentCard"
+
+import styles from "./allCampaigns.module.css"
+
+import type { ImageVaultAsset } from "@scandic-hotels/trpc/types/imageVault"
+
+interface AllCampaignsProps {
+ heading: string
+ preamble?: string | null
+ cards: {
+ url: string
+ heading: string
+ text: string | null
+ image: ImageVaultAsset
+ }[]
+}
+
+export default function AllCampaigns({
+ heading,
+ preamble,
+ cards,
+}: AllCampaignsProps) {
+ if (!cards.length) {
+ return null
+ }
+
+ return (
+
+
+
+ {heading}
+
+ {preamble ? (
+
+ {preamble}
+
+ ) : null}
+
+
+ {cards.map(({ url, image, heading, text }) => (
+ -
+
+
+ ))}
+
+
+
+ {cards.map(({ url, heading, text, image }) => (
+
+
+
+ ))}
+
+
+
+
+
+
+ )
+}
diff --git a/apps/scandic-web/components/ContentType/CampaignOverviewPage/Blocks/index.tsx b/apps/scandic-web/components/ContentType/CampaignOverviewPage/Blocks/index.tsx
index b05b2e140..f0308865f 100644
--- a/apps/scandic-web/components/ContentType/CampaignOverviewPage/Blocks/index.tsx
+++ b/apps/scandic-web/components/ContentType/CampaignOverviewPage/Blocks/index.tsx
@@ -1,5 +1,6 @@
import { BlocksEnums } from "@scandic-hotels/trpc/types/blocksEnum"
+import AllCampaigns from "@/components/Blocks/AllCampaigns"
import CampaignHotelListing from "@/components/Blocks/CampaignHotelListing"
import CarouselCards from "@/components/Blocks/CarouselCards"
@@ -26,6 +27,15 @@ export default function Blocks({ blocks }: BlocksProps) {
visibleCountDesktop={3}
/>
)
+ case BlocksEnums.block.CampaignOverviewPageAllCampaigns:
+ return (
+
+ )
default:
return null
}
diff --git a/packages/trpc/lib/graphql/Fragments/Blocks/AllCampaigns.graphql b/packages/trpc/lib/graphql/Fragments/Blocks/AllCampaigns.graphql
new file mode 100644
index 000000000..53b13236a
--- /dev/null
+++ b/packages/trpc/lib/graphql/Fragments/Blocks/AllCampaigns.graphql
@@ -0,0 +1,38 @@
+#import "../CampaignPage/Ref.graphql"
+
+fragment AllCampaigns on CampaignOverviewPageBlocksAllCampaigns {
+ all_campaigns {
+ heading
+ preamble
+ campaignsConnection {
+ edges {
+ node {
+ ... on CampaignPage {
+ url
+ card_content {
+ heading
+ image
+ text
+ }
+ system {
+ locale
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+fragment AllCampaignsRefs on CampaignOverviewPageBlocksAllCampaigns {
+ all_campaigns {
+ campaignsConnection {
+ edges {
+ node {
+ __typename
+ ...CampaignPageRef
+ }
+ }
+ }
+ }
+}
diff --git a/packages/trpc/lib/graphql/Query/CampaignOverviewPage/CampaignOverviewPage.graphql b/packages/trpc/lib/graphql/Query/CampaignOverviewPage/CampaignOverviewPage.graphql
index 93586dc11..ca5079793 100644
--- a/packages/trpc/lib/graphql/Query/CampaignOverviewPage/CampaignOverviewPage.graphql
+++ b/packages/trpc/lib/graphql/Query/CampaignOverviewPage/CampaignOverviewPage.graphql
@@ -3,6 +3,7 @@
#import "../../Fragments/CampaignOverviewPage/NavigationLinks.graphql"
#import "../../Fragments/CampaignOverviewPage/TopCampaign.graphql"
+#import "../../Fragments/Blocks/AllCampaigns.graphql"
#import "../../Fragments/Blocks/CarouselCards.graphql"
#import "../../Fragments/Blocks/HotelListing.graphql"
@@ -23,6 +24,7 @@ query GetCampaignOverviewPage($locale: String!, $uid: String!) {
}
blocks {
__typename
+ ...AllCampaigns
...CarouselCards_CampaignOverviewPage
...HotelListing_CampaignOverviewPage
}
@@ -52,6 +54,7 @@ query GetCampaignOverviewPageRefs($locale: String!, $uid: String!) {
blocks {
__typename
...CarouselCards_CampaignOverviewPageRefs
+ ...AllCampaignsRefs
}
system {
...System
diff --git a/packages/trpc/lib/routers/contentstack/campaignOverviewPage/output.ts b/packages/trpc/lib/routers/contentstack/campaignOverviewPage/output.ts
index 9a5c7bc9c..9ef5e3e74 100644
--- a/packages/trpc/lib/routers/contentstack/campaignOverviewPage/output.ts
+++ b/packages/trpc/lib/routers/contentstack/campaignOverviewPage/output.ts
@@ -8,6 +8,10 @@ import {
heroSchema,
includedHotelsSchema,
} from "../campaignPage/output"
+import {
+ allCampaignsRefsSchema,
+ allCampaignsSchema,
+} from "../schemas/blocks/allCampaigns"
import {
carouselCardsRefsSchema,
carouselCardsSchema,
@@ -71,6 +75,14 @@ const campaignOverviewPageCarouselCards = z
})
.merge(carouselCardsSchema)
+const campaignOverviewPageAllCampaigns = z
+ .object({
+ __typename: z.literal(
+ CampaignOverviewPageEnum.ContentStack.blocks.AllCampaigns
+ ),
+ })
+ .merge(allCampaignsSchema)
+
export const campaignOverviewPageHotelListing = z
.object({
__typename: z.literal(
@@ -80,6 +92,7 @@ export const campaignOverviewPageHotelListing = z
.merge(campaignOverviewPageHotelListingSchema)
export const blocksSchema = z.discriminatedUnion("__typename", [
+ campaignOverviewPageAllCampaigns,
campaignOverviewPageCarouselCards,
campaignOverviewPageHotelListing,
])
@@ -134,7 +147,16 @@ const campaignOverviewPageCarouselCardsRef = z
})
.merge(carouselCardsRefsSchema)
+const campaignOverviewPageAllCampaignsRef = z
+ .object({
+ __typename: z.literal(
+ CampaignOverviewPageEnum.ContentStack.blocks.AllCampaigns
+ ),
+ })
+ .merge(allCampaignsRefsSchema)
+
const blockRefsSchema = z.discriminatedUnion("__typename", [
+ campaignOverviewPageAllCampaignsRef,
campaignOverviewPageCarouselCardsRef,
])
diff --git a/packages/trpc/lib/routers/contentstack/campaignOverviewPage/utils.ts b/packages/trpc/lib/routers/contentstack/campaignOverviewPage/utils.ts
index dc830334f..d46d27842 100644
--- a/packages/trpc/lib/routers/contentstack/campaignOverviewPage/utils.ts
+++ b/packages/trpc/lib/routers/contentstack/campaignOverviewPage/utils.ts
@@ -45,6 +45,12 @@ export function getConnections({
})
break
}
+ case CampaignOverviewPageEnum.ContentStack.blocks.AllCampaigns: {
+ block.all_campaigns.campaignsConnection.edges.forEach(({ node }) => {
+ connections.push(node.system)
+ })
+ break
+ }
}
})
}
diff --git a/packages/trpc/lib/routers/contentstack/schemas/blocks/allCampaigns.ts b/packages/trpc/lib/routers/contentstack/schemas/blocks/allCampaigns.ts
new file mode 100644
index 000000000..c756e8081
--- /dev/null
+++ b/packages/trpc/lib/routers/contentstack/schemas/blocks/allCampaigns.ts
@@ -0,0 +1,80 @@
+import { z } from "zod"
+
+import { removeMultipleSlashes } from "@scandic-hotels/common/utils/url"
+
+import { BlocksEnums } from "../../../../types/blocksEnum"
+import { tempImageVaultAssetSchema } from "../imageVault"
+import { campaignPageRefSchema } from "../pageLinks"
+
+export const campaignPageCardSchema = z.object({
+ image: tempImageVaultAssetSchema,
+ heading: z.string(),
+ text: z.string(),
+})
+
+export const allCampaignsSchema = z.object({
+ typename: z
+ .literal(BlocksEnums.block.CampaignOverviewPageAllCampaigns)
+ .optional()
+ .default(BlocksEnums.block.CampaignOverviewPageAllCampaigns),
+ all_campaigns: z
+ .object({
+ heading: z.string(),
+ preamble: z.string().nullish(),
+ campaignsConnection: z.object({
+ edges: z
+ .array(
+ z.object({
+ node: z.object({
+ url: z.string(),
+ card_content: z
+ .object({
+ image: tempImageVaultAssetSchema,
+ heading: z.string().nullish(),
+ text: z.string().nullish(),
+ })
+ .nullish(),
+ system: z.object({
+ locale: z.string(),
+ }),
+ }),
+ })
+ )
+ .transform((data) => {
+ const mappedCards = data.map(({ node }) => {
+ const { url, card_content } = node
+ if (url && card_content?.image && card_content?.heading) {
+ return {
+ url: removeMultipleSlashes(`/${node.system.locale}/${url}`),
+ heading: card_content.heading,
+ image: card_content.image,
+ text: card_content.text ?? null,
+ }
+ }
+
+ return null
+ })
+
+ return mappedCards.filter((card) => !!card)
+ }),
+ }),
+ })
+ .transform((data) => {
+ return {
+ ...data,
+ cards: data.campaignsConnection.edges,
+ }
+ }),
+})
+
+export const allCampaignsRefsSchema = z.object({
+ all_campaigns: z.object({
+ campaignsConnection: z.object({
+ edges: z.array(
+ z.object({
+ node: campaignPageRefSchema,
+ })
+ ),
+ }),
+ }),
+})
diff --git a/packages/trpc/lib/types/blocksEnum.ts b/packages/trpc/lib/types/blocksEnum.ts
index 5807dbb06..b0eb5c8eb 100644
--- a/packages/trpc/lib/types/blocksEnum.ts
+++ b/packages/trpc/lib/types/blocksEnum.ts
@@ -8,6 +8,7 @@ export namespace BlocksEnums {
DynamicContent = "DynamicContent",
FullWidthCampaign = "FullWidthCampaign",
CampaignOverviewPageHotelListing = "CampaignOverviewPageHotelListing",
+ CampaignOverviewPageAllCampaigns = "CampaignOverviewPageAllCampaigns",
CampaignPageHotelListing = "CampaignPageHotelListing",
ContentPageHotelListing = "ContentPageHotelListing",
JoinScandicFriends = "JoinScandicFriends",
diff --git a/packages/trpc/lib/types/campaignOverviewPageEnum.ts b/packages/trpc/lib/types/campaignOverviewPageEnum.ts
index 75f442971..0d9e1c6f3 100644
--- a/packages/trpc/lib/types/campaignOverviewPageEnum.ts
+++ b/packages/trpc/lib/types/campaignOverviewPageEnum.ts
@@ -3,6 +3,7 @@ export namespace CampaignOverviewPageEnum {
export const enum blocks {
CarouselCards = "CampaignOverviewPageBlocksCarouselCards",
HotelListing = "CampaignOverviewPageBlocksHotelListing",
+ AllCampaigns = "CampaignOverviewPageBlocksAllCampaigns",
}
}
}