From d5efaa686cf9c7e4f10de8a68ef2e9333f3b1b48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matilda=20Landstr=C3=B6m?= Date: Mon, 4 Nov 2024 12:10:51 +0000 Subject: [PATCH] Merged in feat/SW-286-collectionPage (pull request #765) Feat(SW-286): CollectionPage Approved-by: Erik Tiekstra Approved-by: Fredrik Thorsson --- .../(public)/[contentType]/[uid]/page.tsx | 8 +- components/Blocks/CardsGrid.tsx | 6 +- .../StaticPages/CollectionPage/index.tsx | 22 +++ .../StaticPages/ContentPage/index.tsx | 17 ++ .../{ContentPage => StaticPages}/index.tsx | 25 +-- .../staticPage.module.css} | 27 +++- .../ContentType/StaticPages/staticPage.ts | 15 ++ .../ContentType/StaticPages/variants.ts | 15 ++ .../TempDesignSystem/Card/card.module.css | 1 + .../Fragments/Blocks/CardsGrid.graphql | 33 ++++ .../Fragments/Blocks/Shortcuts.graphql | 14 ++ lib/graphql/Fragments/Blocks/UspGrid.graphql | 61 +++++++ .../CollectionPage/NavigationLinks.graphql | 21 +++ .../Fragments/CollectionPage/Ref.graphql | 7 + .../PageLink/CollectionPageLink.graphql | 12 ++ lib/graphql/Query/BookingWidgetToggle.graphql | 8 + .../Query/Breadcrumbs/CollectionPage.graphql | 28 ++++ .../CollectionPage/CollectionPage.graphql | 83 ++++++++++ lib/graphql/Query/ResolveEntry.graphql | 8 + .../contentstack/bookingwidget/output.ts | 1 + .../contentstack/bookingwidget/query.ts | 4 + .../contentstack/breadcrumbs/output.ts | 18 +++ .../routers/contentstack/breadcrumbs/query.ts | 52 ++++++ .../contentstack/collectionPage/index.ts | 5 + .../contentstack/collectionPage/output.ts | 121 ++++++++++++++ .../contentstack/collectionPage/query.ts | 78 +++++++++ .../contentstack/collectionPage/utils.ts | 152 ++++++++++++++++++ .../routers/contentstack/contentPage/utils.ts | 12 ++ server/routers/contentstack/index.ts | 2 + .../contentstack/languageSwitcher/query.ts | 8 + .../contentstack/schemas/blocks/cardsGrid.ts | 3 +- .../contentstack/schemas/linkConnection.ts | 1 + .../routers/contentstack/schemas/pageLinks.ts | 14 ++ .../schemas/sidebar/scriptedCard.ts | 13 +- types/components/blocks/cardsGrid.ts | 2 +- types/components/blocks/index.ts | 7 +- types/components/tracking.ts | 1 + types/enums/collectionPage.ts | 9 ++ types/enums/content.ts | 1 + types/enums/scriptedCard.ts | 9 ++ types/params.ts | 6 +- types/requests/contentType.ts | 1 + types/requests/entry.ts | 1 + types/requests/pageType.ts | 1 + .../routers/contentstack/collectionPage.ts | 20 +++ 45 files changed, 918 insertions(+), 35 deletions(-) create mode 100644 components/ContentType/StaticPages/CollectionPage/index.tsx create mode 100644 components/ContentType/StaticPages/ContentPage/index.tsx rename components/ContentType/{ContentPage => StaticPages}/index.tsx (75%) rename components/ContentType/{ContentPage/contentPage.module.css => StaticPages/staticPage.module.css} (87%) create mode 100644 components/ContentType/StaticPages/staticPage.ts create mode 100644 components/ContentType/StaticPages/variants.ts create mode 100644 lib/graphql/Fragments/CollectionPage/NavigationLinks.graphql create mode 100644 lib/graphql/Fragments/CollectionPage/Ref.graphql create mode 100644 lib/graphql/Fragments/PageLink/CollectionPageLink.graphql create mode 100644 lib/graphql/Query/Breadcrumbs/CollectionPage.graphql create mode 100644 lib/graphql/Query/CollectionPage/CollectionPage.graphql create mode 100644 server/routers/contentstack/collectionPage/index.ts create mode 100644 server/routers/contentstack/collectionPage/output.ts create mode 100644 server/routers/contentstack/collectionPage/query.ts create mode 100644 server/routers/contentstack/collectionPage/utils.ts create mode 100644 types/enums/collectionPage.ts create mode 100644 types/enums/scriptedCard.ts create mode 100644 types/trpc/routers/contentstack/collectionPage.ts diff --git a/app/[lang]/(live)/(public)/[contentType]/[uid]/page.tsx b/app/[lang]/(live)/(public)/[contentType]/[uid]/page.tsx index 08fa09422..d96f10f38 100644 --- a/app/[lang]/(live)/(public)/[contentType]/[uid]/page.tsx +++ b/app/[lang]/(live)/(public)/[contentType]/[uid]/page.tsx @@ -2,9 +2,10 @@ import { notFound } from "next/navigation" import { env } from "@/env/server" -import ContentPage from "@/components/ContentType/ContentPage" import HotelPage from "@/components/ContentType/HotelPage" import LoyaltyPage from "@/components/ContentType/LoyaltyPage" +import CollectionPage from "@/components/ContentType/StaticPages/CollectionPage" +import ContentPage from "@/components/ContentType/StaticPages/ContentPage" import { setLang } from "@/i18n/serverContext" import { @@ -22,6 +23,11 @@ export default function ContentTypePage({ setLang(params.lang) switch (params.contentType) { + case "collection-page": + if (env.HIDE_FOR_NEXT_RELEASE) { + return notFound() + } + return case "content-page": if (env.HIDE_FOR_NEXT_RELEASE) { return notFound() diff --git a/components/Blocks/CardsGrid.tsx b/components/Blocks/CardsGrid.tsx index 1c07b73ec..92d98a61b 100644 --- a/components/Blocks/CardsGrid.tsx +++ b/components/Blocks/CardsGrid.tsx @@ -42,13 +42,17 @@ export default function CardsGrid({ case CardsGridEnum.cards.Card: return ( ) case CardsGridEnum.cards.TeaserCard: diff --git a/components/ContentType/StaticPages/CollectionPage/index.tsx b/components/ContentType/StaticPages/CollectionPage/index.tsx new file mode 100644 index 000000000..41a06391c --- /dev/null +++ b/components/ContentType/StaticPages/CollectionPage/index.tsx @@ -0,0 +1,22 @@ +import { serverClient } from "@/lib/trpc/server" + +import StaticPage from ".." + +export default async function CollectionPage() { + const collectionPageRes = + await serverClient().contentstack.collectionPage.get() + + if (!collectionPageRes) { + return null + } + + const { tracking, collectionPage } = collectionPageRes + + return ( + + ) +} diff --git a/components/ContentType/StaticPages/ContentPage/index.tsx b/components/ContentType/StaticPages/ContentPage/index.tsx new file mode 100644 index 000000000..037f011b8 --- /dev/null +++ b/components/ContentType/StaticPages/ContentPage/index.tsx @@ -0,0 +1,17 @@ +import { serverClient } from "@/lib/trpc/server" + +import StaticPage from ".." + +export default async function ContentPage() { + const contentPageRes = await serverClient().contentstack.contentPage.get() + + if (!contentPageRes) { + return null + } + + const { tracking, contentPage } = contentPageRes + + return ( + + ) +} diff --git a/components/ContentType/ContentPage/index.tsx b/components/ContentType/StaticPages/index.tsx similarity index 75% rename from components/ContentType/ContentPage/index.tsx rename to components/ContentType/StaticPages/index.tsx index b6a556dc5..4eed6b89b 100644 --- a/components/ContentType/ContentPage/index.tsx +++ b/components/ContentType/StaticPages/index.tsx @@ -1,5 +1,3 @@ -import { serverClient } from "@/lib/trpc/server" - import Blocks from "@/components/Blocks" import Hero from "@/components/Hero" import Sidebar from "@/components/Sidebar" @@ -8,21 +6,22 @@ import Preamble from "@/components/TempDesignSystem/Text/Preamble" import Title from "@/components/TempDesignSystem/Text/Title" import TrackingSDK from "@/components/TrackingSDK" -import styles from "./contentPage.module.css" +import { staticPageVariants } from "./variants" -export default async function ContentPage() { - const contentPageRes = await serverClient().contentstack.contentPage.get() +import styles from "./staticPage.module.css" - if (!contentPageRes) { - return null - } +import type { StaticPageProps } from "./staticPage" - const { tracking, contentPage } = contentPageRes - const { blocks, hero_image, header, sidebar } = contentPage +export default function StaticPage({ + content, + tracking, + pageType, +}: StaticPageProps) { + const { blocks, hero_image, header } = content return ( <> -
+
{header ? ( @@ -54,7 +53,9 @@ export default async function ContentPage() { {blocks ? : null} - {sidebar?.length ? : null} + {"sidebar" in content && content.sidebar?.length ? ( + + ) : null}
diff --git a/components/ContentType/ContentPage/contentPage.module.css b/components/ContentType/StaticPages/staticPage.module.css similarity index 87% rename from components/ContentType/ContentPage/contentPage.module.css rename to components/ContentType/StaticPages/staticPage.module.css index 825a2445d..13d2f440e 100644 --- a/components/ContentType/ContentPage/contentPage.module.css +++ b/components/ContentType/StaticPages/staticPage.module.css @@ -1,4 +1,4 @@ -.contentPage { +.page { padding-bottom: var(--Spacing-x9); } @@ -32,20 +32,27 @@ } .contentContainer { + padding: var(--Spacing-x4) var(--Spacing-x2) 0; +} + +.content .contentContainer { display: grid; grid-template-areas: "main" "sidebar"; gap: var(--Spacing-x4); align-items: start; - padding: var(--Spacing-x4) var(--Spacing-x2) 0; } .mainContent { - grid-area: main; display: grid; gap: var(--Spacing-x4); width: 100%; + gap: var(--Spacing-x6); +} + +.content .mainContent { + grid-area: main; } @media (min-width: 768px) { @@ -58,12 +65,20 @@ .heroContainer { padding: var(--Spacing-x4) 0; } + .contentContainer { + max-width: var(--max-width-content); + padding: var(--Spacing-x4) 0 0; + margin: 0 auto; + } + + .content .contentContainer { grid-template-areas: "main sidebar"; grid-template-columns: var(--max-width-text-block) 1fr; gap: var(--Spacing-x9); - max-width: var(--max-width-content); - margin: 0 auto; - padding: var(--Spacing-x4) 0 0; + } + + .mainContent { + gap: var(--Spacing-x9); } } diff --git a/components/ContentType/StaticPages/staticPage.ts b/components/ContentType/StaticPages/staticPage.ts new file mode 100644 index 000000000..5a3bf84b4 --- /dev/null +++ b/components/ContentType/StaticPages/staticPage.ts @@ -0,0 +1,15 @@ +import { staticPageVariants } from "./variants" + +import type { VariantProps } from "class-variance-authority" + +import type { TrackingSDKPageData } from "@/types/components/tracking" +import type { CollectionPage } from "@/types/trpc/routers/contentstack/collectionPage" +import type { ContentPage } from "@/types/trpc/routers/contentstack/contentPage" + +export interface StaticPageProps + extends Omit, "content">, + VariantProps { + pageType?: "collection" | "content" + content: CollectionPage["collection_page"] | ContentPage["content_page"] + tracking: TrackingSDKPageData +} diff --git a/components/ContentType/StaticPages/variants.ts b/components/ContentType/StaticPages/variants.ts new file mode 100644 index 000000000..4d59bc641 --- /dev/null +++ b/components/ContentType/StaticPages/variants.ts @@ -0,0 +1,15 @@ +import { cva } from "class-variance-authority" + +import styles from "./staticPage.module.css" + +export const staticPageVariants = cva(styles.page, { + variants: { + pageType: { + collection: styles.collection, + content: styles.content, + }, + }, + defaultVariants: { + pageType: "content", + }, +}) diff --git a/components/TempDesignSystem/Card/card.module.css b/components/TempDesignSystem/Card/card.module.css index 6dd063c76..8d0acdebe 100644 --- a/components/TempDesignSystem/Card/card.module.css +++ b/components/TempDesignSystem/Card/card.module.css @@ -41,6 +41,7 @@ .content { margin: var(--Spacing-x0) var(--Spacing-x4); + position: absolute; display: grid; gap: var(--Spacing-x2); } diff --git a/lib/graphql/Fragments/Blocks/CardsGrid.graphql b/lib/graphql/Fragments/Blocks/CardsGrid.graphql index ce4eb3886..2011d8491 100644 --- a/lib/graphql/Fragments/Blocks/CardsGrid.graphql +++ b/lib/graphql/Fragments/Blocks/CardsGrid.graphql @@ -5,6 +5,7 @@ #import "./Refs/Card.graphql" #import "./Refs/LoyaltyCard.graphql" #import "./Refs/TeaserCard.graphql" + fragment CardsGrid_ContentPage on ContentPageBlocksCardsGrid { cards_grid { layout @@ -39,6 +40,38 @@ fragment CardsGrid_ContentPageRefs on ContentPageBlocksCardsGrid { } } +fragment CardsGrid_CollectionPage on CollectionPageBlocksCardsGrid { + cards_grid { + layout + preamble + theme + title + cardConnection(limit: 10) { + edges { + node { + __typename + ...CardBlock + ...TeaserCardBlock + } + } + } + } +} + +fragment CardsGrid_CollectionPageRefs on CollectionPageBlocksCardsGrid { + cards_grid { + cardConnection(limit: 10) { + edges { + node { + __typename + ...CardBlockRef + ...TeaserCardBlockRef + } + } + } + } +} + fragment CardsGrid_LoyaltyPage on LoyaltyPageBlocksCardsGrid { cards_grid { layout diff --git a/lib/graphql/Fragments/Blocks/Shortcuts.graphql b/lib/graphql/Fragments/Blocks/Shortcuts.graphql index 4ba566634..cfdb9bcbe 100644 --- a/lib/graphql/Fragments/Blocks/Shortcuts.graphql +++ b/lib/graphql/Fragments/Blocks/Shortcuts.graphql @@ -1,8 +1,10 @@ #import "../AccountPage/Ref.graphql" +#import "../CollectionPage/Ref.graphql" #import "../ContentPage/Ref.graphql" #import "../LoyaltyPage/Ref.graphql" #import "../PageLink/AccountPageLink.graphql" +#import "../PageLink/CollectionPageLink.graphql" #import "../PageLink/ContentPageLink.graphql" #import "../PageLink/LoyaltyPageLink.graphql" @@ -32,6 +34,12 @@ fragment Shortcuts_AccountPage on AccountPageContentShortcuts { } } +fragment Shortcuts_CollectionPage on CollectionPageBlocksShortcuts { + shortcuts { + ...Shortcuts + } +} + fragment Shortcuts_ContentPage on ContentPageBlocksShortcuts { shortcuts { ...Shortcuts @@ -65,6 +73,12 @@ fragment Shortcuts_AccountPageRefs on AccountPageContentShortcuts { } } +fragment Shortcuts_CollectionPageRefs on CollectionPageBlocksShortcuts { + shortcuts { + ...ShortcutsRefs + } +} + fragment Shortcuts_ContentPageRefs on ContentPageBlocksShortcuts { shortcuts { ...ShortcutsRefs diff --git a/lib/graphql/Fragments/Blocks/UspGrid.graphql b/lib/graphql/Fragments/Blocks/UspGrid.graphql index ae2df5aa8..e7f435b5a 100644 --- a/lib/graphql/Fragments/Blocks/UspGrid.graphql +++ b/lib/graphql/Fragments/Blocks/UspGrid.graphql @@ -68,3 +68,64 @@ fragment UspGrid_ContentPageRefs on ContentPageBlocksUspGrid { } } } + +fragment UspGrid_CollectionPage on CollectionPageBlocksUspGrid { + __typename + usp_grid { + cardsConnection { + edges { + node { + ... on UspGrid { + usp_card { + __typename + icon + text { + embedded_itemsConnection { + totalCount + edges { + node { + __typename + ...AccountPageLink + ...ContentPageLink + ...HotelPageLink + ...LoyaltyPageLink + } + } + } + json + } + } + } + } + } + } + } +} + +fragment UspGrid_CollectionPageRefs on CollectionPageBlocksUspGrid { + usp_grid { + cardsConnection { + edges { + node { + ... on UspGrid { + usp_card { + text { + embedded_itemsConnection { + edges { + node { + __typename + ...AccountPageRef + ...ContentPageRef + ...HotelPageRef + ...LoyaltyPageRef + } + } + } + } + } + } + } + } + } + } +} diff --git a/lib/graphql/Fragments/CollectionPage/NavigationLinks.graphql b/lib/graphql/Fragments/CollectionPage/NavigationLinks.graphql new file mode 100644 index 000000000..55a7572a1 --- /dev/null +++ b/lib/graphql/Fragments/CollectionPage/NavigationLinks.graphql @@ -0,0 +1,21 @@ +#import "../PageLink/CollectionPageLink.graphql" +#import "../PageLink/ContentPageLink.graphql" +#import "../PageLink/HotelPageLink.graphql" +#import "../PageLink/LoyaltyPageLink.graphql" + +fragment NavigationLinks on CollectionPageHeader { + navigation_links { + title + linkConnection { + edges { + node { + __typename + ...HotelPageLink + ...CollectionPageLink + ...ContentPageLink + ...LoyaltyPageLink + } + } + } + } +} diff --git a/lib/graphql/Fragments/CollectionPage/Ref.graphql b/lib/graphql/Fragments/CollectionPage/Ref.graphql new file mode 100644 index 000000000..dd746f5f4 --- /dev/null +++ b/lib/graphql/Fragments/CollectionPage/Ref.graphql @@ -0,0 +1,7 @@ +#import "../System.graphql" + +fragment CollectionPageRef on CollectionPage { + system { + ...System + } +} diff --git a/lib/graphql/Fragments/PageLink/CollectionPageLink.graphql b/lib/graphql/Fragments/PageLink/CollectionPageLink.graphql new file mode 100644 index 000000000..9ebbb4f11 --- /dev/null +++ b/lib/graphql/Fragments/PageLink/CollectionPageLink.graphql @@ -0,0 +1,12 @@ +#import "../System.graphql" + +fragment CollectionPageLink on CollectionPage { + title + url + system { + ...System + } + web { + original_url + } +} diff --git a/lib/graphql/Query/BookingWidgetToggle.graphql b/lib/graphql/Query/BookingWidgetToggle.graphql index fa6f73fff..017f07f9d 100644 --- a/lib/graphql/Query/BookingWidgetToggle.graphql +++ b/lib/graphql/Query/BookingWidgetToggle.graphql @@ -14,6 +14,14 @@ query GetLoyaltyPageSettings($uid: String!, $locale: String!) { } } +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 { diff --git a/lib/graphql/Query/Breadcrumbs/CollectionPage.graphql b/lib/graphql/Query/Breadcrumbs/CollectionPage.graphql new file mode 100644 index 000000000..1e9c3d522 --- /dev/null +++ b/lib/graphql/Query/Breadcrumbs/CollectionPage.graphql @@ -0,0 +1,28 @@ +#import "../../Fragments/Breadcrumbs/Breadcrumbs.graphql" +#import "../../Fragments/System.graphql" + +query GetCollectionPageBreadcrumbs($locale: String!, $uid: String!) { + collection_page(locale: $locale, uid: $uid) { + web { + breadcrumbs { + ...Breadcrumbs + } + } + system { + ...System + } + } +} + +query GetCollectionPageBreadcrumbsRefs($locale: String!, $uid: String!) { + collection_page(locale: $locale, uid: $uid) { + web { + breadcrumbs { + ...BreadcrumbsRefs + } + } + system { + ...System + } + } +} diff --git a/lib/graphql/Query/CollectionPage/CollectionPage.graphql b/lib/graphql/Query/CollectionPage/CollectionPage.graphql new file mode 100644 index 000000000..36d40b9fc --- /dev/null +++ b/lib/graphql/Query/CollectionPage/CollectionPage.graphql @@ -0,0 +1,83 @@ +#import "../../Fragments/System.graphql" + +#import "../../Fragments/Blocks/CardsGrid.graphql" +#import "../../Fragments/Blocks/Shortcuts.graphql" +#import "../../Fragments/Blocks/UspGrid.graphql" + +#import "../../Fragments/CollectionPage/NavigationLinks.graphql" + +query GetCollectionPage($locale: String!, $uid: String!) { + collection_page(uid: $uid, locale: $locale) { + hero_image + title + header { + heading + preamble + ...NavigationLinks + } + blocks { + __typename + ...CardsGrid_CollectionPage + ...Shortcuts_CollectionPage + ...UspGrid_CollectionPage + } + system { + ...System + created_at + updated_at + } + } +} + +query GetCollectionPageRefs($locale: String!, $uid: String!) { + collection_page(locale: $locale, uid: $uid) { + header { + navigation_links { + linkConnection { + edges { + node { + __typename + ...CollectionPageRef + ...ContentPageRef + ...HotelPageRef + ...LoyaltyPageRef + } + } + } + } + } + blocks { + __typename + ...CardsGrid_CollectionPageRefs + ...Shortcuts_CollectionPageRefs + ...UspGrid_CollectionPageRefs + } + system { + ...System + } + } +} + +query GetDaDeEnUrlsCollectionPage($uid: String!) { + de: collection_page(locale: "de", uid: $uid) { + url + } + en: collection_page(locale: "en", uid: $uid) { + url + } + da: collection_page(locale: "da", uid: $uid) { + url + } +} + +query GetFiNoSvUrlsCollectionPage($uid: String!) { + fi: collection_page(locale: "fi", uid: $uid) { + url + } + no: collection_page(locale: "no", uid: $uid) { + url + } + sv: collection_page(locale: "sv", uid: $uid) { + url + } +} diff --git a/lib/graphql/Query/ResolveEntry.graphql b/lib/graphql/Query/ResolveEntry.graphql index 0a07a9cbe..f512e1110 100644 --- a/lib/graphql/Query/ResolveEntry.graphql +++ b/lib/graphql/Query/ResolveEntry.graphql @@ -9,6 +9,14 @@ query ResolveEntryByUrl($locale: String!, $url: String!) { } total } + all_collection_page(where: { url: $url }, locale: $locale) { + items { + system { + ...System + } + } + total + } all_content_page(where: { url: $url }, locale: $locale) { items { system { diff --git a/server/routers/contentstack/bookingwidget/output.ts b/server/routers/contentstack/bookingwidget/output.ts index e113bae95..d13951a63 100644 --- a/server/routers/contentstack/bookingwidget/output.ts +++ b/server/routers/contentstack/bookingwidget/output.ts @@ -11,6 +11,7 @@ const bookingWidgetToggleSchema = z export const validateBookingWidgetToggleSchema = z.object({ account_page: bookingWidgetToggleSchema, loyalty_page: bookingWidgetToggleSchema, + collection_page: bookingWidgetToggleSchema, content_page: bookingWidgetToggleSchema, hotel_page: bookingWidgetToggleSchema, current_blocks_page: bookingWidgetToggleSchema, diff --git a/server/routers/contentstack/bookingwidget/query.ts b/server/routers/contentstack/bookingwidget/query.ts index f87899965..50af970e1 100644 --- a/server/routers/contentstack/bookingwidget/query.ts +++ b/server/routers/contentstack/bookingwidget/query.ts @@ -2,6 +2,7 @@ import { ValueOf } from "next/dist/shared/lib/constants" import { GetAccountPageSettings, + GetCollectionPageSettings, GetContentPageSettings, GetCurrentBlocksPageSettings, GetHotelPageSettings, @@ -43,6 +44,9 @@ export const bookingwidgetQueryRouter = router({ case ContentTypeEnum.loyaltyPage: GetPageSettings = GetLoyaltyPageSettings break + case ContentTypeEnum.collectionPage: + GetPageSettings = GetCollectionPageSettings + break case ContentTypeEnum.contentPage: GetPageSettings = GetContentPageSettings break diff --git a/server/routers/contentstack/breadcrumbs/output.ts b/server/routers/contentstack/breadcrumbs/output.ts index e5a058699..d9b8b2f95 100644 --- a/server/routers/contentstack/breadcrumbs/output.ts +++ b/server/routers/contentstack/breadcrumbs/output.ts @@ -50,6 +50,16 @@ export type GetLoyaltyPageBreadcrumbsRefsData = z.infer< typeof validateLoyaltyPageBreadcrumbsRefsContentstackSchema > +export const validateCollectionPageBreadcrumbsRefsContentstackSchema = z.object( + { + collection_page: breadcrumbsRefs, + } +) + +export type GetCollectionPageBreadcrumbsRefsData = z.infer< + typeof validateCollectionPageBreadcrumbsRefsContentstackSchema +> + export const validateContentPageBreadcrumbsRefsContentstackSchema = z.object({ content_page: breadcrumbsRefs, }) @@ -107,3 +117,11 @@ export const validateContentPageBreadcrumbsContentstackSchema = z.object({ export type GetContentPageBreadcrumbsData = z.infer< typeof validateContentPageBreadcrumbsContentstackSchema > + +export const validateCollectionPageBreadcrumbsContentstackSchema = z.object({ + collection_page: page, +}) + +export type GetCollectionPageBreadcrumbsData = z.infer< + typeof validateCollectionPageBreadcrumbsContentstackSchema +> diff --git a/server/routers/contentstack/breadcrumbs/query.ts b/server/routers/contentstack/breadcrumbs/query.ts index b4dc3ecd2..ff96fcc49 100644 --- a/server/routers/contentstack/breadcrumbs/query.ts +++ b/server/routers/contentstack/breadcrumbs/query.ts @@ -2,6 +2,10 @@ import { GetMyPagesBreadcrumbs, GetMyPagesBreadcrumbsRefs, } from "@/lib/graphql/Query/Breadcrumbs/AccountPage.graphql" +import { + GetCollectionPageBreadcrumbs, + GetCollectionPageBreadcrumbsRefs, +} from "@/lib/graphql/Query/Breadcrumbs/CollectionPage.graphql" import { GetContentPageBreadcrumbs, GetContentPageBreadcrumbsRefs, @@ -13,12 +17,16 @@ import { import { contentstackExtendedProcedureUID, router } from "@/server/trpc" import { + GetCollectionPageBreadcrumbsData, + GetCollectionPageBreadcrumbsRefsData, type GetContentPageBreadcrumbsData, type GetContentPageBreadcrumbsRefsData, type GetLoyaltyPageBreadcrumbsData, type GetLoyaltyPageBreadcrumbsRefsData, type GetMyPagesBreadcrumbsData, type GetMyPagesBreadcrumbsRefsData, + validateCollectionPageBreadcrumbsContentstackSchema, + validateCollectionPageBreadcrumbsRefsContentstackSchema, validateContentPageBreadcrumbsContentstackSchema, validateContentPageBreadcrumbsRefsContentstackSchema, validateLoyaltyPageBreadcrumbsContentstackSchema, @@ -84,6 +92,48 @@ async function getLoyaltyPageBreadcrumbs(variables: Variables) { ) } +async function getCollectionPageBreadcrumbs(variables: Variables) { + const refsResponse = + await getRefsResponse( + GetCollectionPageBreadcrumbsRefs, + variables + ) + const validatedRefsData = + validateCollectionPageBreadcrumbsRefsContentstackSchema.safeParse( + refsResponse.data + ) + + if (!validatedRefsData.success) { + console.error( + `Failed to validate CollectionPpage Breadcrumbs Refs - (uid: ${variables.uid})` + ) + console.error(validatedRefsData.error) + return null + } + const tags = getTags(validatedRefsData.data.collection_page, variables) + const response = await getResponse( + GetCollectionPageBreadcrumbs, + variables, + tags + ) + if (!response.data.collection_page.web?.breadcrumbs?.title) { + return null + } + const validatedBreadcrumbsData = + validateCollectionPageBreadcrumbsContentstackSchema.safeParse(response.data) + if (!validatedBreadcrumbsData.success) { + console.error( + `Failed to validate Collectionpage Breadcrumbs Data - (uid: ${variables.uid})` + ) + console.error(validatedBreadcrumbsData.error) + return null + } + return getBreadcrumbs( + validatedBreadcrumbsData.data.collection_page, + variables.locale + ) +} + async function getContentPageBreadcrumbs(variables: Variables) { const refsResponse = await getRefsResponse( GetContentPageBreadcrumbsRefs, @@ -189,6 +239,8 @@ export const breadcrumbsQueryRouter = router({ switch (ctx.contentType) { case PageTypeEnum.accountPage: return await getMyPagesBreadcrumbs(variables) + case PageTypeEnum.collectionPage: + return await getCollectionPageBreadcrumbs(variables) case PageTypeEnum.contentPage: return await getContentPageBreadcrumbs(variables) case PageTypeEnum.loyaltyPage: diff --git a/server/routers/contentstack/collectionPage/index.ts b/server/routers/contentstack/collectionPage/index.ts new file mode 100644 index 000000000..04f372da8 --- /dev/null +++ b/server/routers/contentstack/collectionPage/index.ts @@ -0,0 +1,5 @@ +import { mergeRouters } from "@/server/trpc" + +import { collectionPageQueryRouter } from "./query" + +export const collectionPageRouter = mergeRouters(collectionPageQueryRouter) diff --git a/server/routers/contentstack/collectionPage/output.ts b/server/routers/contentstack/collectionPage/output.ts new file mode 100644 index 000000000..5ea3fa9d4 --- /dev/null +++ b/server/routers/contentstack/collectionPage/output.ts @@ -0,0 +1,121 @@ +import { z } from "zod" + +import { discriminatedUnionArray } from "@/lib/discriminatedUnion" + +import { + cardGridRefsSchema, + cardsGridSchema, +} from "../schemas/blocks/cardsGrid" +import { + shortcutsRefsSchema, + shortcutsSchema, +} from "../schemas/blocks/shortcuts" +import { uspGridRefsSchema, uspGridSchema } from "../schemas/blocks/uspGrid" +import { tempImageVaultAssetSchema } from "../schemas/imageVault" +import { + linkAndTitleSchema, + linkConnectionRefs, +} from "../schemas/linkConnection" +import { systemSchema } from "../schemas/system" + +import { CollectionPageEnum } from "@/types/enums/collectionPage" + +// Block schemas +export const collectionPageCards = z + .object({ + __typename: z.literal(CollectionPageEnum.ContentStack.blocks.CardsGrid), + }) + .merge(cardsGridSchema) + +export const collectionPageShortcuts = z + .object({ + __typename: z.literal(CollectionPageEnum.ContentStack.blocks.Shortcuts), + }) + .merge(shortcutsSchema) + +export const collectionPageUspGrid = z + .object({ + __typename: z.literal(CollectionPageEnum.ContentStack.blocks.UspGrid), + }) + .merge(uspGridSchema) + +export const blocksSchema = z.discriminatedUnion("__typename", [ + collectionPageCards, + collectionPageShortcuts, + collectionPageUspGrid, +]) + +const navigationLinksSchema = z + .array(linkAndTitleSchema) + .nullable() + .transform((data) => { + if (!data) { + return null + } + + return data + .filter((item) => !!item.link) + .map((item) => ({ + url: item.link!.url, + title: item.title || item.link!.title, + })) + }) + +// Content Page Schema and types +export const collectionPageSchema = z.object({ + collection_page: z.object({ + hero_image: tempImageVaultAssetSchema, + blocks: discriminatedUnionArray(blocksSchema.options).nullable(), + title: z.string(), + header: z.object({ + heading: z.string(), + preamble: z.string(), + navigation_links: navigationLinksSchema, + }), + system: systemSchema.merge( + z.object({ + created_at: z.string(), + updated_at: z.string(), + }) + ), + }), +}) + +/** REFS */ +const collectionPageCardsRefs = z + .object({ + __typename: z.literal(CollectionPageEnum.ContentStack.blocks.CardsGrid), + }) + .merge(cardGridRefsSchema) + +const collectionPageShortcutsRefs = z + .object({ + __typename: z.literal(CollectionPageEnum.ContentStack.blocks.Shortcuts), + }) + .merge(shortcutsRefsSchema) + +const collectionPageUspGridRefs = z + .object({ + __typename: z.literal(CollectionPageEnum.ContentStack.blocks.UspGrid), + }) + .merge(uspGridRefsSchema) + +const collectionPageBlockRefsItem = z.discriminatedUnion("__typename", [ + collectionPageShortcutsRefs, + collectionPageCardsRefs, + collectionPageUspGridRefs, +]) + +const collectionPageHeaderRefs = z.object({ + navigation_links: z.array(linkConnectionRefs), +}) + +export const collectionPageRefsSchema = z.object({ + collection_page: z.object({ + header: collectionPageHeaderRefs, + blocks: discriminatedUnionArray( + collectionPageBlockRefsItem.options + ).nullable(), + system: systemSchema, + }), +}) diff --git a/server/routers/contentstack/collectionPage/query.ts b/server/routers/contentstack/collectionPage/query.ts new file mode 100644 index 000000000..196eb0098 --- /dev/null +++ b/server/routers/contentstack/collectionPage/query.ts @@ -0,0 +1,78 @@ +import { Lang } from "@/constants/languages" +import { GetCollectionPage } from "@/lib/graphql/Query/CollectionPage/CollectionPage.graphql" +import { request } from "@/lib/graphql/request" +import { contentstackExtendedProcedureUID, router } from "@/server/trpc" + +import { collectionPageSchema } from "./output" +import { + fetchCollectionPageRefs, + generatePageTags, + getCollectionPageCounter, + validateCollectionPageRefs, +} from "./utils" + +import { + TrackingChannelEnum, + type TrackingSDKPageData, +} from "@/types/components/tracking" +import { GetCollectionPageSchema } from "@/types/trpc/routers/contentstack/collectionPage" + +export const collectionPageQueryRouter = router({ + get: contentstackExtendedProcedureUID.query(async ({ ctx }) => { + const { lang, uid } = ctx + + const collectionPageRefsData = await fetchCollectionPageRefs(lang, uid) + + const collectionPageRefs = validateCollectionPageRefs( + collectionPageRefsData, + lang, + uid + ) + if (!collectionPageRefs) { + return null + } + const tags = generatePageTags(collectionPageRefs, lang) + + getCollectionPageCounter.add(1, { lang, uid }) + console.info( + "contentstack.collectionPage start", + JSON.stringify({ + query: { lang, uid }, + }) + ) + + const response = await request( + GetCollectionPage, + { locale: lang, uid }, + { + cache: "force-cache", + next: { + tags, + }, + } + ) + + const collectionPage = collectionPageSchema.safeParse(response.data) + if (!collectionPage.success) { + console.error( + `Failed to validate CollectionPage Data - (lang: ${lang}, uid: ${uid})` + ) + console.error(collectionPage.error?.format()) + return null + } + + const tracking: TrackingSDKPageData = { + pageId: collectionPage.data.collection_page.system.uid, + lang: collectionPage.data.collection_page.system.locale as Lang, + publishedDate: collectionPage.data.collection_page.system.updated_at, + createdDate: collectionPage.data.collection_page.system.created_at, + channel: TrackingChannelEnum["collection-page"], + pageType: "collectionpage", + } + + return { + collectionPage: collectionPage.data.collection_page, + tracking, + } + }), +}) diff --git a/server/routers/contentstack/collectionPage/utils.ts b/server/routers/contentstack/collectionPage/utils.ts new file mode 100644 index 000000000..cfb9ceca9 --- /dev/null +++ b/server/routers/contentstack/collectionPage/utils.ts @@ -0,0 +1,152 @@ +import { metrics } from "@opentelemetry/api" + +import { Lang } from "@/constants/languages" +import { GetCollectionPageRefs } from "@/lib/graphql/Query/CollectionPage/CollectionPage.graphql" +import { request } from "@/lib/graphql/request" +import { notFound } from "@/server/errors/trpc" + +import { generateTag, generateTagsFromSystem } from "@/utils/generateTag" + +import { collectionPageRefsSchema } from "./output" + +import { CollectionPageEnum } from "@/types/enums/collectionPage" +import { System } from "@/types/requests/system" +import { + CollectionPageRefs, + GetCollectionPageRefsSchema, +} from "@/types/trpc/routers/contentstack/collectionPage" + +const meter = metrics.getMeter("trpc.collectionPage") +// OpenTelemetry metrics: CollectionPage + +export const getCollectionPageCounter = meter.createCounter( + "trpc.contentstack.collectionPage.get" +) + +const getCollectionPageRefsCounter = meter.createCounter( + "trpc.contentstack.collectionPage.get" +) +const getCollectionPageRefsFailCounter = meter.createCounter( + "trpc.contentstack.collectionPage.get-fail" +) +const getCollectionPageRefsSuccessCounter = meter.createCounter( + "trpc.contentstack.collectionPage.get-success" +) + +export async function fetchCollectionPageRefs(lang: Lang, uid: string) { + getCollectionPageRefsCounter.add(1, { lang, uid }) + console.info( + "contentstack.collectionPage.refs start", + JSON.stringify({ + query: { lang, uid }, + }) + ) + const refsResponse = await request( + GetCollectionPageRefs, + { locale: lang, uid }, + { + cache: "force-cache", + next: { + tags: [generateTag(lang, uid)], + }, + } + ) + + if (!refsResponse.data) { + const notFoundError = notFound(refsResponse) + getCollectionPageRefsFailCounter.add(1, { + lang, + uid, + error_type: "http_error", + error: JSON.stringify({ + code: notFoundError.code, + }), + }) + console.error( + "contentstack.collectionPage.refs not found error", + JSON.stringify({ + query: { + lang, + uid, + }, + error: { code: notFoundError.code }, + }) + ) + throw notFoundError + } + + return refsResponse.data +} + +export function validateCollectionPageRefs( + data: GetCollectionPageRefsSchema, + lang: Lang, + uid: string +) { + const validatedData = collectionPageRefsSchema.safeParse(data) + if (!validatedData.success) { + getCollectionPageRefsFailCounter.add(1, { + lang, + uid, + error_type: "validation_error", + error: JSON.stringify(validatedData.error), + }) + console.error( + "contentstack.collectionPage.refs validation error", + JSON.stringify({ + query: { lang, uid }, + error: validatedData.error, + }) + ) + return null + } + getCollectionPageRefsSuccessCounter.add(1, { lang, uid }) + console.info( + "contentstack.collectionPage.refs success", + JSON.stringify({ + query: { lang, uid }, + }) + ) + + return validatedData.data +} + +export function generatePageTags( + validatedData: CollectionPageRefs, + lang: Lang +): string[] { + const connections = getConnections(validatedData) + return [ + generateTagsFromSystem(lang, connections), + generateTag(lang, validatedData.collection_page.system.uid), + ].flat() +} + +export function getConnections({ collection_page }: CollectionPageRefs) { + const connections: System["system"][] = [collection_page.system] + if (collection_page.blocks) { + collection_page.blocks.forEach((block) => { + switch (block.__typename) { + case CollectionPageEnum.ContentStack.blocks.Shortcuts: { + if (block.shortcuts.shortcuts.length) { + connections.push(...block.shortcuts.shortcuts) + } + break + } + case CollectionPageEnum.ContentStack.blocks.CardsGrid: { + if (block.cards_grid.length) { + connections.push(...block.cards_grid) + } + break + } + case CollectionPageEnum.ContentStack.blocks.UspGrid: { + if (block.usp_grid.length) { + connections.push(...block.usp_grid) + } + } + } + }) + } + + return connections +} diff --git a/server/routers/contentstack/contentPage/utils.ts b/server/routers/contentstack/contentPage/utils.ts index 6e41c92e4..092595813 100644 --- a/server/routers/contentstack/contentPage/utils.ts +++ b/server/routers/contentstack/contentPage/utils.ts @@ -162,6 +162,18 @@ export function getConnections({ content_page }: ContentPageRefs) { } } break + case ContentPageEnum.ContentStack.blocks.CardsGrid: { + if (block.cards_grid.length) { + connections.push(...block.cards_grid) + } + break + } + case ContentPageEnum.ContentStack.blocks.DynamicContent: { + if (block.dynamic_content.link) { + connections.push(block.dynamic_content.link) + } + break + } case ContentPageEnum.ContentStack.blocks.Shortcuts: { if (block.shortcuts.shortcuts.length) { connections.push(...block.shortcuts.shortcuts) diff --git a/server/routers/contentstack/index.ts b/server/routers/contentstack/index.ts index bde6065db..2456c4f97 100644 --- a/server/routers/contentstack/index.ts +++ b/server/routers/contentstack/index.ts @@ -4,6 +4,7 @@ import { accountPageRouter } from "./accountPage" import { baseRouter } from "./base" import { bookingwidgetRouter } from "./bookingwidget" import { breadcrumbsRouter } from "./breadcrumbs" +import { collectionPageRouter } from "./collectionPage" import { contentPageRouter } from "./contentPage" import { hotelPageRouter } from "./hotelPage" import { languageSwitcherRouter } from "./languageSwitcher" @@ -21,6 +22,7 @@ export const contentstackRouter = router({ hotelPage: hotelPageRouter, languageSwitcher: languageSwitcherRouter, loyaltyPage: loyaltyPageRouter, + collectionPage: collectionPageRouter, contentPage: contentPageRouter, myPages: myPagesRouter, metaData: metaDataRouter, diff --git a/server/routers/contentstack/languageSwitcher/query.ts b/server/routers/contentstack/languageSwitcher/query.ts index 89e7f82ce..3aa4cea6d 100644 --- a/server/routers/contentstack/languageSwitcher/query.ts +++ b/server/routers/contentstack/languageSwitcher/query.ts @@ -7,6 +7,10 @@ import { GetDaDeEnUrlsAccountPage, GetFiNoSvUrlsAccountPage, } from "@/lib/graphql/Query/AccountPage/AccountPage.graphql" +import { + GetDaDeEnUrlsCollectionPage, + GetFiNoSvUrlsCollectionPage, +} from "@/lib/graphql/Query/CollectionPage/CollectionPage.graphql" import { GetDaDeEnUrlsContentPage, GetFiNoSvUrlsContentPage, @@ -88,6 +92,10 @@ async function getLanguageSwitcher(options: LanguageSwitcherVariables) { daDeEnDocument = GetDaDeEnUrlsContentPage fiNoSvDocument = GetFiNoSvUrlsContentPage break + case PageTypeEnum.collectionPage: + daDeEnDocument = GetDaDeEnUrlsCollectionPage + fiNoSvDocument = GetFiNoSvUrlsCollectionPage + break default: console.error(`type: [${options.contentType}]`) console.error(`Trying to get a content type that is not supported`) diff --git a/server/routers/contentstack/schemas/blocks/cardsGrid.ts b/server/routers/contentstack/schemas/blocks/cardsGrid.ts index a5d75f02c..0cf13859e 100644 --- a/server/routers/contentstack/schemas/blocks/cardsGrid.ts +++ b/server/routers/contentstack/schemas/blocks/cardsGrid.ts @@ -11,6 +11,7 @@ import { imageContainerSchema } from "./imageContainer" import { BlocksEnums } from "@/types/enums/blocks" import { CardsGridEnum, CardsGridLayoutEnum } from "@/types/enums/cardsGrid" +import { scriptedCardThemeEnum } from "@/types/enums/scriptedCard" export const cardBlockSchema = z.object({ __typename: z.literal(CardsGridEnum.cards.Card), @@ -161,7 +162,7 @@ export const cardsGridSchema = z.object({ }), layout: z.nativeEnum(CardsGridLayoutEnum), preamble: z.string().optional().default(""), - theme: z.enum(["one", "two", "three"]).nullable(), + theme: z.nativeEnum(scriptedCardThemeEnum).nullable(), title: z.string().optional().default(""), }) .transform((data) => { diff --git a/server/routers/contentstack/schemas/linkConnection.ts b/server/routers/contentstack/schemas/linkConnection.ts index 902e6fca1..8fd074ba9 100644 --- a/server/routers/contentstack/schemas/linkConnection.ts +++ b/server/routers/contentstack/schemas/linkConnection.ts @@ -5,6 +5,7 @@ import * as pageLinks from "@/server/routers/contentstack/schemas/pageLinks" const linkUnionSchema = z.discriminatedUnion("__typename", [ pageLinks.contentPageSchema, + pageLinks.collectionPageSchema, pageLinks.hotelPageSchema, pageLinks.loyaltyPageSchema, ]) diff --git a/server/routers/contentstack/schemas/pageLinks.ts b/server/routers/contentstack/schemas/pageLinks.ts index c98a47d2b..b23c85d96 100644 --- a/server/routers/contentstack/schemas/pageLinks.ts +++ b/server/routers/contentstack/schemas/pageLinks.ts @@ -30,6 +30,16 @@ export const extendedPageLinkSchema = pageLinkSchema.merge( }), }) ) +export const collectionPageSchema = z + .object({ + __typename: z.literal(ContentEnum.blocks.CollectionPage), + }) + .merge(extendedPageLinkSchema) + +export const collectionPageRefSchema = z.object({ + __typename: z.literal(ContentEnum.blocks.CollectionPage), + system: systemSchema, +}) export const contentPageSchema = z .object({ @@ -67,6 +77,7 @@ export const loyaltyPageRefSchema = z.object({ type Data = | z.output | z.output + | z.output | z.output | z.output | Object @@ -83,6 +94,7 @@ export function transform(data: Data) { url: removeMultipleSlashes(`/${data.system.locale}/${data.url}`), } case ContentEnum.blocks.ContentPage: + case ContentEnum.blocks.CollectionPage: case ContentEnum.blocks.LoyaltyPage: // TODO: Once all links use this transform // `web` can be removed and not to be worried @@ -102,6 +114,7 @@ export function transform(data: Data) { type RefData = | z.output + | z.output | z.output | z.output | z.output @@ -112,6 +125,7 @@ export function transformRef(data: RefData) { switch (data.__typename) { case ContentEnum.blocks.AccountPage: case ContentEnum.blocks.ContentPage: + case ContentEnum.blocks.CollectionPage: case ContentEnum.blocks.HotelPage: case ContentEnum.blocks.LoyaltyPage: return data.system diff --git a/server/routers/contentstack/schemas/sidebar/scriptedCard.ts b/server/routers/contentstack/schemas/sidebar/scriptedCard.ts index 0579a4be4..a391f4bc0 100644 --- a/server/routers/contentstack/schemas/sidebar/scriptedCard.ts +++ b/server/routers/contentstack/schemas/sidebar/scriptedCard.ts @@ -7,6 +7,7 @@ import { transformCardBlockRefs, } from "../blocks/cardsGrid" +import { scriptedCardThemeEnum } from "@/types/enums/scriptedCard" import { SidebarEnums } from "@/types/enums/sidebar" export const scriptedCardsSchema = z.object({ @@ -16,17 +17,7 @@ export const scriptedCardsSchema = z.object({ .default(SidebarEnums.blocks.ScriptedCard), scripted_card: z .object({ - theme: z - .enum([ - "one", - "two", - "three", - "primaryDim", - "primaryDark", - "primaryInverted", - "primaryStrong", - ]) - .nullable(), + theme: z.nativeEnum(scriptedCardThemeEnum).nullable(), scripted_cardConnection: z.object({ edges: z.array( z.object({ diff --git a/types/components/blocks/cardsGrid.ts b/types/components/blocks/cardsGrid.ts index 5b1566b27..c4a5f0a91 100644 --- a/types/components/blocks/cardsGrid.ts +++ b/types/components/blocks/cardsGrid.ts @@ -1,4 +1,4 @@ -import { CardsGrid } from "@/types/trpc/routers/contentstack/blocks" +import type { CardsGrid } from "@/types/trpc/routers/contentstack/blocks" export interface CardsGridProps extends Pick { firstItem?: boolean diff --git a/types/components/blocks/index.ts b/types/components/blocks/index.ts index 5ddc0765c..501e8dfc9 100644 --- a/types/components/blocks/index.ts +++ b/types/components/blocks/index.ts @@ -1,8 +1,13 @@ import type { Block as AccountPageBlock } from "@/types/trpc/routers/contentstack/accountPage" +import type { Block as CollectionPageBlock } from "@/types/trpc/routers/contentstack/collectionPage" import type { Block as ContentPageBlock } from "@/types/trpc/routers/contentstack/contentPage" import type { Block as LoyaltyPageBlock } from "@/types/trpc/routers/contentstack/loyaltyPage" -export type Blocks = AccountPageBlock | ContentPageBlock | LoyaltyPageBlock +export type Blocks = + | AccountPageBlock + | CollectionPageBlock + | ContentPageBlock + | LoyaltyPageBlock export interface BlocksProps { blocks: Blocks[] diff --git a/types/components/tracking.ts b/types/components/tracking.ts index 72aa6f853..aa42ae5fe 100644 --- a/types/components/tracking.ts +++ b/types/components/tracking.ts @@ -5,6 +5,7 @@ import type { Lang } from "@/constants/languages" export enum TrackingChannelEnum { "scandic-friends" = "scandic-friends", "static-content-page" = "static-content-page", + "collection-page" = "collection-page", } export type TrackingChannel = keyof typeof TrackingChannelEnum diff --git a/types/enums/collectionPage.ts b/types/enums/collectionPage.ts new file mode 100644 index 000000000..d48d68e34 --- /dev/null +++ b/types/enums/collectionPage.ts @@ -0,0 +1,9 @@ +export namespace CollectionPageEnum { + export namespace ContentStack { + export const enum blocks { + CardsGrid = "CollectionPageBlocksCardsGrid", + Shortcuts = "CollectionPageBlocksShortcuts", + UspGrid = "CollectionPageBlocksUspGrid", + } + } +} diff --git a/types/enums/content.ts b/types/enums/content.ts index ad94dbd28..cc2a84e15 100644 --- a/types/enums/content.ts +++ b/types/enums/content.ts @@ -1,6 +1,7 @@ export namespace ContentEnum { export const enum blocks { AccountPage = "AccountPage", + CollectionPage = "CollectionPage", ContentPage = "ContentPage", HotelPage = "HotelPage", ImageContainer = "ImageContainer", diff --git a/types/enums/scriptedCard.ts b/types/enums/scriptedCard.ts new file mode 100644 index 000000000..658a84621 --- /dev/null +++ b/types/enums/scriptedCard.ts @@ -0,0 +1,9 @@ +export enum scriptedCardThemeEnum { + one = "one", + two = "two", + three = "three", + primaryDim = "primaryDim", + primaryDark = "primaryDark", + primaryInverted = "primaryInverted", + primaryStrong = "primaryStrong", +} diff --git a/types/params.ts b/types/params.ts index fff91effc..ed2706c37 100644 --- a/types/params.ts +++ b/types/params.ts @@ -17,7 +17,11 @@ export type StatusParams = { } export type ContentTypeParams = { - contentType: "loyalty-page" | "content-page" | "hotel-page" + contentType: + | "loyalty-page" + | "content-page" + | "hotel-page" + | "collection-page" } export type ContentTypeWebviewParams = { diff --git a/types/requests/contentType.ts b/types/requests/contentType.ts index 605c96c9b..1744af9a0 100644 --- a/types/requests/contentType.ts +++ b/types/requests/contentType.ts @@ -2,6 +2,7 @@ export enum ContentTypeEnum { accountPage = "account_page", loyaltyPage = "loyalty_page", hotelPage = "hotel_page", + collectionPage = "collection_page", contentPage = "content_page", currentBlocksPage = "current_blocks_page", } diff --git a/types/requests/entry.ts b/types/requests/entry.ts index e86b1a4ca..6429fee68 100644 --- a/types/requests/entry.ts +++ b/types/requests/entry.ts @@ -14,6 +14,7 @@ const entryResolveSchema = z.object({ export const validateEntryResolveSchema = z.object({ all_account_page: entryResolveSchema, + all_collection_page: entryResolveSchema, all_content_page: entryResolveSchema, all_loyalty_page: entryResolveSchema, all_current_blocks_page: entryResolveSchema, diff --git a/types/requests/pageType.ts b/types/requests/pageType.ts index 001e6a486..6ac02e9f4 100644 --- a/types/requests/pageType.ts +++ b/types/requests/pageType.ts @@ -3,5 +3,6 @@ export enum PageTypeEnum { loyaltyPage = "loyalty-page", hotelPage = "hotel-page", contentPage = "content-page", + collectionPage = "collection-page", currentBlocksPage = "current-blocks-page", } diff --git a/types/trpc/routers/contentstack/collectionPage.ts b/types/trpc/routers/contentstack/collectionPage.ts new file mode 100644 index 000000000..f1936fac9 --- /dev/null +++ b/types/trpc/routers/contentstack/collectionPage.ts @@ -0,0 +1,20 @@ +import { z } from "zod" + +import { + blocksSchema, + collectionPageRefsSchema, + collectionPageSchema, +} from "@/server/routers/contentstack/collectionPage/output" + +export interface GetCollectionPageRefsSchema + extends z.input {} + +export interface CollectionPageRefs + extends z.output {} + +export interface GetCollectionPageSchema + extends z.input {} + +export interface CollectionPage extends z.output {} + +export type Block = z.output