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 {
|
||||
heading: string
|
||||
preamble?: string | null
|
||||
hotels: HotelDataWithUrl[]
|
||||
visibleCountMobile?: 3 | 6
|
||||
visibleCountDesktop?: 3 | 6
|
||||
@@ -27,6 +28,7 @@ interface CampaignHotelListingClientProps {
|
||||
|
||||
export default function CampaignHotelListingClient({
|
||||
heading,
|
||||
preamble,
|
||||
hotels,
|
||||
visibleCountMobile = 3,
|
||||
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
|
||||
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
|
||||
const canShowAll =
|
||||
@@ -93,6 +95,11 @@ export default function CampaignHotelListingClient({
|
||||
<Typography variant="Title/Subtitle/lg">
|
||||
<h3>{heading}</h3>
|
||||
</Typography>
|
||||
{preamble ? (
|
||||
<Typography variant="Body/Paragraph/mdRegular">
|
||||
<p>{preamble}</p>
|
||||
</Typography>
|
||||
) : null}
|
||||
</header>
|
||||
<ul className={styles.list}>
|
||||
{hotels.map(({ hotel, url }, index) => (
|
||||
|
||||
@@ -8,6 +8,11 @@
|
||||
scroll-margin-top: var(--scroll-margin-top);
|
||||
}
|
||||
|
||||
.header {
|
||||
display: grid;
|
||||
gap: var(--Space-x15);
|
||||
}
|
||||
|
||||
.list {
|
||||
list-style: none;
|
||||
display: grid;
|
||||
|
||||
@@ -4,6 +4,7 @@ import CampaignHotelListingClient from "./Client"
|
||||
|
||||
interface CampaignHotelListingProps {
|
||||
heading: string
|
||||
preamble?: string | null
|
||||
hotelIds: string[]
|
||||
visibleCountMobile?: 3 | 6
|
||||
visibleCountDesktop?: 3 | 6
|
||||
@@ -11,6 +12,7 @@ interface CampaignHotelListingProps {
|
||||
|
||||
export default async function CampaignHotelListing({
|
||||
heading,
|
||||
preamble,
|
||||
hotelIds,
|
||||
visibleCountMobile,
|
||||
visibleCountDesktop,
|
||||
@@ -24,6 +26,7 @@ export default async function CampaignHotelListing({
|
||||
return (
|
||||
<CampaignHotelListingClient
|
||||
heading={heading}
|
||||
preamble={preamble}
|
||||
hotels={hotels}
|
||||
visibleCountMobile={visibleCountMobile}
|
||||
visibleCountDesktop={visibleCountDesktop}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { BlocksEnums } from "@scandic-hotels/trpc/types/blocks"
|
||||
|
||||
import CampaignHotelListing from "@/components/Blocks/CampaignHotelListing"
|
||||
import CarouselCards from "@/components/Blocks/CarouselCards"
|
||||
|
||||
import type { BlocksProps } from "@/types/components/blocks"
|
||||
@@ -14,6 +15,17 @@ export default function Blocks({ blocks }: BlocksProps) {
|
||||
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:
|
||||
return null
|
||||
}
|
||||
|
||||
@@ -29,3 +29,19 @@ fragment HotelListing_CampaignPage on CampaignPageBlocksHotelListing {
|
||||
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/Blocks/CarouselCards.graphql"
|
||||
#import "../../Fragments/Blocks/HotelListing.graphql"
|
||||
|
||||
query GetCampaignOverviewPage($locale: String!, $uid: String!) {
|
||||
campaign_overview_page(uid: $uid, locale: $locale) {
|
||||
@@ -23,6 +24,7 @@ query GetCampaignOverviewPage($locale: String!, $uid: String!) {
|
||||
blocks {
|
||||
__typename
|
||||
...CarouselCards_CampaignOverviewPage
|
||||
...HotelListing_CampaignOverviewPage
|
||||
}
|
||||
system {
|
||||
...System
|
||||
|
||||
@@ -12,6 +12,7 @@ import {
|
||||
carouselCardsRefsSchema,
|
||||
carouselCardsSchema,
|
||||
} from "../schemas/blocks/carouselCards"
|
||||
import { campaignOverviewPageHotelListingSchema } from "../schemas/blocks/hotelListing"
|
||||
import {
|
||||
linkAndTitleSchema,
|
||||
linkConnectionRefs,
|
||||
@@ -70,8 +71,17 @@ const campaignOverviewPageCarouselCards = z
|
||||
})
|
||||
.merge(carouselCardsSchema)
|
||||
|
||||
export const campaignOverviewPageHotelListing = z
|
||||
.object({
|
||||
__typename: z.literal(
|
||||
CampaignOverviewPageEnum.ContentStack.blocks.HotelListing
|
||||
),
|
||||
})
|
||||
.merge(campaignOverviewPageHotelListingSchema)
|
||||
|
||||
export const blocksSchema = z.discriminatedUnion("__typename", [
|
||||
campaignOverviewPageCarouselCards,
|
||||
campaignOverviewPageHotelListing,
|
||||
])
|
||||
|
||||
export const campaignOverviewPageSchema = z.object({
|
||||
|
||||
@@ -69,3 +69,34 @@ export const campaignPageHotelListingSchema = z.object({
|
||||
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",
|
||||
DynamicContent = "DynamicContent",
|
||||
FullWidthCampaign = "FullWidthCampaign",
|
||||
CampaignOverviewPageHotelListing = "CampaignOverviewPageHotelListing",
|
||||
CampaignPageHotelListing = "CampaignPageHotelListing",
|
||||
ContentPageHotelListing = "ContentPageHotelListing",
|
||||
JoinScandicFriends = "JoinScandicFriends",
|
||||
|
||||
@@ -2,6 +2,7 @@ export namespace CampaignOverviewPageEnum {
|
||||
export namespace ContentStack {
|
||||
export const enum blocks {
|
||||
CarouselCards = "CampaignOverviewPageBlocksCarouselCards",
|
||||
HotelListing = "CampaignOverviewPageBlocksHotelListing",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user