feat/BOOK-755 alert content pages
* feat(BOOK-755): Added alert block on Collection pages * feat(BOOK-755): Added alert block on Content pages * feat(BOOK-755): Added alert functionality for RTE Approved-by: Bianca Widstam
This commit is contained in:
13
apps/scandic-web/components/Blocks/Alert/index.tsx
Normal file
13
apps/scandic-web/components/Blocks/Alert/index.tsx
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
import { Alert } from "@scandic-hotels/design-system/Alert"
|
||||||
|
|
||||||
|
import type { AlertBlock } from "@scandic-hotels/trpc/types/blocks"
|
||||||
|
|
||||||
|
interface AlertBlockProps extends Pick<AlertBlock, "alert"> {}
|
||||||
|
|
||||||
|
export function AlertBlock({ alert }: AlertBlockProps) {
|
||||||
|
if (!alert) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
return <Alert {...alert} />
|
||||||
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
import { JsonToHtml } from "@scandic-hotels/design-system/JsonToHtml"
|
import { JsonToHtml } from "@scandic-hotels/design-system/JsonToHtml"
|
||||||
import { BlocksEnums } from "@scandic-hotels/trpc/types/blocksEnum"
|
import { BlocksEnums } from "@scandic-hotels/trpc/types/blocksEnum"
|
||||||
|
|
||||||
|
import { AlertBlock } from "@/components/Blocks/Alert"
|
||||||
import CardsGrid from "@/components/Blocks/CardsGrid"
|
import CardsGrid from "@/components/Blocks/CardsGrid"
|
||||||
import CarouselCards from "@/components/Blocks/CarouselCards"
|
import CarouselCards from "@/components/Blocks/CarouselCards"
|
||||||
import DynamicContent from "@/components/Blocks/DynamicContent"
|
import DynamicContent from "@/components/Blocks/DynamicContent"
|
||||||
@@ -30,6 +31,10 @@ export default function Blocks({ blocks }: BlocksProps) {
|
|||||||
key={`${block.typename}-${idx}`}
|
key={`${block.typename}-${idx}`}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
|
case BlocksEnums.block.Alert:
|
||||||
|
return (
|
||||||
|
<AlertBlock alert={block.alert} key={`${block.typename}-${idx}`} />
|
||||||
|
)
|
||||||
case BlocksEnums.block.CardsGrid:
|
case BlocksEnums.block.CardsGrid:
|
||||||
return (
|
return (
|
||||||
<CardsGrid
|
<CardsGrid
|
||||||
|
|||||||
@@ -4,7 +4,9 @@ import { nodesToHtml } from "./utils"
|
|||||||
|
|
||||||
import styles from "./jsontohtml.module.css"
|
import styles from "./jsontohtml.module.css"
|
||||||
|
|
||||||
|
import { AlertTypeEnum } from "@scandic-hotels/common/constants/alert"
|
||||||
import { ImageVaultAsset } from "@scandic-hotels/common/utils/imageVault"
|
import { ImageVaultAsset } from "@scandic-hotels/common/utils/imageVault"
|
||||||
|
import { AlertSidepeekContent } from "../../types/sidepeekContent"
|
||||||
import { ContentBlockType } from "./types/rte/enums"
|
import { ContentBlockType } from "./types/rte/enums"
|
||||||
import type { RTENode } from "./types/rte/node"
|
import type { RTENode } from "./types/rte/node"
|
||||||
import type { RenderOptions } from "./types/rte/option"
|
import type { RenderOptions } from "./types/rte/option"
|
||||||
@@ -15,7 +17,7 @@ export type Node<T> = {
|
|||||||
|
|
||||||
export type Embeds =
|
export type Embeds =
|
||||||
| {
|
| {
|
||||||
__typename: Exclude<ContentBlockType, "ImageContainer">
|
__typename: Exclude<ContentBlockType, "ImageContainer" | "Alert">
|
||||||
system?: { uid: string } | null
|
system?: { uid: string } | null
|
||||||
url?: string | null
|
url?: string | null
|
||||||
permanent_url?: string | null
|
permanent_url?: string | null
|
||||||
@@ -29,6 +31,25 @@ export type Embeds =
|
|||||||
image_left?: ImageVaultAsset
|
image_left?: ImageVaultAsset
|
||||||
image_right?: ImageVaultAsset
|
image_right?: ImageVaultAsset
|
||||||
}
|
}
|
||||||
|
| {
|
||||||
|
__typename: "Alert"
|
||||||
|
system?: { uid: string } | null
|
||||||
|
type: AlertTypeEnum
|
||||||
|
heading: string | null
|
||||||
|
text: string
|
||||||
|
phoneContact?: {
|
||||||
|
displayText: string
|
||||||
|
phoneNumber: string
|
||||||
|
footnote?: string | null
|
||||||
|
} | null
|
||||||
|
sidepeekContent?: AlertSidepeekContent | null
|
||||||
|
sidepeekCtaText?: string | null
|
||||||
|
link?: {
|
||||||
|
url: string
|
||||||
|
title: string
|
||||||
|
keepSearchParams?: boolean
|
||||||
|
} | null
|
||||||
|
}
|
||||||
|
|
||||||
export type EmbedByUid = Record<string, Node<Embeds>>
|
export type EmbedByUid = Record<string, Node<Embeds>>
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import {
|
|||||||
mapImageVaultAssetResponseToImageVaultAsset,
|
mapImageVaultAssetResponseToImageVaultAsset,
|
||||||
mapInsertResponseToImageVaultAsset,
|
mapInsertResponseToImageVaultAsset,
|
||||||
} from "@scandic-hotels/common/utils/imageVault"
|
} from "@scandic-hotels/common/utils/imageVault"
|
||||||
|
import { Alert } from "../Alert"
|
||||||
import { TextLink } from "../TextLink"
|
import { TextLink } from "../TextLink"
|
||||||
import type { EmbedByUid } from "./JsonToHtml"
|
import type { EmbedByUid } from "./JsonToHtml"
|
||||||
import type { Attributes } from "./types/rte/attrs"
|
import type { Attributes } from "./types/rte/attrs"
|
||||||
@@ -458,6 +459,8 @@ export const renderOptions: RenderOptions = {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
return null
|
return null
|
||||||
|
} else if (entry?.node.__typename === "Alert") {
|
||||||
|
return <Alert key={node.uid} {...entry.node} />
|
||||||
} else if (
|
} else if (
|
||||||
entry?.node.__typename === "AccountPage" ||
|
entry?.node.__typename === "AccountPage" ||
|
||||||
entry?.node.__typename === "CampaignOverviewPage" ||
|
entry?.node.__typename === "CampaignOverviewPage" ||
|
||||||
|
|||||||
@@ -12,9 +12,11 @@ import { HotelPageLink } from "./PageLink/HotelPageLink.graphql"
|
|||||||
import { LoyaltyPageLink } from "./PageLink/LoyaltyPageLink.graphql"
|
import { LoyaltyPageLink } from "./PageLink/LoyaltyPageLink.graphql"
|
||||||
import { PromoCampaignPageLink } from "./PageLink/PromoCampaignPageLink.graphql"
|
import { PromoCampaignPageLink } from "./PageLink/PromoCampaignPageLink.graphql"
|
||||||
import { StartPageLink } from "./PageLink/StartPageLink.graphql"
|
import { StartPageLink } from "./PageLink/StartPageLink.graphql"
|
||||||
|
import { System } from "./System.graphql"
|
||||||
|
|
||||||
export const Alert = gql`
|
export const Alert = gql`
|
||||||
fragment Alert on Alert {
|
fragment Alert on Alert {
|
||||||
|
__typename
|
||||||
type
|
type
|
||||||
heading
|
heading
|
||||||
text
|
text
|
||||||
@@ -76,6 +78,9 @@ export const Alert = gql`
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
visible_on
|
visible_on
|
||||||
|
system {
|
||||||
|
...System
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
${AccountPageLink}
|
${AccountPageLink}
|
||||||
@@ -90,4 +95,5 @@ export const Alert = gql`
|
|||||||
${LoyaltyPageLink}
|
${LoyaltyPageLink}
|
||||||
${StartPageLink}
|
${StartPageLink}
|
||||||
${PromoCampaignPageLink}
|
${PromoCampaignPageLink}
|
||||||
|
${System}
|
||||||
`
|
`
|
||||||
|
|||||||
35
packages/trpc/lib/graphql/Fragments/Blocks/Alert.graphql.ts
Normal file
35
packages/trpc/lib/graphql/Fragments/Blocks/Alert.graphql.ts
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
import { gql } from "graphql-tag"
|
||||||
|
|
||||||
|
import { Alert } from "../Alert.graphql"
|
||||||
|
|
||||||
|
export const Alert_ContentPage = gql`
|
||||||
|
fragment Alert_ContentPage on ContentPageBlocksAlert {
|
||||||
|
__typename
|
||||||
|
alert {
|
||||||
|
alertConnection {
|
||||||
|
edges {
|
||||||
|
node {
|
||||||
|
...Alert
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
${Alert}
|
||||||
|
`
|
||||||
|
|
||||||
|
export const Alert_CollectionPage = gql`
|
||||||
|
fragment Alert_CollectionPage on CollectionPageBlocksAlert {
|
||||||
|
__typename
|
||||||
|
alert {
|
||||||
|
alertConnection {
|
||||||
|
edges {
|
||||||
|
node {
|
||||||
|
...Alert
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
${Alert}
|
||||||
|
`
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
import { gql } from "graphql-tag"
|
import { gql } from "graphql-tag"
|
||||||
|
|
||||||
|
import { Alert } from "../Alert.graphql"
|
||||||
import { ImageContainer } from "../ImageContainer.graphql"
|
import { ImageContainer } from "../ImageContainer.graphql"
|
||||||
import { AccountPageLink } from "../PageLink/AccountPageLink.graphql"
|
import { AccountPageLink } from "../PageLink/AccountPageLink.graphql"
|
||||||
import { CampaignOverviewPageLink } from "../PageLink/CampaignOverviewPageLink.graphql"
|
import { CampaignOverviewPageLink } from "../PageLink/CampaignOverviewPageLink.graphql"
|
||||||
@@ -24,6 +25,7 @@ export const Content_ContentPage = gql`
|
|||||||
node {
|
node {
|
||||||
__typename
|
__typename
|
||||||
...SysAsset
|
...SysAsset
|
||||||
|
...Alert
|
||||||
...ImageContainer
|
...ImageContainer
|
||||||
...AccountPageLink
|
...AccountPageLink
|
||||||
...CampaignOverviewPageLink
|
...CampaignOverviewPageLink
|
||||||
@@ -45,6 +47,7 @@ export const Content_ContentPage = gql`
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
${SysAsset}
|
${SysAsset}
|
||||||
|
${Alert}
|
||||||
${ImageContainer}
|
${ImageContainer}
|
||||||
${AccountPageLink}
|
${AccountPageLink}
|
||||||
${CampaignOverviewPageLink}
|
${CampaignOverviewPageLink}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { gql } from "graphql-tag"
|
import { gql } from "graphql-tag"
|
||||||
|
|
||||||
|
import { Alert_CollectionPage } from "../../Fragments/Blocks/Alert.graphql"
|
||||||
import { CardsGrid_CollectionPage } from "../../Fragments/Blocks/CardsGrid.graphql"
|
import { CardsGrid_CollectionPage } from "../../Fragments/Blocks/CardsGrid.graphql"
|
||||||
import { DynamicContent_CollectionPage } from "../../Fragments/Blocks/DynamicContent.graphql"
|
import { DynamicContent_CollectionPage } from "../../Fragments/Blocks/DynamicContent.graphql"
|
||||||
import { Shortcuts_CollectionPage } from "../../Fragments/Blocks/Shortcuts.graphql"
|
import { Shortcuts_CollectionPage } from "../../Fragments/Blocks/Shortcuts.graphql"
|
||||||
@@ -35,6 +36,7 @@ export const GetCollectionPage = gql`
|
|||||||
...UspGrid_CollectionPage
|
...UspGrid_CollectionPage
|
||||||
...DynamicContent_CollectionPage
|
...DynamicContent_CollectionPage
|
||||||
...VideoCard_CollectionPage
|
...VideoCard_CollectionPage
|
||||||
|
...Alert_CollectionPage
|
||||||
}
|
}
|
||||||
system {
|
system {
|
||||||
...System
|
...System
|
||||||
@@ -55,6 +57,7 @@ export const GetCollectionPage = gql`
|
|||||||
${DynamicContent_CollectionPage}
|
${DynamicContent_CollectionPage}
|
||||||
${VideoCard_CollectionPage}
|
${VideoCard_CollectionPage}
|
||||||
${Video}
|
${Video}
|
||||||
|
${Alert_CollectionPage}
|
||||||
`
|
`
|
||||||
|
|
||||||
export const GetDaDeEnUrlsCollectionPage = gql`
|
export const GetDaDeEnUrlsCollectionPage = gql`
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { gql } from "graphql-tag"
|
import { gql } from "graphql-tag"
|
||||||
|
|
||||||
import { Accordion_ContentPage } from "../../Fragments/Blocks/Accordion.graphql"
|
import { Accordion_ContentPage } from "../../Fragments/Blocks/Accordion.graphql"
|
||||||
|
import { Alert_ContentPage } from "../../Fragments/Blocks/Alert.graphql"
|
||||||
import { CardsGrid_ContentPage } from "../../Fragments/Blocks/CardsGrid.graphql"
|
import { CardsGrid_ContentPage } from "../../Fragments/Blocks/CardsGrid.graphql"
|
||||||
import { Content_ContentPage } from "../../Fragments/Blocks/Content.graphql"
|
import { Content_ContentPage } from "../../Fragments/Blocks/Content.graphql"
|
||||||
import { DynamicContent_ContentPage } from "../../Fragments/Blocks/DynamicContent.graphql"
|
import { DynamicContent_ContentPage } from "../../Fragments/Blocks/DynamicContent.graphql"
|
||||||
@@ -112,6 +113,7 @@ export const GetContentPageBlocksBatch2 = gql`
|
|||||||
...Table_ContentPage
|
...Table_ContentPage
|
||||||
...TextCols_ContentPage
|
...TextCols_ContentPage
|
||||||
...UspGrid_ContentPage
|
...UspGrid_ContentPage
|
||||||
|
...Alert_ContentPage
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -120,6 +122,7 @@ export const GetContentPageBlocksBatch2 = gql`
|
|||||||
${Table_ContentPage}
|
${Table_ContentPage}
|
||||||
${TextCols_ContentPage}
|
${TextCols_ContentPage}
|
||||||
${UspGrid_ContentPage}
|
${UspGrid_ContentPage}
|
||||||
|
${Alert_ContentPage}
|
||||||
`
|
`
|
||||||
|
|
||||||
export const GetDaDeEnUrlsContentPage = gql`
|
export const GetDaDeEnUrlsContentPage = gql`
|
||||||
|
|||||||
@@ -1,15 +1,13 @@
|
|||||||
import { z, ZodError, ZodIssueCode } from "zod"
|
import { z, ZodError, ZodIssueCode } from "zod"
|
||||||
|
|
||||||
import {
|
import { AlertVisibleOnEnum } from "@scandic-hotels/common/constants/alert"
|
||||||
AlertTypeEnum,
|
|
||||||
AlertVisibleOnEnum,
|
|
||||||
} from "@scandic-hotels/common/constants/alert"
|
|
||||||
import { Lang } from "@scandic-hotels/common/constants/language"
|
import { Lang } from "@scandic-hotels/common/constants/language"
|
||||||
import { logger } from "@scandic-hotels/common/logger"
|
import { logger } from "@scandic-hotels/common/logger"
|
||||||
import { removeMultipleSlashes } from "@scandic-hotels/common/utils/url"
|
import { removeMultipleSlashes } from "@scandic-hotels/common/utils/url"
|
||||||
import { nullableStringValidator } from "@scandic-hotels/common/utils/zod/stringValidator"
|
import { nullableStringValidator } from "@scandic-hotels/common/utils/zod/stringValidator"
|
||||||
|
|
||||||
import { discriminatedUnion } from "../../../utils/discriminatedUnion"
|
import { discriminatedUnion } from "../../../utils/discriminatedUnion"
|
||||||
|
import { transformedAlertSchema } from "../schemas/alert"
|
||||||
import {
|
import {
|
||||||
infoCardBlockSchema,
|
infoCardBlockSchema,
|
||||||
transformInfoCardBlock,
|
transformInfoCardBlock,
|
||||||
@@ -410,85 +408,6 @@ export const headerSchema = z
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
export const alertSchema = z
|
|
||||||
.object({
|
|
||||||
type: z.nativeEnum(AlertTypeEnum),
|
|
||||||
text: z.string(),
|
|
||||||
heading: z.string(),
|
|
||||||
phone_contact: z.object({
|
|
||||||
display_text: z.string(),
|
|
||||||
phone_number: z.string().nullable(),
|
|
||||||
footnote: z.string().nullable(),
|
|
||||||
}),
|
|
||||||
has_link: z.boolean(),
|
|
||||||
link: linkAndTitleSchema,
|
|
||||||
has_sidepeek_button: z.boolean(),
|
|
||||||
sidepeek_button: z.object({
|
|
||||||
cta_text: z.string(),
|
|
||||||
}),
|
|
||||||
sidepeek_content: z.object({
|
|
||||||
heading: z.string(),
|
|
||||||
content: z.object({
|
|
||||||
json: z.any(),
|
|
||||||
embedded_itemsConnection: z.object({
|
|
||||||
edges: z.array(
|
|
||||||
z.object({
|
|
||||||
node: linkUnionSchema.transform((data) => {
|
|
||||||
const link = transformPageLink(data)
|
|
||||||
if (link) {
|
|
||||||
return link
|
|
||||||
}
|
|
||||||
return data
|
|
||||||
}),
|
|
||||||
})
|
|
||||||
),
|
|
||||||
}),
|
|
||||||
}),
|
|
||||||
}),
|
|
||||||
visible_on: z.array(z.string()).nullish().default([]),
|
|
||||||
})
|
|
||||||
.transform(
|
|
||||||
({
|
|
||||||
type,
|
|
||||||
heading,
|
|
||||||
text,
|
|
||||||
phone_contact,
|
|
||||||
has_link,
|
|
||||||
link,
|
|
||||||
has_sidepeek_button,
|
|
||||||
sidepeek_button,
|
|
||||||
sidepeek_content,
|
|
||||||
visible_on,
|
|
||||||
}) => {
|
|
||||||
const hasLink = has_link && link.link
|
|
||||||
return {
|
|
||||||
type,
|
|
||||||
text,
|
|
||||||
heading,
|
|
||||||
visible_on,
|
|
||||||
phoneContact:
|
|
||||||
phone_contact.display_text && phone_contact.phone_number
|
|
||||||
? {
|
|
||||||
displayText: phone_contact.display_text,
|
|
||||||
phoneNumber: phone_contact.phone_number,
|
|
||||||
footnote: phone_contact.footnote,
|
|
||||||
}
|
|
||||||
: null,
|
|
||||||
hasSidepeekButton: !!has_sidepeek_button,
|
|
||||||
link: hasLink
|
|
||||||
? {
|
|
||||||
url: link.link.url,
|
|
||||||
title: link.title,
|
|
||||||
}
|
|
||||||
: null,
|
|
||||||
sidepeekButton:
|
|
||||||
!hasLink && has_sidepeek_button ? sidepeek_button : null,
|
|
||||||
sidepeekContent:
|
|
||||||
!hasLink && has_sidepeek_button ? sidepeek_content : null,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
export const siteConfigSchema = z
|
export const siteConfigSchema = z
|
||||||
.object({
|
.object({
|
||||||
all_site_config: z.object({
|
all_site_config: z.object({
|
||||||
@@ -503,7 +422,7 @@ export const siteConfigSchema = z
|
|||||||
alertConnection: z.object({
|
alertConnection: z.object({
|
||||||
edges: z.array(
|
edges: z.array(
|
||||||
z.object({
|
z.object({
|
||||||
node: alertSchema,
|
node: transformedAlertSchema,
|
||||||
})
|
})
|
||||||
),
|
),
|
||||||
}),
|
}),
|
||||||
|
|||||||
@@ -5,11 +5,11 @@ import { logger } from "@scandic-hotels/common/logger"
|
|||||||
|
|
||||||
import { getValueFromContactConfig } from "../../../utils/contactConfig"
|
import { getValueFromContactConfig } from "../../../utils/contactConfig"
|
||||||
|
|
||||||
import type { AlertOutput } from "../../../types/siteConfig"
|
import type { Alert } from "../schemas/alert"
|
||||||
import type { ContactConfig } from "./output"
|
import type { ContactConfig } from "./output"
|
||||||
|
|
||||||
export function getAlertPhoneContactData(
|
export function getAlertPhoneContactData(
|
||||||
alert: AlertOutput,
|
alert: Alert,
|
||||||
contactConfig: ContactConfig
|
contactConfig: ContactConfig
|
||||||
) {
|
) {
|
||||||
if (alert.phoneContact) {
|
if (alert.phoneContact) {
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import { transformedImageVaultAssetSchema } from "@scandic-hotels/common/utils/i
|
|||||||
|
|
||||||
import { CollectionPageEnum } from "../../../types/collectionPage"
|
import { CollectionPageEnum } from "../../../types/collectionPage"
|
||||||
import { discriminatedUnionArray } from "../../../utils/discriminatedUnion"
|
import { discriminatedUnionArray } from "../../../utils/discriminatedUnion"
|
||||||
|
import { alertBlockSchema } from "../schemas/blocks/alert"
|
||||||
import { cardsGridSchema } from "../schemas/blocks/cardsGrid"
|
import { cardsGridSchema } from "../schemas/blocks/cardsGrid"
|
||||||
import { dynamicContentSchema as blockDynamicContentSchema } from "../schemas/blocks/dynamicContent"
|
import { dynamicContentSchema as blockDynamicContentSchema } from "../schemas/blocks/dynamicContent"
|
||||||
import { shortcutsSchema } from "../schemas/blocks/shortcuts"
|
import { shortcutsSchema } from "../schemas/blocks/shortcuts"
|
||||||
@@ -47,12 +48,19 @@ export const collectionPageVideoCard = z
|
|||||||
})
|
})
|
||||||
.merge(videoCardSchema)
|
.merge(videoCardSchema)
|
||||||
|
|
||||||
|
export const collectionPageAlert = z
|
||||||
|
.object({
|
||||||
|
__typename: z.literal(CollectionPageEnum.ContentStack.blocks.Alert),
|
||||||
|
})
|
||||||
|
.merge(alertBlockSchema)
|
||||||
|
|
||||||
export const blocksSchema = z.discriminatedUnion("__typename", [
|
export const blocksSchema = z.discriminatedUnion("__typename", [
|
||||||
collectionPageCards,
|
collectionPageCards,
|
||||||
collectionPageDynamicContent,
|
collectionPageDynamicContent,
|
||||||
collectionPageShortcuts,
|
collectionPageShortcuts,
|
||||||
collectionPageUspGrid,
|
collectionPageUspGrid,
|
||||||
collectionPageVideoCard,
|
collectionPageVideoCard,
|
||||||
|
collectionPageAlert,
|
||||||
])
|
])
|
||||||
|
|
||||||
const navigationLinksSchema = z
|
const navigationLinksSchema = z
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import { transformedImageVaultAssetSchema } from "@scandic-hotels/common/utils/i
|
|||||||
import { ContentPageEnum } from "../../../types/contentPage"
|
import { ContentPageEnum } from "../../../types/contentPage"
|
||||||
import { discriminatedUnionArray } from "../../../utils/discriminatedUnion"
|
import { discriminatedUnionArray } from "../../../utils/discriminatedUnion"
|
||||||
import { accordionSchema } from "../schemas/blocks/accordion"
|
import { accordionSchema } from "../schemas/blocks/accordion"
|
||||||
|
import { alertBlockSchema } from "../schemas/blocks/alert"
|
||||||
import { cardsGridSchema } from "../schemas/blocks/cardsGrid"
|
import { cardsGridSchema } from "../schemas/blocks/cardsGrid"
|
||||||
import { contentSchema as blockContentSchema } from "../schemas/blocks/content"
|
import { contentSchema as blockContentSchema } from "../schemas/blocks/content"
|
||||||
import { dynamicContentSchema as blockDynamicContentSchema } from "../schemas/blocks/dynamicContent"
|
import { dynamicContentSchema as blockDynamicContentSchema } from "../schemas/blocks/dynamicContent"
|
||||||
@@ -101,6 +102,12 @@ export const contentPageVideo = z
|
|||||||
})
|
})
|
||||||
.merge(videoBlockSchema)
|
.merge(videoBlockSchema)
|
||||||
|
|
||||||
|
export const contentPageAlert = z
|
||||||
|
.object({
|
||||||
|
__typename: z.literal(ContentPageEnum.ContentStack.blocks.Alert),
|
||||||
|
})
|
||||||
|
.merge(alertBlockSchema)
|
||||||
|
|
||||||
export const blocksSchema = z.discriminatedUnion("__typename", [
|
export const blocksSchema = z.discriminatedUnion("__typename", [
|
||||||
contentPageAccordion,
|
contentPageAccordion,
|
||||||
contentPageCards,
|
contentPageCards,
|
||||||
@@ -114,6 +121,7 @@ export const blocksSchema = z.discriminatedUnion("__typename", [
|
|||||||
contentPageHotelListing,
|
contentPageHotelListing,
|
||||||
contentPageVideoCard,
|
contentPageVideoCard,
|
||||||
contentPageVideo,
|
contentPageVideo,
|
||||||
|
contentPageAlert,
|
||||||
])
|
])
|
||||||
|
|
||||||
export const contentPageSidebarContent = z
|
export const contentPageSidebarContent = z
|
||||||
|
|||||||
92
packages/trpc/lib/routers/contentstack/schemas/alert.ts
Normal file
92
packages/trpc/lib/routers/contentstack/schemas/alert.ts
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
import z from "zod"
|
||||||
|
|
||||||
|
import { AlertTypeEnum } from "@scandic-hotels/common/constants/alert"
|
||||||
|
|
||||||
|
import { linkAndTitleSchema } from "./linkConnection"
|
||||||
|
import { linkUnionSchema, transformPageLink } from "./pageLinks"
|
||||||
|
import { systemSchema } from "./system"
|
||||||
|
|
||||||
|
export const alertSchema = z.object({
|
||||||
|
type: z.nativeEnum(AlertTypeEnum),
|
||||||
|
text: z.string(),
|
||||||
|
heading: z.string(),
|
||||||
|
phone_contact: z.object({
|
||||||
|
display_text: z.string(),
|
||||||
|
phone_number: z.string().nullish(),
|
||||||
|
footnote: z.string().nullish(),
|
||||||
|
}),
|
||||||
|
has_link: z.boolean(),
|
||||||
|
link: linkAndTitleSchema,
|
||||||
|
has_sidepeek_button: z.boolean(),
|
||||||
|
sidepeek_button: z.object({
|
||||||
|
cta_text: z.string(),
|
||||||
|
}),
|
||||||
|
sidepeek_content: z.object({
|
||||||
|
heading: z.string(),
|
||||||
|
content: z.object({
|
||||||
|
json: z.any(),
|
||||||
|
embedded_itemsConnection: z.object({
|
||||||
|
edges: z.array(
|
||||||
|
z.object({
|
||||||
|
node: linkUnionSchema.transform((data) => {
|
||||||
|
const link = transformPageLink(data)
|
||||||
|
if (link) {
|
||||||
|
return link
|
||||||
|
}
|
||||||
|
return data
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
),
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
visible_on: z.array(z.string()).nullish().default([]),
|
||||||
|
system: systemSchema,
|
||||||
|
})
|
||||||
|
|
||||||
|
export const transformedAlertSchema =
|
||||||
|
alertSchema.transform(transformAlertSchema)
|
||||||
|
|
||||||
|
export function transformAlertSchema(data: typeof alertSchema._type) {
|
||||||
|
const {
|
||||||
|
type,
|
||||||
|
heading,
|
||||||
|
text,
|
||||||
|
phone_contact,
|
||||||
|
has_link,
|
||||||
|
link,
|
||||||
|
has_sidepeek_button,
|
||||||
|
sidepeek_button,
|
||||||
|
sidepeek_content,
|
||||||
|
visible_on,
|
||||||
|
system,
|
||||||
|
} = data
|
||||||
|
|
||||||
|
const hasLink = has_link && link.link
|
||||||
|
return {
|
||||||
|
type,
|
||||||
|
text,
|
||||||
|
heading,
|
||||||
|
visible_on,
|
||||||
|
phoneContact:
|
||||||
|
phone_contact.display_text && phone_contact.phone_number
|
||||||
|
? {
|
||||||
|
displayText: phone_contact.display_text,
|
||||||
|
phoneNumber: phone_contact.phone_number,
|
||||||
|
footnote: phone_contact.footnote,
|
||||||
|
}
|
||||||
|
: null,
|
||||||
|
hasSidepeekButton: !!has_sidepeek_button,
|
||||||
|
link: hasLink
|
||||||
|
? {
|
||||||
|
url: link.link.url,
|
||||||
|
title: link.title,
|
||||||
|
}
|
||||||
|
: null,
|
||||||
|
sidepeekButton: !hasLink && has_sidepeek_button ? sidepeek_button : null,
|
||||||
|
sidepeekContent: !hasLink && has_sidepeek_button ? sidepeek_content : null,
|
||||||
|
system,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export type Alert = z.output<typeof transformedAlertSchema>
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
import { z } from "zod"
|
||||||
|
|
||||||
|
import { BlocksEnums } from "../../../../types/blocksEnum"
|
||||||
|
import { transformedAlertSchema } from "../alert"
|
||||||
|
|
||||||
|
export const alertBlockSchema = z.object({
|
||||||
|
typename: z.literal(BlocksEnums.block.Alert).default(BlocksEnums.block.Alert),
|
||||||
|
alert: z
|
||||||
|
.object({
|
||||||
|
alertConnection: z.object({
|
||||||
|
edges: z.array(
|
||||||
|
z.object({
|
||||||
|
node: transformedAlertSchema,
|
||||||
|
})
|
||||||
|
),
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
.transform((data) => {
|
||||||
|
const alert = data.alertConnection.edges[0]?.node
|
||||||
|
if (!alert) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
return alert
|
||||||
|
}),
|
||||||
|
})
|
||||||
@@ -1,6 +1,8 @@
|
|||||||
import { z } from "zod"
|
import { z } from "zod"
|
||||||
|
|
||||||
import { BlocksEnums } from "../../../../types/blocksEnum"
|
import { BlocksEnums } from "../../../../types/blocksEnum"
|
||||||
|
import { ContentEnum } from "../../../../types/content"
|
||||||
|
import { alertSchema, transformAlertSchema } from "../alert"
|
||||||
import { rawLinkUnionSchema, transformPageLink } from "../pageLinks"
|
import { rawLinkUnionSchema, transformPageLink } from "../pageLinks"
|
||||||
import { imageContainerSchema } from "./imageContainer"
|
import { imageContainerSchema } from "./imageContainer"
|
||||||
import { sysAssetSchema } from "./sysAsset"
|
import { sysAssetSchema } from "./sysAsset"
|
||||||
@@ -22,6 +24,11 @@ export const contentSchema = z.object({
|
|||||||
.discriminatedUnion("__typename", [
|
.discriminatedUnion("__typename", [
|
||||||
imageContainerSchema,
|
imageContainerSchema,
|
||||||
sysAssetSchema,
|
sysAssetSchema,
|
||||||
|
alertSchema.merge(
|
||||||
|
z.object({
|
||||||
|
__typename: z.literal(ContentEnum.blocks.Alert),
|
||||||
|
})
|
||||||
|
),
|
||||||
...rawLinkUnionSchema.options,
|
...rawLinkUnionSchema.options,
|
||||||
])
|
])
|
||||||
.transform((data) => {
|
.transform((data) => {
|
||||||
@@ -29,6 +36,12 @@ export const contentSchema = z.object({
|
|||||||
if (link) {
|
if (link) {
|
||||||
return link
|
return link
|
||||||
}
|
}
|
||||||
|
if (data.__typename === ContentEnum.blocks.Alert) {
|
||||||
|
return {
|
||||||
|
__typename: data.__typename,
|
||||||
|
...transformAlertSchema(data),
|
||||||
|
}
|
||||||
|
}
|
||||||
return data
|
return data
|
||||||
}),
|
}),
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import type { uspGridSchema } from "@scandic-hotels/trpc/routers/contentstack/sc
|
|||||||
import type { videoCardSchema } from "@scandic-hotels/trpc/routers/contentstack/schemas/blocks/videoCard"
|
import type { videoCardSchema } from "@scandic-hotels/trpc/routers/contentstack/schemas/blocks/videoCard"
|
||||||
import type { z } from "zod"
|
import type { z } from "zod"
|
||||||
|
|
||||||
|
import type { alertBlockSchema } from "../routers/contentstack/schemas/blocks/alert"
|
||||||
import type { videoBlockSchema } from "../routers/contentstack/schemas/blocks/video"
|
import type { videoBlockSchema } from "../routers/contentstack/schemas/blocks/video"
|
||||||
|
|
||||||
export interface TeaserCard extends z.output<typeof teaserCardBlockSchema> {}
|
export interface TeaserCard extends z.output<typeof teaserCardBlockSchema> {}
|
||||||
@@ -32,3 +33,4 @@ export interface CarouselCards extends z.output<typeof carouselCardsSchema> {}
|
|||||||
export interface CardGallery extends z.output<typeof cardGallerySchema> {}
|
export interface CardGallery extends z.output<typeof cardGallerySchema> {}
|
||||||
export interface VideoCard extends z.output<typeof videoCardSchema> {}
|
export interface VideoCard extends z.output<typeof videoCardSchema> {}
|
||||||
export interface VideoBlock extends z.output<typeof videoBlockSchema> {}
|
export interface VideoBlock extends z.output<typeof videoBlockSchema> {}
|
||||||
|
export interface AlertBlock extends z.output<typeof alertBlockSchema> {}
|
||||||
|
|||||||
@@ -21,5 +21,6 @@ export namespace BlocksEnums {
|
|||||||
Essentials = "Essentials",
|
Essentials = "Essentials",
|
||||||
VideoCard = "VideoCard",
|
VideoCard = "VideoCard",
|
||||||
Video = "Video",
|
Video = "Video",
|
||||||
|
Alert = "Alert",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ export namespace CollectionPageEnum {
|
|||||||
Shortcuts = "CollectionPageBlocksShortcuts",
|
Shortcuts = "CollectionPageBlocksShortcuts",
|
||||||
UspGrid = "CollectionPageBlocksUspGrid",
|
UspGrid = "CollectionPageBlocksUspGrid",
|
||||||
VideoCard = "CollectionPageBlocksVideoCard",
|
VideoCard = "CollectionPageBlocksVideoCard",
|
||||||
|
Alert = "CollectionPageBlocksAlert",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,5 +14,6 @@ export namespace ContentEnum {
|
|||||||
StartPage = "StartPage",
|
StartPage = "StartPage",
|
||||||
PromoCampaignPage = "PromoCampaignPage",
|
PromoCampaignPage = "PromoCampaignPage",
|
||||||
SysAsset = "SysAsset",
|
SysAsset = "SysAsset",
|
||||||
|
Alert = "Alert",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ export namespace ContentPageEnum {
|
|||||||
export namespace ContentStack {
|
export namespace ContentStack {
|
||||||
export const enum blocks {
|
export const enum blocks {
|
||||||
Accordion = "ContentPageBlocksAccordion",
|
Accordion = "ContentPageBlocksAccordion",
|
||||||
|
Alert = "ContentPageBlocksAlert",
|
||||||
CardsGrid = "ContentPageBlocksCardsGrid",
|
CardsGrid = "ContentPageBlocksCardsGrid",
|
||||||
Content = "ContentPageBlocksContent",
|
Content = "ContentPageBlocksContent",
|
||||||
DynamicContent = "ContentPageBlocksDynamicContent",
|
DynamicContent = "ContentPageBlocksDynamicContent",
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import type { z } from "zod"
|
import type { z } from "zod"
|
||||||
|
|
||||||
import type {
|
import type {
|
||||||
alertSchema,
|
|
||||||
siteConfigSchema,
|
siteConfigSchema,
|
||||||
sitewideCampaignBannerSchema,
|
sitewideCampaignBannerSchema,
|
||||||
} from "../routers/contentstack/base/output"
|
} from "../routers/contentstack/base/output"
|
||||||
@@ -9,19 +8,6 @@ import type {
|
|||||||
export type GetSiteConfigData = z.input<typeof siteConfigSchema>
|
export type GetSiteConfigData = z.input<typeof siteConfigSchema>
|
||||||
export type SiteConfig = z.output<typeof siteConfigSchema>
|
export type SiteConfig = z.output<typeof siteConfigSchema>
|
||||||
|
|
||||||
export type AlertOutput = z.output<typeof alertSchema>
|
|
||||||
export type SidepeekContent = AlertOutput["sidepeekContent"]
|
|
||||||
|
|
||||||
export type AlertPhoneContact = {
|
|
||||||
displayText: string
|
|
||||||
phoneNumber?: string
|
|
||||||
footnote?: string | null
|
|
||||||
}
|
|
||||||
|
|
||||||
export type Alert = Omit<AlertOutput, "phoneContact"> & {
|
|
||||||
phoneContact: AlertPhoneContact | null
|
|
||||||
}
|
|
||||||
|
|
||||||
export type GetSitewideCampaignBannerData = z.output<
|
export type GetSitewideCampaignBannerData = z.output<
|
||||||
typeof sitewideCampaignBannerSchema
|
typeof sitewideCampaignBannerSchema
|
||||||
>
|
>
|
||||||
|
|||||||
Reference in New Issue
Block a user