Merge branch 'develop' into feat/sw-703-image-loader
This commit is contained in:
@@ -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 <CollectionPage />
|
||||
case "content-page":
|
||||
if (env.HIDE_FOR_NEXT_RELEASE) {
|
||||
return notFound()
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { notFound } from "next/navigation"
|
||||
|
||||
import { getProfileSafely } from "@/lib/trpc/memoizedRequests"
|
||||
import { dt } from "@/lib/dt"
|
||||
import { getLocations, getProfileSafely } from "@/lib/trpc/memoizedRequests"
|
||||
import { serverClient } from "@/lib/trpc/server"
|
||||
import { HotelIncludeEnum } from "@/server/routers/hotels/input"
|
||||
|
||||
@@ -21,6 +22,17 @@ export default async function SelectRatePage({
|
||||
}: PageArgs<LangParams & { section: string }, SelectRateSearchParams>) {
|
||||
setLang(params.lang)
|
||||
|
||||
const locations = await getLocations()
|
||||
if (!locations || "error" in locations) {
|
||||
return null
|
||||
}
|
||||
const hotel = locations.data.find(
|
||||
(location) =>
|
||||
"operaId" in location && location.operaId == searchParams.hotel
|
||||
)
|
||||
if (!hotel) {
|
||||
return notFound()
|
||||
}
|
||||
const selectRoomParams = new URLSearchParams(searchParams)
|
||||
const selectRoomParamsObject =
|
||||
getHotelReservationQueryParams(selectRoomParams)
|
||||
@@ -29,7 +41,16 @@ export default async function SelectRatePage({
|
||||
return notFound()
|
||||
}
|
||||
|
||||
const adults = selectRoomParamsObject.room[0].adults // TODO: Handle multiple rooms
|
||||
const validFromDate =
|
||||
searchParams.fromDate &&
|
||||
dt(searchParams.fromDate).isAfter(dt().subtract(1, "day"))
|
||||
? searchParams.fromDate
|
||||
: dt().utc().format("YYYY-MM-DD")
|
||||
const validToDate =
|
||||
searchParams.toDate && dt(searchParams.toDate).isAfter(validFromDate)
|
||||
? searchParams.toDate
|
||||
: dt().utc().add(1, "day").format("YYYY-MM-DD")
|
||||
const adults = selectRoomParamsObject.room[0].adults || 1 // TODO: Handle multiple rooms
|
||||
const childrenCount = selectRoomParamsObject.room[0].child?.length
|
||||
const children = selectRoomParamsObject.room[0].child
|
||||
? generateChildrenString(selectRoomParamsObject.room[0].child)
|
||||
@@ -43,8 +64,8 @@ export default async function SelectRatePage({
|
||||
}),
|
||||
serverClient().hotel.availability.rooms({
|
||||
hotelId: parseInt(searchParams.hotel, 10),
|
||||
roomStayStartDate: searchParams.fromDate,
|
||||
roomStayEndDate: searchParams.toDate,
|
||||
roomStayStartDate: validFromDate,
|
||||
roomStayEndDate: validToDate,
|
||||
adults,
|
||||
children,
|
||||
}),
|
||||
|
||||
@@ -1,26 +1,29 @@
|
||||
import InitLivePreview from "@/components/Current/LivePreview"
|
||||
import { setLang } from "@/i18n/serverContext"
|
||||
import "@/app/globals.css"
|
||||
import "@scandic-hotels/design-system/style.css"
|
||||
|
||||
import type { Metadata } from "next"
|
||||
import TrpcProvider from "@/lib/trpc/Provider"
|
||||
|
||||
import InitLivePreview from "@/components/LivePreview"
|
||||
import { getIntl } from "@/i18n"
|
||||
import ServerIntlProvider from "@/i18n/Provider"
|
||||
import { setLang } from "@/i18n/serverContext"
|
||||
|
||||
import type { LangParams, LayoutArgs } from "@/types/params"
|
||||
|
||||
export const metadata: Metadata = {
|
||||
description: "New web",
|
||||
title: "Scandic Hotels",
|
||||
}
|
||||
|
||||
export default function RootLayout({
|
||||
export default async function RootLayout({
|
||||
children,
|
||||
params,
|
||||
}: React.PropsWithChildren<LayoutArgs<LangParams>>) {
|
||||
setLang(params.lang)
|
||||
const { defaultLocale, locale, messages } = await getIntl()
|
||||
|
||||
return (
|
||||
<html lang={params.lang}>
|
||||
<body>
|
||||
<InitLivePreview />
|
||||
{children}
|
||||
<ServerIntlProvider intl={{ defaultLocale, locale, messages }}>
|
||||
<TrpcProvider>{children}</TrpcProvider>
|
||||
</ServerIntlProvider>
|
||||
</body>
|
||||
</html>
|
||||
)
|
||||
|
||||
@@ -1,6 +1,14 @@
|
||||
import { ContentstackLivePreview } from "@contentstack/live-preview-utils"
|
||||
import { notFound } from "next/navigation"
|
||||
|
||||
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 LoadingSpinner from "@/components/LoadingSpinner"
|
||||
import { setLang } from "@/i18n/serverContext"
|
||||
|
||||
import {
|
||||
import type {
|
||||
ContentTypeParams,
|
||||
LangParams,
|
||||
PageArgs,
|
||||
@@ -13,12 +21,32 @@ export default async function PreviewPage({
|
||||
}: PageArgs<LangParams & ContentTypeParams & UIDParams, {}>) {
|
||||
setLang(params.lang)
|
||||
|
||||
return (
|
||||
<div>
|
||||
<p>
|
||||
Preview for {params.contentType}:{params.uid} in {params.lang} with
|
||||
params <pre>{JSON.stringify(searchParams, null, 2)}</pre> goes here
|
||||
</p>
|
||||
</div>
|
||||
)
|
||||
try {
|
||||
ContentstackLivePreview.setConfigFromParams(searchParams)
|
||||
|
||||
if (!searchParams.live_preview) {
|
||||
return <LoadingSpinner />
|
||||
}
|
||||
|
||||
switch (params.contentType) {
|
||||
case "content-page":
|
||||
return <ContentPage />
|
||||
case "loyalty-page":
|
||||
return <LoyaltyPage />
|
||||
case "collection-page":
|
||||
return <CollectionPage />
|
||||
case "hotel-page":
|
||||
return <HotelPage />
|
||||
default:
|
||||
console.log({ PREVIEW: params })
|
||||
const type = params.contentType
|
||||
console.error(`Unsupported content type given: ${type}`)
|
||||
notFound()
|
||||
}
|
||||
} catch (error) {
|
||||
// TODO: throw 500
|
||||
console.error("Error in preview page")
|
||||
console.error(error)
|
||||
throw new Error("Something went wrong")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import Footer from "@/components/Current/Footer"
|
||||
import LangPopup from "@/components/Current/LangPopup"
|
||||
import InitLivePreview from "@/components/Current/LivePreview"
|
||||
import InitLivePreview from "@/components/LivePreview"
|
||||
import SkipToMainContent from "@/components/SkipToMainContent"
|
||||
import { setLang } from "@/i18n/serverContext"
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import ContentstackLivePreview from "@contentstack/live-preview-utils"
|
||||
import { ContentstackLivePreview } from "@contentstack/live-preview-utils"
|
||||
|
||||
import { previewRequest } from "@/lib/graphql/previewRequest"
|
||||
import { GetCurrentBlockPage } from "@/lib/graphql/Query/Current/CurrentBlockPage.graphql"
|
||||
|
||||
@@ -42,13 +42,17 @@ export default function CardsGrid({
|
||||
case CardsGridEnum.cards.Card:
|
||||
return (
|
||||
<Card
|
||||
theme={cards_grid.theme ?? "one"}
|
||||
theme={
|
||||
cards_grid.theme ?? card.backgroundImage ? "image" : "one"
|
||||
}
|
||||
key={card.system.uid}
|
||||
scriptedTopTitle={card.scripted_top_title}
|
||||
heading={card.heading}
|
||||
bodyText={card.body_text}
|
||||
secondaryButton={card.secondaryButton}
|
||||
primaryButton={card.primaryButton}
|
||||
backgroundImage={card.backgroundImage}
|
||||
imageGradient
|
||||
/>
|
||||
)
|
||||
case CardsGridEnum.cards.TeaserCard:
|
||||
|
||||
@@ -70,7 +70,7 @@ function RewardTableHeader({ name, description }: RewardTableHeaderProps) {
|
||||
<details className={styles.details}>
|
||||
<summary className={styles.summary}>
|
||||
<hgroup className={styles.rewardHeader}>
|
||||
<Title as="h5" level="h2" textTransform={"regular"}>
|
||||
<Title as="h4" level="h2" textTransform={"regular"}>
|
||||
{name}
|
||||
</Title>
|
||||
<span className={styles.chevron}>
|
||||
|
||||
@@ -19,7 +19,7 @@ export default function RewardCard({
|
||||
<details className={styles.details}>
|
||||
<summary className={styles.summary}>
|
||||
<hgroup className={styles.rewardCardHeader}>
|
||||
<Title as="h5" level="h2" textTransform={"regular"}>
|
||||
<Title as="h4" level="h2" textTransform={"regular"}>
|
||||
{title}
|
||||
</Title>
|
||||
<span className={styles.chevron}>
|
||||
|
||||
@@ -56,7 +56,7 @@ export default async function NextLevelRewardsBlock({
|
||||
{ level: nextLevelRewards.level?.name }
|
||||
)}
|
||||
</Body>
|
||||
<Title level="h4" as="h5" color="pale" textAlign="center">
|
||||
<Title level="h4" as="h4" color="pale" textAlign="center">
|
||||
{reward.label}
|
||||
</Title>
|
||||
</div>
|
||||
|
||||
@@ -7,7 +7,7 @@ export default async function EmptyPreviousStaysBlock() {
|
||||
const { formatMessage } = await getIntl()
|
||||
return (
|
||||
<section className={styles.container}>
|
||||
<Title as="h5" level="h3" color="red" textAlign="center">
|
||||
<Title as="h4" level="h3" color="red" textAlign="center">
|
||||
{formatMessage({
|
||||
id: "You have no previous stays.",
|
||||
})}
|
||||
|
||||
@@ -14,7 +14,7 @@ export default async function EmptyUpcomingStaysBlock() {
|
||||
return (
|
||||
<section className={styles.container}>
|
||||
<div className={styles.titleContainer}>
|
||||
<Title as="h5" level="h3" color="red" className={styles.title}>
|
||||
<Title as="h4" level="h3" color="red" className={styles.title}>
|
||||
{formatMessage({ id: "You have no upcoming stays." })}
|
||||
<span className={styles.burgundyTitle}>
|
||||
{formatMessage({ id: "Where should you go next?" })}
|
||||
|
||||
@@ -47,7 +47,7 @@ export default function StayCard({ stay }: StayCardProps) {
|
||||
height={240}
|
||||
/>
|
||||
<footer className={styles.footer}>
|
||||
<Title as="h5" className={styles.hotel} level="h3">
|
||||
<Title as="h4" className={styles.hotel} level="h3">
|
||||
{hotelInformation.hotelName}
|
||||
</Title>
|
||||
<div className={styles.date}>
|
||||
|
||||
@@ -14,7 +14,7 @@ export default async function EmptyUpcomingStaysBlock() {
|
||||
return (
|
||||
<section className={styles.container}>
|
||||
<div className={styles.titleContainer}>
|
||||
<Title as="h5" level="h3" color="red" className={styles.title}>
|
||||
<Title as="h4" level="h3" color="red" className={styles.title}>
|
||||
{formatMessage({ id: "You have no upcoming stays." })}
|
||||
<span className={styles.burgundyTitle}>
|
||||
{formatMessage({ id: "Where should you go next?" })}
|
||||
|
||||
@@ -47,10 +47,10 @@ export default function BookingWidgetClient({
|
||||
const bookingWidgetSearchData: BookingWidgetSearchParams | undefined =
|
||||
searchParams
|
||||
? (getFormattedUrlQueryParams(new URLSearchParams(searchParams), {
|
||||
adults: "number",
|
||||
age: "number",
|
||||
bed: "number",
|
||||
}) as BookingWidgetSearchParams)
|
||||
adults: "number",
|
||||
age: "number",
|
||||
bed: "number",
|
||||
}) as BookingWidgetSearchParams)
|
||||
: undefined
|
||||
|
||||
const getLocationObj = (destination: string): Location | undefined => {
|
||||
@@ -67,18 +67,20 @@ export default function BookingWidgetClient({
|
||||
return undefined
|
||||
}
|
||||
|
||||
const reqFromDate = bookingWidgetSearchData?.fromDate?.toString()
|
||||
const reqToDate = bookingWidgetSearchData?.toDate?.toString()
|
||||
|
||||
const isDateParamValid =
|
||||
bookingWidgetSearchData?.fromDate &&
|
||||
bookingWidgetSearchData?.toDate &&
|
||||
dt(bookingWidgetSearchData?.toDate.toString()).isAfter(
|
||||
dt(bookingWidgetSearchData?.fromDate.toString())
|
||||
)
|
||||
reqFromDate &&
|
||||
reqToDate &&
|
||||
dt(reqFromDate).isAfter(dt().subtract(1, "day")) &&
|
||||
dt(reqToDate).isAfter(dt(reqFromDate))
|
||||
|
||||
const selectedLocation = bookingWidgetSearchData
|
||||
? getLocationObj(
|
||||
(bookingWidgetSearchData.city ??
|
||||
bookingWidgetSearchData.hotel) as string
|
||||
)
|
||||
(bookingWidgetSearchData.city ??
|
||||
bookingWidgetSearchData.hotel) as string
|
||||
)
|
||||
: undefined
|
||||
|
||||
const methods = useForm<BookingWidgetSchema>({
|
||||
|
||||
22
components/ContentType/StaticPages/CollectionPage/index.tsx
Normal file
22
components/ContentType/StaticPages/CollectionPage/index.tsx
Normal file
@@ -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 (
|
||||
<StaticPage
|
||||
content={collectionPage}
|
||||
tracking={tracking}
|
||||
pageType="collection"
|
||||
/>
|
||||
)
|
||||
}
|
||||
17
components/ContentType/StaticPages/ContentPage/index.tsx
Normal file
17
components/ContentType/StaticPages/ContentPage/index.tsx
Normal file
@@ -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 (
|
||||
<StaticPage content={contentPage} tracking={tracking} pageType="content" />
|
||||
)
|
||||
}
|
||||
@@ -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 (
|
||||
<>
|
||||
<section className={styles.contentPage}>
|
||||
<section className={staticPageVariants({ pageType })}>
|
||||
<header className={styles.header}>
|
||||
<div className={styles.headerContent}>
|
||||
{header ? (
|
||||
@@ -54,7 +53,9 @@ export default async function ContentPage() {
|
||||
{blocks ? <Blocks blocks={blocks} /> : null}
|
||||
</main>
|
||||
|
||||
{sidebar?.length ? <Sidebar blocks={sidebar} /> : null}
|
||||
{"sidebar" in content && content.sidebar?.length ? (
|
||||
<Sidebar blocks={content.sidebar} />
|
||||
) : null}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
15
components/ContentType/StaticPages/staticPage.ts
Normal file
15
components/ContentType/StaticPages/staticPage.ts
Normal file
@@ -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<React.HTMLAttributes<HTMLDivElement>, "content">,
|
||||
VariantProps<typeof staticPageVariants> {
|
||||
pageType?: "collection" | "content"
|
||||
content: CollectionPage["collection_page"] | ContentPage["content_page"]
|
||||
tracking: TrackingSDKPageData
|
||||
}
|
||||
15
components/ContentType/StaticPages/variants.ts
Normal file
15
components/ContentType/StaticPages/variants.ts
Normal file
@@ -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",
|
||||
},
|
||||
})
|
||||
@@ -14,6 +14,7 @@
|
||||
outline: none;
|
||||
padding: 0;
|
||||
width: 100%;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.body {
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
outline: none;
|
||||
padding: 0;
|
||||
width: 100%;
|
||||
text-align: left;
|
||||
}
|
||||
.body {
|
||||
opacity: 0.8;
|
||||
|
||||
@@ -11,7 +11,12 @@ import Subtitle from "@/components/TempDesignSystem/Text/Subtitle"
|
||||
|
||||
import styles from "./sectionAccordion.module.css"
|
||||
|
||||
import {
|
||||
StepEnum,
|
||||
StepStoreKeys,
|
||||
} from "@/types/components/hotelReservation/enterDetails/step"
|
||||
import { SectionAccordionProps } from "@/types/components/hotelReservation/selectRate/sectionAccordion"
|
||||
import { BreakfastPackageEnum } from "@/types/enums/breakfast"
|
||||
|
||||
export default function SectionAccordion({
|
||||
header,
|
||||
@@ -23,9 +28,27 @@ export default function SectionAccordion({
|
||||
const currentStep = useEnterDetailsStore((state) => state.currentStep)
|
||||
const [isComplete, setIsComplete] = useState(false)
|
||||
const [isOpen, setIsOpen] = useState(false)
|
||||
|
||||
const isValid = useEnterDetailsStore((state) => state.isValid[step])
|
||||
const navigate = useEnterDetailsStore((state) => state.navigate)
|
||||
const stepData = useEnterDetailsStore((state) => state.userData)
|
||||
const stepStoreKey = StepStoreKeys[step]
|
||||
const [title, setTitle] = useState(label)
|
||||
|
||||
useEffect(() => {
|
||||
if (step === StepEnum.selectBed) {
|
||||
const value = stepData.bedType
|
||||
value && setTitle(value)
|
||||
}
|
||||
// If breakfast step, check if an option has been selected
|
||||
if (step === StepEnum.breakfast && stepData.breakfast) {
|
||||
const value = stepData.breakfast
|
||||
if (value === BreakfastPackageEnum.NO_BREAKFAST) {
|
||||
setTitle(intl.formatMessage({ id: "No breakfast" }))
|
||||
} else {
|
||||
setTitle(intl.formatMessage({ id: "Breakfast buffet" }))
|
||||
}
|
||||
}
|
||||
}, [stepData, stepStoreKey, step, intl])
|
||||
|
||||
useEffect(() => {
|
||||
// We need to set the state on mount because of hydration errors
|
||||
@@ -39,7 +62,6 @@ export default function SectionAccordion({
|
||||
function onModify() {
|
||||
navigate(step)
|
||||
}
|
||||
|
||||
return (
|
||||
<section className={styles.wrapper} data-open={isOpen} data-step={step}>
|
||||
<div className={styles.iconWrapper}>
|
||||
@@ -65,7 +87,7 @@ export default function SectionAccordion({
|
||||
className={styles.selection}
|
||||
color="uiTextHighContrast"
|
||||
>
|
||||
{label}
|
||||
{title}
|
||||
</Subtitle>
|
||||
</div>
|
||||
{isComplete && !isOpen && (
|
||||
|
||||
@@ -20,7 +20,7 @@ export default function SelectionCard({
|
||||
return (
|
||||
<div className={styles.card}>
|
||||
<div>
|
||||
<Title className={styles.name} as="h5" level="h3">
|
||||
<Title className={styles.name} as="h4" level="h3">
|
||||
{title}
|
||||
</Title>
|
||||
<div className={styles.nameInfo}>i</div>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"use client"
|
||||
|
||||
import ContentstackLivePreview from "@contentstack/live-preview-utils"
|
||||
import { ContentstackLivePreview } from "@contentstack/live-preview-utils"
|
||||
import { useEffect } from "react"
|
||||
|
||||
export default function InitLivePreview() {
|
||||
@@ -60,7 +60,7 @@ export default function Sidebar({ blocks }: SidebarProps) {
|
||||
<TeaserCard
|
||||
title={block.teaser_card.heading}
|
||||
description={block.teaser_card.body_text}
|
||||
style={block.teaser_card.theme}
|
||||
intent={block.teaser_card.theme}
|
||||
key={block.teaser_card.system.uid}
|
||||
primaryButton={block.teaser_card.primaryButton}
|
||||
secondaryButton={block.teaser_card.secondaryButton}
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
|
||||
.content {
|
||||
margin: var(--Spacing-x0) var(--Spacing-x4);
|
||||
position: absolute;
|
||||
display: grid;
|
||||
gap: var(--Spacing-x2);
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ export default function LoyaltyCard({
|
||||
focalPoint={image.focalPoint}
|
||||
/>
|
||||
) : null}
|
||||
<Title as="h5" level="h3" textAlign="center">
|
||||
<Title as="h4" level="h3" textAlign="center">
|
||||
{heading}
|
||||
</Title>
|
||||
{bodyText ? <Body textAlign="center">{bodyText}</Body> : null}
|
||||
|
||||
@@ -41,7 +41,7 @@ function SidePeek({
|
||||
|
||||
if (isSSR) {
|
||||
return (
|
||||
<div>
|
||||
<div className={styles.visuallyHidden}>
|
||||
<h2>{title}</h2>
|
||||
{children}
|
||||
</div>
|
||||
|
||||
@@ -21,6 +21,12 @@
|
||||
}
|
||||
}
|
||||
|
||||
.visuallyHidden {
|
||||
position: absolute;
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.overlay {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
@@ -40,7 +46,7 @@
|
||||
height: 100vh;
|
||||
background-color: var(--Base-Background-Primary-Normal);
|
||||
z-index: var(--sidepeek-z-index);
|
||||
box-shadow: 0 0 10px rgba(0, 0, 0, 0.85);
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.modal[data-entering] {
|
||||
|
||||
@@ -21,7 +21,7 @@ export default function TeaserCardSidepeek({
|
||||
const { heading, content, primary_button, secondary_button } = sidePeekContent
|
||||
|
||||
return (
|
||||
<>
|
||||
<div>
|
||||
<Button
|
||||
onPress={() => setSidePeekIsOpen(true)}
|
||||
theme="base"
|
||||
@@ -77,6 +77,6 @@ export default function TeaserCardSidepeek({
|
||||
)}
|
||||
</div>
|
||||
</SidePeek>
|
||||
</>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -19,25 +19,23 @@ export default function TeaserCard({
|
||||
sidePeekButton,
|
||||
sidePeekContent,
|
||||
image,
|
||||
style = "default",
|
||||
intent,
|
||||
alwaysStack = false,
|
||||
className,
|
||||
}: TeaserCardProps) {
|
||||
const cardClasses = teaserCardVariants({ style, alwaysStack, className })
|
||||
const classNames = teaserCardVariants({ intent, alwaysStack, className })
|
||||
|
||||
return (
|
||||
<article className={cardClasses}>
|
||||
<article className={classNames}>
|
||||
{image && (
|
||||
<div className={styles.imageContainer}>
|
||||
<Image
|
||||
src={image.url}
|
||||
alt={image.meta?.alt || ""}
|
||||
className={styles.backgroundImage}
|
||||
width={399}
|
||||
height={201}
|
||||
focalPoint={image.focalPoint}
|
||||
/>
|
||||
</div>
|
||||
<Image
|
||||
src={image.url}
|
||||
alt={image.meta?.alt || ""}
|
||||
className={styles.image}
|
||||
width={Math.ceil(image.dimensions.aspectRatio * 200)}
|
||||
height={200}
|
||||
focalPoint={image.focalPoint}
|
||||
/>
|
||||
)}
|
||||
<div className={styles.content}>
|
||||
<Subtitle textAlign="left" type="two" color="black">
|
||||
|
||||
@@ -18,24 +18,17 @@
|
||||
border: 1px solid var(--Base-Border-Subtle);
|
||||
}
|
||||
|
||||
.imageContainer {
|
||||
.image {
|
||||
width: 100%;
|
||||
height: 12.58625rem; /* 201.38px / 16 = 12.58625rem */
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.backgroundImage {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
height: 12.5rem; /* 200px */
|
||||
}
|
||||
|
||||
.content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
display: grid;
|
||||
gap: var(--Spacing-x-one-and-half);
|
||||
align-items: flex-start;
|
||||
padding: var(--Spacing-x2) var(--Spacing-x3);
|
||||
grid-template-rows: auto 1fr auto;
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.description {
|
||||
@@ -53,17 +46,6 @@
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.body {
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 3;
|
||||
line-clamp: 3;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
/* line-height variables are in %, so using the value in rem instead */
|
||||
max-height: calc(3 * 1.5rem);
|
||||
}
|
||||
|
||||
@media (min-width: 1367px) {
|
||||
.card:not(.alwaysStack) .ctaContainer {
|
||||
grid-template-columns: repeat(auto-fit, minmax(0, 1fr));
|
||||
|
||||
@@ -4,7 +4,7 @@ import styles from "./teaserCard.module.css"
|
||||
|
||||
export const teaserCardVariants = cva(styles.card, {
|
||||
variants: {
|
||||
style: {
|
||||
intent: {
|
||||
default: styles.default,
|
||||
featured: styles.featured,
|
||||
},
|
||||
@@ -14,7 +14,7 @@ export const teaserCardVariants = cva(styles.card, {
|
||||
},
|
||||
},
|
||||
defaultVariants: {
|
||||
style: "default",
|
||||
intent: "default",
|
||||
alwaysStack: false,
|
||||
},
|
||||
})
|
||||
|
||||
@@ -4,7 +4,9 @@
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.h1 {
|
||||
/* Temporarily remove h1 styling until design tokens är updated */
|
||||
|
||||
/* .h1 {
|
||||
font-family: var(--typography-Title-1-fontFamily);
|
||||
font-size: clamp(
|
||||
var(--typography-Title-1-Mobile-fontSize),
|
||||
@@ -14,9 +16,9 @@
|
||||
letter-spacing: var(--typography-Title-1-letterSpacing);
|
||||
line-height: var(--typography-Title-1-lineHeight);
|
||||
text-decoration: var(--typography-Title-1-textDecoration);
|
||||
}
|
||||
} */
|
||||
|
||||
.h2 {
|
||||
.h1 {
|
||||
font-family: var(--typography-Title-2-fontFamily);
|
||||
font-size: clamp(
|
||||
var(--typography-Title-2-Mobile-fontSize),
|
||||
@@ -26,9 +28,10 @@
|
||||
letter-spacing: var(--typography-Title-2-letterSpacing);
|
||||
line-height: var(--typography-Title-2-lineHeight);
|
||||
text-decoration: var(--typography-Title-2-textDecoration);
|
||||
font-weight: var(--typography-Title-2-fontWeight);
|
||||
}
|
||||
|
||||
.h3 {
|
||||
.h2 {
|
||||
font-family: var(--typography-Title-3-fontFamily);
|
||||
font-size: clamp(
|
||||
var(--typography-Title-3-Mobile-fontSize),
|
||||
@@ -38,9 +41,10 @@
|
||||
letter-spacing: var(--typography-Title-3-letterSpacing);
|
||||
line-height: var(--typography-Title-3-lineHeight);
|
||||
text-decoration: var(--typography-Title-3-textDecoration);
|
||||
font-weight: var(--typography-Title-3-fontWeight);
|
||||
}
|
||||
|
||||
.h4 {
|
||||
.h3 {
|
||||
font-family: var(--typography-Title-4-fontFamily);
|
||||
font-size: clamp(
|
||||
var(--typography-Title-4-Mobile-fontSize),
|
||||
@@ -50,9 +54,10 @@
|
||||
letter-spacing: var(--typography-Title-4-letterSpacing);
|
||||
line-height: var(--typography-Title-4-lineHeight);
|
||||
text-decoration: var(--typography-Title-4-textDecoration);
|
||||
font-weight: var(--typography-Title-4-fontWeight);
|
||||
}
|
||||
|
||||
.h5 {
|
||||
.h4 {
|
||||
font-family: var(--typography-Title-5-fontFamily);
|
||||
font-size: clamp(
|
||||
var(--typography-Title-5-Mobile-fontSize),
|
||||
@@ -62,6 +67,7 @@
|
||||
letter-spacing: var(--typography-Title-5-letterSpacing);
|
||||
line-height: var(--typography-Title-5-lineHeight);
|
||||
text-decoration: var(--typography-Title-5-textDecoration);
|
||||
font-weight: var(--typography-Title-5-fontWeight);
|
||||
}
|
||||
|
||||
.capitalize {
|
||||
|
||||
@@ -26,7 +26,7 @@ const config = {
|
||||
h2: styles.h2,
|
||||
h3: styles.h3,
|
||||
h4: styles.h4,
|
||||
h5: styles.h5,
|
||||
h5: styles.h4,
|
||||
},
|
||||
},
|
||||
defaultVariants: {
|
||||
|
||||
@@ -95,7 +95,6 @@ export default function useStickyPosition({
|
||||
}, 100)
|
||||
|
||||
resizeObserver = new ResizeObserver(debouncedResizeHandler)
|
||||
console.log("Initialized ResizeObserver")
|
||||
}
|
||||
|
||||
resizeObserver.observe(document.body)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
21
lib/graphql/Fragments/CollectionPage/NavigationLinks.graphql
Normal file
21
lib/graphql/Fragments/CollectionPage/NavigationLinks.graphql
Normal file
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
7
lib/graphql/Fragments/CollectionPage/Ref.graphql
Normal file
7
lib/graphql/Fragments/CollectionPage/Ref.graphql
Normal file
@@ -0,0 +1,7 @@
|
||||
#import "../System.graphql"
|
||||
|
||||
fragment CollectionPageRef on CollectionPage {
|
||||
system {
|
||||
...System
|
||||
}
|
||||
}
|
||||
12
lib/graphql/Fragments/PageLink/CollectionPageLink.graphql
Normal file
12
lib/graphql/Fragments/PageLink/CollectionPageLink.graphql
Normal file
@@ -0,0 +1,12 @@
|
||||
#import "../System.graphql"
|
||||
|
||||
fragment CollectionPageLink on CollectionPage {
|
||||
title
|
||||
url
|
||||
system {
|
||||
...System
|
||||
}
|
||||
web {
|
||||
original_url
|
||||
}
|
||||
}
|
||||
@@ -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 {
|
||||
|
||||
28
lib/graphql/Query/Breadcrumbs/CollectionPage.graphql
Normal file
28
lib/graphql/Query/Breadcrumbs/CollectionPage.graphql
Normal file
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
83
lib/graphql/Query/CollectionPage/CollectionPage.graphql
Normal file
83
lib/graphql/Query/CollectionPage/CollectionPage.graphql
Normal file
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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 {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import "server-only"
|
||||
|
||||
import { ContentstackLivePreview } from "@contentstack/live-preview-utils"
|
||||
import { ClientError, GraphQLClient } from "graphql-request"
|
||||
|
||||
import { Lang } from "@/constants/languages"
|
||||
@@ -16,40 +17,54 @@ export async function request<T>(
|
||||
params?: RequestInit
|
||||
): Promise<Data<T>> {
|
||||
try {
|
||||
if (params?.cache) {
|
||||
client.requestConfig.cache = params.cache
|
||||
}
|
||||
if (params?.headers) {
|
||||
client.requestConfig.headers = params.headers
|
||||
}
|
||||
if (params?.next) {
|
||||
client.requestConfig.next = params.next
|
||||
}
|
||||
client.setHeaders({
|
||||
access_token: env.CMS_ACCESS_TOKEN,
|
||||
"Content-Type": "application/json",
|
||||
})
|
||||
|
||||
if (env.PRINT_QUERY) {
|
||||
const print = (await import("graphql/language/printer")).print
|
||||
const rawResponse = await client.rawRequest<T>(
|
||||
print(query as DocumentNode),
|
||||
variables,
|
||||
{
|
||||
access_token: env.CMS_ACCESS_TOKEN,
|
||||
"Content-Type": "application/json",
|
||||
const previewHash = ContentstackLivePreview.hash
|
||||
if (previewHash) {
|
||||
client.setEndpoint(env.CMS_PREVIEW_URL)
|
||||
client.setHeader("preview_token", env.CMS_PREVIEW_TOKEN)
|
||||
client.setHeader("live_preview", previewHash)
|
||||
} else {
|
||||
if (params?.cache) {
|
||||
client.requestConfig.cache = params.cache
|
||||
}
|
||||
if (params?.headers) {
|
||||
client.requestConfig.headers = params.headers
|
||||
}
|
||||
if (params?.next) {
|
||||
client.requestConfig.next = params.next
|
||||
}
|
||||
|
||||
if (env.PRINT_QUERY) {
|
||||
const print = (await import("graphql/language/printer")).print
|
||||
const rawResponse = await client.rawRequest<T>(
|
||||
print(query as DocumentNode),
|
||||
variables,
|
||||
{
|
||||
access_token: env.CMS_ACCESS_TOKEN,
|
||||
"Content-Type": "application/json",
|
||||
}
|
||||
)
|
||||
|
||||
/**
|
||||
* TODO: Send to Monitoring (Logging and Metrics)
|
||||
*/
|
||||
console.log({
|
||||
complexityLimit: rawResponse.headers.get("x-query-complexity"),
|
||||
})
|
||||
console.log({
|
||||
referenceDepth: rawResponse.headers.get("x-reference-depth"),
|
||||
})
|
||||
console.log({
|
||||
resolverCost: rawResponse.headers.get("x-resolver-cost"),
|
||||
})
|
||||
|
||||
return {
|
||||
data: rawResponse.data,
|
||||
}
|
||||
)
|
||||
|
||||
/**
|
||||
* TODO: Send to Monitoring (Logging and Metrics)
|
||||
*/
|
||||
console.log({
|
||||
complexityLimit: rawResponse.headers.get("x-query-complexity"),
|
||||
})
|
||||
console.log({
|
||||
referenceDepth: rawResponse.headers.get("x-reference-depth"),
|
||||
})
|
||||
console.log({ resolverCost: rawResponse.headers.get("x-resolver-cost") })
|
||||
|
||||
return {
|
||||
data: rawResponse.data,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,10 +93,6 @@ export async function request<T>(
|
||||
|
||||
const response = await client.request<T>({
|
||||
document: query,
|
||||
requestHeaders: {
|
||||
access_token: env.CMS_ACCESS_TOKEN,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
variables,
|
||||
})
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import "server-only"
|
||||
|
||||
import ContentstackLivePreview from "@contentstack/live-preview-utils"
|
||||
import { ContentstackLivePreview } from "@contentstack/live-preview-utils"
|
||||
import { request as graphqlRequest } from "graphql-request"
|
||||
|
||||
import { env } from "@/env/server"
|
||||
|
||||
@@ -2,7 +2,6 @@ import { NextResponse } from "next/server"
|
||||
|
||||
import { notFound } from "@/server/errors/next"
|
||||
|
||||
import { resolve as resolveEntry } from "@/utils/entry"
|
||||
import { findLang } from "@/utils/languages"
|
||||
import { removeTrailingSlash } from "@/utils/url"
|
||||
|
||||
@@ -18,17 +17,21 @@ export const middleware: NextMiddleware = async (request) => {
|
||||
|
||||
const pathWithoutTrailingSlash = removeTrailingSlash(nextUrl.pathname)
|
||||
|
||||
const pathNameWithoutLang = pathWithoutTrailingSlash.replace(`/${lang}`, "")
|
||||
const contentTypePathName = pathWithoutTrailingSlash.replace(`/${lang}`, "")
|
||||
const isPreview = request.nextUrl.pathname.includes("/preview")
|
||||
|
||||
const searchParams = new URLSearchParams(request.nextUrl.searchParams)
|
||||
|
||||
const { contentType, uid } = await fetchAndCacheEntry(
|
||||
pathNameWithoutLang,
|
||||
isPreview
|
||||
? contentTypePathName.replace("/preview", "")
|
||||
: contentTypePathName,
|
||||
lang
|
||||
)
|
||||
|
||||
if (!contentType || !uid) {
|
||||
throw notFound(
|
||||
`Unable to resolve CMS entry for locale "${lang}": ${pathNameWithoutLang}`
|
||||
`Unable to resolve CMS entry for locale "${lang}": ${contentTypePathName}`
|
||||
)
|
||||
}
|
||||
const headers = getDefaultRequestHeaders(request)
|
||||
@@ -37,9 +40,9 @@ export const middleware: NextMiddleware = async (request) => {
|
||||
|
||||
const isCurrent = contentType ? contentType.indexOf("current") >= 0 : false
|
||||
|
||||
if (request.nextUrl.pathname.includes("/preview")) {
|
||||
if (isPreview) {
|
||||
if (isCurrent) {
|
||||
searchParams.set("uri", pathNameWithoutLang.replace("/preview", ""))
|
||||
searchParams.set("uri", contentTypePathName.replace("/preview", ""))
|
||||
return NextResponse.rewrite(
|
||||
new URL(`/${lang}/preview-current?${searchParams.toString()}`, nextUrl),
|
||||
{
|
||||
@@ -65,7 +68,7 @@ export const middleware: NextMiddleware = async (request) => {
|
||||
|
||||
if (isCurrent) {
|
||||
searchParams.set("uid", uid)
|
||||
searchParams.set("uri", pathNameWithoutLang)
|
||||
searchParams.set("uri", contentTypePathName)
|
||||
return NextResponse.rewrite(
|
||||
new URL(
|
||||
`/${lang}/current-content-page?${searchParams.toString()}`,
|
||||
|
||||
437
package-lock.json
generated
437
package-lock.json
generated
@@ -10,7 +10,7 @@
|
||||
"hasInstallScript": true,
|
||||
"dependencies": {
|
||||
"@azure/monitor-opentelemetry-exporter": "^1.0.0-beta.24",
|
||||
"@contentstack/live-preview-utils": "^1.4.0",
|
||||
"@contentstack/live-preview-utils": "^2.0.4",
|
||||
"@hookform/error-message": "^2.0.1",
|
||||
"@hookform/resolvers": "^3.3.4",
|
||||
"@netlify/plugin-nextjs": "^5.1.1",
|
||||
@@ -118,16 +118,15 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@auth/core": {
|
||||
"version": "0.32.0",
|
||||
"resolved": "https://registry.npmjs.org/@auth/core/-/core-0.32.0.tgz",
|
||||
"integrity": "sha512-3+ssTScBd+1fd0/fscAyQN1tSygXzuhysuVVzB942ggU4mdfiTbv36P0ccVnExKWYJKvu3E2r3/zxXCCAmTOrg==",
|
||||
"license": "ISC",
|
||||
"version": "0.37.2",
|
||||
"resolved": "https://registry.npmjs.org/@auth/core/-/core-0.37.2.tgz",
|
||||
"integrity": "sha512-kUvzyvkcd6h1vpeMAojK2y7+PAV5H+0Cc9+ZlKYDFhDY31AlvsB+GW5vNO4qE3Y07KeQgvNO9U0QUx/fN62kBw==",
|
||||
"dependencies": {
|
||||
"@panva/hkdf": "^1.1.1",
|
||||
"@panva/hkdf": "^1.2.1",
|
||||
"@types/cookie": "0.6.0",
|
||||
"cookie": "0.6.0",
|
||||
"jose": "^5.1.3",
|
||||
"oauth4webapi": "^2.9.0",
|
||||
"cookie": "0.7.1",
|
||||
"jose": "^5.9.3",
|
||||
"oauth4webapi": "^3.0.0",
|
||||
"preact": "10.11.3",
|
||||
"preact-render-to-string": "5.2.3"
|
||||
},
|
||||
@@ -2460,13 +2459,16 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@contentstack/live-preview-utils": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@contentstack/live-preview-utils/-/live-preview-utils-1.4.1.tgz",
|
||||
"integrity": "sha512-CbC+Wtc+t8NkD3qTTZaxl7KHCzNCrnKtpkPoarxig1ffyGk8GeEZwW5tLyEtqQ7zsvwLA+RIuWY55gKQumJQLQ==",
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@contentstack/live-preview-utils/-/live-preview-utils-2.0.4.tgz",
|
||||
"integrity": "sha512-+56ExpzsOau5MEEg6sy1czaQMzPmEZAyGYx+LIyqeKKCbxFmTHcvg4Ag4vJ7KUf4LCtoGMUUT/Mkf6hqSkCvDA==",
|
||||
"dependencies": {
|
||||
"goober": "^2.1.14",
|
||||
"just-camel-case": "^4.0.2",
|
||||
"lodash-es": "^4.17.21",
|
||||
"morphdom": "^2.6.1",
|
||||
"mustache": "^4.2.0",
|
||||
"post-robot": "8.0.31",
|
||||
"uuid": "^8.3.2"
|
||||
}
|
||||
},
|
||||
@@ -3382,10 +3384,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@next/env": {
|
||||
"version": "14.2.7",
|
||||
"resolved": "https://registry.npmjs.org/@next/env/-/env-14.2.7.tgz",
|
||||
"integrity": "sha512-OTx9y6I3xE/eih+qtthppwLytmpJVPM5PPoJxChFsbjIEFXIayG0h/xLzefHGJviAa3Q5+Fd+9uYojKkHDKxoQ==",
|
||||
"license": "MIT"
|
||||
"version": "14.2.16",
|
||||
"resolved": "https://registry.npmjs.org/@next/env/-/env-14.2.16.tgz",
|
||||
"integrity": "sha512-fLrX5TfJzHCbnZ9YUSnGW63tMV3L4nSfhgOQ0iCcX21Pt+VSTDuaLsSuL8J/2XAiVA5AnzvXDpf6pMs60QxOag=="
|
||||
},
|
||||
"node_modules/@next/eslint-plugin-next": {
|
||||
"version": "14.1.4",
|
||||
@@ -3397,13 +3398,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@next/swc-darwin-arm64": {
|
||||
"version": "14.2.7",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.2.7.tgz",
|
||||
"integrity": "sha512-UhZGcOyI9LE/tZL3h9rs/2wMZaaJKwnpAyegUVDGZqwsla6hMfeSj9ssBWQS9yA4UXun3pPhrFLVnw5KXZs3vw==",
|
||||
"version": "14.2.16",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.2.16.tgz",
|
||||
"integrity": "sha512-uFT34QojYkf0+nn6MEZ4gIWQ5aqGF11uIZ1HSxG+cSbj+Mg3+tYm8qXYd3dKN5jqKUm5rBVvf1PBRO/MeQ6rxw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
@@ -3413,13 +3413,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@next/swc-darwin-x64": {
|
||||
"version": "14.2.7",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.2.7.tgz",
|
||||
"integrity": "sha512-ys2cUgZYRc+CbyDeLAaAdZgS7N1Kpyy+wo0b/gAj+SeOeaj0Lw/q+G1hp+DuDiDAVyxLBCJXEY/AkhDmtihUTA==",
|
||||
"version": "14.2.16",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.2.16.tgz",
|
||||
"integrity": "sha512-mCecsFkYezem0QiZlg2bau3Xul77VxUD38b/auAjohMA22G9KTJneUYMv78vWoCCFkleFAhY1NIvbyjj1ncG9g==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
@@ -3429,13 +3428,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@next/swc-linux-arm64-gnu": {
|
||||
"version": "14.2.7",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.2.7.tgz",
|
||||
"integrity": "sha512-2xoWtE13sUJ3qrC1lwE/HjbDPm+kBQYFkkiVECJWctRASAHQ+NwjMzgrfqqMYHfMxFb5Wws3w9PqzZJqKFdWcQ==",
|
||||
"version": "14.2.16",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.2.16.tgz",
|
||||
"integrity": "sha512-yhkNA36+ECTC91KSyZcgWgKrYIyDnXZj8PqtJ+c2pMvj45xf7y/HrgI17hLdrcYamLfVt7pBaJUMxADtPaczHA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
@@ -3445,13 +3443,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@next/swc-linux-arm64-musl": {
|
||||
"version": "14.2.7",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.2.7.tgz",
|
||||
"integrity": "sha512-+zJ1gJdl35BSAGpkCbfyiY6iRTaPrt3KTl4SF/B1NyELkqqnrNX6cp4IjjjxKpd64/7enI0kf6b9O1Uf3cL0pw==",
|
||||
"version": "14.2.16",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.2.16.tgz",
|
||||
"integrity": "sha512-X2YSyu5RMys8R2lA0yLMCOCtqFOoLxrq2YbazFvcPOE4i/isubYjkh+JCpRmqYfEuCVltvlo+oGfj/b5T2pKUA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
@@ -3461,13 +3458,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@next/swc-linux-x64-gnu": {
|
||||
"version": "14.2.7",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.2.7.tgz",
|
||||
"integrity": "sha512-m6EBqrskeMUzykBrv0fDX/28lWIBGhMzOYaStp0ihkjzIYJiKUOzVYD1gULHc8XDf5EMSqoH/0/TRAgXqpQwmw==",
|
||||
"version": "14.2.16",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.2.16.tgz",
|
||||
"integrity": "sha512-9AGcX7VAkGbc5zTSa+bjQ757tkjr6C/pKS7OK8cX7QEiK6MHIIezBLcQ7gQqbDW2k5yaqba2aDtaBeyyZh1i6Q==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
@@ -3477,13 +3473,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@next/swc-linux-x64-musl": {
|
||||
"version": "14.2.7",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.2.7.tgz",
|
||||
"integrity": "sha512-gUu0viOMvMlzFRz1r1eQ7Ql4OE+hPOmA7smfZAhn8vC4+0swMZaZxa9CSIozTYavi+bJNDZ3tgiSdMjmMzRJlQ==",
|
||||
"version": "14.2.16",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.2.16.tgz",
|
||||
"integrity": "sha512-Klgeagrdun4WWDaOizdbtIIm8khUDQJ/5cRzdpXHfkbY91LxBXeejL4kbZBrpR/nmgRrQvmz4l3OtttNVkz2Sg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
@@ -3493,13 +3488,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@next/swc-win32-arm64-msvc": {
|
||||
"version": "14.2.7",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.2.7.tgz",
|
||||
"integrity": "sha512-PGbONHIVIuzWlYmLvuFKcj+8jXnLbx4WrlESYlVnEzDsa3+Q2hI1YHoXaSmbq0k4ZwZ7J6sWNV4UZfx1OeOlbQ==",
|
||||
"version": "14.2.16",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.2.16.tgz",
|
||||
"integrity": "sha512-PwW8A1UC1Y0xIm83G3yFGPiOBftJK4zukTmk7DI1CebyMOoaVpd8aSy7K6GhobzhkjYvqS/QmzcfsWG2Dwizdg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
@@ -3509,13 +3503,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@next/swc-win32-ia32-msvc": {
|
||||
"version": "14.2.7",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.2.7.tgz",
|
||||
"integrity": "sha512-BiSY5umlx9ed5RQDoHcdbuKTUkuFORDqzYKPHlLeS+STUWQKWziVOn3Ic41LuTBvqE0TRJPKpio9GSIblNR+0w==",
|
||||
"version": "14.2.16",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.2.16.tgz",
|
||||
"integrity": "sha512-jhPl3nN0oKEshJBNDAo0etGMzv0j3q3VYorTSFqH1o3rwv1MQRdor27u1zhkgsHPNeY1jxcgyx1ZsCkDD1IHgg==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
@@ -3525,13 +3518,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@next/swc-win32-x64-msvc": {
|
||||
"version": "14.2.7",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.2.7.tgz",
|
||||
"integrity": "sha512-pxsI23gKWRt/SPHFkDEsP+w+Nd7gK37Hpv0ngc5HpWy2e7cKx9zR/+Q2ptAUqICNTecAaGWvmhway7pj/JLEWA==",
|
||||
"version": "14.2.16",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.2.16.tgz",
|
||||
"integrity": "sha512-OA7NtfxgirCjfqt+02BqxC3MIgM/JaGjw9tOe4fyZgPsqfseNiMPnCRP44Pfs+Gpo9zPN+SXaFsgP6vk8d571A==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
@@ -3703,7 +3695,6 @@
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@panva/hkdf/-/hkdf-1.2.1.tgz",
|
||||
"integrity": "sha512-6oclG6Y3PiDFcoyk8srjLfVKyMfVCKJ27JwNPViuXziFpmdz+MZnZN/aKY0JGXgYuO/VghU0jcOAZgWXZ1Dmrw==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/panva"
|
||||
}
|
||||
@@ -6378,8 +6369,7 @@
|
||||
"node_modules/@types/cookie": {
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz",
|
||||
"integrity": "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==",
|
||||
"license": "MIT"
|
||||
"integrity": "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA=="
|
||||
},
|
||||
"node_modules/@types/google.maps": {
|
||||
"version": "3.58.0",
|
||||
@@ -7348,9 +7338,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/axios": {
|
||||
"version": "1.6.8",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-1.6.8.tgz",
|
||||
"integrity": "sha512-v/ZHtJDU39mDpyBoFVkETcd/uNdxrWRrg3bKpOKzXFA6Bvqopts6ALSMU3y6ijYxbw2B+wPrIv46egTzJXCLGQ==",
|
||||
"version": "1.7.7",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-1.7.7.tgz",
|
||||
"integrity": "sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"follow-redirects": "^1.15.6",
|
||||
@@ -8640,10 +8630,9 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/cookie": {
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz",
|
||||
"integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==",
|
||||
"license": "MIT",
|
||||
"version": "0.7.1",
|
||||
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz",
|
||||
"integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==",
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
@@ -8764,6 +8753,22 @@
|
||||
"integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/cross-domain-safe-weakmap": {
|
||||
"version": "1.0.29",
|
||||
"resolved": "https://registry.npmjs.org/cross-domain-safe-weakmap/-/cross-domain-safe-weakmap-1.0.29.tgz",
|
||||
"integrity": "sha512-VLoUgf2SXnf3+na8NfeUFV59TRZkIJqCIATaMdbhccgtnTlSnHXkyTRwokngEGYdQXx8JbHT9GDYitgR2sdjuA==",
|
||||
"dependencies": {
|
||||
"cross-domain-utils": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/cross-domain-utils": {
|
||||
"version": "2.0.38",
|
||||
"resolved": "https://registry.npmjs.org/cross-domain-utils/-/cross-domain-utils-2.0.38.tgz",
|
||||
"integrity": "sha512-zZfi3+2EIR9l4chrEiXI2xFleyacsJf8YMLR1eJ0Veb5FTMXeJ3DpxDjZkto2FhL/g717WSELqbptNSo85UJDw==",
|
||||
"dependencies": {
|
||||
"zalgo-promise": "^1.0.11"
|
||||
}
|
||||
},
|
||||
"node_modules/cross-fetch": {
|
||||
"version": "3.1.8",
|
||||
"resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.8.tgz",
|
||||
@@ -9612,6 +9617,18 @@
|
||||
"url": "https://github.com/fb55/entities?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/environment": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/environment/-/environment-1.1.0.tgz",
|
||||
"integrity": "sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/errno": {
|
||||
"version": "0.1.8",
|
||||
"resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz",
|
||||
@@ -11093,6 +11110,14 @@
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/goober": {
|
||||
"version": "2.1.16",
|
||||
"resolved": "https://registry.npmjs.org/goober/-/goober-2.1.16.tgz",
|
||||
"integrity": "sha512-erjk19y1U33+XAMe1VTvIONHYoSqE4iS7BYUZfHaqeohLmnC0FdxEh7rQU+6MZ4OajItzjZFSRtVANrQwNq6/g==",
|
||||
"peerDependencies": {
|
||||
"csstype": "^3.0.10"
|
||||
}
|
||||
},
|
||||
"node_modules/gopd": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz",
|
||||
@@ -13259,10 +13284,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/jose": {
|
||||
"version": "5.6.3",
|
||||
"resolved": "https://registry.npmjs.org/jose/-/jose-5.6.3.tgz",
|
||||
"integrity": "sha512-1Jh//hEEwMhNYPDDLwXHa2ePWgWiFNNUadVmguAAw2IJ6sj9mNxV5tGXJNqlMkJAybF6Lgw1mISDxTePP/187g==",
|
||||
"license": "MIT",
|
||||
"version": "5.9.6",
|
||||
"resolved": "https://registry.npmjs.org/jose/-/jose-5.9.6.tgz",
|
||||
"integrity": "sha512-AMlnetc9+CV9asI19zHmrgS/WYsWUwCn2R7RzlbJWD7F9eWYUTGyBmU9o6PxngtLGOiDGPRu+Uc4fhKzbpteZQ==",
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/panva"
|
||||
}
|
||||
@@ -13840,9 +13864,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/koa-route/node_modules/path-to-regexp": {
|
||||
"version": "1.8.0",
|
||||
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz",
|
||||
"integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==",
|
||||
"version": "1.9.0",
|
||||
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.9.0.tgz",
|
||||
"integrity": "sha512-xIp7/apCFJuUHdDLWe8O1HIkb0kQrOMb/0u6FXQjemHn/ii5LrIzU6bdECnsiTF/GjZkMEKg1xdiZwNqDYlZ6g==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"isarray": "0.0.1"
|
||||
@@ -14020,12 +14044,15 @@
|
||||
"integrity": "sha512-Ctgq2lXUpEJo5j1762NOzl2xo7z7pqmVWYai0p07LvAkQ32tbPv3wb+tcUeHEiXhKU5buM4H9MXsXo6OlM6C2g=="
|
||||
},
|
||||
"node_modules/lilconfig": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.0.0.tgz",
|
||||
"integrity": "sha512-K2U4W2Ff5ibV7j7ydLr+zLAkIg5JJ4lPn1Ltsdt+Tz/IjQ8buJ55pZAxoP34lqIiwtF9iAvtLv3JGv7CAyAg+g==",
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.2.tgz",
|
||||
"integrity": "sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/antonk52"
|
||||
}
|
||||
},
|
||||
"node_modules/lines-and-columns": {
|
||||
@@ -14036,21 +14063,21 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/lint-staged": {
|
||||
"version": "15.2.2",
|
||||
"resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-15.2.2.tgz",
|
||||
"integrity": "sha512-TiTt93OPh1OZOsb5B7k96A/ATl2AjIZo+vnzFZ6oHK5FuTk63ByDtxGQpHm+kFETjEWqgkF95M8FRXKR/LEBcw==",
|
||||
"version": "15.2.10",
|
||||
"resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-15.2.10.tgz",
|
||||
"integrity": "sha512-5dY5t743e1byO19P9I4b3x8HJwalIznL5E1FWYnU6OWw33KxNBSLAc6Cy7F2PsFEO8FKnLwjwm5hx7aMF0jzZg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"chalk": "5.3.0",
|
||||
"commander": "11.1.0",
|
||||
"debug": "4.3.4",
|
||||
"execa": "8.0.1",
|
||||
"lilconfig": "3.0.0",
|
||||
"listr2": "8.0.1",
|
||||
"micromatch": "4.0.5",
|
||||
"pidtree": "0.6.0",
|
||||
"string-argv": "0.3.2",
|
||||
"yaml": "2.3.4"
|
||||
"chalk": "~5.3.0",
|
||||
"commander": "~12.1.0",
|
||||
"debug": "~4.3.6",
|
||||
"execa": "~8.0.1",
|
||||
"lilconfig": "~3.1.2",
|
||||
"listr2": "~8.2.4",
|
||||
"micromatch": "~4.0.8",
|
||||
"pidtree": "~0.6.0",
|
||||
"string-argv": "~0.3.2",
|
||||
"yaml": "~2.5.0"
|
||||
},
|
||||
"bin": {
|
||||
"lint-staged": "bin/lint-staged.js"
|
||||
@@ -14063,21 +14090,24 @@
|
||||
}
|
||||
},
|
||||
"node_modules/lint-staged/node_modules/ansi-escapes": {
|
||||
"version": "6.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-6.2.1.tgz",
|
||||
"integrity": "sha512-4nJ3yixlEthEJ9Rk4vPcdBRkZvQZlYyu8j4/Mqz5sgIkddmEnH2Yj2ZrnP9S3tQOvSNRUIgVNF/1yPpRAGNRig==",
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-7.0.0.tgz",
|
||||
"integrity": "sha512-GdYO7a61mR0fOlAsvC9/rIHf7L96sBc6dEWzeOu+KAea5bZyQRPIpojrVoI4AXGJS/ycu/fBTdLrUkA4ODrvjw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"environment": "^1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.16"
|
||||
"node": ">=18"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/lint-staged/node_modules/ansi-regex": {
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz",
|
||||
"integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==",
|
||||
"version": "6.1.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz",
|
||||
"integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
@@ -14111,15 +14141,15 @@
|
||||
}
|
||||
},
|
||||
"node_modules/lint-staged/node_modules/cli-cursor": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-4.0.0.tgz",
|
||||
"integrity": "sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==",
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-5.0.0.tgz",
|
||||
"integrity": "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"restore-cursor": "^4.0.0"
|
||||
"restore-cursor": "^5.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
|
||||
"node": ">=18"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
@@ -14142,18 +14172,35 @@
|
||||
}
|
||||
},
|
||||
"node_modules/lint-staged/node_modules/commander": {
|
||||
"version": "11.1.0",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz",
|
||||
"integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==",
|
||||
"version": "12.1.0",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz",
|
||||
"integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=16"
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/lint-staged/node_modules/debug": {
|
||||
"version": "4.3.7",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
|
||||
"integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"ms": "^2.1.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"supports-color": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/lint-staged/node_modules/emoji-regex": {
|
||||
"version": "10.3.0",
|
||||
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.3.0.tgz",
|
||||
"integrity": "sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==",
|
||||
"version": "10.4.0",
|
||||
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.4.0.tgz",
|
||||
"integrity": "sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/lint-staged/node_modules/execa": {
|
||||
@@ -14225,16 +14272,16 @@
|
||||
}
|
||||
},
|
||||
"node_modules/lint-staged/node_modules/listr2": {
|
||||
"version": "8.0.1",
|
||||
"resolved": "https://registry.npmjs.org/listr2/-/listr2-8.0.1.tgz",
|
||||
"integrity": "sha512-ovJXBXkKGfq+CwmKTjluEqFi3p4h8xvkxGQQAQan22YCgef4KZ1mKGjzfGh6PL6AW5Csw0QiQPNuQyH+6Xk3hA==",
|
||||
"version": "8.2.5",
|
||||
"resolved": "https://registry.npmjs.org/listr2/-/listr2-8.2.5.tgz",
|
||||
"integrity": "sha512-iyAZCeyD+c1gPyE9qpFu8af0Y+MRtmKOncdGoA2S5EY8iFq99dmmvkNnHiWo+pj0s7yH7l3KPIgee77tKpXPWQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"cli-truncate": "^4.0.0",
|
||||
"colorette": "^2.0.20",
|
||||
"eventemitter3": "^5.0.1",
|
||||
"log-update": "^6.0.0",
|
||||
"rfdc": "^1.3.0",
|
||||
"log-update": "^6.1.0",
|
||||
"rfdc": "^1.4.1",
|
||||
"wrap-ansi": "^9.0.0"
|
||||
},
|
||||
"engines": {
|
||||
@@ -14242,14 +14289,14 @@
|
||||
}
|
||||
},
|
||||
"node_modules/lint-staged/node_modules/log-update": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/log-update/-/log-update-6.0.0.tgz",
|
||||
"integrity": "sha512-niTvB4gqvtof056rRIrTZvjNYE4rCUzO6X/X+kYjd7WFxXeJ0NwEFnRxX6ehkvv3jTwrXnNdtAak5XYZuIyPFw==",
|
||||
"version": "6.1.0",
|
||||
"resolved": "https://registry.npmjs.org/log-update/-/log-update-6.1.0.tgz",
|
||||
"integrity": "sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"ansi-escapes": "^6.2.0",
|
||||
"cli-cursor": "^4.0.0",
|
||||
"slice-ansi": "^7.0.0",
|
||||
"ansi-escapes": "^7.0.0",
|
||||
"cli-cursor": "^5.0.0",
|
||||
"slice-ansi": "^7.1.0",
|
||||
"strip-ansi": "^7.1.0",
|
||||
"wrap-ansi": "^9.0.0"
|
||||
},
|
||||
@@ -14303,6 +14350,12 @@
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/lint-staged/node_modules/ms": {
|
||||
"version": "2.1.3",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
||||
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/lint-staged/node_modules/npm-run-path": {
|
||||
"version": "5.3.0",
|
||||
"resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz",
|
||||
@@ -14346,51 +14399,36 @@
|
||||
}
|
||||
},
|
||||
"node_modules/lint-staged/node_modules/restore-cursor": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-4.0.0.tgz",
|
||||
"integrity": "sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==",
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-5.1.0.tgz",
|
||||
"integrity": "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"onetime": "^5.1.0",
|
||||
"signal-exit": "^3.0.2"
|
||||
"onetime": "^7.0.0",
|
||||
"signal-exit": "^4.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
|
||||
"node": ">=18"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/lint-staged/node_modules/restore-cursor/node_modules/mimic-fn": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
|
||||
"integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/lint-staged/node_modules/restore-cursor/node_modules/onetime": {
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
|
||||
"integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/onetime/-/onetime-7.0.0.tgz",
|
||||
"integrity": "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"mimic-fn": "^2.1.0"
|
||||
"mimic-function": "^5.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
"node": ">=18"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/lint-staged/node_modules/restore-cursor/node_modules/signal-exit": {
|
||||
"version": "3.0.7",
|
||||
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
|
||||
"integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/lint-staged/node_modules/signal-exit": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
|
||||
@@ -14420,9 +14458,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/lint-staged/node_modules/string-width": {
|
||||
"version": "7.1.0",
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-7.1.0.tgz",
|
||||
"integrity": "sha512-SEIJCWiX7Kg4c129n48aDRwLbFb2LJmXXFrWBG4NGaRtMQ3myKPKbwrD1BKqQn74oCoNMBVrfDEr5M9YxCsrkw==",
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz",
|
||||
"integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"emoji-regex": "^10.3.0",
|
||||
@@ -14588,6 +14626,11 @@
|
||||
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/lodash-es": {
|
||||
"version": "4.17.21",
|
||||
"resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz",
|
||||
"integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw=="
|
||||
},
|
||||
"node_modules/lodash.assignwith": {
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.assignwith/-/lodash.assignwith-4.2.0.tgz",
|
||||
@@ -15077,12 +15120,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/micromatch": {
|
||||
"version": "4.0.5",
|
||||
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz",
|
||||
"integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==",
|
||||
"version": "4.0.8",
|
||||
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
|
||||
"integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"braces": "^3.0.2",
|
||||
"braces": "^3.0.3",
|
||||
"picomatch": "^2.3.1"
|
||||
},
|
||||
"engines": {
|
||||
@@ -15132,6 +15175,18 @@
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/mimic-function": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/mimic-function/-/mimic-function-5.0.1.tgz",
|
||||
"integrity": "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/mimic-response": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz",
|
||||
@@ -15366,12 +15421,11 @@
|
||||
}
|
||||
},
|
||||
"node_modules/next": {
|
||||
"version": "14.2.7",
|
||||
"resolved": "https://registry.npmjs.org/next/-/next-14.2.7.tgz",
|
||||
"integrity": "sha512-4Qy2aK0LwH4eQiSvQWyKuC7JXE13bIopEQesWE0c/P3uuNRnZCQanI0vsrMLmUQJLAto+A+/8+sve2hd+BQuOQ==",
|
||||
"license": "MIT",
|
||||
"version": "14.2.16",
|
||||
"resolved": "https://registry.npmjs.org/next/-/next-14.2.16.tgz",
|
||||
"integrity": "sha512-LcO7WnFu6lYSvCzZoo1dB+IO0xXz5uEv52HF1IUN0IqVTUIZGHuuR10I5efiLadGt+4oZqTcNZyVVEem/TM5nA==",
|
||||
"dependencies": {
|
||||
"@next/env": "14.2.7",
|
||||
"@next/env": "14.2.16",
|
||||
"@swc/helpers": "0.5.5",
|
||||
"busboy": "1.6.0",
|
||||
"caniuse-lite": "^1.0.30001579",
|
||||
@@ -15386,15 +15440,15 @@
|
||||
"node": ">=18.17.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@next/swc-darwin-arm64": "14.2.7",
|
||||
"@next/swc-darwin-x64": "14.2.7",
|
||||
"@next/swc-linux-arm64-gnu": "14.2.7",
|
||||
"@next/swc-linux-arm64-musl": "14.2.7",
|
||||
"@next/swc-linux-x64-gnu": "14.2.7",
|
||||
"@next/swc-linux-x64-musl": "14.2.7",
|
||||
"@next/swc-win32-arm64-msvc": "14.2.7",
|
||||
"@next/swc-win32-ia32-msvc": "14.2.7",
|
||||
"@next/swc-win32-x64-msvc": "14.2.7"
|
||||
"@next/swc-darwin-arm64": "14.2.16",
|
||||
"@next/swc-darwin-x64": "14.2.16",
|
||||
"@next/swc-linux-arm64-gnu": "14.2.16",
|
||||
"@next/swc-linux-arm64-musl": "14.2.16",
|
||||
"@next/swc-linux-x64-gnu": "14.2.16",
|
||||
"@next/swc-linux-x64-musl": "14.2.16",
|
||||
"@next/swc-win32-arm64-msvc": "14.2.16",
|
||||
"@next/swc-win32-ia32-msvc": "14.2.16",
|
||||
"@next/swc-win32-x64-msvc": "14.2.16"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@opentelemetry/api": "^1.1.0",
|
||||
@@ -15416,17 +15470,16 @@
|
||||
}
|
||||
},
|
||||
"node_modules/next-auth": {
|
||||
"version": "5.0.0-beta.19",
|
||||
"resolved": "https://registry.npmjs.org/next-auth/-/next-auth-5.0.0-beta.19.tgz",
|
||||
"integrity": "sha512-YHu1igcAxZPh8ZB7GIM93dqgY6gcAzq66FOhQFheAdOx1raxNcApt05nNyNCSB6NegSiyJ4XOPsaNow4pfDmsg==",
|
||||
"license": "ISC",
|
||||
"version": "5.0.0-beta.25",
|
||||
"resolved": "https://registry.npmjs.org/next-auth/-/next-auth-5.0.0-beta.25.tgz",
|
||||
"integrity": "sha512-2dJJw1sHQl2qxCrRk+KTQbeH+izFbGFPuJj5eGgBZFYyiYYtvlrBeUw1E/OJJxTRjuxbSYGnCTkUIRsIIW0bog==",
|
||||
"dependencies": {
|
||||
"@auth/core": "0.32.0"
|
||||
"@auth/core": "0.37.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@simplewebauthn/browser": "^9.0.1",
|
||||
"@simplewebauthn/server": "^9.0.2",
|
||||
"next": "^14 || ^15.0.0-0",
|
||||
"next": "^14.0.0-0 || ^15.0.0-0",
|
||||
"nodemailer": "^6.6.5",
|
||||
"react": "^18.2.0 || ^19.0.0-0"
|
||||
},
|
||||
@@ -15559,10 +15612,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/oauth4webapi": {
|
||||
"version": "2.11.1",
|
||||
"resolved": "https://registry.npmjs.org/oauth4webapi/-/oauth4webapi-2.11.1.tgz",
|
||||
"integrity": "sha512-aNzOnL98bL6izG97zgnZs1PFEyO4WDVRhz2Pd066NPak44w5ESLRCYmJIyey8avSBPOMtBjhF3ZDDm7bIb7UOg==",
|
||||
"license": "MIT",
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/oauth4webapi/-/oauth4webapi-3.1.2.tgz",
|
||||
"integrity": "sha512-KQZkNU+xn02lWrFu5Vjqg9E81yPtDSxUZorRHlLWVoojD+H/0GFbH59kcnz5Thdjj7c4/mYMBPj/mhvGe/kKXA==",
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/panva"
|
||||
}
|
||||
@@ -16047,9 +16099,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/path-to-regexp": {
|
||||
"version": "6.2.2",
|
||||
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.2.2.tgz",
|
||||
"integrity": "sha512-GQX3SSMokngb36+whdpRXE+3f9V8UzyAorlYvOGx87ufGHehNTn5lCxrKtLyZ4Yl/wEKnNnr98ZzOwwDZV5ogw==",
|
||||
"version": "6.3.0",
|
||||
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.3.0.tgz",
|
||||
"integrity": "sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/path-type": {
|
||||
@@ -16224,6 +16276,16 @@
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/post-robot": {
|
||||
"version": "8.0.31",
|
||||
"resolved": "https://registry.npmjs.org/post-robot/-/post-robot-8.0.31.tgz",
|
||||
"integrity": "sha512-nUhtKgtmcgyuPm4RnIhUB3gsDYJBHOgFry3TvOxhIHpgfwYY/T69d4oB90tw4YUllFZUUwqLEv1Wgyg6eOoJ7A==",
|
||||
"dependencies": {
|
||||
"cross-domain-safe-weakmap": "^1.0.1",
|
||||
"cross-domain-utils": "^2.0.0",
|
||||
"zalgo-promise": "^1.0.3"
|
||||
}
|
||||
},
|
||||
"node_modules/postcss": {
|
||||
"version": "8.4.31",
|
||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz",
|
||||
@@ -16365,7 +16427,6 @@
|
||||
"version": "10.11.3",
|
||||
"resolved": "https://registry.npmjs.org/preact/-/preact-10.11.3.tgz",
|
||||
"integrity": "sha512-eY93IVpod/zG3uMF22Unl8h9KkrcKIRs2EGar8hwLZZDU1lkjph303V9HZBwufh2s736U6VXuhD109LYqPoffg==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/preact"
|
||||
@@ -16375,7 +16436,6 @@
|
||||
"version": "5.2.3",
|
||||
"resolved": "https://registry.npmjs.org/preact-render-to-string/-/preact-render-to-string-5.2.3.tgz",
|
||||
"integrity": "sha512-aPDxUn5o3GhWdtJtW0svRC2SS/l8D9MAgo2+AWml+BhDImb27ALf04Q2d+AHqUUOc6RdSXFIBVa2gxzgMKgtZA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"pretty-format": "^3.8.0"
|
||||
},
|
||||
@@ -16422,8 +16482,7 @@
|
||||
"node_modules/pretty-format": {
|
||||
"version": "3.8.0",
|
||||
"resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-3.8.0.tgz",
|
||||
"integrity": "sha512-WuxUnVtlWL1OfZFQFuqvnvs6MiAGk9UNsBostyBOB0Is9wb5uRESevA6rnl/rkksXaGX3GzZhPup5d6Vp1nFew==",
|
||||
"license": "MIT"
|
||||
"integrity": "sha512-WuxUnVtlWL1OfZFQFuqvnvs6MiAGk9UNsBostyBOB0Is9wb5uRESevA6rnl/rkksXaGX3GzZhPup5d6Vp1nFew=="
|
||||
},
|
||||
"node_modules/process": {
|
||||
"version": "0.11.10",
|
||||
@@ -17428,9 +17487,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/rfdc": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.1.tgz",
|
||||
"integrity": "sha512-r5a3l5HzYlIC68TpmYKlxWjmOP6wiPJ1vWv2HeLhNsRZMrCkxeqxiHlQ21oXmQ4F3SiryXBHhAD7JZqvOJjFmg==",
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz",
|
||||
"integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/rimraf": {
|
||||
@@ -19883,10 +19942,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/yaml": {
|
||||
"version": "2.3.4",
|
||||
"resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.4.tgz",
|
||||
"integrity": "sha512-8aAvwVUSHpfEqTQ4w/KMlf3HcRdt50E5ODIQJBw1fQ5RL34xabzxtUlzTXVqc4rkZsPbvrXKWnABCD7kWSmocA==",
|
||||
"version": "2.5.1",
|
||||
"resolved": "https://registry.npmjs.org/yaml/-/yaml-2.5.1.tgz",
|
||||
"integrity": "sha512-bLQOjaX/ADgQ20isPJRvF0iRUHIxVhYvr53Of7wGcWlO2jvtUlH5m87DsmulFVxRpNLOnI4tB6p/oh8D7kpn9Q==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"yaml": "bin.mjs"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 14"
|
||||
}
|
||||
@@ -19958,6 +20020,11 @@
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/zalgo-promise": {
|
||||
"version": "1.0.48",
|
||||
"resolved": "https://registry.npmjs.org/zalgo-promise/-/zalgo-promise-1.0.48.tgz",
|
||||
"integrity": "sha512-LLHANmdm53+MucY9aOFIggzYtUdkSBFxUsy4glTTQYNyK6B3uCPWTbfiGvSrEvLojw0mSzyFJ1/RRLv+QMNdzQ=="
|
||||
},
|
||||
"node_modules/zod": {
|
||||
"version": "3.22.4",
|
||||
"resolved": "https://registry.npmjs.org/zod/-/zod-3.22.4.tgz",
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@azure/monitor-opentelemetry-exporter": "^1.0.0-beta.24",
|
||||
"@contentstack/live-preview-utils": "^1.4.0",
|
||||
"@contentstack/live-preview-utils": "^2.0.4",
|
||||
"@hookform/error-message": "^2.0.1",
|
||||
"@hookform/resolvers": "^3.3.4",
|
||||
"@netlify/plugin-nextjs": "^5.1.1",
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
>
|
||||
|
||||
@@ -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<GetCollectionPageBreadcrumbsRefsData>(
|
||||
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<GetCollectionPageBreadcrumbsData>(
|
||||
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<GetContentPageBreadcrumbsRefsData>(
|
||||
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:
|
||||
|
||||
5
server/routers/contentstack/collectionPage/index.ts
Normal file
5
server/routers/contentstack/collectionPage/index.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import { mergeRouters } from "@/server/trpc"
|
||||
|
||||
import { collectionPageQueryRouter } from "./query"
|
||||
|
||||
export const collectionPageRouter = mergeRouters(collectionPageQueryRouter)
|
||||
121
server/routers/contentstack/collectionPage/output.ts
Normal file
121
server/routers/contentstack/collectionPage/output.ts
Normal file
@@ -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,
|
||||
}),
|
||||
})
|
||||
78
server/routers/contentstack/collectionPage/query.ts
Normal file
78
server/routers/contentstack/collectionPage/query.ts
Normal file
@@ -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<GetCollectionPageSchema>(
|
||||
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,
|
||||
}
|
||||
}),
|
||||
})
|
||||
152
server/routers/contentstack/collectionPage/utils.ts
Normal file
152
server/routers/contentstack/collectionPage/utils.ts
Normal file
@@ -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<GetCollectionPageRefsSchema>(
|
||||
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
|
||||
}
|
||||
@@ -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)
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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`)
|
||||
|
||||
@@ -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),
|
||||
@@ -91,7 +92,22 @@ export const teaserCardBlockSchema = z.object({
|
||||
has_secondary_button: z.boolean().default(false),
|
||||
secondary_button: buttonSchema,
|
||||
})
|
||||
.optional(),
|
||||
.optional()
|
||||
.transform((data) => {
|
||||
if (!data) {
|
||||
return undefined
|
||||
}
|
||||
|
||||
return {
|
||||
...data,
|
||||
primary_button: data.has_primary_button
|
||||
? data.primary_button
|
||||
: undefined,
|
||||
secondary_button: data.has_secondary_button
|
||||
? data.secondary_button
|
||||
: undefined,
|
||||
}
|
||||
}),
|
||||
system: systemSchema,
|
||||
})
|
||||
|
||||
@@ -146,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) => {
|
||||
|
||||
@@ -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,
|
||||
])
|
||||
|
||||
@@ -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<typeof accountPageSchema>
|
||||
| z.output<typeof contentPageSchema>
|
||||
| z.output<typeof collectionPageSchema>
|
||||
| z.output<typeof hotelPageSchema>
|
||||
| z.output<typeof loyaltyPageSchema>
|
||||
| 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<typeof accountPageRefSchema>
|
||||
| z.output<typeof collectionPageRefSchema>
|
||||
| z.output<typeof contentPageRefSchema>
|
||||
| z.output<typeof hotelPageRefSchema>
|
||||
| z.output<typeof loyaltyPageRefSchema>
|
||||
@@ -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
|
||||
|
||||
@@ -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({
|
||||
|
||||
@@ -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<CardsGrid, "cards_grid"> {
|
||||
firstItem?: boolean
|
||||
|
||||
@@ -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[]
|
||||
|
||||
@@ -4,3 +4,10 @@ export enum StepEnum {
|
||||
details = "details",
|
||||
payment = "payment",
|
||||
}
|
||||
|
||||
export const StepStoreKeys: Record<StepEnum, "bedType" | "breakfast" | null> = {
|
||||
"select-bed": "bedType",
|
||||
breakfast: "breakfast",
|
||||
details: null,
|
||||
payment: null,
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
9
types/enums/collectionPage.ts
Normal file
9
types/enums/collectionPage.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
export namespace CollectionPageEnum {
|
||||
export namespace ContentStack {
|
||||
export const enum blocks {
|
||||
CardsGrid = "CollectionPageBlocksCardsGrid",
|
||||
Shortcuts = "CollectionPageBlocksShortcuts",
|
||||
UspGrid = "CollectionPageBlocksUspGrid",
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
export namespace ContentEnum {
|
||||
export const enum blocks {
|
||||
AccountPage = "AccountPage",
|
||||
CollectionPage = "CollectionPage",
|
||||
ContentPage = "ContentPage",
|
||||
HotelPage = "HotelPage",
|
||||
ImageContainer = "ImageContainer",
|
||||
|
||||
9
types/enums/scriptedCard.ts
Normal file
9
types/enums/scriptedCard.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
export enum scriptedCardThemeEnum {
|
||||
one = "one",
|
||||
two = "two",
|
||||
three = "three",
|
||||
primaryDim = "primaryDim",
|
||||
primaryDark = "primaryDark",
|
||||
primaryInverted = "primaryInverted",
|
||||
primaryStrong = "primaryStrong",
|
||||
}
|
||||
@@ -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 = {
|
||||
|
||||
@@ -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",
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -3,5 +3,6 @@ export enum PageTypeEnum {
|
||||
loyaltyPage = "loyalty-page",
|
||||
hotelPage = "hotel-page",
|
||||
contentPage = "content-page",
|
||||
collectionPage = "collection-page",
|
||||
currentBlocksPage = "current-blocks-page",
|
||||
}
|
||||
|
||||
20
types/trpc/routers/contentstack/collectionPage.ts
Normal file
20
types/trpc/routers/contentstack/collectionPage.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
import { z } from "zod"
|
||||
|
||||
import {
|
||||
blocksSchema,
|
||||
collectionPageRefsSchema,
|
||||
collectionPageSchema,
|
||||
} from "@/server/routers/contentstack/collectionPage/output"
|
||||
|
||||
export interface GetCollectionPageRefsSchema
|
||||
extends z.input<typeof collectionPageRefsSchema> {}
|
||||
|
||||
export interface CollectionPageRefs
|
||||
extends z.output<typeof collectionPageRefsSchema> {}
|
||||
|
||||
export interface GetCollectionPageSchema
|
||||
extends z.input<typeof collectionPageSchema> {}
|
||||
|
||||
export interface CollectionPage extends z.output<typeof collectionPageSchema> {}
|
||||
|
||||
export type Block = z.output<typeof blocksSchema>
|
||||
Reference in New Issue
Block a user