From caffa1821f34f35e77335ccf6a3746a7e1f72b3b Mon Sep 17 00:00:00 2001 From: Erik Tiekstra Date: Fri, 22 Aug 2025 09:30:45 +0000 Subject: [PATCH] feat(SW-3288): Added sort order on campaign pages to sort campaigns on hotel pages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Approved-by: Matilda Landström --- .../CampaignPagesByHotelUid.graphql | 7 +++-- .../contentstack/campaignPage/output.ts | 5 +++- .../routers/contentstack/hotelPage/utils.ts | 28 ++++++++++++++++++- 3 files changed, 36 insertions(+), 4 deletions(-) diff --git a/packages/trpc/lib/graphql/Query/CampaignPage/CampaignPagesByHotelUid.graphql b/packages/trpc/lib/graphql/Query/CampaignPage/CampaignPagesByHotelUid.graphql index 6e841d1f5..1cebbd641 100644 --- a/packages/trpc/lib/graphql/Query/CampaignPage/CampaignPagesByHotelUid.graphql +++ b/packages/trpc/lib/graphql/Query/CampaignPage/CampaignPagesByHotelUid.graphql @@ -8,7 +8,6 @@ query GetCampaignPagesByHotelUid( $today: DateTime! ) { all_campaign_page( - locale: $locale where: { OR: [ { included_hotels: { list_1: { hotel_page: { uid: $hotelPageUid } } } } @@ -19,10 +18,13 @@ query GetCampaignPagesByHotelUid( { OR: [{ enddate: null }, { enddate_gte: $today }] } ] } + locale: $locale + limit: 100 ) { items { heading url + sort_order card_content { heading image @@ -42,7 +44,6 @@ query GetCampaignPagesByHotelUidRefs( $today: DateTime! ) { all_campaign_page( - locale: $locale where: { OR: [ { included_hotels: { list_1: { hotel_page: { uid: $hotelPageUid } } } } @@ -53,6 +54,8 @@ query GetCampaignPagesByHotelUidRefs( { OR: [{ enddate: null }, { enddate_gte: $today }] } ] } + locale: $locale + limit: 100 ) { items { ...CampaignPageRef diff --git a/packages/trpc/lib/routers/contentstack/campaignPage/output.ts b/packages/trpc/lib/routers/contentstack/campaignPage/output.ts index e1294ae55..1bded036a 100644 --- a/packages/trpc/lib/routers/contentstack/campaignPage/output.ts +++ b/packages/trpc/lib/routers/contentstack/campaignPage/output.ts @@ -185,6 +185,7 @@ export const campaignPagesByHotelUidSchema = z z.object({ heading: z.string(), url: z.string(), + sort_order: z.number().nullish(), card_content: z .object({ image: tempImageVaultAssetSchema, @@ -198,7 +199,8 @@ export const campaignPagesByHotelUidSchema = z ) .transform((data) => { const mappedCampaigns = data.map((campaign) => { - const { card_content, hero, system, heading, url } = campaign + const { card_content, hero, system, heading, sort_order, url } = + campaign const hasImage = !!(card_content?.image || hero.image) const cardContentImage = card_content?.image || hero.image const heroImage = hero.image || card_content?.image @@ -207,6 +209,7 @@ export const campaignPagesByHotelUidSchema = z return { id: system.uid, url: removeMultipleSlashes(`/${system.locale}/${url}`), + sort_order, card_content: { ...card_content, heading: card_content?.heading || heading, diff --git a/packages/trpc/lib/routers/contentstack/hotelPage/utils.ts b/packages/trpc/lib/routers/contentstack/hotelPage/utils.ts index 24937524d..f4176ffce 100644 --- a/packages/trpc/lib/routers/contentstack/hotelPage/utils.ts +++ b/packages/trpc/lib/routers/contentstack/hotelPage/utils.ts @@ -103,11 +103,37 @@ export function getSortedCampaigns( prioritizedCampaignUids: string[], campaigns: Campaigns ) { + // First we'll sort on the list of prioritizedCampaignUids provided by the + // hotel page. If the campaign is not in the prioritized list, it will be + // added to the end of the sorted list using the default order from Contentstack. const prioritizedSet = new Set(prioritizedCampaignUids) const prioritized = prioritizedCampaignUids.flatMap((id) => { const found = campaigns.find((c) => c.id === id) return found ? [found] : [] }) const others = campaigns.filter((c) => !prioritizedSet.has(c.id)) - return [...prioritized, ...others] + const sortedCampaigns = [...prioritized, ...others] + + // Finally, we'll sort the campaigns by their sort_order, which gets higher priority + // than the order by prioritizedCampaignUids. If sort_order is not provided, + // we'll keep the original order. The higher the sort_order value, the higher the priority. + return sortedCampaigns.sort((a, b) => { + const aSortOrder = a.sort_order + const bSortOrder = b.sort_order + + const aHasSortOrder = typeof aSortOrder === "number" + const bHasSortOrder = typeof bSortOrder === "number" + + if (aHasSortOrder && bHasSortOrder) { + // Descending order: higher sort_order comes first + return bSortOrder - aSortOrder + } + if (aHasSortOrder && !bHasSortOrder) { + return -1 + } + if (!aHasSortOrder && bHasSortOrder) { + return 1 + } + return 0 + }) }