feat(SW-2270): Added hotel listing block to campaign overview page
Approved-by: Matilda Landström
This commit is contained in:
@@ -20,6 +20,7 @@ import type { HotelDataWithUrl } from "@scandic-hotels/trpc/types/hotel"
|
|||||||
|
|
||||||
interface CampaignHotelListingClientProps {
|
interface CampaignHotelListingClientProps {
|
||||||
heading: string
|
heading: string
|
||||||
|
preamble?: string | null
|
||||||
hotels: HotelDataWithUrl[]
|
hotels: HotelDataWithUrl[]
|
||||||
visibleCountMobile?: 3 | 6
|
visibleCountMobile?: 3 | 6
|
||||||
visibleCountDesktop?: 3 | 6
|
visibleCountDesktop?: 3 | 6
|
||||||
@@ -27,6 +28,7 @@ interface CampaignHotelListingClientProps {
|
|||||||
|
|
||||||
export default function CampaignHotelListingClient({
|
export default function CampaignHotelListingClient({
|
||||||
heading,
|
heading,
|
||||||
|
preamble,
|
||||||
hotels,
|
hotels,
|
||||||
visibleCountMobile = 3,
|
visibleCountMobile = 3,
|
||||||
visibleCountDesktop = 6,
|
visibleCountDesktop = 6,
|
||||||
@@ -46,7 +48,7 @@ export default function CampaignHotelListingClient({
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Only show the show more/less button if the length of hotels exceeds the threshold count
|
// Only show the show more/less button if the length of hotels exceeds the threshold count
|
||||||
const showButton = hotels.length >= thresholdCount
|
const showButton = hotels.length > thresholdCount
|
||||||
|
|
||||||
// Determine if we are at the stage where the user can click to show all hotels
|
// Determine if we are at the stage where the user can click to show all hotels
|
||||||
const canShowAll =
|
const canShowAll =
|
||||||
@@ -93,6 +95,11 @@ export default function CampaignHotelListingClient({
|
|||||||
<Typography variant="Title/Subtitle/lg">
|
<Typography variant="Title/Subtitle/lg">
|
||||||
<h3>{heading}</h3>
|
<h3>{heading}</h3>
|
||||||
</Typography>
|
</Typography>
|
||||||
|
{preamble ? (
|
||||||
|
<Typography variant="Body/Paragraph/mdRegular">
|
||||||
|
<p>{preamble}</p>
|
||||||
|
</Typography>
|
||||||
|
) : null}
|
||||||
</header>
|
</header>
|
||||||
<ul className={styles.list}>
|
<ul className={styles.list}>
|
||||||
{hotels.map(({ hotel, url }, index) => (
|
{hotels.map(({ hotel, url }, index) => (
|
||||||
|
|||||||
@@ -8,6 +8,11 @@
|
|||||||
scroll-margin-top: var(--scroll-margin-top);
|
scroll-margin-top: var(--scroll-margin-top);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.header {
|
||||||
|
display: grid;
|
||||||
|
gap: var(--Space-x15);
|
||||||
|
}
|
||||||
|
|
||||||
.list {
|
.list {
|
||||||
list-style: none;
|
list-style: none;
|
||||||
display: grid;
|
display: grid;
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import CampaignHotelListingClient from "./Client"
|
|||||||
|
|
||||||
interface CampaignHotelListingProps {
|
interface CampaignHotelListingProps {
|
||||||
heading: string
|
heading: string
|
||||||
|
preamble?: string | null
|
||||||
hotelIds: string[]
|
hotelIds: string[]
|
||||||
visibleCountMobile?: 3 | 6
|
visibleCountMobile?: 3 | 6
|
||||||
visibleCountDesktop?: 3 | 6
|
visibleCountDesktop?: 3 | 6
|
||||||
@@ -11,6 +12,7 @@ interface CampaignHotelListingProps {
|
|||||||
|
|
||||||
export default async function CampaignHotelListing({
|
export default async function CampaignHotelListing({
|
||||||
heading,
|
heading,
|
||||||
|
preamble,
|
||||||
hotelIds,
|
hotelIds,
|
||||||
visibleCountMobile,
|
visibleCountMobile,
|
||||||
visibleCountDesktop,
|
visibleCountDesktop,
|
||||||
@@ -24,6 +26,7 @@ export default async function CampaignHotelListing({
|
|||||||
return (
|
return (
|
||||||
<CampaignHotelListingClient
|
<CampaignHotelListingClient
|
||||||
heading={heading}
|
heading={heading}
|
||||||
|
preamble={preamble}
|
||||||
hotels={hotels}
|
hotels={hotels}
|
||||||
visibleCountMobile={visibleCountMobile}
|
visibleCountMobile={visibleCountMobile}
|
||||||
visibleCountDesktop={visibleCountDesktop}
|
visibleCountDesktop={visibleCountDesktop}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { BlocksEnums } from "@scandic-hotels/trpc/types/blocks"
|
import { BlocksEnums } from "@scandic-hotels/trpc/types/blocks"
|
||||||
|
|
||||||
|
import CampaignHotelListing from "@/components/Blocks/CampaignHotelListing"
|
||||||
import CarouselCards from "@/components/Blocks/CarouselCards"
|
import CarouselCards from "@/components/Blocks/CarouselCards"
|
||||||
|
|
||||||
import type { BlocksProps } from "@/types/components/blocks"
|
import type { BlocksProps } from "@/types/components/blocks"
|
||||||
@@ -14,6 +15,17 @@ export default function Blocks({ blocks }: BlocksProps) {
|
|||||||
key={block.carousel_cards.heading}
|
key={block.carousel_cards.heading}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
|
case BlocksEnums.block.CampaignOverviewPageHotelListing:
|
||||||
|
return (
|
||||||
|
<CampaignHotelListing
|
||||||
|
key={block.hotel_listing.heading}
|
||||||
|
heading={block.hotel_listing.heading}
|
||||||
|
preamble={block.hotel_listing.preamble}
|
||||||
|
hotelIds={block.hotel_listing.hotelIds}
|
||||||
|
visibleCountMobile={3}
|
||||||
|
visibleCountDesktop={3}
|
||||||
|
/>
|
||||||
|
)
|
||||||
default:
|
default:
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,3 +29,19 @@ fragment HotelListing_CampaignPage on CampaignPageBlocksHotelListing {
|
|||||||
heading
|
heading
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fragment HotelListing_CampaignOverviewPage on CampaignOverviewPageBlocksHotelListing {
|
||||||
|
hotel_listing {
|
||||||
|
heading
|
||||||
|
preamble
|
||||||
|
included_hotelsConnection {
|
||||||
|
edges {
|
||||||
|
node {
|
||||||
|
... on HotelPage {
|
||||||
|
hotel_page_id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
#import "../../Fragments/CampaignOverviewPage/TopCampaign.graphql"
|
#import "../../Fragments/CampaignOverviewPage/TopCampaign.graphql"
|
||||||
|
|
||||||
#import "../../Fragments/Blocks/CarouselCards.graphql"
|
#import "../../Fragments/Blocks/CarouselCards.graphql"
|
||||||
|
#import "../../Fragments/Blocks/HotelListing.graphql"
|
||||||
|
|
||||||
query GetCampaignOverviewPage($locale: String!, $uid: String!) {
|
query GetCampaignOverviewPage($locale: String!, $uid: String!) {
|
||||||
campaign_overview_page(uid: $uid, locale: $locale) {
|
campaign_overview_page(uid: $uid, locale: $locale) {
|
||||||
@@ -23,6 +24,7 @@ query GetCampaignOverviewPage($locale: String!, $uid: String!) {
|
|||||||
blocks {
|
blocks {
|
||||||
__typename
|
__typename
|
||||||
...CarouselCards_CampaignOverviewPage
|
...CarouselCards_CampaignOverviewPage
|
||||||
|
...HotelListing_CampaignOverviewPage
|
||||||
}
|
}
|
||||||
system {
|
system {
|
||||||
...System
|
...System
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import {
|
|||||||
carouselCardsRefsSchema,
|
carouselCardsRefsSchema,
|
||||||
carouselCardsSchema,
|
carouselCardsSchema,
|
||||||
} from "../schemas/blocks/carouselCards"
|
} from "../schemas/blocks/carouselCards"
|
||||||
|
import { campaignOverviewPageHotelListingSchema } from "../schemas/blocks/hotelListing"
|
||||||
import {
|
import {
|
||||||
linkAndTitleSchema,
|
linkAndTitleSchema,
|
||||||
linkConnectionRefs,
|
linkConnectionRefs,
|
||||||
@@ -70,8 +71,17 @@ const campaignOverviewPageCarouselCards = z
|
|||||||
})
|
})
|
||||||
.merge(carouselCardsSchema)
|
.merge(carouselCardsSchema)
|
||||||
|
|
||||||
|
export const campaignOverviewPageHotelListing = z
|
||||||
|
.object({
|
||||||
|
__typename: z.literal(
|
||||||
|
CampaignOverviewPageEnum.ContentStack.blocks.HotelListing
|
||||||
|
),
|
||||||
|
})
|
||||||
|
.merge(campaignOverviewPageHotelListingSchema)
|
||||||
|
|
||||||
export const blocksSchema = z.discriminatedUnion("__typename", [
|
export const blocksSchema = z.discriminatedUnion("__typename", [
|
||||||
campaignOverviewPageCarouselCards,
|
campaignOverviewPageCarouselCards,
|
||||||
|
campaignOverviewPageHotelListing,
|
||||||
])
|
])
|
||||||
|
|
||||||
export const campaignOverviewPageSchema = z.object({
|
export const campaignOverviewPageSchema = z.object({
|
||||||
|
|||||||
@@ -69,3 +69,34 @@ export const campaignPageHotelListingSchema = z.object({
|
|||||||
heading: z.string(),
|
heading: z.string(),
|
||||||
}),
|
}),
|
||||||
})
|
})
|
||||||
|
|
||||||
|
export const campaignOverviewPageHotelListingSchema = z.object({
|
||||||
|
typename: z
|
||||||
|
.literal(BlocksEnums.block.CampaignOverviewPageHotelListing)
|
||||||
|
.default(BlocksEnums.block.CampaignOverviewPageHotelListing),
|
||||||
|
hotel_listing: z
|
||||||
|
.object({
|
||||||
|
heading: z.string(),
|
||||||
|
preamble: z.string().nullish(),
|
||||||
|
included_hotelsConnection: z.object({
|
||||||
|
edges: z.array(
|
||||||
|
z.object({
|
||||||
|
node: z.object({
|
||||||
|
hotel_page_id: z.string(),
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
),
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
.transform((data) => {
|
||||||
|
const { included_hotelsConnection, ...rest } = data
|
||||||
|
const hotelIds = data.included_hotelsConnection.edges
|
||||||
|
.map(({ node }) => node.hotel_page_id)
|
||||||
|
.filter(Boolean)
|
||||||
|
|
||||||
|
return {
|
||||||
|
...rest,
|
||||||
|
hotelIds,
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ export namespace BlocksEnums {
|
|||||||
Content = "Content",
|
Content = "Content",
|
||||||
DynamicContent = "DynamicContent",
|
DynamicContent = "DynamicContent",
|
||||||
FullWidthCampaign = "FullWidthCampaign",
|
FullWidthCampaign = "FullWidthCampaign",
|
||||||
|
CampaignOverviewPageHotelListing = "CampaignOverviewPageHotelListing",
|
||||||
CampaignPageHotelListing = "CampaignPageHotelListing",
|
CampaignPageHotelListing = "CampaignPageHotelListing",
|
||||||
ContentPageHotelListing = "ContentPageHotelListing",
|
ContentPageHotelListing = "ContentPageHotelListing",
|
||||||
JoinScandicFriends = "JoinScandicFriends",
|
JoinScandicFriends = "JoinScandicFriends",
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ export namespace CampaignOverviewPageEnum {
|
|||||||
export namespace ContentStack {
|
export namespace ContentStack {
|
||||||
export const enum blocks {
|
export const enum blocks {
|
||||||
CarouselCards = "CampaignOverviewPageBlocksCarouselCards",
|
CarouselCards = "CampaignOverviewPageBlocksCarouselCards",
|
||||||
|
HotelListing = "CampaignOverviewPageBlocksHotelListing",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user