From 4d63cc57c59ae54b38e252a285db18e72ed720d8 Mon Sep 17 00:00:00 2001 From: Christian Andolf Date: Wed, 5 Feb 2025 15:08:57 +0100 Subject: [PATCH 1/2] feat(SW-1391): add join scandic friends block --- .../Blocks/JoinScandicFriends/index.tsx | 83 +++++++++++++++++++ .../joinScandicFriends.module.css | 76 +++++++++++++++++ components/Blocks/index.tsx | 3 + components/ContentType/StartPage/index.tsx | 4 +- components/Icons/Surprise.tsx | 37 +++++++++ components/Icons/index.tsx | 1 + .../Blocks/JoinScandicFriends.graphql | 77 +++++++++++++++++ lib/graphql/Query/StartPage/StartPage.graphql | 3 + .../schemas/blocks/joinScandicFriends.ts | 36 ++++++++ .../routers/contentstack/startPage/output.ts | 18 ++++ types/enums/blocks.ts | 1 + types/enums/startPage.ts | 1 + types/trpc/routers/contentstack/startPage.ts | 5 ++ 13 files changed, 343 insertions(+), 2 deletions(-) create mode 100644 components/Blocks/JoinScandicFriends/index.tsx create mode 100644 components/Blocks/JoinScandicFriends/joinScandicFriends.module.css create mode 100644 components/Icons/Surprise.tsx create mode 100644 lib/graphql/Fragments/Blocks/JoinScandicFriends.graphql create mode 100644 server/routers/contentstack/schemas/blocks/joinScandicFriends.ts diff --git a/components/Blocks/JoinScandicFriends/index.tsx b/components/Blocks/JoinScandicFriends/index.tsx new file mode 100644 index 000000000..3f0708bf9 --- /dev/null +++ b/components/Blocks/JoinScandicFriends/index.tsx @@ -0,0 +1,83 @@ +import { SurpriseIcon } from "@/components/Icons" +import Image from "@/components/Image" +import Button from "@/components/TempDesignSystem/Button" +import Link from "@/components/TempDesignSystem/Link" +import BiroScript from "@/components/TempDesignSystem/Text/BiroScript" +import Body from "@/components/TempDesignSystem/Text/Body" +import Preamble from "@/components/TempDesignSystem/Text/Preamble" +import Title from "@/components/TempDesignSystem/Text/Title" + +import styles from "./joinScandicFriends.module.css" + +import type { JoinScandicFriends } from "@/types/trpc/routers/contentstack/startPage" + +interface JoinScandicFriendsProps { + content: JoinScandicFriends +} + +export default function JoinScandicFriends({ + content, +}: JoinScandicFriendsProps) { + const { show_header, show_usp, usp, primary_button } = content + + return ( +
+
+ {content.image ? ( + {content.image.title} + ) : ( + + )} +
+
+
+ {show_header ? ( +
+ + {content.scripted_top_title} + + {content.title} +
+ ) : null} + + {content.preamble} + + {show_usp && usp.length ? ( +
    + {usp.map((uspBullet) => ( + +
  • {uspBullet}
  • + + ))} +
+ ) : null} +
+ {content.has_primary_button ? ( +
+ +
+ ) : null} +
+
+ ) +} diff --git a/components/Blocks/JoinScandicFriends/joinScandicFriends.module.css b/components/Blocks/JoinScandicFriends/joinScandicFriends.module.css new file mode 100644 index 000000000..9a35fa09f --- /dev/null +++ b/components/Blocks/JoinScandicFriends/joinScandicFriends.module.css @@ -0,0 +1,76 @@ +.container { + border-radius: var(--Corner-radius-Large); + background-color: var(--Main-Brand-WarmWhite); + background-color: white; + padding: 0 var(--Spacing-x2); + display: flex; + gap: var(--Spacing-x5); +} + +@media screen and (min-width: 768px) { + .container { + padding: 0 var(--Spacing-x4) 0 0; + } +} + +.iconContainer { + display: none; +} + +@media screen and (min-width: 768px) { + .iconContainer { + width: 384px; + display: flex; /* gets rid of whitespace */ + } +} + +.content { + display: flex; + flex-direction: column; + gap: var(--Spacing-x3); + padding: var(--Spacing-x3) 0; +} + +.textContent { + display: flex; + flex-direction: column; + gap: var(--Spacing-x2); +} + +.header { + display: grid; + gap: var(--Spacing-x-quarter); +} + +.usp { + list-style: none; + display: grid; + gap: var(--Spacing-x1); +} + +@media screen and (min-width: 768px) { + .usp { + grid-template-columns: repeat(3, 1fr); + padding: var(--Spacing-x-one-and-half) 0; + } +} + +.usp li { + display: flex; + align-items: center; + gap: var(--Spacing-x1); + padding-left: var(--Spacing-x1); +} + +.usp li:before { + content: url("/_static/icons/heart.svg"); + position: relative; + top: 3px; +} + +@media screen and (min-width: 768px) { + .buttonContainer { + display: flex; + width: 180px; + } +} diff --git a/components/Blocks/index.tsx b/components/Blocks/index.tsx index 6b4995b1a..f0a5acf37 100644 --- a/components/Blocks/index.tsx +++ b/components/Blocks/index.tsx @@ -10,6 +10,7 @@ import { SasTierComparison } from "@/components/SasTierComparison" import AccordionSection from "./Accordion" import FullWidthCampaign from "./FullWidthCampaign" import HotelListing from "./HotelListing" +import JoinScandicFriends from "./JoinScandicFriends" import Table from "./Table" import type { BlocksProps } from "@/types/components/blocks" @@ -104,6 +105,8 @@ export default function Blocks({ blocks }: BlocksProps) { return case BlocksEnums.block.FullWidthCampaign: return + case BlocksEnums.block.JoinScandicFriends: + return default: return null } diff --git a/components/ContentType/StartPage/index.tsx b/components/ContentType/StartPage/index.tsx index 17b177b3d..c19a21ad8 100644 --- a/components/ContentType/StartPage/index.tsx +++ b/components/ContentType/StartPage/index.tsx @@ -45,7 +45,7 @@ export default async function StartPage() { ) : null}
- {(blocks || []).map((block) => { + {(blocks || []).map((block, index) => { if (block.typename === BlocksEnums.block.FullWidthCampaign) { return ( +
) diff --git a/components/Icons/Surprise.tsx b/components/Icons/Surprise.tsx new file mode 100644 index 000000000..f590d198e --- /dev/null +++ b/components/Icons/Surprise.tsx @@ -0,0 +1,37 @@ +import type { IconProps } from "@/types/components/icon" + +export default function SurpriseIcon({ color, ...props }: IconProps) { + return ( + + + + + + + + + ) +} diff --git a/components/Icons/index.tsx b/components/Icons/index.tsx index 5a7045654..4e7131d1b 100644 --- a/components/Icons/index.tsx +++ b/components/Icons/index.tsx @@ -162,6 +162,7 @@ export { default as SpeakerIcon } from "./Speaker" export { default as StarFilledIcon } from "./StarFilled" export { default as StoreIcon } from "./Store" export { default as StreetIcon } from "./Street" +export { default as SurpriseIcon } from "./Surprise" export { default as SwimIcon } from "./Swim" export { default as ThermostatIcon } from "./Thermostat" export { default as TrainIcon } from "./Train" diff --git a/lib/graphql/Fragments/Blocks/JoinScandicFriends.graphql b/lib/graphql/Fragments/Blocks/JoinScandicFriends.graphql new file mode 100644 index 000000000..54827fde9 --- /dev/null +++ b/lib/graphql/Fragments/Blocks/JoinScandicFriends.graphql @@ -0,0 +1,77 @@ +#import "../PageLink/AccountPageLink.graphql" +#import "../PageLink/ContentPageLink.graphql" +#import "../PageLink/LoyaltyPageLink.graphql" +#import "../PageLink/HotelPageLink.graphql" +#import "../PageLink/CollectionPageLink.graphql" +#import "../PageLink/DestinationCityPageLink.graphql" +#import "../PageLink/DestinationCountryPageLink.graphql" +#import "../PageLink/DestinationOverviewPageLink.graphql" + +#import "../AccountPage/Ref.graphql" +#import "../ContentPage/Ref.graphql" +#import "../HotelPage/Ref.graphql" +#import "../LoyaltyPage/Ref.graphql" +#import "../CollectionPage/Ref.graphql" +#import "../DestinationCityPage/Ref.graphql" +#import "../DestinationCountryPage/Ref.graphql" +#import "../DestinationOverviewPage/Ref.graphql" + +fragment JoinScandicFriends_StartPage on StartPageBlocksJoinScandicFriends { + __typename + join_scandic_friends { + show_header + scripted_top_title + title + preamble + image + show_usp + usp + 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 + ...DestinationCityPageLink + ...DestinationCountryPageLink + ...DestinationOverviewPageLink + } + } + } + } + } +} + +fragment JoinScandicFriends_StartPageRefs on StartPageBlocksJoinScandicFriends { + join_scandic_friends { + primary_button { + linkConnection { + edges { + node { + __typename + ...AccountPageRef + ...ContentPageRef + ...HotelPageRef + ...LoyaltyPageRef + ...CollectionPageRef + ...DestinationCityPageRef + ...DestinationCountryPageRef + ...DestinationOverviewPageRef + } + } + } + } + } +} diff --git a/lib/graphql/Query/StartPage/StartPage.graphql b/lib/graphql/Query/StartPage/StartPage.graphql index 03c113478..6ba478994 100644 --- a/lib/graphql/Query/StartPage/StartPage.graphql +++ b/lib/graphql/Query/StartPage/StartPage.graphql @@ -2,6 +2,7 @@ #import "../../Fragments/Blocks/CardsGrid.graphql" #import "../../Fragments/Blocks/FullWidthCampaign.graphql" #import "../../Fragments/Blocks/CarouselCards.graphql" +#import "../../Fragments/Blocks/JoinScandicFriends.graphql" query GetStartPage($locale: String!, $uid: String!) { start_page(locale: $locale, uid: $uid) { @@ -27,6 +28,7 @@ query GetStartPage($locale: String!, $uid: String!) { } } } + ...JoinScandicFriends_StartPage } system { ...System @@ -56,6 +58,7 @@ query GetStartPageRefs($locale: String!, $uid: String!) { } } } + ...JoinScandicFriends_StartPageRefs } system { ...System diff --git a/server/routers/contentstack/schemas/blocks/joinScandicFriends.ts b/server/routers/contentstack/schemas/blocks/joinScandicFriends.ts new file mode 100644 index 000000000..6bb25a868 --- /dev/null +++ b/server/routers/contentstack/schemas/blocks/joinScandicFriends.ts @@ -0,0 +1,36 @@ +import { z } from "zod" + +import { tempImageVaultAssetSchema } from "../imageVault" +import { buttonSchema } from "./utils/buttonLinkSchema" +import { linkConnectionRefsSchema } from "./utils/linkConnection" + +import { BlocksEnums } from "@/types/enums/blocks" + +export const joinScandicFriendsSchema = z.object({ + join_scandic_friends: z.object({ + show_header: z.boolean().default(false), + scripted_top_title: z.string(), + title: z.string(), + preamble: z.string(), + image: tempImageVaultAssetSchema, + show_usp: z.boolean().default(false), + usp: z.array(z.string()), + has_primary_button: z.boolean().default(false), + primary_button: buttonSchema, + }), +}) + +export const joinScandicFriendsBlockSchema = z + .object({ + typename: z + .literal(BlocksEnums.block.JoinScandicFriends) + .optional() + .default(BlocksEnums.block.JoinScandicFriends), + }) + .merge(joinScandicFriendsSchema) + +export const joinScandicFriendsBlockRefsSchema = z.object({ + join_scandic_friends: z.object({ + primary_button: linkConnectionRefsSchema, + }), +}) diff --git a/server/routers/contentstack/startPage/output.ts b/server/routers/contentstack/startPage/output.ts index 4ee6b6212..e0372230e 100644 --- a/server/routers/contentstack/startPage/output.ts +++ b/server/routers/contentstack/startPage/output.ts @@ -14,6 +14,10 @@ import { fullWidthCampaignBlockRefsSchema, fullWidthCampaignBlockSchema, } from "../schemas/blocks/fullWidthCampaign" +import { + joinScandicFriendsBlockRefsSchema, + joinScandicFriendsBlockSchema, +} from "../schemas/blocks/joinScandicFriends" import { tempImageVaultAssetSchema } from "../schemas/imageVault" import { systemSchema } from "../schemas/system" @@ -37,10 +41,17 @@ const startPageFullWidthCampaign = z }) .merge(fullWidthCampaignBlockSchema) +const startPageJoinScandicFriends = z + .object({ + __typename: z.literal(StartPageEnum.ContentStack.blocks.JoinScandicFriends), + }) + .merge(joinScandicFriendsBlockSchema) + export const blocksSchema = z.discriminatedUnion("__typename", [ startPageCards, startPageFullWidthCampaign, startPageCarouselCards, + startPageJoinScandicFriends, ]) export const startPageSchema = z.object({ @@ -82,10 +93,17 @@ const startPageCarouselCardsRef = z }) .merge(carouselCardsRefsSchema) +const startPageJoinScandicFriendsRef = z + .object({ + __typename: z.literal(StartPageEnum.ContentStack.blocks.JoinScandicFriends), + }) + .merge(joinScandicFriendsBlockRefsSchema) + const startPageBlockRefsItem = z.discriminatedUnion("__typename", [ startPageCardsRefs, startPageFullWidthCampaignRef, startPageCarouselCardsRef, + startPageJoinScandicFriendsRef, ]) export const startPageRefsSchema = z.object({ diff --git a/types/enums/blocks.ts b/types/enums/blocks.ts index ad3532441..b833e4a76 100644 --- a/types/enums/blocks.ts +++ b/types/enums/blocks.ts @@ -13,5 +13,6 @@ export namespace BlocksEnums { HotelListing = "HotelListing", FullWidthCampaign = "FullWidthCampaign", CarouselCards = "CarouselCards", + JoinScandicFriends = "JoinScandicFriends", } } diff --git a/types/enums/startPage.ts b/types/enums/startPage.ts index 684cfd7de..da55c58ca 100644 --- a/types/enums/startPage.ts +++ b/types/enums/startPage.ts @@ -4,6 +4,7 @@ export namespace StartPageEnum { CardsGrid = "StartPageBlocksCardsGrid", CarouselCards = "StartPageBlocksCarouselCards", FullWidthCampaign = "StartPageBlocksFullWidthCampaign", + JoinScandicFriends = "StartPageBlocksJoinScandicFriends", } } } diff --git a/types/trpc/routers/contentstack/startPage.ts b/types/trpc/routers/contentstack/startPage.ts index ae93ef46a..a1d24bb76 100644 --- a/types/trpc/routers/contentstack/startPage.ts +++ b/types/trpc/routers/contentstack/startPage.ts @@ -1,6 +1,7 @@ import type { z } from "zod" import type { fullWidthCampaignSchema } from "@/server/routers/contentstack/schemas/blocks/fullWidthCampaign" +import type { joinScandicFriendsSchema } from "@/server/routers/contentstack/schemas/blocks/joinScandicFriends" import type { blocksSchema, startPageRefsSchema, @@ -20,3 +21,7 @@ export type Block = z.output export type FullWidthCampaign = z.output< typeof fullWidthCampaignSchema >["full_width_campaign"] + +export type JoinScandicFriends = z.output< + typeof joinScandicFriendsSchema +>["join_scandic_friends"] From 053ce3f4de76d5aef0a5afb765526a77eaeab7c5 Mon Sep 17 00:00:00 2001 From: Christian Andolf Date: Thu, 6 Feb 2025 14:59:16 +0100 Subject: [PATCH 2/2] fix: startpage background is now white by default and jsf block is back to original design --- .../Blocks/JoinScandicFriends/joinScandicFriends.module.css | 1 - components/ContentType/StartPage/index.tsx | 4 ++-- components/ContentType/StartPage/startPage.module.css | 4 ++++ 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/components/Blocks/JoinScandicFriends/joinScandicFriends.module.css b/components/Blocks/JoinScandicFriends/joinScandicFriends.module.css index 9a35fa09f..a249af5c8 100644 --- a/components/Blocks/JoinScandicFriends/joinScandicFriends.module.css +++ b/components/Blocks/JoinScandicFriends/joinScandicFriends.module.css @@ -1,7 +1,6 @@ .container { border-radius: var(--Corner-radius-Large); background-color: var(--Main-Brand-WarmWhite); - background-color: white; padding: 0 var(--Spacing-x2); display: flex; gap: var(--Spacing-x5); diff --git a/components/ContentType/StartPage/index.tsx b/components/ContentType/StartPage/index.tsx index c19a21ad8..01e174ecd 100644 --- a/components/ContentType/StartPage/index.tsx +++ b/components/ContentType/StartPage/index.tsx @@ -21,7 +21,7 @@ export default async function StartPage() { const { header, blocks } = content.startPage return ( - <> +
@@ -65,6 +65,6 @@ export default async function StartPage() { <Suspense fallback={null}> <TrackingSDK pageData={content.tracking} /> </Suspense> - </> + </div> ) } diff --git a/components/ContentType/StartPage/startPage.module.css b/components/ContentType/StartPage/startPage.module.css index 2c9b1f6b3..3116430fc 100644 --- a/components/ContentType/StartPage/startPage.module.css +++ b/components/ContentType/StartPage/startPage.module.css @@ -1,3 +1,7 @@ +.background { + background-color: var(--Base-Surface-Primary-light-Normal); +} + .header { height: 560px; position: relative;