feat(SW-1389): refactor page settings

This commit is contained in:
Michael Zetterberg
2025-02-17 06:15:21 +01:00
parent 504fe7cb99
commit 82ba219e2b
18 changed files with 203 additions and 181 deletions

View File

@@ -1,5 +1,4 @@
import { env } from "@/env/server" import { env } from "@/env/server"
import { serverClient } from "@/lib/trpc/server"
import BookingWidget, { preload } from "@/components/BookingWidget" import BookingWidget, { preload } from "@/components/BookingWidget"
@@ -15,13 +14,5 @@ export default async function BookingWidgetPage({
preload() preload()
// Get the booking widget show/hide status based on page specific settings
const bookingWidgetToggle =
await serverClient().contentstack.bookingwidget.toggle.get()
if (bookingWidgetToggle.hideBookingWidget) {
return null
}
return <BookingWidget bookingWidgetSearchParams={searchParams} /> return <BookingWidget bookingWidgetSearchParams={searchParams} />
} }

View File

@@ -5,10 +5,10 @@ import { z } from "zod"
import { Lang } from "@/constants/languages" import { Lang } from "@/constants/languages"
import { env } from "@/env/server" import { env } from "@/env/server"
import { badRequest, internalServerError } from "@/server/errors/next" import { badRequest, internalServerError } from "@/server/errors/next"
import { affix as bookingwidgetAffix } from "@/server/routers/contentstack/bookingwidget/utils"
import { affix as breadcrumbsAffix } from "@/server/routers/contentstack/breadcrumbs/utils" import { affix as breadcrumbsAffix } from "@/server/routers/contentstack/breadcrumbs/utils"
import { languageSwitcherAffix } from "@/server/routers/contentstack/languageSwitcher/utils" import { languageSwitcherAffix } from "@/server/routers/contentstack/languageSwitcher/utils"
import { affix as metadataAffix } from "@/server/routers/contentstack/metadata/utils" import { affix as metadataAffix } from "@/server/routers/contentstack/metadata/utils"
import { affix as pageSettingsAffix } from "@/server/routers/contentstack/pageSettings/utils"
import { import {
generateRefsResponseTag, generateRefsResponseTag,
@@ -124,15 +124,15 @@ export async function POST(request: NextRequest) {
revalidateTag(breadcrumbsTag) revalidateTag(breadcrumbsTag)
} }
if (entry.page_settings?.hide_booking_widget) { if (entry.page_settings) {
const bookingwidgetTag = generateTag( const pageSettingsTag = generateTag(
entryLocale, entryLocale,
entry.uid, entry.uid,
bookingwidgetAffix pageSettingsAffix
) )
console.info(`Revalidating breadcrumbsTag: ${bookingwidgetTag}`) console.info(`Revalidating pageSettingsTag: ${pageSettingsTag}`)
revalidateTag(bookingwidgetTag) revalidateTag(pageSettingsTag)
} }
return Response.json({ revalidated: true, now: Date.now() }) return Response.json({ revalidated: true, now: Date.now() })

View File

@@ -1,6 +1,7 @@
import { getLocations, getSiteConfig } from "@/lib/trpc/memoizedRequests" import {
getLocations,
import { getLang } from "@/i18n/serverContext" isBookingWidgetHidden,
} from "@/lib/trpc/memoizedRequests"
import BookingWidgetClient from "./Client" import BookingWidgetClient from "./Client"
@@ -14,11 +15,15 @@ export default async function BookingWidget({
type, type,
bookingWidgetSearchParams, bookingWidgetSearchParams,
}: BookingWidgetProps) { }: BookingWidgetProps) {
const lang = await getLang() const isHidden = await isBookingWidgetHidden()
const locations = await getLocations()
const siteConfig = await getSiteConfig(lang)
if (!locations || "error" in locations || siteConfig?.bookingWidgetDisabled) { if (isHidden) {
return null
}
const locations = await getLocations()
if (!locations || "error" in locations) {
return null return null
} }

View File

@@ -0,0 +1,3 @@
fragment PageSettings on PageSettings {
hide_booking_widget
}

View File

@@ -1,68 +0,0 @@
query GetAccountPageSettings($uid: String!, $locale: String!) {
account_page(uid: $uid, locale: $locale) {
page_settings {
hide_booking_widget
}
}
}
query GetLoyaltyPageSettings($uid: String!, $locale: String!) {
loyalty_page(uid: $uid, locale: $locale) {
page_settings {
hide_booking_widget
}
}
}
query GetCollectionPageSettings($uid: String!, $locale: String!) {
collection_page(uid: $uid, locale: $locale) {
page_settings {
hide_booking_widget
}
}
}
query GetContentPageSettings($uid: String!, $locale: String!) {
content_page(uid: $uid, locale: $locale) {
page_settings {
hide_booking_widget
}
}
}
query GetDestinationOverviewPageSettings($uid: String!, $locale: String!) {
destination_overview_page(uid: $uid, locale: $locale) {
page_settings {
hide_booking_widget
}
}
}
query GetDestinationCountryPageSettings($uid: String!, $locale: String!) {
destination_country_page(uid: $uid, locale: $locale) {
page_settings {
hide_booking_widget
}
}
}
query GetDestinationCityPageSettings($uid: String!, $locale: String!) {
destination_city_page(uid: $uid, locale: $locale) {
page_settings {
hide_booking_widget
}
}
}
query GetHotelPageSettings($uid: String!, $locale: String!) {
hotel_page(uid: $uid, locale: $locale) {
page_settings {
hide_booking_widget
}
}
}
query GetCurrentBlocksPageSettings($uid: String!, $locale: String!) {
current_blocks_page(uid: $uid, locale: $locale) {
page_settings {
hide_booking_widget
}
}
}

View File

@@ -0,0 +1,81 @@
#import "../Fragments/PageSettings.graphql"
query GetAccountPageSettings($uid: String!, $locale: String!) {
page: account_page(uid: $uid, locale: $locale) {
settings: page_settings {
...PageSettings
}
}
}
query GetCollectionPageSettings($uid: String!, $locale: String!) {
page: collection_page(uid: $uid, locale: $locale) {
settings: page_settings {
...PageSettings
}
}
}
query GetContentPageSettings($uid: String!, $locale: String!) {
page: content_page(uid: $uid, locale: $locale) {
settings: page_settings {
...PageSettings
}
}
}
query GetCurrentBlocksPageSettings($uid: String!, $locale: String!) {
page: current_blocks_page(uid: $uid, locale: $locale) {
settings: page_settings {
...PageSettings
}
}
}
query GetDestinationCityPageSettings($uid: String!, $locale: String!) {
page: destination_city_page(uid: $uid, locale: $locale) {
settings: page_settings {
...PageSettings
}
}
}
query GetDestinationCountryPageSettings($uid: String!, $locale: String!) {
page: destination_country_page(uid: $uid, locale: $locale) {
settings: page_settings {
...PageSettings
}
}
}
query GetDestinationOverviewPageSettings($uid: String!, $locale: String!) {
page: destination_overview_page(uid: $uid, locale: $locale) {
settings: page_settings {
...PageSettings
}
}
}
query GetHotelPageSettings($uid: String!, $locale: String!) {
page: hotel_page(uid: $uid, locale: $locale) {
settings: page_settings {
...PageSettings
}
}
}
query GetLoyaltyPageSettings($uid: String!, $locale: String!) {
page: loyalty_page(uid: $uid, locale: $locale) {
settings: page_settings {
...PageSettings
}
}
}
query GetStartPageSettings($uid: String!, $locale: String!) {
page: start_page(uid: $uid, locale: $locale) {
settings: page_settings {
...PageSettings
}
}
}

View File

@@ -1,3 +1,4 @@
import { getLang } from "@/i18n/serverContext"
import { cache } from "@/utils/cache" import { cache } from "@/utils/cache"
import { serverClient } from "../server" import { serverClient } from "../server"
@@ -228,3 +229,36 @@ export const getDestinationCityPage = cache(
export const getStartPage = cache(async function getMemoizedStartPage() { export const getStartPage = cache(async function getMemoizedStartPage() {
return serverClient().contentstack.startPage.get() return serverClient().contentstack.startPage.get()
}) })
export const getPageSettings = cache(async function getMemoizedPageSettings(
lang: Lang
) {
return serverClient().contentstack.pageSettings.get({ lang })
})
export const isBookingWidgetHidden = cache(
async function isMemoizedBookingWidgetHidden() {
const lang = getLang()
const [pageSettingsResult, siteConfigResults] = await Promise.allSettled([
getPageSettings(lang),
getSiteConfig(lang),
])
const pageSettings =
pageSettingsResult.status === "fulfilled"
? pageSettingsResult.value
: null
const siteConfig =
siteConfigResults.status === "fulfilled" ? siteConfigResults.value : null
if (pageSettings) {
return pageSettings.page.settings.hide_booking_widget
}
if (siteConfig) {
return siteConfig.bookingWidgetDisabled
}
return false
}
)

View File

@@ -1,5 +0,0 @@
import { z } from "zod"
import { Lang } from "@/constants/languages"
export const langInput = z.object({ lang: z.nativeEnum(Lang) })

View File

@@ -18,6 +18,7 @@ import {
import { request } from "@/lib/graphql/request" import { request } from "@/lib/graphql/request"
import { notFound } from "@/server/errors/trpc" import { notFound } from "@/server/errors/trpc"
import { contentstackBaseProcedure, router } from "@/server/trpc" import { contentstackBaseProcedure, router } from "@/server/trpc"
import { langInput } from "@/server/utils"
import { import {
generateRefsResponseTag, generateRefsResponseTag,
@@ -26,7 +27,6 @@ import {
generateTagsFromSystem, generateTagsFromSystem,
} from "@/utils/generateTag" } from "@/utils/generateTag"
import { langInput } from "./input"
import { import {
type ContactConfigData, type ContactConfigData,
type CurrentFooterDataRaw, type CurrentFooterDataRaw,
@@ -619,7 +619,7 @@ export const baseQueryRouter = router({
siteConfig: contentstackBaseProcedure siteConfig: contentstackBaseProcedure
.input(langInput) .input(langInput)
.query(async ({ input, ctx }) => { .query(async ({ input, ctx }) => {
const lang = input?.lang ?? ctx.lang const lang = input.lang ?? ctx.lang
getSiteConfigRefCounter.add(1, { lang }) getSiteConfigRefCounter.add(1, { lang })
console.info( console.info(

View File

@@ -1,5 +0,0 @@
import { mergeRouters } from "@/server/trpc"
import { bookingwidgetQueryRouter } from "./query"
export const bookingwidgetRouter = mergeRouters(bookingwidgetQueryRouter)

View File

@@ -1,26 +0,0 @@
import { z } from "zod"
const bookingWidgetToggleSchema = z
.object({
page_settings: z.object({
hide_booking_widget: z.boolean(),
}),
})
.optional()
export const validateBookingWidgetToggleSchema = z.object({
account_page: bookingWidgetToggleSchema,
collection_page: bookingWidgetToggleSchema,
content_page: bookingWidgetToggleSchema,
current_blocks_page: bookingWidgetToggleSchema,
destination_overview_page: bookingWidgetToggleSchema,
destination_country_page: bookingWidgetToggleSchema,
destination_city_page: bookingWidgetToggleSchema,
hotel_page: bookingWidgetToggleSchema,
loyalty_page: bookingWidgetToggleSchema,
start_page: bookingWidgetToggleSchema,
})
export type ValidateBookingWidgetToggleType = z.infer<
typeof validateBookingWidgetToggleSchema
>

View File

@@ -1 +0,0 @@
export const affix = "bookingwidget"

View File

@@ -2,7 +2,6 @@ import { router } from "@/server/trpc"
import { accountPageRouter } from "./accountPage" import { accountPageRouter } from "./accountPage"
import { baseRouter } from "./base" import { baseRouter } from "./base"
import { bookingwidgetRouter } from "./bookingwidget"
import { breadcrumbsRouter } from "./breadcrumbs" import { breadcrumbsRouter } from "./breadcrumbs"
import { collectionPageRouter } from "./collectionPage" import { collectionPageRouter } from "./collectionPage"
import { contentPageRouter } from "./contentPage" import { contentPageRouter } from "./contentPage"
@@ -14,6 +13,7 @@ import { languageSwitcherRouter } from "./languageSwitcher"
import { loyaltyLevelRouter } from "./loyaltyLevel" import { loyaltyLevelRouter } from "./loyaltyLevel"
import { loyaltyPageRouter } from "./loyaltyPage" import { loyaltyPageRouter } from "./loyaltyPage"
import { metadataRouter } from "./metadata" import { metadataRouter } from "./metadata"
import { pageSettingsRouter } from "./pageSettings"
import { partnerRouter } from "./partner" import { partnerRouter } from "./partner"
import { rewardRouter } from "./reward" import { rewardRouter } from "./reward"
import { startPageRouter } from "./startPage" import { startPageRouter } from "./startPage"
@@ -21,7 +21,6 @@ import { startPageRouter } from "./startPage"
export const contentstackRouter = router({ export const contentstackRouter = router({
accountPage: accountPageRouter, accountPage: accountPageRouter,
base: baseRouter, base: baseRouter,
bookingwidget: bookingwidgetRouter,
breadcrumbs: breadcrumbsRouter, breadcrumbs: breadcrumbsRouter,
hotelPage: hotelPageRouter, hotelPage: hotelPageRouter,
languageSwitcher: languageSwitcherRouter, languageSwitcher: languageSwitcherRouter,
@@ -32,6 +31,7 @@ export const contentstackRouter = router({
destinationCountryPage: destinationCountryPageRouter, destinationCountryPage: destinationCountryPageRouter,
destinationCityPage: destinationCityPageRouter, destinationCityPage: destinationCityPageRouter,
metadata: metadataRouter, metadata: metadataRouter,
pageSettings: pageSettingsRouter,
rewards: rewardRouter, rewards: rewardRouter,
loyaltyLevels: loyaltyLevelRouter, loyaltyLevels: loyaltyLevelRouter,
startPage: startPageRouter, startPage: startPageRouter,

View File

@@ -0,0 +1,5 @@
import { mergeRouters } from "@/server/trpc"
import { pageSettingsQueryRouter } from "./query"
export const pageSettingsRouter = mergeRouters(pageSettingsQueryRouter)

View File

@@ -0,0 +1,15 @@
import { z } from "zod"
export const pageSettingsSchema = z.object({
hide_booking_widget: z.boolean(),
})
export type PageSettingsSchema = z.output<typeof pageSettingsSchema>
export const getPageSettingsSchema = z.object({
page: z.object({
settings: pageSettingsSchema,
}),
})
export type GetPageSettingsSchema = z.output<typeof getPageSettingsSchema>

View File

@@ -8,74 +8,76 @@ import {
GetDestinationOverviewPageSettings, GetDestinationOverviewPageSettings,
GetHotelPageSettings, GetHotelPageSettings,
GetLoyaltyPageSettings, GetLoyaltyPageSettings,
} from "@/lib/graphql/Query/BookingWidgetToggle.graphql" GetStartPageSettings,
} from "@/lib/graphql/Query/PageSettings.graphql"
import { request } from "@/lib/graphql/request" import { request } from "@/lib/graphql/request"
import { contentstackBaseProcedure, router } from "@/server/trpc" import { contentstackBaseProcedure, router } from "@/server/trpc"
import { langInput } from "@/server/utils"
import { generateTag } from "@/utils/generateTag" import { generateTag } from "@/utils/generateTag"
import { import { type GetPageSettingsSchema, getPageSettingsSchema } from "./output"
validateBookingWidgetToggleSchema, import { affix } from "./utils"
type ValidateBookingWidgetToggleType,
} from "./output"
import { affix as bookingwidgetAffix } from "./utils"
import type { ValueOf } from "next/dist/shared/lib/constants"
import { PageContentTypeEnum } from "@/types/requests/contentType" import { PageContentTypeEnum } from "@/types/requests/contentType"
export const bookingwidgetQueryRouter = router({ export const pageSettingsQueryRouter = router({
toggle: router({ get: contentstackBaseProcedure
get: contentstackBaseProcedure.query(async ({ ctx }) => { .input(langInput)
const failedResponse = { hideBookingWidget: false } .query(async ({ input, ctx }) => {
const { contentType, uid, lang } = ctx const { contentType, uid } = ctx
const lang = input.lang ?? ctx.lang
// This condition is to handle 404 page case and booking flow // This condition is to handle 404 page case and booking flow
if (!contentType || !uid) { if (!contentType || !uid) {
console.log("No proper params defined: ", contentType, uid) console.log("No proper params defined: ", contentType, uid)
return failedResponse return null
} }
let GetPageSettings = ""
const contentTypeCMS = <ValueOf<typeof PageContentTypeEnum>>(
contentType.replaceAll("-", "_")
)
switch (contentTypeCMS) { let GetPageSettings = ""
switch (contentType) {
case PageContentTypeEnum.accountPage: case PageContentTypeEnum.accountPage:
GetPageSettings = GetAccountPageSettings GetPageSettings = GetAccountPageSettings
break break
case PageContentTypeEnum.loyaltyPage:
GetPageSettings = GetLoyaltyPageSettings
break
case PageContentTypeEnum.collectionPage: case PageContentTypeEnum.collectionPage:
GetPageSettings = GetCollectionPageSettings GetPageSettings = GetCollectionPageSettings
break break
case PageContentTypeEnum.contentPage: case PageContentTypeEnum.contentPage:
GetPageSettings = GetContentPageSettings GetPageSettings = GetContentPageSettings
break break
case PageContentTypeEnum.destinationOverviewPage: case PageContentTypeEnum.currentBlocksPage:
GetPageSettings = GetDestinationOverviewPageSettings GetPageSettings = GetCurrentBlocksPageSettings
break
case PageContentTypeEnum.destinationCountryPage:
GetPageSettings = GetDestinationCountryPageSettings
break break
case PageContentTypeEnum.destinationCityPage: case PageContentTypeEnum.destinationCityPage:
GetPageSettings = GetDestinationCityPageSettings GetPageSettings = GetDestinationCityPageSettings
break break
case PageContentTypeEnum.destinationCountryPage:
GetPageSettings = GetDestinationCountryPageSettings
break
case PageContentTypeEnum.destinationOverviewPage:
GetPageSettings = GetDestinationOverviewPageSettings
break
case PageContentTypeEnum.hotelPage: case PageContentTypeEnum.hotelPage:
GetPageSettings = GetHotelPageSettings GetPageSettings = GetHotelPageSettings
break break
case PageContentTypeEnum.currentBlocksPage: case PageContentTypeEnum.loyaltyPage:
GetPageSettings = GetCurrentBlocksPageSettings GetPageSettings = GetLoyaltyPageSettings
break
case PageContentTypeEnum.startPage:
GetPageSettings = GetStartPageSettings
break break
} }
if (!GetPageSettings) { if (!GetPageSettings) {
console.error("No proper Content type defined: ", contentType) console.error(
return failedResponse "[pageSettings] No proper Content type defined: ",
contentType
)
return null
} }
const response = await request<ValidateBookingWidgetToggleType>( const response = await request<GetPageSettingsSchema>(
GetPageSettings, GetPageSettings,
{ {
uid: uid, uid: uid,
@@ -84,28 +86,18 @@ export const bookingwidgetQueryRouter = router({
{ {
cache: "force-cache", cache: "force-cache",
next: { next: {
tags: [generateTag(lang, uid, bookingwidgetAffix)], tags: [generateTag(lang, uid, affix)],
}, },
} }
) )
const bookingWidgetToggleData = const result = getPageSettingsSchema.safeParse(response.data)
validateBookingWidgetToggleSchema.safeParse(response.data)
if (!bookingWidgetToggleData.success) { if (!result.success) {
console.error( console.error("Page settings fetch error: ", result.error)
"Flag hide_booking_widget fetch error: ", return null
bookingWidgetToggleData.error
)
return failedResponse
} }
const hideBookingWidget = return result.data
!!bookingWidgetToggleData.data[contentTypeCMS]?.page_settings
?.hide_booking_widget
return {
hideBookingWidget,
}
}), }),
}),
}) })

View File

@@ -0,0 +1 @@
export const affix = "pageSettings"

View File

@@ -8,8 +8,8 @@ import {
protectedProcedure, protectedProcedure,
router, router,
} from "@/server/trpc" } from "@/server/trpc"
import { langInput } from "@/server/utils"
import { langInput } from "../base/input"
import { getAllLoyaltyLevels, getLoyaltyLevel } from "../loyaltyLevel/query" import { getAllLoyaltyLevels, getLoyaltyLevel } from "../loyaltyLevel/query"
import { import {
rewardsAllInput, rewardsAllInput,