Merged in chore/cleanup-scandic-web (pull request #2831)
chore: Cleanup scandic-web * Remove unused files * Remove unused and add missing packages * Remove unused exports Approved-by: Linus Flood
This commit is contained in:
@@ -2,7 +2,7 @@ import { mapRewardToIcon } from "./data"
|
|||||||
|
|
||||||
import type { LogoAndIllustrationProps } from "@scandic-hotels/design-system/Icons"
|
import type { LogoAndIllustrationProps } from "@scandic-hotels/design-system/Icons"
|
||||||
|
|
||||||
export interface RewardIconProps extends LogoAndIllustrationProps {
|
interface RewardIconProps extends LogoAndIllustrationProps {
|
||||||
rewardId: string
|
rewardId: string
|
||||||
iconSize?: "small" | "medium" | "large"
|
iconSize?: "small" | "medium" | "large"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -119,4 +119,3 @@ Carousel.Previous = CarouselPrevious
|
|||||||
Carousel.Dots = CarouselDots
|
Carousel.Dots = CarouselDots
|
||||||
|
|
||||||
export { Carousel }
|
export { Carousel }
|
||||||
export type { CarouselApi }
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ export const usePageType = () => {
|
|||||||
return context
|
return context
|
||||||
}
|
}
|
||||||
|
|
||||||
export type PageTypeProviderProps = {
|
type PageTypeProviderProps = {
|
||||||
value: "city" | "country" | "overview" | null
|
value: "city" | "country" | "overview" | null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ export async function getConferenceRoomTexts(
|
|||||||
return { seatingText, roomText }
|
return { seatingText, roomText }
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getRoomText(roomSizes: number[]) {
|
async function getRoomText(roomSizes: number[]) {
|
||||||
const largestRoom = Math.max(...roomSizes)
|
const largestRoom = Math.max(...roomSizes)
|
||||||
const smallestRoom = Math.min(...roomSizes)
|
const smallestRoom = Math.min(...roomSizes)
|
||||||
const intl = await getIntl()
|
const intl = await getIntl()
|
||||||
@@ -47,7 +47,7 @@ export async function getRoomText(roomSizes: number[]) {
|
|||||||
return roomText
|
return roomText
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getSeatingText(roomSeating: number[]) {
|
async function getSeatingText(roomSeating: number[]) {
|
||||||
const biggestSeating = Math.max(...roomSeating)
|
const biggestSeating = Math.max(...roomSeating)
|
||||||
const smallestSeating = Math.min(...roomSeating)
|
const smallestSeating = Math.min(...roomSeating)
|
||||||
const intl = await getIntl()
|
const intl = await getIntl()
|
||||||
|
|||||||
@@ -1,20 +0,0 @@
|
|||||||
import { nodesToHtml } from "./utils"
|
|
||||||
|
|
||||||
import styles from "./jsontohtml.module.css"
|
|
||||||
|
|
||||||
import type { DeprecatedJsonToHtmlProps } from "@/types/components/deprecatedjsontohtml"
|
|
||||||
|
|
||||||
export default function DeprecatedJsonToHtml({
|
|
||||||
embeds,
|
|
||||||
nodes,
|
|
||||||
renderOptions = {},
|
|
||||||
}: DeprecatedJsonToHtmlProps) {
|
|
||||||
if (!Array.isArray(nodes) || !nodes.length) {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
return (
|
|
||||||
<section className={styles.container}>
|
|
||||||
{nodesToHtml(nodes, embeds, renderOptions).filter(Boolean)}
|
|
||||||
</section>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,68 +0,0 @@
|
|||||||
.image {
|
|
||||||
max-width: 100%;
|
|
||||||
width: 100%;
|
|
||||||
height: 365px;
|
|
||||||
object-fit: cover;
|
|
||||||
border-radius: var(--Corner-radius-md);
|
|
||||||
margin: var(--Spacing-x1) var(--Spacing-x0);
|
|
||||||
}
|
|
||||||
|
|
||||||
.ul,
|
|
||||||
.ol {
|
|
||||||
padding: var(--Spacing-x2) var(--Spacing-x0);
|
|
||||||
display: grid;
|
|
||||||
gap: var(--Spacing-x1);
|
|
||||||
}
|
|
||||||
|
|
||||||
.ol > li::marker {
|
|
||||||
color: var(--Primary-Light-On-Surface-Accent);
|
|
||||||
}
|
|
||||||
|
|
||||||
.li:has(.heart),
|
|
||||||
.li:has(.check) {
|
|
||||||
list-style: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.li {
|
|
||||||
margin-left: var(--Spacing-x3);
|
|
||||||
}
|
|
||||||
|
|
||||||
.li:has(.heart):before {
|
|
||||||
content: url("/_static/icons/heart.svg");
|
|
||||||
position: relative;
|
|
||||||
height: 8px;
|
|
||||||
top: 3px;
|
|
||||||
margin-right: var(--Spacing-x1);
|
|
||||||
margin-left: calc(var(--Spacing-x3) * -1);
|
|
||||||
}
|
|
||||||
|
|
||||||
.li:has(.check)::before {
|
|
||||||
content: url("/_static/icons/check-ring.svg");
|
|
||||||
position: relative;
|
|
||||||
height: 8px;
|
|
||||||
top: 3px;
|
|
||||||
margin-right: var(--Spacing-x1);
|
|
||||||
margin-left: calc(var(--Spacing-x3) * -1);
|
|
||||||
}
|
|
||||||
|
|
||||||
.container {
|
|
||||||
display: grid;
|
|
||||||
gap: var(--Spacing-x3);
|
|
||||||
max-width: 1197px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.li > p {
|
|
||||||
display: inline;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tableContainer {
|
|
||||||
max-width: 100%;
|
|
||||||
overflow-x: auto;
|
|
||||||
}
|
|
||||||
@media screen and (min-width: 768px) {
|
|
||||||
.ol:has(li:nth-last-child(n + 5)),
|
|
||||||
.ul:has(li:nth-last-child(n + 5)) {
|
|
||||||
grid-template-columns: 1fr 1fr;
|
|
||||||
grid-auto-flow: column;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,687 +0,0 @@
|
|||||||
import {
|
|
||||||
type DeprecatedImageVaultAssetResponse,
|
|
||||||
type ImageVaultAssetResponse,
|
|
||||||
mapImageVaultAssetResponseToImageVaultAsset,
|
|
||||||
mapInsertResponseToImageVaultAsset,
|
|
||||||
} from "@scandic-hotels/common/utils/imageVault"
|
|
||||||
import { removeMultipleSlashes } from "@scandic-hotels/common/utils/url"
|
|
||||||
import Body from "@scandic-hotels/design-system/Body"
|
|
||||||
import Caption from "@scandic-hotels/design-system/Caption"
|
|
||||||
import { Divider } from "@scandic-hotels/design-system/Divider"
|
|
||||||
import Footnote from "@scandic-hotels/design-system/Footnote"
|
|
||||||
import Image from "@scandic-hotels/design-system/Image"
|
|
||||||
import ImageContainer from "@scandic-hotels/design-system/ImageContainer"
|
|
||||||
import Link from "@scandic-hotels/design-system/Link"
|
|
||||||
import Subtitle from "@scandic-hotels/design-system/Subtitle"
|
|
||||||
import Table from "@scandic-hotels/design-system/Table"
|
|
||||||
import Title from "@scandic-hotels/design-system/Title"
|
|
||||||
import {
|
|
||||||
AvailableParagraphFormatEnum,
|
|
||||||
RTEItemTypeEnum,
|
|
||||||
RTETypeEnum,
|
|
||||||
} from "@scandic-hotels/trpc/types/RTEenums"
|
|
||||||
|
|
||||||
import BiroScript from "../TempDesignSystem/Text/BiroScript"
|
|
||||||
import { hasAvailableParagraphFormat, hasAvailableULFormat } from "./utils"
|
|
||||||
|
|
||||||
import styles from "./jsontohtml.module.css"
|
|
||||||
|
|
||||||
import type { EmbedByUid } from "@/types/components/deprecatedjsontohtml"
|
|
||||||
import { EmbedEnum } from "@/types/requests/utils/embeds"
|
|
||||||
import type { Attributes } from "@/types/rte/attrs"
|
|
||||||
import {
|
|
||||||
type RTEDefaultNode,
|
|
||||||
type RTEImageNode,
|
|
||||||
RTEMarkType,
|
|
||||||
type RTENext,
|
|
||||||
type RTENode,
|
|
||||||
type RTERegularNode,
|
|
||||||
type RTETextNode,
|
|
||||||
} from "@/types/rte/node"
|
|
||||||
import type { RenderOptions } from "@/types/rte/option"
|
|
||||||
|
|
||||||
function extractPossibleAttributes(attrs: Attributes | undefined) {
|
|
||||||
if (!attrs) return {}
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
||||||
const props: Record<string, any> = {}
|
|
||||||
if (attrs.id) {
|
|
||||||
props.id = attrs.id
|
|
||||||
}
|
|
||||||
|
|
||||||
if (attrs.class) {
|
|
||||||
props.className = attrs.class
|
|
||||||
} else if (attrs["class-name"]) {
|
|
||||||
props.className = attrs["class-name"]
|
|
||||||
} else if (attrs.classname) {
|
|
||||||
props.className = attrs.classname
|
|
||||||
} else if (attrs?.style?.["text-align"]) {
|
|
||||||
props.style = {
|
|
||||||
textAlign: attrs?.style?.["text-align"],
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return props
|
|
||||||
}
|
|
||||||
|
|
||||||
export const renderOptions: RenderOptions = {
|
|
||||||
[RTETypeEnum.a]: (
|
|
||||||
node: RTERegularNode,
|
|
||||||
embeds: EmbedByUid,
|
|
||||||
next: RTENext,
|
|
||||||
fullRenderOptions: RenderOptions
|
|
||||||
) => {
|
|
||||||
if (node.attrs.url) {
|
|
||||||
const props = extractPossibleAttributes(node.attrs)
|
|
||||||
return (
|
|
||||||
<Link
|
|
||||||
{...props}
|
|
||||||
href={node.attrs.url}
|
|
||||||
key={node.uid}
|
|
||||||
target={node.attrs.target ?? "_blank"}
|
|
||||||
textDecoration="underline"
|
|
||||||
>
|
|
||||||
{next(node.children, embeds, fullRenderOptions)}
|
|
||||||
</Link>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
return null
|
|
||||||
},
|
|
||||||
|
|
||||||
[RTETypeEnum.blockquote]: (
|
|
||||||
node: RTEDefaultNode,
|
|
||||||
embeds: EmbedByUid,
|
|
||||||
next: RTENext,
|
|
||||||
fullRenderOptions: RenderOptions
|
|
||||||
) => {
|
|
||||||
const props = extractPossibleAttributes(node.attrs)
|
|
||||||
return (
|
|
||||||
<BiroScript key={node.uid} {...props}>
|
|
||||||
{next(node.children, embeds, fullRenderOptions)}
|
|
||||||
</BiroScript>
|
|
||||||
)
|
|
||||||
},
|
|
||||||
|
|
||||||
[RTETypeEnum.code]: (
|
|
||||||
node: RTEDefaultNode,
|
|
||||||
embeds: EmbedByUid,
|
|
||||||
next: RTENext,
|
|
||||||
fullRenderOptions: RenderOptions
|
|
||||||
) => {
|
|
||||||
const props = extractPossibleAttributes(node.attrs)
|
|
||||||
return (
|
|
||||||
<code key={node.uid} {...props}>
|
|
||||||
{next(node.children, embeds, fullRenderOptions)}
|
|
||||||
</code>
|
|
||||||
)
|
|
||||||
},
|
|
||||||
|
|
||||||
[RTETypeEnum.embed]: (
|
|
||||||
node: RTEDefaultNode,
|
|
||||||
embeds: EmbedByUid,
|
|
||||||
next: RTENext,
|
|
||||||
fullRenderOptions: RenderOptions
|
|
||||||
) => {
|
|
||||||
const props = extractPossibleAttributes(node.attrs)
|
|
||||||
if (node.attrs.src) {
|
|
||||||
props.src = node.attrs.src
|
|
||||||
}
|
|
||||||
if (node.attrs.url) {
|
|
||||||
props.src = node.attrs.url
|
|
||||||
}
|
|
||||||
if (!props.src) {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
return (
|
|
||||||
<iframe key={node.uid} {...props}>
|
|
||||||
{next(node.children, embeds, fullRenderOptions)}
|
|
||||||
</iframe>
|
|
||||||
)
|
|
||||||
},
|
|
||||||
|
|
||||||
[RTETypeEnum.h1]: (
|
|
||||||
node: RTEDefaultNode,
|
|
||||||
embeds: EmbedByUid,
|
|
||||||
next: RTENext,
|
|
||||||
fullRenderOptions: RenderOptions
|
|
||||||
) => {
|
|
||||||
const props = extractPossibleAttributes(node.attrs)
|
|
||||||
return (
|
|
||||||
<Title key={node.uid} {...props} level="h1">
|
|
||||||
{next(node.children, embeds, fullRenderOptions)}
|
|
||||||
</Title>
|
|
||||||
)
|
|
||||||
},
|
|
||||||
|
|
||||||
[RTETypeEnum.h2]: (
|
|
||||||
node: RTEDefaultNode,
|
|
||||||
embeds: EmbedByUid,
|
|
||||||
next: RTENext,
|
|
||||||
fullRenderOptions: RenderOptions
|
|
||||||
) => {
|
|
||||||
const props = extractPossibleAttributes(node.attrs)
|
|
||||||
return (
|
|
||||||
<Title key={node.uid} {...props} level="h2">
|
|
||||||
{next(node.children, embeds, fullRenderOptions)}
|
|
||||||
</Title>
|
|
||||||
)
|
|
||||||
},
|
|
||||||
|
|
||||||
[RTETypeEnum.h3]: (
|
|
||||||
node: RTEDefaultNode,
|
|
||||||
embeds: EmbedByUid,
|
|
||||||
next: RTENext,
|
|
||||||
fullRenderOptions: RenderOptions
|
|
||||||
) => {
|
|
||||||
const props = extractPossibleAttributes(node.attrs)
|
|
||||||
return (
|
|
||||||
<Title key={node.uid} {...props} level="h3">
|
|
||||||
{next(node.children, embeds, fullRenderOptions)}
|
|
||||||
</Title>
|
|
||||||
)
|
|
||||||
},
|
|
||||||
|
|
||||||
[RTETypeEnum.h4]: (
|
|
||||||
node: RTEDefaultNode,
|
|
||||||
embeds: EmbedByUid,
|
|
||||||
next: RTENext,
|
|
||||||
fullRenderOptions: RenderOptions
|
|
||||||
) => {
|
|
||||||
const props = extractPossibleAttributes(node.attrs)
|
|
||||||
return (
|
|
||||||
<Title key={node.uid} {...props} level="h4">
|
|
||||||
{next(node.children, embeds, fullRenderOptions)}
|
|
||||||
</Title>
|
|
||||||
)
|
|
||||||
},
|
|
||||||
|
|
||||||
[RTETypeEnum.h5]: (
|
|
||||||
node: RTEDefaultNode,
|
|
||||||
embeds: EmbedByUid,
|
|
||||||
next: RTENext,
|
|
||||||
fullRenderOptions: RenderOptions
|
|
||||||
) => {
|
|
||||||
const props = extractPossibleAttributes(node.attrs)
|
|
||||||
return (
|
|
||||||
<Title key={node.uid} {...props} level="h5">
|
|
||||||
{next(node.children, embeds, fullRenderOptions)}
|
|
||||||
</Title>
|
|
||||||
)
|
|
||||||
},
|
|
||||||
|
|
||||||
[RTETypeEnum.hr]: () => {
|
|
||||||
return <Divider color="burgundy" />
|
|
||||||
},
|
|
||||||
|
|
||||||
[RTETypeEnum.li]: (
|
|
||||||
node: RTEDefaultNode,
|
|
||||||
embeds: EmbedByUid,
|
|
||||||
next: RTENext,
|
|
||||||
fullRenderOptions: RenderOptions
|
|
||||||
) => {
|
|
||||||
const props = extractPossibleAttributes(node.attrs)
|
|
||||||
return (
|
|
||||||
<li key={node.uid} {...props} className={styles.li}>
|
|
||||||
{next(node.children, embeds, fullRenderOptions)}
|
|
||||||
</li>
|
|
||||||
)
|
|
||||||
},
|
|
||||||
|
|
||||||
[RTETypeEnum.ol]: (
|
|
||||||
node: RTEDefaultNode,
|
|
||||||
embeds: EmbedByUid,
|
|
||||||
next: RTENext,
|
|
||||||
fullRenderOptions: RenderOptions
|
|
||||||
) => {
|
|
||||||
const props = extractPossibleAttributes(node.attrs)
|
|
||||||
|
|
||||||
// Set the number of rows dynamically to create even rows for each column. We want the li:s
|
|
||||||
// to flow with the column, so therefore this is needed.
|
|
||||||
let numberOfRows: number | undefined
|
|
||||||
if (node.children.length > 4) {
|
|
||||||
const half = node.children.length / 2
|
|
||||||
numberOfRows = Math.ceil(half)
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<ol
|
|
||||||
key={node.uid}
|
|
||||||
{...props}
|
|
||||||
className={styles.ol}
|
|
||||||
style={
|
|
||||||
numberOfRows
|
|
||||||
? { gridTemplateRows: `repeat(${numberOfRows}, auto)` }
|
|
||||||
: {}
|
|
||||||
}
|
|
||||||
>
|
|
||||||
{next(node.children, embeds, fullRenderOptions)}
|
|
||||||
</ol>
|
|
||||||
)
|
|
||||||
},
|
|
||||||
|
|
||||||
[RTETypeEnum.p]: (
|
|
||||||
node: RTEDefaultNode,
|
|
||||||
embeds: EmbedByUid,
|
|
||||||
next: RTENext,
|
|
||||||
fullRenderOptions: RenderOptions
|
|
||||||
) => {
|
|
||||||
const props = extractPossibleAttributes(node.attrs)
|
|
||||||
|
|
||||||
const hasFormat = node.children.some((item) =>
|
|
||||||
hasAvailableParagraphFormat((item as RTETextNode)?.classname)
|
|
||||||
)
|
|
||||||
|
|
||||||
// If a child node has an available format as className, we wrap it in a
|
|
||||||
// span and render the children with the correct component
|
|
||||||
if (hasFormat) {
|
|
||||||
return next(node.children, embeds, fullRenderOptions)
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Body {...props} key={node.uid}>
|
|
||||||
{next(node.children, embeds, fullRenderOptions)}
|
|
||||||
</Body>
|
|
||||||
)
|
|
||||||
},
|
|
||||||
|
|
||||||
[RTETypeEnum.reference]: (
|
|
||||||
node: RTENode,
|
|
||||||
embeds: EmbedByUid,
|
|
||||||
next: RTENext,
|
|
||||||
fullRenderOptions: RenderOptions
|
|
||||||
) => {
|
|
||||||
if ("attrs" in node) {
|
|
||||||
const type = node.attrs.type
|
|
||||||
if (type === RTEItemTypeEnum.asset) {
|
|
||||||
const image = embeds?.[node?.attrs?.["asset-uid"]]
|
|
||||||
if (image?.node.__typename === EmbedEnum.SysAsset) {
|
|
||||||
const alt = image?.node?.title ?? node.attrs.alt
|
|
||||||
const props = extractPossibleAttributes(node.attrs)
|
|
||||||
props.className = styles.image
|
|
||||||
return (
|
|
||||||
<Image
|
|
||||||
key={node.uid}
|
|
||||||
alt={alt}
|
|
||||||
height={image.node.dimension.height}
|
|
||||||
src={image?.node?.url}
|
|
||||||
width={image.node.dimension.width}
|
|
||||||
{...props}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
} else if (type === RTEItemTypeEnum.entry) {
|
|
||||||
const entry = embeds?.[node?.attrs?.["entry-uid"]]
|
|
||||||
|
|
||||||
if (entry?.node.__typename === EmbedEnum.ImageContainer) {
|
|
||||||
if (entry.node.image_left && entry.node.image_right) {
|
|
||||||
return (
|
|
||||||
<ImageContainer
|
|
||||||
leftImage={entry.node.image_left}
|
|
||||||
rightImage={entry.node.image_right}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
return null
|
|
||||||
} else if (
|
|
||||||
entry?.node.__typename === EmbedEnum.LoyaltyPage ||
|
|
||||||
entry?.node.__typename === EmbedEnum.ContentPage ||
|
|
||||||
entry?.node.__typename === EmbedEnum.AccountPage
|
|
||||||
) {
|
|
||||||
// If entry is not an ImageContainer, it is a page and we return it as a link
|
|
||||||
const props = extractPossibleAttributes(node.attrs)
|
|
||||||
let href = ""
|
|
||||||
if (entry?.node.__typename === EmbedEnum.AccountPage) {
|
|
||||||
href = removeMultipleSlashes(
|
|
||||||
`/${entry.node.system.locale}${entry.node.url}`
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
href =
|
|
||||||
entry.node?.web?.original_url ||
|
|
||||||
removeMultipleSlashes(
|
|
||||||
`/${entry.node.system.locale}${entry.node.url}`
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Link
|
|
||||||
{...props}
|
|
||||||
href={href}
|
|
||||||
key={node.uid}
|
|
||||||
textDecoration="underline"
|
|
||||||
>
|
|
||||||
{next(node.children, embeds, fullRenderOptions)}
|
|
||||||
</Link>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null
|
|
||||||
},
|
|
||||||
|
|
||||||
[RTETypeEnum.ImageVault]: (node: RTEImageNode) => {
|
|
||||||
const type = node.type
|
|
||||||
if (!("attrs" in node) || type !== RTETypeEnum.ImageVault) {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
let image = undefined
|
|
||||||
if ("imageVaultId" in node.attrs && "fileName" in node.attrs) {
|
|
||||||
image = mapImageVaultAssetResponseToImageVaultAsset(
|
|
||||||
node.attrs as unknown as ImageVaultAssetResponse
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
if ("Name" in node.attrs && "Id" in node.attrs) {
|
|
||||||
image = mapInsertResponseToImageVaultAsset(
|
|
||||||
node.attrs as unknown as DeprecatedImageVaultAssetResponse
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!image) {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
const alt = image.meta.alt ?? image.title
|
|
||||||
const props = extractPossibleAttributes(node.attrs)
|
|
||||||
|
|
||||||
return (
|
|
||||||
<section key={node.uid}>
|
|
||||||
<Image
|
|
||||||
alt={alt}
|
|
||||||
className={styles.image}
|
|
||||||
fill
|
|
||||||
sizes="(min-width: 1367px) 800px, (max-width: 1366px) and (min-width: 1200px) 1200px, 100vw"
|
|
||||||
src={image.url}
|
|
||||||
focalPoint={image.focalPoint}
|
|
||||||
dimensions={image.dimensions}
|
|
||||||
{...props}
|
|
||||||
/>
|
|
||||||
<Caption>{image.meta.caption}</Caption>
|
|
||||||
</section>
|
|
||||||
)
|
|
||||||
|
|
||||||
return null
|
|
||||||
},
|
|
||||||
|
|
||||||
[RTETypeEnum.table]: (
|
|
||||||
node: RTEDefaultNode,
|
|
||||||
embeds: EmbedByUid,
|
|
||||||
next: RTENext,
|
|
||||||
fullRenderOptions: RenderOptions
|
|
||||||
) => {
|
|
||||||
const props = extractPossibleAttributes(node.attrs)
|
|
||||||
return (
|
|
||||||
<div className={styles.tableContainer}>
|
|
||||||
<Table key={node.uid} {...props}>
|
|
||||||
{next(node.children, embeds, fullRenderOptions)}
|
|
||||||
</Table>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
},
|
|
||||||
|
|
||||||
[RTETypeEnum.thead]: (
|
|
||||||
node: RTEDefaultNode,
|
|
||||||
embeds: EmbedByUid,
|
|
||||||
next: RTENext,
|
|
||||||
fullRenderOptions: RenderOptions
|
|
||||||
) => {
|
|
||||||
// Override the styling of p tags inside the thead tag
|
|
||||||
const theadChildPRenderOptions = {
|
|
||||||
...fullRenderOptions,
|
|
||||||
[RTETypeEnum.p]: (
|
|
||||||
node: RTEDefaultNode,
|
|
||||||
embeds: EmbedByUid,
|
|
||||||
next: RTENext,
|
|
||||||
fullRenderOptions: RenderOptions
|
|
||||||
) => (
|
|
||||||
<Body color={"burgundy"} textTransform={"bold"}>
|
|
||||||
{next(node.children, embeds, fullRenderOptions)}
|
|
||||||
</Body>
|
|
||||||
),
|
|
||||||
}
|
|
||||||
const props = extractPossibleAttributes(node.attrs)
|
|
||||||
return (
|
|
||||||
<Table.THead key={node.uid} {...props}>
|
|
||||||
{next(node.children, embeds, theadChildPRenderOptions)}
|
|
||||||
</Table.THead>
|
|
||||||
)
|
|
||||||
},
|
|
||||||
|
|
||||||
[RTETypeEnum.tbody]: (
|
|
||||||
node: RTEDefaultNode,
|
|
||||||
embeds: EmbedByUid,
|
|
||||||
next: RTENext,
|
|
||||||
fullRenderOptions: RenderOptions
|
|
||||||
) => {
|
|
||||||
const props = extractPossibleAttributes(node.attrs)
|
|
||||||
return (
|
|
||||||
<Table.TBody key={node.uid} {...props}>
|
|
||||||
{next(node.children, embeds, fullRenderOptions)}
|
|
||||||
</Table.TBody>
|
|
||||||
)
|
|
||||||
},
|
|
||||||
|
|
||||||
[RTETypeEnum.tfoot]: (
|
|
||||||
node: RTEDefaultNode,
|
|
||||||
embeds: EmbedByUid,
|
|
||||||
next: RTENext,
|
|
||||||
fullRenderOptions: RenderOptions
|
|
||||||
) => {
|
|
||||||
const props = extractPossibleAttributes(node.attrs)
|
|
||||||
return (
|
|
||||||
<tfoot key={node.uid} {...props}>
|
|
||||||
{next(node.children, embeds, fullRenderOptions)}
|
|
||||||
</tfoot>
|
|
||||||
)
|
|
||||||
},
|
|
||||||
|
|
||||||
[RTETypeEnum.fragment]: (
|
|
||||||
node: RTEDefaultNode,
|
|
||||||
embeds: EmbedByUid,
|
|
||||||
next: RTENext,
|
|
||||||
fullRenderOptions: RenderOptions
|
|
||||||
) => {
|
|
||||||
return <>{next(node.children, embeds, fullRenderOptions)}</>
|
|
||||||
},
|
|
||||||
|
|
||||||
[RTETypeEnum.tr]: (
|
|
||||||
node: RTEDefaultNode,
|
|
||||||
embeds: EmbedByUid,
|
|
||||||
next: RTENext,
|
|
||||||
fullRenderOptions: RenderOptions
|
|
||||||
) => {
|
|
||||||
const props = extractPossibleAttributes(node.attrs)
|
|
||||||
return (
|
|
||||||
<Table.TR key={node.uid} {...props}>
|
|
||||||
{next(node.children, embeds, fullRenderOptions)}
|
|
||||||
</Table.TR>
|
|
||||||
)
|
|
||||||
},
|
|
||||||
|
|
||||||
[RTETypeEnum.th]: (
|
|
||||||
node: RTEDefaultNode,
|
|
||||||
embeds: EmbedByUid,
|
|
||||||
next: RTENext,
|
|
||||||
fullRenderOptions: RenderOptions
|
|
||||||
) => {
|
|
||||||
const props = extractPossibleAttributes(node.attrs)
|
|
||||||
return (
|
|
||||||
<Table.TH key={node.uid} {...props}>
|
|
||||||
{next(node.children, embeds, fullRenderOptions)}
|
|
||||||
</Table.TH>
|
|
||||||
)
|
|
||||||
},
|
|
||||||
|
|
||||||
[RTETypeEnum.td]: (
|
|
||||||
node: RTEDefaultNode,
|
|
||||||
embeds: EmbedByUid,
|
|
||||||
next: RTENext,
|
|
||||||
fullRenderOptions: RenderOptions
|
|
||||||
) => {
|
|
||||||
const props = extractPossibleAttributes(node.attrs)
|
|
||||||
return (
|
|
||||||
<Table.TD key={node.uid} {...props}>
|
|
||||||
{next(node.children, embeds, fullRenderOptions)}
|
|
||||||
</Table.TD>
|
|
||||||
)
|
|
||||||
},
|
|
||||||
|
|
||||||
[RTETypeEnum.ul]: (
|
|
||||||
node: RTEDefaultNode,
|
|
||||||
embeds: EmbedByUid,
|
|
||||||
next: RTENext,
|
|
||||||
fullRenderOptions: RenderOptions
|
|
||||||
) => {
|
|
||||||
const props = extractPossibleAttributes(node.attrs)
|
|
||||||
|
|
||||||
// Set the number of rows dynamically to create even rows for each column. We want the li:s
|
|
||||||
// to flow with the column, so therefore this is needed.
|
|
||||||
let numberOfRows: number | undefined
|
|
||||||
if (node.children.length > 4) {
|
|
||||||
const half = node.children.length / 2
|
|
||||||
numberOfRows = Math.ceil(half)
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<ul
|
|
||||||
key={node.uid}
|
|
||||||
{...props}
|
|
||||||
className={styles.ul}
|
|
||||||
style={
|
|
||||||
numberOfRows
|
|
||||||
? {
|
|
||||||
gridTemplateRows: `repeat(${numberOfRows}, auto)`,
|
|
||||||
}
|
|
||||||
: {}
|
|
||||||
}
|
|
||||||
>
|
|
||||||
{next(node.children, embeds, fullRenderOptions)}
|
|
||||||
</ul>
|
|
||||||
)
|
|
||||||
},
|
|
||||||
|
|
||||||
/** TextNode wrappers */
|
|
||||||
[RTEMarkType.bold]: (children: React.ReactNode) => {
|
|
||||||
return <strong>{children}</strong>
|
|
||||||
},
|
|
||||||
|
|
||||||
[RTEMarkType.italic]: (children: React.ReactNode) => {
|
|
||||||
return <em>{children}</em>
|
|
||||||
},
|
|
||||||
|
|
||||||
[RTEMarkType.underline]: (children: React.ReactNode) => {
|
|
||||||
return <u>{children}</u>
|
|
||||||
},
|
|
||||||
|
|
||||||
[RTEMarkType.strikethrough]: (children: React.ReactNode) => {
|
|
||||||
return <s>{children}</s>
|
|
||||||
},
|
|
||||||
|
|
||||||
[RTEMarkType.inlineCode]: (children: React.ReactNode) => {
|
|
||||||
return <span>{children}</span>
|
|
||||||
},
|
|
||||||
|
|
||||||
[RTEMarkType.subscript]: (children: React.ReactNode) => {
|
|
||||||
return <sub>{children}</sub>
|
|
||||||
},
|
|
||||||
|
|
||||||
[RTEMarkType.superscript]: (children: React.ReactNode) => {
|
|
||||||
return <sup>{children}</sup>
|
|
||||||
},
|
|
||||||
|
|
||||||
[RTEMarkType.break]: (children: React.ReactNode) => {
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<br />
|
|
||||||
{children}
|
|
||||||
</>
|
|
||||||
)
|
|
||||||
},
|
|
||||||
|
|
||||||
[RTEMarkType.classnameOrId]: (
|
|
||||||
children: React.ReactNode,
|
|
||||||
className?: string,
|
|
||||||
id?: string
|
|
||||||
) => {
|
|
||||||
const props = {
|
|
||||||
className,
|
|
||||||
id,
|
|
||||||
}
|
|
||||||
if (!className) {
|
|
||||||
delete props.className
|
|
||||||
}
|
|
||||||
if (!id) {
|
|
||||||
delete props.id
|
|
||||||
}
|
|
||||||
|
|
||||||
if (className) {
|
|
||||||
if (hasAvailableULFormat(className)) {
|
|
||||||
props.className = styles[className]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (className === AvailableParagraphFormatEnum.footnote) {
|
|
||||||
return (
|
|
||||||
<Footnote key={id} {...props}>
|
|
||||||
{children}
|
|
||||||
</Footnote>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (className === AvailableParagraphFormatEnum.caption) {
|
|
||||||
return (
|
|
||||||
<Caption key={id} {...props}>
|
|
||||||
{children}
|
|
||||||
</Caption>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (className === AvailableParagraphFormatEnum["script-1"]) {
|
|
||||||
return (
|
|
||||||
<BiroScript key={id} type="one" {...props}>
|
|
||||||
{children}
|
|
||||||
</BiroScript>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (className === AvailableParagraphFormatEnum["script-2"]) {
|
|
||||||
return (
|
|
||||||
<BiroScript key={id} type="two" {...props}>
|
|
||||||
{children}
|
|
||||||
</BiroScript>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (className === AvailableParagraphFormatEnum["subtitle-1"]) {
|
|
||||||
return (
|
|
||||||
<Subtitle key={id} {...props} type="one">
|
|
||||||
{children}
|
|
||||||
</Subtitle>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
if (className === AvailableParagraphFormatEnum["subtitle-2"]) {
|
|
||||||
return (
|
|
||||||
<Subtitle key={id} {...props} type="two">
|
|
||||||
{children}
|
|
||||||
</Subtitle>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
return (
|
|
||||||
<span key={id} {...props}>
|
|
||||||
{children}
|
|
||||||
</span>
|
|
||||||
)
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Contentstack can return something called `default` as seen here in their
|
|
||||||
* own SDK (https://github.com/contentstack/contentstack-utils-javascript/blob/master/src/options/default-node-options.ts#L89)
|
|
||||||
*/
|
|
||||||
default: (
|
|
||||||
node: RTEDefaultNode,
|
|
||||||
embeds: EmbedByUid,
|
|
||||||
next: RTENext,
|
|
||||||
fullRenderOptions: RenderOptions
|
|
||||||
) => {
|
|
||||||
return next(node.children, embeds, fullRenderOptions)
|
|
||||||
},
|
|
||||||
}
|
|
||||||
@@ -1,150 +0,0 @@
|
|||||||
import { cloneElement } from "react"
|
|
||||||
|
|
||||||
import {
|
|
||||||
AvailableParagraphFormatEnum,
|
|
||||||
AvailableULFormatEnum,
|
|
||||||
RTETypeEnum,
|
|
||||||
} from "@scandic-hotels/trpc/types/RTEenums"
|
|
||||||
|
|
||||||
import { renderOptions } from "./renderOptions"
|
|
||||||
|
|
||||||
import type { Node } from "@scandic-hotels/trpc/types/edges"
|
|
||||||
|
|
||||||
import type { EmbedByUid } from "@/types/components/deprecatedjsontohtml"
|
|
||||||
import type { Embeds } from "@/types/requests/embeds"
|
|
||||||
import {
|
|
||||||
RTEMarkType,
|
|
||||||
type RTENode,
|
|
||||||
type RTERenderMark,
|
|
||||||
type RTERenderOptionComponent,
|
|
||||||
type RTETextNode,
|
|
||||||
} from "@/types/rte/node"
|
|
||||||
import type { RenderOptions } from "@/types/rte/option"
|
|
||||||
|
|
||||||
export function groupEmbedsByUid(embedsArray: Node<Embeds>[]) {
|
|
||||||
const embedsByUid = embedsArray.reduce<EmbedByUid>((acc, embed) => {
|
|
||||||
if (embed.node.system?.uid) {
|
|
||||||
acc[embed.node.system.uid] = embed
|
|
||||||
}
|
|
||||||
return acc
|
|
||||||
}, {})
|
|
||||||
|
|
||||||
return embedsByUid
|
|
||||||
}
|
|
||||||
|
|
||||||
export function nodeChildrenToHtml(
|
|
||||||
nodes: RTENode[],
|
|
||||||
embeds: EmbedByUid,
|
|
||||||
fullRenderOptions: RenderOptions
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
||||||
): any {
|
|
||||||
return nodes
|
|
||||||
.map((node, i) => {
|
|
||||||
// This function either returns a JSX element or null
|
|
||||||
const element = nodeToHtml(node, embeds, fullRenderOptions)
|
|
||||||
if (!element) {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
return cloneElement(element, {
|
|
||||||
key: `child-rte-${i}`,
|
|
||||||
})
|
|
||||||
})
|
|
||||||
.filter(Boolean)
|
|
||||||
}
|
|
||||||
|
|
||||||
export function textNodeToHtml(
|
|
||||||
node: RTETextNode,
|
|
||||||
fullRenderOptions: RenderOptions
|
|
||||||
) {
|
|
||||||
let text = <>{node.text}</>
|
|
||||||
|
|
||||||
if (node.classname || node.id) {
|
|
||||||
text = (fullRenderOptions[RTEMarkType.classnameOrId] as RTERenderMark)(
|
|
||||||
text,
|
|
||||||
node.classname,
|
|
||||||
node.id
|
|
||||||
)
|
|
||||||
}
|
|
||||||
if (node.break) {
|
|
||||||
text = (fullRenderOptions[RTEMarkType.break] as RTERenderMark)(text)
|
|
||||||
}
|
|
||||||
if (node.superscript) {
|
|
||||||
text = (fullRenderOptions[RTEMarkType.superscript] as RTERenderMark)(text)
|
|
||||||
}
|
|
||||||
if (node.subscript) {
|
|
||||||
text = (fullRenderOptions[RTEMarkType.subscript] as RTERenderMark)(text)
|
|
||||||
}
|
|
||||||
if (node.inlineCode) {
|
|
||||||
text = (fullRenderOptions[RTEMarkType.inlineCode] as RTERenderMark)(text)
|
|
||||||
}
|
|
||||||
if (node.strikethrough) {
|
|
||||||
text = (fullRenderOptions[RTEMarkType.strikethrough] as RTERenderMark)(text)
|
|
||||||
}
|
|
||||||
if (node.underline) {
|
|
||||||
text = (fullRenderOptions[RTEMarkType.underline] as RTERenderMark)(text)
|
|
||||||
}
|
|
||||||
if (node.italic) {
|
|
||||||
text = (fullRenderOptions[RTEMarkType.italic] as RTERenderMark)(text)
|
|
||||||
}
|
|
||||||
if (node.bold) {
|
|
||||||
text = (fullRenderOptions[RTEMarkType.bold] as RTERenderMark)(text)
|
|
||||||
}
|
|
||||||
return text
|
|
||||||
}
|
|
||||||
|
|
||||||
function next(
|
|
||||||
nodes: RTENode[],
|
|
||||||
embeds: EmbedByUid,
|
|
||||||
fullRenderOptions: RenderOptions
|
|
||||||
) {
|
|
||||||
return nodeChildrenToHtml(nodes, embeds, fullRenderOptions)
|
|
||||||
}
|
|
||||||
|
|
||||||
export function hasAvailableParagraphFormat(className?: string) {
|
|
||||||
if (!className) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return Object.keys(AvailableParagraphFormatEnum).includes(className)
|
|
||||||
}
|
|
||||||
|
|
||||||
export function hasAvailableULFormat(className?: string) {
|
|
||||||
if (!className) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return Object.keys(AvailableULFormatEnum).includes(className)
|
|
||||||
}
|
|
||||||
|
|
||||||
export function nodeToHtml(
|
|
||||||
node: RTENode,
|
|
||||||
embeds: EmbedByUid,
|
|
||||||
fullRenderOptions: RenderOptions
|
|
||||||
) {
|
|
||||||
if ("type" in node === false) {
|
|
||||||
return textNodeToHtml(node, fullRenderOptions)
|
|
||||||
} else {
|
|
||||||
if (fullRenderOptions[node.type] !== undefined) {
|
|
||||||
if (node.type === RTETypeEnum.doc) {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
return (fullRenderOptions[node.type] as RTERenderOptionComponent)(
|
|
||||||
node,
|
|
||||||
embeds,
|
|
||||||
next,
|
|
||||||
fullRenderOptions
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
return next(node.children, embeds, fullRenderOptions)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function nodesToHtml(
|
|
||||||
nodes: RTENode[],
|
|
||||||
embedsArray: Node<Embeds>[],
|
|
||||||
overrideRenderOptions: RenderOptions
|
|
||||||
) {
|
|
||||||
const embeds = groupEmbedsByUid(embedsArray)
|
|
||||||
const fullRenderOptions = { ...renderOptions, ...overrideRenderOptions }
|
|
||||||
return nodes.map((node) => nodeToHtml(node, embeds, fullRenderOptions))
|
|
||||||
}
|
|
||||||
@@ -1,83 +0,0 @@
|
|||||||
"use client"
|
|
||||||
|
|
||||||
import { useEffect, useState } from "react"
|
|
||||||
|
|
||||||
import { clearPaymentInfoSessionStorage } from "@scandic-hotels/booking-flow/components/EnterDetails/Payment/helpers"
|
|
||||||
import { useSearchHistory } from "@scandic-hotels/booking-flow/hooks/useSearchHistory"
|
|
||||||
import { useBookingConfirmationStore } from "@scandic-hotels/booking-flow/stores/booking-confirmation"
|
|
||||||
import { TrackingSDK } from "@scandic-hotels/tracking/TrackingSDK"
|
|
||||||
|
|
||||||
import useLang from "@/hooks/useLang"
|
|
||||||
|
|
||||||
import { getTracking } from "./tracking"
|
|
||||||
|
|
||||||
import type { Room } from "@scandic-hotels/booking-flow/types/stores/booking-confirmation"
|
|
||||||
import type { BookingConfirmation } from "@scandic-hotels/trpc/types/bookingConfirmation"
|
|
||||||
|
|
||||||
export default function Tracking({
|
|
||||||
bookingConfirmation,
|
|
||||||
refId,
|
|
||||||
}: {
|
|
||||||
bookingConfirmation: BookingConfirmation
|
|
||||||
refId: string
|
|
||||||
}) {
|
|
||||||
const lang = useLang()
|
|
||||||
const bookingRooms = useBookingConfirmationStore((state) => state.rooms)
|
|
||||||
|
|
||||||
const [loadedBookingConfirmationRefId] = useState(() => {
|
|
||||||
if (typeof window !== "undefined") {
|
|
||||||
return sessionStorage.getItem("loadedBookingConfirmationRefId")
|
|
||||||
}
|
|
||||||
return null
|
|
||||||
})
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
sessionStorage.setItem("loadedBookingConfirmationRefId", refId)
|
|
||||||
}, [refId])
|
|
||||||
|
|
||||||
const searchHistory = useSearchHistory()
|
|
||||||
const searchTerm = searchHistory.searchHistory[0]?.name
|
|
||||||
|
|
||||||
let trackingData = null
|
|
||||||
|
|
||||||
if (bookingRooms.every(Boolean)) {
|
|
||||||
const rooms = bookingRooms.filter((room): room is Room => !!room)
|
|
||||||
trackingData = getTracking(
|
|
||||||
lang,
|
|
||||||
bookingConfirmation.booking,
|
|
||||||
bookingConfirmation.hotel,
|
|
||||||
rooms,
|
|
||||||
searchTerm
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (trackingData?.paymentInfo) {
|
|
||||||
clearPaymentInfoSessionStorage()
|
|
||||||
}
|
|
||||||
}, [trackingData])
|
|
||||||
|
|
||||||
if (!trackingData) {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
const { hotelsTrackingData, pageTrackingData, paymentInfo, ancillaries } =
|
|
||||||
trackingData
|
|
||||||
|
|
||||||
return (
|
|
||||||
<TrackingSDK
|
|
||||||
pageData={pageTrackingData}
|
|
||||||
hotelInfo={
|
|
||||||
loadedBookingConfirmationRefId === refId
|
|
||||||
? undefined
|
|
||||||
: hotelsTrackingData
|
|
||||||
}
|
|
||||||
paymentInfo={
|
|
||||||
loadedBookingConfirmationRefId === refId ? undefined : paymentInfo
|
|
||||||
}
|
|
||||||
ancillaries={
|
|
||||||
loadedBookingConfirmationRefId === refId ? undefined : ancillaries
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,213 +0,0 @@
|
|||||||
import { createHash } from "crypto"
|
|
||||||
import { differenceInCalendarDays, format, isWeekend } from "date-fns"
|
|
||||||
|
|
||||||
import { readPaymentInfoFromSessionStorage } from "@scandic-hotels/booking-flow/components/EnterDetails/Payment/helpers"
|
|
||||||
import { invertedBedTypeMap } from "@scandic-hotels/booking-flow/utils/SelectRate"
|
|
||||||
import { getSpecialRoomType } from "@scandic-hotels/booking-flow/utils/specialRoomType"
|
|
||||||
import { CancellationRuleEnum } from "@scandic-hotels/common/constants/booking"
|
|
||||||
import { CurrencyEnum } from "@scandic-hotels/common/constants/currency"
|
|
||||||
import { RateEnum } from "@scandic-hotels/common/constants/rate"
|
|
||||||
import {
|
|
||||||
TrackingChannelEnum,
|
|
||||||
type TrackingSDKAncillaries,
|
|
||||||
type TrackingSDKHotelInfo,
|
|
||||||
type TrackingSDKPageData,
|
|
||||||
type TrackingSDKPaymentInfo,
|
|
||||||
} from "@scandic-hotels/tracking/types"
|
|
||||||
import { BreakfastPackageEnum } from "@scandic-hotels/trpc/enums/breakfast"
|
|
||||||
import { RoomPackageCodeEnum } from "@scandic-hotels/trpc/enums/roomFilter"
|
|
||||||
|
|
||||||
import type { Room } from "@scandic-hotels/booking-flow/types/stores/booking-confirmation"
|
|
||||||
import type { Lang } from "@scandic-hotels/common/constants/language"
|
|
||||||
import type { BookingConfirmation } from "@scandic-hotels/trpc/types/bookingConfirmation"
|
|
||||||
import type { RateDefinition } from "@scandic-hotels/trpc/types/roomAvailability"
|
|
||||||
|
|
||||||
function getRate(cancellationRule: RateDefinition["cancellationRule"] | null) {
|
|
||||||
switch (cancellationRule) {
|
|
||||||
case "CancellableBefore6PM":
|
|
||||||
return RateEnum.flex
|
|
||||||
case "Changeable":
|
|
||||||
return RateEnum.change
|
|
||||||
case "NotCancellable":
|
|
||||||
return RateEnum.save
|
|
||||||
default:
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function mapAncillaryPackage(
|
|
||||||
ancillaryPackage: BookingConfirmation["booking"]["packages"][number],
|
|
||||||
operaId: string
|
|
||||||
) {
|
|
||||||
const isPoints = ancillaryPackage.currency === CurrencyEnum.POINTS
|
|
||||||
return {
|
|
||||||
hotelid: operaId,
|
|
||||||
productCategory: "", // TODO: Add category
|
|
||||||
productId: ancillaryPackage.code,
|
|
||||||
productName: ancillaryPackage.description,
|
|
||||||
productPoints: isPoints ? ancillaryPackage.totalPrice : 0,
|
|
||||||
productPrice: isPoints ? 0 : ancillaryPackage.totalPrice,
|
|
||||||
productType:
|
|
||||||
ancillaryPackage.code === BreakfastPackageEnum.REGULAR_BREAKFAST
|
|
||||||
? "food"
|
|
||||||
: "room preference",
|
|
||||||
productUnits: ancillaryPackage.totalUnit,
|
|
||||||
productDeliveryTime: "",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getTracking(
|
|
||||||
lang: Lang,
|
|
||||||
booking: BookingConfirmation["booking"],
|
|
||||||
hotel: BookingConfirmation["hotel"],
|
|
||||||
rooms: Room[],
|
|
||||||
searchTerm?: string
|
|
||||||
) {
|
|
||||||
const arrivalDate = new Date(booking.checkInDate)
|
|
||||||
const departureDate = new Date(booking.checkOutDate)
|
|
||||||
const paymentInfoSessionData = readPaymentInfoFromSessionStorage()
|
|
||||||
|
|
||||||
const pageTrackingData: TrackingSDKPageData = {
|
|
||||||
channel: TrackingChannelEnum.hotelreservation,
|
|
||||||
domainLanguage: lang,
|
|
||||||
pageId: "booking-confirmation",
|
|
||||||
pageName: `hotelreservation|confirmation`,
|
|
||||||
pageType: "confirmation",
|
|
||||||
siteSections: `hotelreservation|confirmation`,
|
|
||||||
siteVersion: "new-web",
|
|
||||||
}
|
|
||||||
|
|
||||||
const noOfAdults = rooms.map((r) => r.adults).join(",")
|
|
||||||
const noOfChildren = rooms.map((r) => r.childrenAges?.length ?? 0).join(",")
|
|
||||||
const noOfRooms = rooms.length
|
|
||||||
const isFlexBooking =
|
|
||||||
booking.rateDefinition.cancellationRule ===
|
|
||||||
CancellationRuleEnum.CancellableBefore6PM
|
|
||||||
const isGuaranteedFlexBooking = booking.guaranteeInfo && isFlexBooking
|
|
||||||
|
|
||||||
const ancillaries: TrackingSDKAncillaries = rooms
|
|
||||||
.flatMap((r) => r.packages)
|
|
||||||
.filter(
|
|
||||||
(p) =>
|
|
||||||
p.code === RoomPackageCodeEnum.PET_ROOM ||
|
|
||||||
p.code === BreakfastPackageEnum.REGULAR_BREAKFAST
|
|
||||||
)
|
|
||||||
.map((pkg) => mapAncillaryPackage(pkg, hotel.operaId))
|
|
||||||
|
|
||||||
const hotelsTrackingData: TrackingSDKHotelInfo = {
|
|
||||||
ageOfChildren: rooms.map((r) => r.childrenAges?.join(",") ?? "").join("|"),
|
|
||||||
analyticsRateCode: rooms
|
|
||||||
.map((r) => getRate(r.rateDefinition.cancellationRule))
|
|
||||||
.join("|"),
|
|
||||||
arrivalDate: format(arrivalDate, "yyyy-MM-dd"),
|
|
||||||
bedType: rooms
|
|
||||||
.map((r) => r.bedType)
|
|
||||||
.join(",")
|
|
||||||
.toLowerCase(),
|
|
||||||
bnr: rooms.map((r) => r.confirmationNumber).join(","),
|
|
||||||
bookingCode: rooms.map((room) => room.bookingCode ?? "n/a").join(", "),
|
|
||||||
bookingCodeAvailability: booking.bookingCode
|
|
||||||
? rooms.map((room) => (room.bookingCode ? "true" : "false")).join(", ")
|
|
||||||
: undefined,
|
|
||||||
bookingTypeofDay: isWeekend(arrivalDate) ? "weekend" : "weekday",
|
|
||||||
breakfastOption: rooms
|
|
||||||
.map((r) => {
|
|
||||||
if (r.breakfastIncluded || r.breakfast) {
|
|
||||||
return "breakfast buffet"
|
|
||||||
}
|
|
||||||
return "no breakfast"
|
|
||||||
})
|
|
||||||
.join(","),
|
|
||||||
childBedPreference: rooms
|
|
||||||
.map(
|
|
||||||
(r) =>
|
|
||||||
r.childBedPreferences
|
|
||||||
.map((cbp) =>
|
|
||||||
Array(cbp.quantity).fill(invertedBedTypeMap[cbp.bedType])
|
|
||||||
)
|
|
||||||
.join(",") ?? ""
|
|
||||||
)
|
|
||||||
.join("|"),
|
|
||||||
country: hotel?.address.country,
|
|
||||||
departureDate: format(departureDate, "yyyy-MM-dd"),
|
|
||||||
duration: differenceInCalendarDays(departureDate, arrivalDate),
|
|
||||||
hotelID: hotel.operaId,
|
|
||||||
leadTime: differenceInCalendarDays(arrivalDate, new Date()),
|
|
||||||
noOfAdults,
|
|
||||||
noOfChildren,
|
|
||||||
noOfRooms,
|
|
||||||
rateCode: rooms.map((r) => r.rateDefinition.rateCode).join(","),
|
|
||||||
rateCodeCancellationRule: rooms
|
|
||||||
.map((r) => r.rateDefinition.cancellationRule)
|
|
||||||
.join(",")
|
|
||||||
.toLowerCase(),
|
|
||||||
rateCodeName: rooms.map(constructRateCodeName).join(","),
|
|
||||||
rateCodeType: rooms.map((r) => r.rateCodeType?.toLowerCase()).join(","),
|
|
||||||
region: hotel?.address.city,
|
|
||||||
revenueCurrencyCode: [...new Set(rooms.map((r) => r.currencyCode))].join(
|
|
||||||
","
|
|
||||||
),
|
|
||||||
rewardNight: booking.roomPoints > 0 ? "yes" : "no",
|
|
||||||
rewardNightAvailability: booking.roomPoints > 0 ? "true" : "false",
|
|
||||||
points: booking.roomPoints > 0 ? booking.roomPoints : undefined,
|
|
||||||
roomPrice: rooms.reduce((total, room) => total + room.roomPrice, 0),
|
|
||||||
roomTypeCode: rooms.map((r) => r.roomTypeCode ?? "").join(","),
|
|
||||||
searchTerm,
|
|
||||||
searchType: "hotel",
|
|
||||||
specialRoomType: rooms
|
|
||||||
.map((room) => getSpecialRoomType(room.packages))
|
|
||||||
.join(","),
|
|
||||||
totalPrice: rooms.reduce((total, room) => total + room.totalPrice, 0),
|
|
||||||
lateArrivalGuarantee: booking.rateDefinition.mustBeGuaranteed
|
|
||||||
? "mandatory"
|
|
||||||
: isFlexBooking
|
|
||||||
? booking.guaranteeInfo
|
|
||||||
? "yes"
|
|
||||||
: "no"
|
|
||||||
: "na",
|
|
||||||
guaranteedProduct: isGuaranteedFlexBooking ? "room" : "na",
|
|
||||||
emailId: getSHAHash(booking.guest.email),
|
|
||||||
mobileNumber: getSHAHash(booking.guest.phoneNumber),
|
|
||||||
}
|
|
||||||
|
|
||||||
const paymentInfo: TrackingSDKPaymentInfo = {
|
|
||||||
paymentStatus: isGuaranteedFlexBooking
|
|
||||||
? "glacardsaveconfirmed"
|
|
||||||
: "confirmed",
|
|
||||||
type:
|
|
||||||
booking.guaranteeInfo?.cardType ?? paymentInfoSessionData?.paymentMethod,
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
hotelsTrackingData,
|
|
||||||
pageTrackingData,
|
|
||||||
paymentInfo,
|
|
||||||
ancillaries,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function constructRateCodeName(room: Room) {
|
|
||||||
if (room.cheques) {
|
|
||||||
return "corporate cheque"
|
|
||||||
} else if (room.vouchers) {
|
|
||||||
return "voucher"
|
|
||||||
} else if (room.roomPoints) {
|
|
||||||
return "redemption"
|
|
||||||
}
|
|
||||||
|
|
||||||
const rate = getRate(room.rateDefinition.cancellationRule)
|
|
||||||
|
|
||||||
const bookingCodeStr = room.bookingCode ? room.bookingCode.toUpperCase() : ""
|
|
||||||
|
|
||||||
const breakfastIncludedStr = room.breakfastIncluded
|
|
||||||
? "incl. breakfast"
|
|
||||||
: "excl. breakfast"
|
|
||||||
|
|
||||||
return [bookingCodeStr, rate, breakfastIncludedStr]
|
|
||||||
.filter(Boolean)
|
|
||||||
.join(" - ")
|
|
||||||
}
|
|
||||||
|
|
||||||
function getSHAHash(key: string) {
|
|
||||||
return createHash("sha256").update(key).digest("hex")
|
|
||||||
}
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
import { BreakfastPackageEnum } from "@scandic-hotels/trpc/enums/breakfast"
|
import { BreakfastPackageEnum } from "@scandic-hotels/trpc/enums/breakfast"
|
||||||
|
|
||||||
export function hasBreakfastPackageFromBookingFlow(
|
function hasBreakfastPackageFromBookingFlow(
|
||||||
packages: {
|
packages: {
|
||||||
code: string
|
code: string
|
||||||
}[]
|
}[]
|
||||||
@@ -13,26 +13,6 @@ export function hasBreakfastPackageFromBookingFlow(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getBreakfastPackagesFromBookingFlow<T extends { code: string }>(
|
|
||||||
packages: T[]
|
|
||||||
): T[] | undefined {
|
|
||||||
// Since `FREE_CHILD_BREAKFAST` has the same code when breakfast is added
|
|
||||||
// in the booking flow and as ancillary we can't just do a simple filter on the codes.
|
|
||||||
// So we shortcircuit if there are no booking flow specific packages.
|
|
||||||
if (!packages || !hasBreakfastPackageFromBookingFlow(packages)) {
|
|
||||||
return undefined
|
|
||||||
}
|
|
||||||
|
|
||||||
return packages.filter(
|
|
||||||
(p) =>
|
|
||||||
p.code === BreakfastPackageEnum.REGULAR_BREAKFAST ||
|
|
||||||
p.code === BreakfastPackageEnum.FREE_MEMBER_BREAKFAST ||
|
|
||||||
p.code === BreakfastPackageEnum.CHILD_PAYING_BREAKFAST ||
|
|
||||||
p.code === BreakfastPackageEnum.FREE_CHILD_BREAKFAST ||
|
|
||||||
p.code === BreakfastPackageEnum.SPECIAL_PACKAGE_BREAKFAST
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getBreakfastPackagesFromAncillaryFlow<
|
export function getBreakfastPackagesFromAncillaryFlow<
|
||||||
T extends { code: string },
|
T extends { code: string },
|
||||||
>(packages: T[]): T[] | undefined {
|
>(packages: T[]): T[] | undefined {
|
||||||
|
|||||||
@@ -1,27 +0,0 @@
|
|||||||
.avatar {
|
|
||||||
display: inline-flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
vertical-align: middle;
|
|
||||||
overflow: hidden;
|
|
||||||
cursor: pointer;
|
|
||||||
width: 35px;
|
|
||||||
height: 35px;
|
|
||||||
border-radius: 100%;
|
|
||||||
background-color: rgba(0, 0, 0, 0.05);
|
|
||||||
}
|
|
||||||
|
|
||||||
.avatarInitialsText {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
background-color: var(--Primary-Dark-Surface-Normal);
|
|
||||||
color: var(--Primary-Dark-On-Surface-Text);
|
|
||||||
font-size: var(--typography-Caption-Bold-fontSize);
|
|
||||||
font-family: var(--typography-Body-Regular-fontFamily);
|
|
||||||
font-weight: var(--typography-Caption-Bold-fontWeight);
|
|
||||||
line-height: 150%;
|
|
||||||
letter-spacing: 0.096px;
|
|
||||||
}
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
import { getInitials } from "@/utils/user"
|
|
||||||
|
|
||||||
import styles from "./avatar.module.css"
|
|
||||||
|
|
||||||
import type { User } from "@scandic-hotels/trpc/types/user"
|
|
||||||
|
|
||||||
export default function Avatar({
|
|
||||||
firstName,
|
|
||||||
lastName,
|
|
||||||
}: {
|
|
||||||
firstName: User["firstName"]
|
|
||||||
lastName: User["lastName"]
|
|
||||||
}) {
|
|
||||||
const initials = getInitials(firstName, lastName)
|
|
||||||
return (
|
|
||||||
<span className={styles.avatar}>
|
|
||||||
<span data-hj-suppress className={styles.avatarInitialsText}>
|
|
||||||
{initials}
|
|
||||||
</span>
|
|
||||||
</span>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -10,7 +10,7 @@ import styles from "./progressSection.module.css"
|
|||||||
|
|
||||||
import type { ProgressCalculation } from "../../types"
|
import type { ProgressCalculation } from "../../types"
|
||||||
|
|
||||||
export interface ProgressSectionProps {
|
interface ProgressSectionProps {
|
||||||
earned: number
|
earned: number
|
||||||
progress: ProgressCalculation
|
progress: ProgressCalculation
|
||||||
toKeepCurrent?: number
|
toKeepCurrent?: number
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { getIntl } from "@/i18n"
|
|||||||
|
|
||||||
import styles from "./successCard.module.css"
|
import styles from "./successCard.module.css"
|
||||||
|
|
||||||
export interface SuccessCardProps {
|
interface SuccessCardProps {
|
||||||
pointsEarned?: number | null
|
pointsEarned?: number | null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import SectionLink from "../Link"
|
|||||||
|
|
||||||
import styles from "./header.module.css"
|
import styles from "./header.module.css"
|
||||||
|
|
||||||
export type HeaderProps = {
|
type HeaderProps = {
|
||||||
link?: {
|
link?: {
|
||||||
href: string
|
href: string
|
||||||
text: string
|
text: string
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ type PartialHotelRoom = Pick<
|
|||||||
"descriptions" | "images" | "name" | "roomFacilities" | "roomTypes"
|
"descriptions" | "images" | "name" | "roomFacilities" | "roomTypes"
|
||||||
>
|
>
|
||||||
|
|
||||||
export type Room = Pick<
|
type Room = Pick<
|
||||||
BookingConfirmationSchema,
|
BookingConfirmationSchema,
|
||||||
| "adults"
|
| "adults"
|
||||||
| "bookingCode"
|
| "bookingCode"
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ import { debounce } from "@scandic-hotels/common/utils/debounce"
|
|||||||
import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon"
|
import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon"
|
||||||
import { Typography } from "@scandic-hotels/design-system/Typography"
|
import { Typography } from "@scandic-hotels/design-system/Typography"
|
||||||
|
|
||||||
import { Arrow } from "../Popover/Arrow"
|
import { Arrow } from "./Arrow"
|
||||||
import { Breadcrumb } from "./Breadcrumb"
|
import { Breadcrumb } from "./Breadcrumb"
|
||||||
import { splitBreadcrumbs } from "./utils"
|
import { splitBreadcrumbs } from "./utils"
|
||||||
import { breadcrumbsVariants } from "./variants"
|
import { breadcrumbsVariants } from "./variants"
|
||||||
|
|||||||
@@ -4,11 +4,11 @@ import type { TypenameInterface } from "@/types/requests/utils/typename"
|
|||||||
|
|
||||||
export type Order = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
|
export type Order = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
|
||||||
|
|
||||||
export type ColSpan = 2 | 3 | 4 | 6 | 8
|
type ColSpan = 2 | 3 | 4 | 6 | 8
|
||||||
export type RowSpan = 1 | 2 | 3 | 6
|
export type RowSpan = 1 | 2 | 3 | 6
|
||||||
|
|
||||||
// TODO: Extend query and fix type accordingly
|
// TODO: Extend query and fix type accordingly
|
||||||
export interface Row extends TypenameInterface<"Card"> {
|
interface Row extends TypenameInterface<"Card"> {
|
||||||
title: string
|
title: string
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -19,7 +19,7 @@ type Column = {
|
|||||||
}[]
|
}[]
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Grid {
|
interface Grid {
|
||||||
columns: Column[]
|
columns: Column[]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,51 +0,0 @@
|
|||||||
import {
|
|
||||||
Button,
|
|
||||||
Dialog,
|
|
||||||
DialogTrigger,
|
|
||||||
OverlayArrow,
|
|
||||||
Popover as RAPopover,
|
|
||||||
} from "react-aria-components"
|
|
||||||
|
|
||||||
import useSetOverFlowVisibleOnRA from "@scandic-hotels/common/hooks/useSetOverflowVisibleOnRA"
|
|
||||||
import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon"
|
|
||||||
|
|
||||||
import { Arrow } from "./Arrow"
|
|
||||||
|
|
||||||
import styles from "./popover.module.css"
|
|
||||||
|
|
||||||
import type { PopoverProps } from "./popover"
|
|
||||||
|
|
||||||
export default function Popover({
|
|
||||||
triggerContent,
|
|
||||||
children,
|
|
||||||
...props
|
|
||||||
}: PopoverProps) {
|
|
||||||
const setOverflowVisible = useSetOverFlowVisibleOnRA()
|
|
||||||
|
|
||||||
return (
|
|
||||||
<DialogTrigger onOpenChange={setOverflowVisible}>
|
|
||||||
<Button className={styles.trigger}>{triggerContent}</Button>
|
|
||||||
|
|
||||||
<RAPopover
|
|
||||||
{...props}
|
|
||||||
offset={16}
|
|
||||||
crossOffset={-24}
|
|
||||||
className={styles.root}
|
|
||||||
>
|
|
||||||
<OverlayArrow>
|
|
||||||
<Arrow />
|
|
||||||
</OverlayArrow>
|
|
||||||
<Dialog>
|
|
||||||
{({ close }) => (
|
|
||||||
<>
|
|
||||||
<Button className={styles.closeButton} onPress={close}>
|
|
||||||
<MaterialIcon icon="close" size={20} />
|
|
||||||
</Button>
|
|
||||||
{children}
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</Dialog>
|
|
||||||
</RAPopover>
|
|
||||||
</DialogTrigger>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
.root {
|
|
||||||
background-color: var(--Base-Surface-Primary-light-Normal);
|
|
||||||
border-radius: var(--Corner-radius-md);
|
|
||||||
box-shadow: var(--popup-box-shadow);
|
|
||||||
padding: var(--Spacing-x2);
|
|
||||||
max-width: calc(360px + var(--Spacing-x2) * 2);
|
|
||||||
overflow-y: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.root section:focus-visible {
|
|
||||||
outline: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.trigger {
|
|
||||||
background: none;
|
|
||||||
border: none;
|
|
||||||
padding: 0;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
.closeButton {
|
|
||||||
position: absolute;
|
|
||||||
top: 8px;
|
|
||||||
right: 8px;
|
|
||||||
background: none;
|
|
||||||
border: none;
|
|
||||||
cursor: pointer;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
import type { PopoverProps as RAPopoverProps } from "react-aria-components"
|
|
||||||
|
|
||||||
export interface PopoverProps extends Omit<RAPopoverProps, "children"> {
|
|
||||||
triggerContent: React.ReactNode
|
|
||||||
children: React.ReactNode
|
|
||||||
}
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
import styles from "./progressbar.module.css"
|
|
||||||
|
|
||||||
import type { ProgressbarProps } from "./progressbar"
|
|
||||||
|
|
||||||
export default function ProgressBar({ className, progress }: ProgressbarProps) {
|
|
||||||
className = className ?? ""
|
|
||||||
return (
|
|
||||||
<div className={`${className} ${styles.bar}`}>
|
|
||||||
<div className={styles.progress} style={{ width: `${progress}%` }} />
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
.bar {
|
|
||||||
background-color: var(--Main-Grey-White);
|
|
||||||
border-radius: 40px;
|
|
||||||
height: 20px;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.progress {
|
|
||||||
background-color: var(--UI-Opacity-Almost-Black-100);
|
|
||||||
border-radius: 40px;
|
|
||||||
height: 20px;
|
|
||||||
}
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
export interface ProgressbarProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
||||||
progress: number
|
|
||||||
}
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
export const homeHrefs = {
|
|
||||||
development: {
|
|
||||||
da: "https://stage.scandichotels.dk",
|
|
||||||
de: "https://stage.scandichotels.de",
|
|
||||||
en: "https://stage.scandichotels.com",
|
|
||||||
fi: "https://stage.scandichotels.fi",
|
|
||||||
no: "https://stage.scandichotels.no",
|
|
||||||
sv: "https://stage.scandichotels.se",
|
|
||||||
},
|
|
||||||
production: {
|
|
||||||
da: "https://www.scandichotels.dk",
|
|
||||||
de: "https://www.scandichotels.de",
|
|
||||||
en: "https://www.scandichotels.com",
|
|
||||||
fi: "https://www.scandichotels.fi",
|
|
||||||
no: "https://www.scandichotels.no",
|
|
||||||
sv: "https://www.scandichotels.se",
|
|
||||||
},
|
|
||||||
test: {
|
|
||||||
da: "https://test.scandichotels.dk",
|
|
||||||
de: "https://test.scandichotels.de",
|
|
||||||
en: "https://test.scandichotels.com",
|
|
||||||
fi: "https://test.scandichotels.fi",
|
|
||||||
no: "https://test.scandichotels.no",
|
|
||||||
sv: "https://test.scandichotels.se",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
@@ -10,47 +10,7 @@ export const languages: Record<Lang, string> = {
|
|||||||
[Lang.sv]: "Svenska",
|
[Lang.sv]: "Svenska",
|
||||||
}
|
}
|
||||||
|
|
||||||
export const localeToLang: Record<string, Lang> = {
|
const languageSelect = [
|
||||||
en: Lang.en,
|
|
||||||
"en-US": Lang.en,
|
|
||||||
"en-GB": Lang.en,
|
|
||||||
"en-DE": Lang.en,
|
|
||||||
"en-DK": Lang.en,
|
|
||||||
"en-SE": Lang.en,
|
|
||||||
"en-FI": Lang.en,
|
|
||||||
|
|
||||||
sv: Lang.sv,
|
|
||||||
"se-SE": Lang.sv,
|
|
||||||
"sv-SE": Lang.sv,
|
|
||||||
"sv-FI": Lang.sv,
|
|
||||||
|
|
||||||
fi: Lang.fi,
|
|
||||||
"fi-FI": Lang.fi,
|
|
||||||
"se-FI": Lang.fi,
|
|
||||||
"smn-FI": Lang.fi,
|
|
||||||
|
|
||||||
dk: Lang.da,
|
|
||||||
da: Lang.da,
|
|
||||||
"da-DK": Lang.da,
|
|
||||||
"fo-DK": Lang.da,
|
|
||||||
|
|
||||||
de: Lang.de,
|
|
||||||
"de-DE": Lang.de,
|
|
||||||
"dsb-DE": Lang.de,
|
|
||||||
"ksh-DE": Lang.de,
|
|
||||||
"nds-DE": Lang.de,
|
|
||||||
"hsb-DE": Lang.de,
|
|
||||||
"de-CH": Lang.de,
|
|
||||||
"de-AU": Lang.de,
|
|
||||||
|
|
||||||
no: Lang.no,
|
|
||||||
nb: Lang.no,
|
|
||||||
"nb-NO": Lang.no,
|
|
||||||
"nn-NO": Lang.no,
|
|
||||||
"se-NO": Lang.no,
|
|
||||||
} as const
|
|
||||||
|
|
||||||
export const languageSelect = [
|
|
||||||
{ label: "Danish", value: ApiLang.Da },
|
{ label: "Danish", value: ApiLang.Da },
|
||||||
{ label: "German", value: ApiLang.De },
|
{ label: "German", value: ApiLang.De },
|
||||||
{ label: "English", value: ApiLang.En },
|
{ label: "English", value: ApiLang.En },
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ export const benefits = {
|
|||||||
sv: `${myPages.sv}/formaner`,
|
sv: `${myPages.sv}/formaner`,
|
||||||
}
|
}
|
||||||
|
|
||||||
export const points = {
|
const points = {
|
||||||
da: `${myPages.da}/point`,
|
da: `${myPages.da}/point`,
|
||||||
de: `${myPages.de}/punkte`,
|
de: `${myPages.de}/punkte`,
|
||||||
en: `${myPages.en}/points`,
|
en: `${myPages.en}/points`,
|
||||||
@@ -34,7 +34,7 @@ export const points = {
|
|||||||
sv: `${myPages.sv}/poang`,
|
sv: `${myPages.sv}/poang`,
|
||||||
}
|
}
|
||||||
|
|
||||||
export const programOverview = {
|
const programOverview = {
|
||||||
da: `/da/webview/scandic-friends`,
|
da: `/da/webview/scandic-friends`,
|
||||||
de: `/de/webview/scandic-friends`,
|
de: `/de/webview/scandic-friends`,
|
||||||
en: `/en/webview/scandic-friends`,
|
en: `/en/webview/scandic-friends`,
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
import { redirect } from "next/navigation"
|
|
||||||
|
|
||||||
import { cache } from "@/utils/cache"
|
import { cache } from "@/utils/cache"
|
||||||
|
|
||||||
import { serverClient } from "../server"
|
import { serverClient } from "../server"
|
||||||
@@ -7,7 +5,6 @@ import { serverClient } from "../server"
|
|||||||
import type { Lang } from "@scandic-hotels/common/constants/language"
|
import type { Lang } from "@scandic-hotels/common/constants/language"
|
||||||
import type { GetHotelsByCSFilterInput } from "@scandic-hotels/trpc/routers/hotels/input"
|
import type { GetHotelsByCSFilterInput } from "@scandic-hotels/trpc/routers/hotels/input"
|
||||||
import type { GetSavedPaymentCardsInput } from "@scandic-hotels/trpc/routers/user/input"
|
import type { GetSavedPaymentCardsInput } from "@scandic-hotels/trpc/routers/user/input"
|
||||||
import type { RoomsAvailabilityExtendedInputSchema } from "@scandic-hotels/trpc/types/availability"
|
|
||||||
import type { Country } from "@scandic-hotels/trpc/types/country"
|
import type { Country } from "@scandic-hotels/trpc/types/country"
|
||||||
import type { HotelInput } from "@scandic-hotels/trpc/types/hotel"
|
import type { HotelInput } from "@scandic-hotels/trpc/types/hotel"
|
||||||
import type {
|
import type {
|
||||||
@@ -96,13 +93,6 @@ export const getHeader = cache(async function getMemoizedHeader() {
|
|||||||
return caller.contentstack.base.header()
|
return caller.contentstack.base.header()
|
||||||
})
|
})
|
||||||
|
|
||||||
export const getSiteConfig = cache(async function getMemoizedSiteConfig(
|
|
||||||
lang: Lang
|
|
||||||
) {
|
|
||||||
const caller = await serverClient()
|
|
||||||
return caller.contentstack.base.siteConfig({ lang })
|
|
||||||
})
|
|
||||||
|
|
||||||
export const getAncillaryPackages = cache(
|
export const getAncillaryPackages = cache(
|
||||||
async function getMemoizedAncillaryPackages(input: AncillaryPackagesInput) {
|
async function getMemoizedAncillaryPackages(input: AncillaryPackagesInput) {
|
||||||
const caller = await serverClient()
|
const caller = await serverClient()
|
||||||
@@ -165,16 +155,6 @@ export const getMeetingRooms = cache(
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
export const getAdditionalData = cache(
|
|
||||||
async function getMemoizedAdditionalData(input: {
|
|
||||||
hotelId: string
|
|
||||||
language: Lang
|
|
||||||
}) {
|
|
||||||
const caller = await serverClient()
|
|
||||||
return caller.hotel.additionalData(input)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
export const getDestinationOverviewPage = cache(
|
export const getDestinationOverviewPage = cache(
|
||||||
async function getMemoizedDestinationOverviewPage() {
|
async function getMemoizedDestinationOverviewPage() {
|
||||||
const caller = await serverClient()
|
const caller = await serverClient()
|
||||||
@@ -236,33 +216,11 @@ export const getStartPage = cache(async function getMemoizedStartPage() {
|
|||||||
return caller.contentstack.startPage.get()
|
return caller.contentstack.startPage.get()
|
||||||
})
|
})
|
||||||
|
|
||||||
export const getPageSettings = cache(async function getMemoizedPageSettings(
|
|
||||||
lang: Lang
|
|
||||||
) {
|
|
||||||
const caller = await serverClient()
|
|
||||||
return caller.contentstack.pageSettings.get({ lang })
|
|
||||||
})
|
|
||||||
|
|
||||||
export const getJobylonFeed = cache(async function getMemoizedJobylonFeed() {
|
export const getJobylonFeed = cache(async function getMemoizedJobylonFeed() {
|
||||||
const caller = await serverClient()
|
const caller = await serverClient()
|
||||||
return caller.partner.jobylon.feed.get()
|
return caller.partner.jobylon.feed.get()
|
||||||
})
|
})
|
||||||
|
|
||||||
export const getSelectedRoomsAvailabilityEnterDetails = cache(
|
|
||||||
async function getMemoizedSelectedRoomsAvailability(
|
|
||||||
input: RoomsAvailabilityExtendedInputSchema
|
|
||||||
) {
|
|
||||||
const caller = await serverClient()
|
|
||||||
const result = await caller.hotel.availability.enterDetails(input)
|
|
||||||
|
|
||||||
if (typeof result === "string") {
|
|
||||||
redirect(result)
|
|
||||||
}
|
|
||||||
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
export const getCampaignPage = cache(async function getMemoizedCampaignPage() {
|
export const getCampaignPage = cache(async function getMemoizedCampaignPage() {
|
||||||
const caller = await serverClient()
|
const caller = await serverClient()
|
||||||
return caller.contentstack.campaignPage.get()
|
return caller.contentstack.campaignPage.get()
|
||||||
|
|||||||
@@ -52,22 +52,19 @@
|
|||||||
"@tanstack/react-table": "^8.21.3",
|
"@tanstack/react-table": "^8.21.3",
|
||||||
"@testing-library/dom": "^10.4.0",
|
"@testing-library/dom": "^10.4.0",
|
||||||
"@trpc/client": "^11.1.2",
|
"@trpc/client": "^11.1.2",
|
||||||
"@trpc/react-query": "^11.1.2",
|
|
||||||
"@trpc/server": "^11.1.2",
|
"@trpc/server": "^11.1.2",
|
||||||
"@tsparticles/confetti": "^3.8.1",
|
"@tsparticles/confetti": "^3.8.1",
|
||||||
"@types/geojson": "^7946.0.16",
|
"@types/geojson": "^7946.0.16",
|
||||||
"@types/supercluster": "^7.1.3",
|
"@types/supercluster": "^7.1.3",
|
||||||
"@vis.gl/react-google-maps": "^1.5.2",
|
"@vis.gl/react-google-maps": "^1.5.2",
|
||||||
"class-variance-authority": "^0.7.1",
|
"class-variance-authority": "^0.7.1",
|
||||||
|
"client-only": "^0.0.1",
|
||||||
"contentstack": "^3.25.3",
|
"contentstack": "^3.25.3",
|
||||||
"date-fns": "^4.1.0",
|
"date-fns": "^4.1.0",
|
||||||
"dayjs": "^1.11.13",
|
"dayjs": "^1.11.13",
|
||||||
"deepmerge": "^4.3.1",
|
|
||||||
"dialogshift-webchat-sdk": "^2.10.1",
|
"dialogshift-webchat-sdk": "^2.10.1",
|
||||||
"downshift": "^9.0.9",
|
|
||||||
"embla-carousel": "^8.6.0",
|
"embla-carousel": "^8.6.0",
|
||||||
"embla-carousel-react": "^8.6.0",
|
"embla-carousel-react": "^8.6.0",
|
||||||
"fast-deep-equal": "^3.1.3",
|
|
||||||
"flat": "^6.0.1",
|
"flat": "^6.0.1",
|
||||||
"graphql-tag": "^2.12.6",
|
"graphql-tag": "^2.12.6",
|
||||||
"html-react-parser": "^5.2.3",
|
"html-react-parser": "^5.2.3",
|
||||||
@@ -76,7 +73,6 @@
|
|||||||
"input-otp": "^1.4.2",
|
"input-otp": "^1.4.2",
|
||||||
"json-stable-stringify-without-jsonify": "^1.0.1",
|
"json-stable-stringify-without-jsonify": "^1.0.1",
|
||||||
"jsonwebtoken": "^9.0.2",
|
"jsonwebtoken": "^9.0.2",
|
||||||
"libphonenumber-js": "^1.12.7",
|
|
||||||
"lodash-es": "^4.17.21",
|
"lodash-es": "^4.17.21",
|
||||||
"md5": "^2.3.0",
|
"md5": "^2.3.0",
|
||||||
"motion": "^12.10.0",
|
"motion": "^12.10.0",
|
||||||
|
|||||||
@@ -51,14 +51,3 @@ export function isValidSortOption(
|
|||||||
): value is HotelSortOption {
|
): value is HotelSortOption {
|
||||||
return sortItems.map((item) => item.value).includes(value as HotelSortOption)
|
return sortItems.map((item) => item.value).includes(value as HotelSortOption)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getBasePathNameWithoutFilters(
|
|
||||||
pathname: string,
|
|
||||||
filterSlugs: string[]
|
|
||||||
) {
|
|
||||||
const pathSegments = pathname.split("/")
|
|
||||||
const filteredSegments = pathSegments.filter(
|
|
||||||
(segment) => !filterSlugs.includes(segment)
|
|
||||||
)
|
|
||||||
return filteredSegments.join("/")
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ import { produce } from "immer"
|
|||||||
import { useContext } from "react"
|
import { useContext } from "react"
|
||||||
import { create, useStore } from "zustand"
|
import { create, useStore } from "zustand"
|
||||||
|
|
||||||
|
import { BreakfastPackageEnum } from "@scandic-hotels/trpc/enums/breakfast"
|
||||||
|
|
||||||
import { clearAncillarySessionData } from "@/components/HotelReservation/MyStay/utils/ancillaries"
|
import { clearAncillarySessionData } from "@/components/HotelReservation/MyStay/utils/ancillaries"
|
||||||
import { AddAncillaryContext } from "@/contexts/AddAncillary"
|
import { AddAncillaryContext } from "@/contexts/AddAncillary"
|
||||||
|
|
||||||
@@ -10,7 +12,6 @@ import type {
|
|||||||
Ancillary,
|
Ancillary,
|
||||||
SelectedAncillary,
|
SelectedAncillary,
|
||||||
} from "@/types/components/myPages/myStay/ancillaries"
|
} from "@/types/components/myPages/myStay/ancillaries"
|
||||||
import { BreakfastPackageEnum } from "@scandic-hotels/trpc/enums/breakfast"
|
|
||||||
import type { Room } from "@/types/stores/my-stay"
|
import type { Room } from "@/types/stores/my-stay"
|
||||||
|
|
||||||
export enum AncillaryStepEnum {
|
export enum AncillaryStepEnum {
|
||||||
@@ -40,7 +41,7 @@ export type BreakfastData = {
|
|||||||
currency: string
|
currency: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AddAncillaryState {
|
interface AddAncillaryState {
|
||||||
currentStep: number
|
currentStep: number
|
||||||
steps: Steps
|
steps: Steps
|
||||||
booking: Room
|
booking: Room
|
||||||
|
|||||||
@@ -1,136 +0,0 @@
|
|||||||
import { CurrencyEnum } from "@scandic-hotels/common/constants/currency"
|
|
||||||
|
|
||||||
import type { AvailabilityError } from "@scandic-hotels/booking-flow/types/stores/rates"
|
|
||||||
import type {
|
|
||||||
Product,
|
|
||||||
RoomConfiguration,
|
|
||||||
RoomsAvailability,
|
|
||||||
} from "@scandic-hotels/trpc/types/roomAvailability"
|
|
||||||
|
|
||||||
export function findProduct(
|
|
||||||
rateCode: string,
|
|
||||||
product: Product,
|
|
||||||
counterRateCode = ""
|
|
||||||
) {
|
|
||||||
if ("corporateCheque" in product) {
|
|
||||||
return product.corporateCheque.rateCode === rateCode
|
|
||||||
}
|
|
||||||
|
|
||||||
if ("redemption" in product) {
|
|
||||||
return product.redemption.rateCode === rateCode
|
|
||||||
}
|
|
||||||
|
|
||||||
if ("voucher" in product) {
|
|
||||||
return product.voucher.rateCode === rateCode
|
|
||||||
}
|
|
||||||
|
|
||||||
const memberExists = "member" in product
|
|
||||||
const publicExists = "public" in product
|
|
||||||
const isRegularRate = memberExists && publicExists
|
|
||||||
if (isRegularRate) {
|
|
||||||
let isProduct = false
|
|
||||||
if (product.member) {
|
|
||||||
isProduct =
|
|
||||||
product.member.rateCode === rateCode ||
|
|
||||||
product.member.rateCode === counterRateCode
|
|
||||||
}
|
|
||||||
if (product.public) {
|
|
||||||
isProduct =
|
|
||||||
product.public.rateCode === rateCode ||
|
|
||||||
product.public.rateCode === counterRateCode
|
|
||||||
}
|
|
||||||
return isProduct
|
|
||||||
}
|
|
||||||
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
export function findProductInRoom(
|
|
||||||
rateCode: string | undefined | null,
|
|
||||||
room: RoomConfiguration,
|
|
||||||
counterRateCode: string | undefined | null
|
|
||||||
) {
|
|
||||||
if (!rateCode) {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
if (room.campaign.length) {
|
|
||||||
const campaignProduct = room.campaign.find((product) =>
|
|
||||||
findProduct(rateCode, product, counterRateCode || "")
|
|
||||||
)
|
|
||||||
if (campaignProduct) {
|
|
||||||
return campaignProduct
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (room.code.length) {
|
|
||||||
const codeProduct = room.code.find((product) =>
|
|
||||||
findProduct(rateCode, product, counterRateCode || "")
|
|
||||||
)
|
|
||||||
if (codeProduct) {
|
|
||||||
return codeProduct
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (room.redemptions.length) {
|
|
||||||
const redemptionProduct = room.redemptions.find((product) =>
|
|
||||||
findProduct(rateCode, product)
|
|
||||||
)
|
|
||||||
if (redemptionProduct) {
|
|
||||||
return redemptionProduct
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (room.regular.length) {
|
|
||||||
const regularProduct = room.regular.find((product) =>
|
|
||||||
findProduct(rateCode, product, counterRateCode || "")
|
|
||||||
)
|
|
||||||
if (regularProduct) {
|
|
||||||
return regularProduct
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function findSelectedRate(
|
|
||||||
rateCode: string | undefined | null,
|
|
||||||
counterRateCode: string | undefined | null,
|
|
||||||
roomTypeCode: string | undefined | null,
|
|
||||||
rooms: RoomConfiguration[] | AvailabilityError
|
|
||||||
) {
|
|
||||||
if (!Array.isArray(rooms)) {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!rateCode) {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
return rooms.find((room) => {
|
|
||||||
if (room.roomTypeCode !== roomTypeCode) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return findProductInRoom(rateCode, room, counterRateCode)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
export function findDefaultCurrency(
|
|
||||||
roomsAvailability: (RoomsAvailability | AvailabilityError)[] | undefined
|
|
||||||
) {
|
|
||||||
if (!roomsAvailability || !roomsAvailability.length) {
|
|
||||||
return CurrencyEnum.Unknown
|
|
||||||
}
|
|
||||||
|
|
||||||
const availability = roomsAvailability.filter(
|
|
||||||
(room): room is RoomsAvailability => {
|
|
||||||
if ("error" in room) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
)[0]
|
|
||||||
|
|
||||||
const pkg = availability?.packages.find((pkg) => pkg.localPrice.currency)
|
|
||||||
if (!pkg) {
|
|
||||||
return CurrencyEnum.Unknown
|
|
||||||
}
|
|
||||||
|
|
||||||
const defaultCurrency = pkg.localPrice.currency
|
|
||||||
return defaultCurrency
|
|
||||||
}
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
export type Prettify<T> = {
|
|
||||||
[K in keyof T]: T[K]
|
|
||||||
} & {}
|
|
||||||
@@ -13,9 +13,3 @@ export interface AncillaryCardProps {
|
|||||||
description?: string
|
description?: string
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AncillaryChoiceCardProps extends AncillaryCardProps {
|
|
||||||
name: string
|
|
||||||
id?: string
|
|
||||||
value: string
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import type { Block as DestinationCountryPageBlock } from "@scandic-hotels/trpc/
|
|||||||
import type { Block as DestinationOverviewPageBlock } from "@scandic-hotels/trpc/types/destinationOverviewPage"
|
import type { Block as DestinationOverviewPageBlock } from "@scandic-hotels/trpc/types/destinationOverviewPage"
|
||||||
import type { Block as LoyaltyPageBlock } from "@scandic-hotels/trpc/types/loyaltyPage"
|
import type { Block as LoyaltyPageBlock } from "@scandic-hotels/trpc/types/loyaltyPage"
|
||||||
|
|
||||||
export type Blocks =
|
type Blocks =
|
||||||
| AccountPageBlock
|
| AccountPageBlock
|
||||||
| CampaignPageBlock
|
| CampaignPageBlock
|
||||||
| CampaignOverviewPageBlock
|
| CampaignOverviewPageBlock
|
||||||
|
|||||||
@@ -9,14 +9,6 @@ type CardTheme = Exclude<
|
|||||||
"image"
|
"image"
|
||||||
>
|
>
|
||||||
|
|
||||||
export const INFO_CARD_THEMES = [
|
|
||||||
"one",
|
|
||||||
"two",
|
|
||||||
"three",
|
|
||||||
"primaryInverted",
|
|
||||||
"primaryStrong",
|
|
||||||
] as const satisfies readonly CardTheme[]
|
|
||||||
|
|
||||||
export interface InfoCardProps {
|
export interface InfoCardProps {
|
||||||
scriptedTopTitle?: string
|
scriptedTopTitle?: string
|
||||||
heading: string
|
heading: string
|
||||||
|
|||||||
@@ -1,12 +0,0 @@
|
|||||||
import type { Embeds } from "@/types/requests/embeds"
|
|
||||||
import type { Node } from "@scandic-hotels/trpc/types/edges"
|
|
||||||
import type { RTENode } from "../rte/node"
|
|
||||||
import type { RenderOptions } from "../rte/option"
|
|
||||||
|
|
||||||
export type DeprecatedJsonToHtmlProps = {
|
|
||||||
embeds: Node<Embeds>[]
|
|
||||||
nodes: RTENode[]
|
|
||||||
renderOptions?: RenderOptions
|
|
||||||
}
|
|
||||||
|
|
||||||
export type EmbedByUid = Record<string, Node<Embeds>>
|
|
||||||
@@ -18,5 +18,3 @@ export enum DropdownTypeEnum {
|
|||||||
HeaderLanguageSwitcherMobile = "headerLanguageSwitcherMobile",
|
HeaderLanguageSwitcherMobile = "headerLanguageSwitcherMobile",
|
||||||
FooterLanguageSwitcher = "footerLanguageSwitcher",
|
FooterLanguageSwitcher = "footerLanguageSwitcher",
|
||||||
}
|
}
|
||||||
|
|
||||||
export type DropdownType = `${DropdownTypeEnum}`
|
|
||||||
|
|||||||
@@ -1,6 +0,0 @@
|
|||||||
import type { ImageProps } from "next/image"
|
|
||||||
|
|
||||||
export interface AvatarProps {
|
|
||||||
image?: ImageProps
|
|
||||||
initials?: string | null
|
|
||||||
}
|
|
||||||
@@ -68,11 +68,6 @@ export enum MeetingsHeading {
|
|||||||
Default = "Great minds meet here",
|
Default = "Great minds meet here",
|
||||||
}
|
}
|
||||||
|
|
||||||
export type HeadingEnum =
|
|
||||||
| RestaurantHeadings
|
|
||||||
| WellnessHeadings
|
|
||||||
| MeetingsHeading
|
|
||||||
|
|
||||||
export enum HealthFacilitiesEnum {
|
export enum HealthFacilitiesEnum {
|
||||||
Jacuzzi = "Jacuzzi",
|
Jacuzzi = "Jacuzzi",
|
||||||
Gym = "Gym",
|
Gym = "Gym",
|
||||||
@@ -101,15 +96,6 @@ export enum IndoorPoolDetails {
|
|||||||
DepthFrom = "DepthFrom",
|
DepthFrom = "DepthFrom",
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum OutdoorPoolDetails {
|
|
||||||
Length = "Length",
|
|
||||||
Width = "Width",
|
|
||||||
DepthTo = "DepthTo",
|
|
||||||
DepthFrom = "DepthFrom",
|
|
||||||
OpenMonthFrom = "OpenMonthFrom",
|
|
||||||
OpenMonthTo = "OpenMonthTo",
|
|
||||||
}
|
|
||||||
|
|
||||||
export enum SaunaDetails {
|
export enum SaunaDetails {
|
||||||
SeparateMenAndWomen = "SeparateMenAndWomen",
|
SeparateMenAndWomen = "SeparateMenAndWomen",
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import type { meetingRoomsSchema } from "@scandic-hotels/trpc/routers/hotels/schemas/meetingRoom"
|
import type { meetingRoomsSchema } from "@scandic-hotels/trpc/routers/hotels/schemas/meetingRoom"
|
||||||
import type { z } from "zod"
|
import type { z } from "zod"
|
||||||
|
|
||||||
export type MeetingRoomData = z.output<typeof meetingRoomsSchema>
|
type MeetingRoomData = z.output<typeof meetingRoomsSchema>
|
||||||
export type MeetingRooms = MeetingRoomData["data"]
|
export type MeetingRooms = MeetingRoomData["data"]
|
||||||
export type MeetingRoom = MeetingRooms[number]["attributes"]
|
export type MeetingRoom = MeetingRooms[number]["attributes"]
|
||||||
|
|||||||
@@ -1,3 +0,0 @@
|
|||||||
export type BedTypeInfoProps = {
|
|
||||||
hasMultipleBedTypes: boolean
|
|
||||||
}
|
|
||||||
@@ -1,10 +1,6 @@
|
|||||||
import type { Product } from "@scandic-hotels/trpc/types/roomAvailability"
|
|
||||||
|
|
||||||
import type { Price } from "../price"
|
import type { Price } from "../price"
|
||||||
|
|
||||||
export interface RoomPrice {
|
export interface RoomPrice {
|
||||||
perNight: Price
|
perNight: Price
|
||||||
perStay: Price
|
perStay: Price
|
||||||
}
|
}
|
||||||
|
|
||||||
export type RoomRate = Product
|
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
import { z } from "zod"
|
import { z } from "zod"
|
||||||
|
|
||||||
import type { Hotel } from "@scandic-hotels/trpc/types/hotel"
|
|
||||||
|
|
||||||
export const cancelStaySchema = z.object({
|
export const cancelStaySchema = z.object({
|
||||||
rooms: z.array(
|
rooms: z.array(
|
||||||
z.object({
|
z.object({
|
||||||
@@ -11,34 +9,4 @@ export const cancelStaySchema = z.object({
|
|||||||
),
|
),
|
||||||
})
|
})
|
||||||
|
|
||||||
export interface CancelStayProps {
|
|
||||||
handleCloseModal: () => void
|
|
||||||
hotel: Hotel
|
|
||||||
}
|
|
||||||
|
|
||||||
export type CancelStayFormValues = z.output<typeof cancelStaySchema>
|
export type CancelStayFormValues = z.output<typeof cancelStaySchema>
|
||||||
|
|
||||||
export interface RoomDetails {
|
|
||||||
id: string
|
|
||||||
roomName: string
|
|
||||||
roomTypeCode: string
|
|
||||||
rateDefinition: {
|
|
||||||
breakfastIncluded: boolean
|
|
||||||
cancellationRule: string | null
|
|
||||||
cancellationText: string | null
|
|
||||||
generalTerms: string[]
|
|
||||||
isMemberRate: boolean
|
|
||||||
mustBeGuaranteed: boolean
|
|
||||||
rateCode: string
|
|
||||||
title: string | null
|
|
||||||
}
|
|
||||||
isMainBooking?: boolean
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface StayDetails {
|
|
||||||
checkInDate: string
|
|
||||||
checkOutDate: string
|
|
||||||
nightsText: string
|
|
||||||
adultsText: string
|
|
||||||
childrenText: string
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
import { z } from "zod"
|
import { z } from "zod"
|
||||||
|
|
||||||
import { Lang } from "@scandic-hotels/common/constants/language"
|
|
||||||
|
|
||||||
export const changeDatesSchema = z.object({
|
export const changeDatesSchema = z.object({
|
||||||
checkInDate: z.string(),
|
checkInDate: z.string(),
|
||||||
checkOutDate: z.string(),
|
checkOutDate: z.string(),
|
||||||
@@ -9,30 +7,6 @@ export const changeDatesSchema = z.object({
|
|||||||
|
|
||||||
export type ChangeDatesSchema = z.output<typeof changeDatesSchema>
|
export type ChangeDatesSchema = z.output<typeof changeDatesSchema>
|
||||||
|
|
||||||
export interface QueryInput {
|
|
||||||
hotelId: string
|
|
||||||
roomStayStartDate: string
|
|
||||||
roomStayEndDate: string
|
|
||||||
adults: number
|
|
||||||
children: string
|
|
||||||
bookingCode: string
|
|
||||||
rateCode: string
|
|
||||||
roomTypeCode: string
|
|
||||||
lang: Lang
|
|
||||||
}
|
|
||||||
|
|
||||||
export const DEFAULT_QUERY_INPUT: QueryInput = {
|
|
||||||
hotelId: "",
|
|
||||||
roomStayStartDate: "",
|
|
||||||
roomStayEndDate: "",
|
|
||||||
adults: 1,
|
|
||||||
children: "",
|
|
||||||
bookingCode: "",
|
|
||||||
rateCode: "",
|
|
||||||
roomTypeCode: "",
|
|
||||||
lang: Lang.en,
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface ChangeDatesStepsProps {
|
export interface ChangeDatesStepsProps {
|
||||||
closeModal: () => void
|
closeModal: () => void
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,4 @@
|
|||||||
import { z } from "zod"
|
import type { CurrencyEnum } from "@scandic-hotels/common/constants/currency"
|
||||||
|
|
||||||
import { CurrencyEnum } from "@scandic-hotels/common/constants/currency"
|
|
||||||
|
|
||||||
interface TPrice {
|
interface TPrice {
|
||||||
additionalPrice?: number
|
additionalPrice?: number
|
||||||
@@ -14,18 +12,3 @@ export interface Price {
|
|||||||
requested?: TPrice
|
requested?: TPrice
|
||||||
local: TPrice
|
local: TPrice
|
||||||
}
|
}
|
||||||
|
|
||||||
export const PointsPriceSchema = z
|
|
||||||
.object({
|
|
||||||
localPrice: z.object({
|
|
||||||
currency: z.nativeEnum(CurrencyEnum),
|
|
||||||
price: z.number(),
|
|
||||||
additionalPrice: z.number().optional(),
|
|
||||||
additionalPriceCurrency: z.nativeEnum(CurrencyEnum).optional(),
|
|
||||||
}),
|
|
||||||
})
|
|
||||||
.transform((data) => ({
|
|
||||||
local: {
|
|
||||||
...data.localPrice,
|
|
||||||
},
|
|
||||||
}))
|
|
||||||
|
|||||||
@@ -1,11 +0,0 @@
|
|||||||
import type { ProductType } from "@scandic-hotels/trpc/types/availability"
|
|
||||||
import type { Hotel } from "@scandic-hotels/trpc/types/hotel"
|
|
||||||
|
|
||||||
export type HotelData = {
|
|
||||||
hotelData: Hotel
|
|
||||||
price: ProductType
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface NullableHotelData extends Omit<HotelData, "hotelData"> {
|
|
||||||
hotelData: HotelData["hotelData"] | null
|
|
||||||
}
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
import type { Hotel } from "@scandic-hotels/trpc/types/hotel"
|
|
||||||
|
|
||||||
export type HotelFilter = Hotel["detailedFacilities"][number] & {
|
|
||||||
hotelId: string
|
|
||||||
hotelIds: string[]
|
|
||||||
}
|
|
||||||
|
|
||||||
export type CategorizedHotelFilters = {
|
|
||||||
facilityFilters: HotelFilter[]
|
|
||||||
surroundingsFilters: HotelFilter[]
|
|
||||||
}
|
|
||||||
|
|
||||||
export type HotelFiltersProps = {
|
|
||||||
filters: CategorizedHotelFilters
|
|
||||||
className?: string
|
|
||||||
}
|
|
||||||
|
|
||||||
export type HotelFilterModalProps = {
|
|
||||||
filters: CategorizedHotelFilters
|
|
||||||
}
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
import type { ProductTypeCheque } from "@scandic-hotels/trpc/types/availability"
|
|
||||||
import type { Amenities } from "@scandic-hotels/trpc/types/hotel"
|
|
||||||
|
|
||||||
import type { Coordinates } from "@/types/components/maps/coordinates"
|
|
||||||
|
|
||||||
export type HotelPin = {
|
|
||||||
bookingCode?: string | null
|
|
||||||
name: string
|
|
||||||
coordinates: Coordinates
|
|
||||||
chequePrice: ProductTypeCheque["localPrice"] | null
|
|
||||||
publicPrice: number | null
|
|
||||||
memberPrice: number | null
|
|
||||||
redemptionPrice: number | null
|
|
||||||
voucherPrice: number | null
|
|
||||||
rateType: string | null
|
|
||||||
currency: string
|
|
||||||
images: {
|
|
||||||
src: string
|
|
||||||
altText: string
|
|
||||||
altText_En: string
|
|
||||||
title: string
|
|
||||||
title_En: string
|
|
||||||
}[]
|
|
||||||
amenities: Amenities
|
|
||||||
ratings: number | null
|
|
||||||
operaId: string
|
|
||||||
facilityIds: number[]
|
|
||||||
hasEnoughPoints: boolean
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface HotelCardDialogProps {
|
|
||||||
type?: "listing" | "standalone"
|
|
||||||
isOpen: boolean
|
|
||||||
data: HotelPin
|
|
||||||
handleClose: (event: { stopPropagation: () => void }) => void
|
|
||||||
}
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
import type {
|
|
||||||
ProductTypeCheque,
|
|
||||||
ProductTypePrices,
|
|
||||||
ProductTypeVoucher,
|
|
||||||
} from "@scandic-hotels/trpc/types/availability"
|
|
||||||
|
|
||||||
export type PriceCardProps = {
|
|
||||||
productTypePrices: ProductTypePrices
|
|
||||||
isMemberPrice?: boolean
|
|
||||||
className?: string
|
|
||||||
}
|
|
||||||
|
|
||||||
export type VoucherCardProps = {
|
|
||||||
productTypeVoucher: ProductTypeVoucher
|
|
||||||
}
|
|
||||||
|
|
||||||
export type BonusChequeCardProps = {
|
|
||||||
productTypeVoucher: ProductTypeCheque
|
|
||||||
}
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
import type { BookingSearchType } from "@scandic-hotels/booking-flow/searchType"
|
|
||||||
import type { Child } from "@scandic-hotels/trpc/types/child"
|
|
||||||
|
|
||||||
export type SelectHotelBooking = {
|
|
||||||
hotelId?: string
|
|
||||||
city?: string
|
|
||||||
fromDate: string
|
|
||||||
toDate: string
|
|
||||||
rooms: {
|
|
||||||
adults: number
|
|
||||||
childrenInRoom?: Child[]
|
|
||||||
}[]
|
|
||||||
bookingCode?: string
|
|
||||||
searchType?: BookingSearchType
|
|
||||||
}
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
import type { SelectRateBooking } from "@scandic-hotels/booking-flow/types/components/selectRate/selectRate"
|
|
||||||
import type { Hotel } from "@scandic-hotels/trpc/types/hotel"
|
|
||||||
|
|
||||||
export interface HotelInfoCardProps {
|
|
||||||
booking: SelectRateBooking
|
|
||||||
hotel: Hotel
|
|
||||||
}
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
import type { Price } from "../price"
|
|
||||||
|
|
||||||
export interface MobileSummaryProps {
|
|
||||||
isAllRoomsSelected: boolean
|
|
||||||
isUserLoggedIn: boolean
|
|
||||||
totalPriceToShow: Price
|
|
||||||
}
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
import type {
|
|
||||||
Product,
|
|
||||||
RoomConfiguration,
|
|
||||||
} from "@scandic-hotels/trpc/types/roomAvailability"
|
|
||||||
|
|
||||||
export interface RatesProps {
|
|
||||||
roomConfiguration: RoomConfiguration
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface SharedRateCardProps
|
|
||||||
extends Pick<RoomConfiguration, "roomTypeCode"> {
|
|
||||||
handleSelectRate: (product: Product) => void
|
|
||||||
nights: number
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
import type { Package } from "@scandic-hotels/trpc/types/packages"
|
|
||||||
import type { RoomConfiguration } from "@scandic-hotels/trpc/types/roomAvailability"
|
|
||||||
|
|
||||||
export type RoomListItemProps = {
|
|
||||||
roomConfiguration: RoomConfiguration
|
|
||||||
}
|
|
||||||
|
|
||||||
export type RoomListItemImageProps = Pick<
|
|
||||||
RoomConfiguration,
|
|
||||||
"roomType" | "roomTypeCode" | "roomsLeft"
|
|
||||||
> & {
|
|
||||||
roomPackages: Package[]
|
|
||||||
}
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
import type { SelectRateBooking } from "@scandic-hotels/booking-flow/types/components/selectRate/selectRate"
|
|
||||||
import type { Child } from "@scandic-hotels/trpc/types/child"
|
|
||||||
import type { Packages } from "@scandic-hotels/trpc/types/packages"
|
|
||||||
|
|
||||||
import type { RoomPrice, RoomRate } from "./enterDetails/details"
|
|
||||||
import type { Price } from "./price"
|
|
||||||
|
|
||||||
export type RoomsData = {
|
|
||||||
rateDetails: string[] | undefined
|
|
||||||
roomType: string
|
|
||||||
cancellationText: string
|
|
||||||
roomPrice: RoomPrice
|
|
||||||
adults: number
|
|
||||||
children?: Child[]
|
|
||||||
packages: Packages | null
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface SelectRateSummaryProps {
|
|
||||||
booking: SelectRateBooking
|
|
||||||
isMember: boolean
|
|
||||||
totalPrice: Price
|
|
||||||
vat: number
|
|
||||||
rooms: Array<{
|
|
||||||
adults: number
|
|
||||||
childrenInRoom: Child[] | undefined
|
|
||||||
roomType: string
|
|
||||||
roomPrice: RoomPrice
|
|
||||||
roomRate: RoomRate
|
|
||||||
rateDetails: string[] | undefined
|
|
||||||
cancellationText: string
|
|
||||||
packages?: Packages
|
|
||||||
} | null>
|
|
||||||
toggleSummaryOpen: () => void
|
|
||||||
}
|
|
||||||
@@ -7,7 +7,7 @@ export enum LanguageSwitcherTypesEnum {
|
|||||||
Footer = "footer",
|
Footer = "footer",
|
||||||
}
|
}
|
||||||
|
|
||||||
export type LanguageSwitcherTypes = `${LanguageSwitcherTypesEnum}`
|
type LanguageSwitcherTypes = `${LanguageSwitcherTypesEnum}`
|
||||||
|
|
||||||
export interface LanguageSwitcherProps {
|
export interface LanguageSwitcherProps {
|
||||||
type: LanguageSwitcherTypes
|
type: LanguageSwitcherTypes
|
||||||
@@ -20,5 +20,6 @@ export interface LanguageSwitcherContentProps {
|
|||||||
|
|
||||||
export interface LanguageSwitcherContainerProps {
|
export interface LanguageSwitcherContainerProps {
|
||||||
type: LanguageSwitcherTypes
|
type: LanguageSwitcherTypes
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
children: ReactElement<any, any>
|
children: ReactElement<any, any>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,27 +1,17 @@
|
|||||||
import type { Lang } from "@scandic-hotels/common/constants/language"
|
|
||||||
import type { VariantProps } from "class-variance-authority"
|
import type { VariantProps } from "class-variance-authority"
|
||||||
|
|
||||||
import type { awardPointsVariants } from "@/components/Blocks/DynamicContent/Points/EarnAndBurn/AwardPoints/awardPointsVariants"
|
import type { awardPointsVariants } from "@/components/Blocks/DynamicContent/Points/EarnAndBurn/AwardPoints/awardPointsVariants"
|
||||||
import type { UserQueryRouter } from "../user"
|
import type { UserQueryRouter } from "../user"
|
||||||
|
|
||||||
export type TransactionResponse = Awaited<
|
type TransactionResponse = Awaited<
|
||||||
ReturnType<UserQueryRouter["transaction"]["friendTransactions"]>
|
ReturnType<UserQueryRouter["transaction"]["friendTransactions"]>
|
||||||
>
|
>
|
||||||
export type TransactionsNonNullResponseObject = NonNullable<TransactionResponse>
|
type TransactionsNonNullResponseObject = NonNullable<TransactionResponse>
|
||||||
export type Transactions =
|
type Transactions =
|
||||||
NonNullable<TransactionsNonNullResponseObject>["data"]["transactions"]
|
NonNullable<TransactionsNonNullResponseObject>["data"]["transactions"]
|
||||||
export type Transaction =
|
type Transaction =
|
||||||
NonNullable<TransactionsNonNullResponseObject>["data"]["transactions"][number]
|
NonNullable<TransactionsNonNullResponseObject>["data"]["transactions"][number]
|
||||||
|
|
||||||
export type ClientEarnAndBurnProps = {
|
|
||||||
initialData: TransactionsNonNullResponseObject
|
|
||||||
lang: Lang
|
|
||||||
}
|
|
||||||
|
|
||||||
export type EarnAndBurnProps = {
|
|
||||||
lang: Lang
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface ClientTableProps {
|
export interface ClientTableProps {
|
||||||
transactions: Transactions
|
transactions: Transactions
|
||||||
}
|
}
|
||||||
@@ -30,7 +20,4 @@ export interface RowProps {
|
|||||||
transaction: Transaction
|
transaction: Transaction
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AwardPointsProps extends Pick<Transaction, "awardPoints"> {}
|
export type AwardPointsVariantProps = VariantProps<typeof awardPointsVariants>
|
||||||
|
|
||||||
export interface AwardPointsVariantProps
|
|
||||||
extends VariantProps<typeof awardPointsVariants> {}
|
|
||||||
|
|||||||
@@ -8,27 +8,3 @@ export const enum Status {
|
|||||||
error = "error",
|
error = "error",
|
||||||
success = "success",
|
success = "success",
|
||||||
}
|
}
|
||||||
|
|
||||||
type Data = Record<
|
|
||||||
string,
|
|
||||||
string | undefined | Record<string, string | undefined>
|
|
||||||
>
|
|
||||||
|
|
||||||
type Issue = {
|
|
||||||
field: string
|
|
||||||
message: string
|
|
||||||
}
|
|
||||||
|
|
||||||
export type State = {
|
|
||||||
data: Data
|
|
||||||
message: string
|
|
||||||
} & (
|
|
||||||
| {
|
|
||||||
issues: never
|
|
||||||
status: Status.success
|
|
||||||
}
|
|
||||||
| {
|
|
||||||
issues: Issue[]
|
|
||||||
status: Status.error
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|||||||
@@ -24,15 +24,6 @@ export interface AddedAncillariesProps {
|
|||||||
booking: Room
|
booking: Room
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AncillaryProps {
|
|
||||||
ancillary: Ancillary["ancillaryContent"][number]
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface AncillaryGridModalProps {
|
|
||||||
ancillaries: Ancillaries
|
|
||||||
user: User | null
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface AddAncillaryFlowModalProps {
|
export interface AddAncillaryFlowModalProps {
|
||||||
booking: Room
|
booking: Room
|
||||||
packages: Packages | null
|
packages: Packages | null
|
||||||
@@ -40,14 +31,6 @@ export interface AddAncillaryFlowModalProps {
|
|||||||
savedCreditCards: CreditCard[] | null
|
savedCreditCards: CreditCard[] | null
|
||||||
}
|
}
|
||||||
|
|
||||||
export type DeliveryTimeOption = {
|
|
||||||
label: string
|
|
||||||
value: string
|
|
||||||
}
|
|
||||||
export interface DeliveryMethodStepProps {
|
|
||||||
deliveryTimeOptions: DeliveryTimeOption[]
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface SelectQuantityStepProps {
|
export interface SelectQuantityStepProps {
|
||||||
user: User | null
|
user: User | null
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,10 @@
|
|||||||
import type { UserQueryRouter } from "../user"
|
import type { UserQueryRouter } from "../user"
|
||||||
|
|
||||||
export type PreviousStaysResponse = Awaited<
|
type PreviousStaysResponse = Awaited<
|
||||||
ReturnType<UserQueryRouter["stays"]["previous"]>
|
ReturnType<UserQueryRouter["stays"]["previous"]>
|
||||||
>
|
>
|
||||||
export type PreviousStaysNonNullResponseObject =
|
export type PreviousStaysNonNullResponseObject =
|
||||||
NonNullable<PreviousStaysResponse>
|
NonNullable<PreviousStaysResponse>
|
||||||
export type PreviousStays =
|
|
||||||
NonNullable<PreviousStaysNonNullResponseObject>["data"]
|
|
||||||
export type PreviousStay =
|
|
||||||
NonNullable<PreviousStaysNonNullResponseObject>["data"][number]
|
|
||||||
|
|
||||||
export interface PreviousStaysClientProps {
|
export interface PreviousStaysClientProps {
|
||||||
initialPreviousStays: PreviousStaysNonNullResponseObject
|
initialPreviousStays: PreviousStaysNonNullResponseObject
|
||||||
|
|||||||
@@ -1,14 +1,10 @@
|
|||||||
import type { UserQueryRouter } from "../user"
|
import type { UserQueryRouter } from "../user"
|
||||||
|
|
||||||
export type UpcomingStaysResponse = Awaited<
|
type UpcomingStaysResponse = Awaited<
|
||||||
ReturnType<UserQueryRouter["stays"]["upcoming"]>
|
ReturnType<UserQueryRouter["stays"]["upcoming"]>
|
||||||
>
|
>
|
||||||
export type UpcomingStaysNonNullResponseObject =
|
export type UpcomingStaysNonNullResponseObject =
|
||||||
NonNullable<UpcomingStaysResponse>
|
NonNullable<UpcomingStaysResponse>
|
||||||
export type UpcomingStays =
|
|
||||||
NonNullable<UpcomingStaysNonNullResponseObject>["data"]
|
|
||||||
export type UpcomingStay =
|
|
||||||
NonNullable<UpcomingStaysNonNullResponseObject>["data"][number]
|
|
||||||
|
|
||||||
export interface UpcomingStaysClientProps {
|
export interface UpcomingStaysClientProps {
|
||||||
initialUpcomingStays: UpcomingStaysNonNullResponseObject
|
initialUpcomingStays: UpcomingStaysNonNullResponseObject
|
||||||
|
|||||||
@@ -1,8 +0,0 @@
|
|||||||
export interface SearchProps {
|
|
||||||
handlePressEnter: () => void
|
|
||||||
}
|
|
||||||
|
|
||||||
export type SearchHistoryItem = {
|
|
||||||
type: "cities" | "hotels"
|
|
||||||
id: string
|
|
||||||
}
|
|
||||||
@@ -1,12 +1,4 @@
|
|||||||
import type { Room } from "@scandic-hotels/trpc/types/hotel"
|
import type { Room } from "@scandic-hotels/trpc/types/hotel"
|
||||||
import type { SafeUser } from "@/types/user"
|
|
||||||
|
|
||||||
export type BookedRoomSidePeekProps = {
|
|
||||||
close: () => void
|
|
||||||
confirmationNumber: string
|
|
||||||
room: Room
|
|
||||||
user: SafeUser
|
|
||||||
}
|
|
||||||
|
|
||||||
export type RoomDetailsProps = {
|
export type RoomDetailsProps = {
|
||||||
roomDescription: string
|
roomDescription: string
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import type { SidebarBlock as ContentPageSidebarBlock } from "@scandic-hotels/trpc/types/contentPage"
|
import type { SidebarBlock as ContentPageSidebarBlock } from "@scandic-hotels/trpc/types/contentPage"
|
||||||
import type { SidebarBlock as LoyaltyPageSidebarBlock } from "@scandic-hotels/trpc/types/loyaltyPage"
|
import type { SidebarBlock as LoyaltyPageSidebarBlock } from "@scandic-hotels/trpc/types/loyaltyPage"
|
||||||
|
|
||||||
export type Blocks = ContentPageSidebarBlock | LoyaltyPageSidebarBlock
|
type Blocks = ContentPageSidebarBlock | LoyaltyPageSidebarBlock
|
||||||
|
|
||||||
export interface SidebarProps {
|
export interface SidebarProps {
|
||||||
blocks: Blocks[]
|
blocks: Blocks[]
|
||||||
|
|||||||
@@ -1,9 +0,0 @@
|
|||||||
export enum scriptedCardThemeEnum {
|
|
||||||
one = "one",
|
|
||||||
two = "two",
|
|
||||||
three = "three",
|
|
||||||
primaryDim = "primaryDim",
|
|
||||||
primaryDark = "primaryDark",
|
|
||||||
primaryInverted = "primaryInverted",
|
|
||||||
primaryStrong = "primaryStrong",
|
|
||||||
}
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
export enum SignatureHotelEnum {
|
|
||||||
DowntownCamper = "879",
|
|
||||||
GrandHotelOslo = "340",
|
|
||||||
Haymarket = "890",
|
|
||||||
HotelNorge = "785",
|
|
||||||
Marski = "605",
|
|
||||||
TheDock = "796",
|
|
||||||
}
|
|
||||||
16
apps/scandic-web/types/intl.d.ts
vendored
16
apps/scandic-web/types/intl.d.ts
vendored
@@ -1,16 +0,0 @@
|
|||||||
// import type { MessageDescriptor } from "@formatjs/intl"
|
|
||||||
|
|
||||||
// Module augmentation
|
|
||||||
declare module "@formatjs/intl" {
|
|
||||||
// We are unable to override description field on MessageDescriptor from formatjs.
|
|
||||||
// Module augmentation does not allow for that. But we leave it here for reference.
|
|
||||||
// Instead we export our own LokaliseMessageDescriptor and use that where we control the code.
|
|
||||||
// For example in our custom formatter in i18n/formatter.ts
|
|
||||||
// interface MessageDescriptor {
|
|
||||||
// description?: {
|
|
||||||
// context?: string
|
|
||||||
// limit?: number
|
|
||||||
// tags?: string[]
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
import type { MessageDescriptor } from "@formatjs/intl"
|
|
||||||
|
|
||||||
export interface LokaliseMessageDescriptor
|
|
||||||
extends Omit<MessageDescriptor, "description"> {
|
|
||||||
description: {
|
|
||||||
context?: string
|
|
||||||
limit?: number
|
|
||||||
tags?: string
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -7,7 +7,7 @@ export type SearchParams<S = object> = {
|
|||||||
searchParams: Promise<S & { [key: string]: string }>
|
searchParams: Promise<S & { [key: string]: string }>
|
||||||
}
|
}
|
||||||
|
|
||||||
export type Params<P = object> = {
|
type Params<P = object> = {
|
||||||
params: Promise<P>
|
params: Promise<P>
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -41,15 +41,6 @@ export type UIDParams = {
|
|||||||
uid: string
|
uid: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export type UriParams = {
|
|
||||||
uri: string | string[]
|
|
||||||
}
|
|
||||||
|
|
||||||
export type PreviewParams = {
|
|
||||||
uri?: string
|
|
||||||
live_preview?: string
|
|
||||||
}
|
|
||||||
|
|
||||||
export type LayoutArgs<P = undefined> = P extends undefined
|
export type LayoutArgs<P = undefined> = P extends undefined
|
||||||
? unknown
|
? unknown
|
||||||
: Params<P>
|
: Params<P>
|
||||||
|
|||||||
@@ -1,12 +0,0 @@
|
|||||||
import type { SelectRateBooking } from "@scandic-hotels/booking-flow/types/components/selectRate/selectRate"
|
|
||||||
import type { AvailabilityError } from "@scandic-hotels/booking-flow/types/stores/rates"
|
|
||||||
import type { Room } from "@scandic-hotels/trpc/types/hotel"
|
|
||||||
import type { RoomsAvailability } from "@scandic-hotels/trpc/types/roomAvailability"
|
|
||||||
|
|
||||||
export interface RatesProviderProps extends React.PropsWithChildren {
|
|
||||||
booking: SelectRateBooking
|
|
||||||
hotelType: string | undefined
|
|
||||||
roomCategories: Room[]
|
|
||||||
roomsAvailability: (RoomsAvailability | AvailabilityError)[] | undefined
|
|
||||||
vat: number
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
import type { SelectedRoom } from "@scandic-hotels/booking-flow/types/stores/rates"
|
|
||||||
|
|
||||||
export interface RoomProviderProps extends React.PropsWithChildren {
|
|
||||||
idx: number
|
|
||||||
room: SelectedRoom
|
|
||||||
}
|
|
||||||
@@ -1,81 +0,0 @@
|
|||||||
import type { Lang } from "@scandic-hotels/common/constants/language"
|
|
||||||
import type { EdgesWithTotalCount } from "@scandic-hotels/trpc/types/edges"
|
|
||||||
|
|
||||||
import type { Typename } from "../utils/typename"
|
|
||||||
|
|
||||||
export enum Section {
|
|
||||||
ContactBlockSectionsExtraInfo = "ContactBlockSectionsExtraInfo",
|
|
||||||
ContactBlockSectionsMailingAddress = "ContactBlockSectionsMailingAddress",
|
|
||||||
ContactBlockSectionsPhone = "ContactBlockSectionsPhone",
|
|
||||||
ContactBlockSectionsTitle = "ContactBlockSectionsTitle",
|
|
||||||
ContactBlockSectionsVisitingAddress = "ContactBlockSectionsVisitingAddress",
|
|
||||||
}
|
|
||||||
|
|
||||||
type ExtraInfo = Typename<
|
|
||||||
{
|
|
||||||
extra_info: {
|
|
||||||
text: string[]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
Section.ContactBlockSectionsExtraInfo
|
|
||||||
>
|
|
||||||
|
|
||||||
type MailingAddress = Typename<
|
|
||||||
{
|
|
||||||
mailing_address: {
|
|
||||||
city: string
|
|
||||||
country: string
|
|
||||||
name: string
|
|
||||||
street: string
|
|
||||||
zip: string
|
|
||||||
}
|
|
||||||
},
|
|
||||||
Section.ContactBlockSectionsMailingAddress
|
|
||||||
>
|
|
||||||
|
|
||||||
type Phone = Typename<
|
|
||||||
{
|
|
||||||
phone: {
|
|
||||||
number: number
|
|
||||||
title: string
|
|
||||||
}
|
|
||||||
},
|
|
||||||
Section.ContactBlockSectionsPhone
|
|
||||||
>
|
|
||||||
|
|
||||||
type Title = Typename<
|
|
||||||
{
|
|
||||||
title: {
|
|
||||||
text: string
|
|
||||||
}
|
|
||||||
},
|
|
||||||
Section.ContactBlockSectionsTitle
|
|
||||||
>
|
|
||||||
|
|
||||||
type VisitingAddress = Typename<
|
|
||||||
{
|
|
||||||
visiting_address: {
|
|
||||||
city: string
|
|
||||||
country: string
|
|
||||||
street: string
|
|
||||||
zip: string
|
|
||||||
}
|
|
||||||
},
|
|
||||||
Section.ContactBlockSectionsVisitingAddress
|
|
||||||
>
|
|
||||||
|
|
||||||
type Sections = ExtraInfo | MailingAddress | Phone | Title | VisitingAddress
|
|
||||||
|
|
||||||
export type ContactNode = {
|
|
||||||
sections: Sections[]
|
|
||||||
system: {
|
|
||||||
locale: Lang
|
|
||||||
uid: string
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export type Contact = {
|
|
||||||
contact: {
|
|
||||||
contactConnection: EdgesWithTotalCount<ContactNode>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
import type { Puff } from "../puff"
|
|
||||||
|
|
||||||
export type PuffAside = {
|
|
||||||
puff: Puff
|
|
||||||
}
|
|
||||||
@@ -1,49 +0,0 @@
|
|||||||
import type { Typename } from "../utils/typename"
|
|
||||||
|
|
||||||
enum ListItemStyleEnum {
|
|
||||||
checkmark = "checkmark",
|
|
||||||
default = "default",
|
|
||||||
}
|
|
||||||
|
|
||||||
type ListItemStyle = keyof typeof ListItemStyleEnum
|
|
||||||
|
|
||||||
export enum BlockListItemsEnum {
|
|
||||||
CurrentBlocksPageBlocksListBlockListItemsListItem = "CurrentBlocksPageBlocksListBlockListItemsListItem",
|
|
||||||
CurrentBlocksPageBlocksListBlockListItemsListItemExternalLink = "CurrentBlocksPageBlocksListBlockListItemsListItemExternalLink",
|
|
||||||
}
|
|
||||||
|
|
||||||
type ExternalLinkListItem = Typename<
|
|
||||||
{
|
|
||||||
list_item_external_link: {
|
|
||||||
link: {
|
|
||||||
href: string
|
|
||||||
title: string
|
|
||||||
}
|
|
||||||
list_item_style: ListItemStyle
|
|
||||||
subtitle?: string
|
|
||||||
}
|
|
||||||
},
|
|
||||||
BlockListItemsEnum.CurrentBlocksPageBlocksListBlockListItemsListItemExternalLink
|
|
||||||
>
|
|
||||||
|
|
||||||
type RegularListItem = Typename<
|
|
||||||
{
|
|
||||||
list_item: {
|
|
||||||
list_item_style: ListItemStyle
|
|
||||||
subtitle?: string
|
|
||||||
title: string
|
|
||||||
}
|
|
||||||
},
|
|
||||||
BlockListItemsEnum.CurrentBlocksPageBlocksListBlockListItemsListItem
|
|
||||||
>
|
|
||||||
|
|
||||||
export type ListItem = ExternalLinkListItem | RegularListItem
|
|
||||||
|
|
||||||
export type List = {
|
|
||||||
list: {
|
|
||||||
title?: string
|
|
||||||
list_items: ListItem[]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export type ListProps = List
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
import type { Puff } from "../puff"
|
|
||||||
|
|
||||||
export type PuffBlock = {
|
|
||||||
puffs: {
|
|
||||||
puffs: {
|
|
||||||
puff: Puff
|
|
||||||
}[]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
import type { EdgesWithTotalCount } from "@scandic-hotels/trpc/types/edges"
|
|
||||||
|
|
||||||
import type { RTEDocument } from "@/types/rte/node"
|
|
||||||
import type { Embeds } from "../embeds"
|
|
||||||
|
|
||||||
export type Text = {
|
|
||||||
text: {
|
|
||||||
content: {
|
|
||||||
embedded_itemsConnection: EdgesWithTotalCount<Embeds>
|
|
||||||
json: RTEDocument
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
import type { ImageContainer } from "./imageContainer"
|
|
||||||
import type { SysAsset } from "./utils/asset"
|
|
||||||
import type { EmbedEnum } from "./utils/embeds"
|
|
||||||
import type { PageLink, PageLinkWithOriginalUrl } from "./utils/pageLink"
|
|
||||||
import type { TypenameInterface } from "./utils/typename"
|
|
||||||
|
|
||||||
interface AccountPage
|
|
||||||
extends TypenameInterface<EmbedEnum.AccountPage>,
|
|
||||||
PageLink {}
|
|
||||||
interface ContentPage
|
|
||||||
extends TypenameInterface<EmbedEnum.ContentPage>,
|
|
||||||
PageLinkWithOriginalUrl {}
|
|
||||||
interface LoyaltyPage
|
|
||||||
extends TypenameInterface<EmbedEnum.LoyaltyPage>,
|
|
||||||
PageLinkWithOriginalUrl {}
|
|
||||||
|
|
||||||
export type Embeds =
|
|
||||||
| AccountPage
|
|
||||||
| ContentPage
|
|
||||||
| ImageContainer
|
|
||||||
| LoyaltyPage
|
|
||||||
| SysAsset
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
import type { EdgesWithTotalCount } from "@scandic-hotels/trpc/types/edges"
|
|
||||||
import type { Image } from "@scandic-hotels/trpc/types/image"
|
|
||||||
|
|
||||||
export type Hero = {
|
|
||||||
imagesConnection: EdgesWithTotalCount<Image>
|
|
||||||
}
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
import type { ImageVaultAsset } from "@scandic-hotels/common/utils/imageVault"
|
|
||||||
import type { System } from "@scandic-hotels/trpc/routers/contentstack/schemas/system"
|
|
||||||
|
|
||||||
import type { EmbedEnum } from "./utils/embeds"
|
|
||||||
import type { TypenameInterface } from "./utils/typename"
|
|
||||||
|
|
||||||
export interface ImageContainer
|
|
||||||
extends TypenameInterface<EmbedEnum.ImageContainer>,
|
|
||||||
System {
|
|
||||||
image_left?: ImageVaultAsset
|
|
||||||
image_right?: ImageVaultAsset
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
import type { EdgesWithTotalCount } from "@scandic-hotels/trpc/types/edges"
|
|
||||||
|
|
||||||
import type { RTEDocument } from "../rte/node"
|
|
||||||
import type { Embeds } from "./embeds"
|
|
||||||
|
|
||||||
export type Preamble = {
|
|
||||||
text: {
|
|
||||||
embedded_itemsConnection: EdgesWithTotalCount<Embeds>
|
|
||||||
json: RTEDocument
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
import type { EdgesWithTotalCount } from "@scandic-hotels/trpc/types/edges"
|
|
||||||
import type { Image } from "@scandic-hotels/trpc/types/image"
|
|
||||||
|
|
||||||
import type { RTEDocument } from "../rte/node"
|
|
||||||
|
|
||||||
export enum PuffStyleEnum {
|
|
||||||
button = "button",
|
|
||||||
default = "default",
|
|
||||||
}
|
|
||||||
|
|
||||||
export type Puff = {
|
|
||||||
imageConnection: EdgesWithTotalCount<Image>
|
|
||||||
link: {
|
|
||||||
href: string
|
|
||||||
title?: string
|
|
||||||
}
|
|
||||||
puff_style: PuffStyleEnum
|
|
||||||
text: {
|
|
||||||
json: RTEDocument
|
|
||||||
}
|
|
||||||
title: string
|
|
||||||
}
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
export type TrackingData = {
|
|
||||||
current_blocks_page: { url: string; title: string }
|
|
||||||
}
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
export interface AllRequestResponse<T> {
|
|
||||||
items: T[]
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface AllRequestResponseWithTotal<T> {
|
|
||||||
items: T[]
|
|
||||||
total: number
|
|
||||||
}
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
import type { Image } from "@scandic-hotels/trpc/types/image"
|
|
||||||
|
|
||||||
import type { EmbedEnum } from "./embeds"
|
|
||||||
import type { TypenameInterface } from "./typename"
|
|
||||||
|
|
||||||
export interface SysAsset
|
|
||||||
extends TypenameInterface<EmbedEnum.SysAsset>,
|
|
||||||
Image {}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
export enum EmbedEnum {
|
|
||||||
CurrentBlocksPage = "CurrentBlocksPage",
|
|
||||||
SysAsset = "SysAsset",
|
|
||||||
ImageContainer = "ImageContainer",
|
|
||||||
LoyaltyPage = "LoyaltyPage",
|
|
||||||
AccountPage = "AccountPage",
|
|
||||||
ContentPage = "ContentPage",
|
|
||||||
HotelPage = "HotelPage",
|
|
||||||
}
|
|
||||||
|
|
||||||
export type Embed = keyof typeof EmbedEnum
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
import type { z } from "zod"
|
|
||||||
|
|
||||||
import type {
|
|
||||||
extendedPageLinkSchema,
|
|
||||||
pageLinkSchema,
|
|
||||||
} from "@scandic-hotels/trpc/routers/contentstack/schemas/pageLinks"
|
|
||||||
import type { EmbedEnum } from "./embeds"
|
|
||||||
import type { TypenameInterface } from "./typename"
|
|
||||||
|
|
||||||
export interface PageLink extends z.output<typeof pageLinkSchema> {}
|
|
||||||
|
|
||||||
export interface PageLinkWithOriginalUrl
|
|
||||||
extends z.output<typeof extendedPageLinkSchema> {}
|
|
||||||
|
|
||||||
export interface PageLinkType
|
|
||||||
extends TypenameInterface<EmbedEnum.CurrentBlocksPage>,
|
|
||||||
PageLink {}
|
|
||||||
@@ -1,22 +1,3 @@
|
|||||||
export enum AsideTypenameEnum {
|
|
||||||
CurrentBlocksPageAsideContact = "CurrentBlocksPageAsideContact",
|
|
||||||
CurrentBlocksPageAsidePuff = "CurrentBlocksPageAsidePuff",
|
|
||||||
}
|
|
||||||
|
|
||||||
export type AsideTypename = keyof typeof AsideTypenameEnum
|
|
||||||
|
|
||||||
export enum BlocksTypenameEnum {
|
|
||||||
CurrentBlocksPageBlocksList = "CurrentBlocksPageBlocksList",
|
|
||||||
CurrentBlocksPageBlocksPuffs = "CurrentBlocksPageBlocksPuffs",
|
|
||||||
CurrentBlocksPageBlocksText = "CurrentBlocksPageBlocksText",
|
|
||||||
}
|
|
||||||
|
|
||||||
export type BlocksTypename = keyof typeof BlocksTypenameEnum
|
|
||||||
|
|
||||||
export type Typename<T, K> = T & {
|
|
||||||
__typename: K
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface TypenameInterface<K> {
|
export interface TypenameInterface<K> {
|
||||||
__typename: K
|
__typename: K
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,51 +0,0 @@
|
|||||||
import type { Lang } from "@scandic-hotels/common/constants/language"
|
|
||||||
import type {
|
|
||||||
ImageVaultAsset,
|
|
||||||
ImageVaultAssetResponse,
|
|
||||||
} from "@scandic-hotels/common/utils/imageVault"
|
|
||||||
import type {
|
|
||||||
EmbedTypesEnum,
|
|
||||||
RTEItemType,
|
|
||||||
RTEItemTypeEnum,
|
|
||||||
} from "@scandic-hotels/trpc/types/RTEenums"
|
|
||||||
|
|
||||||
export interface Attributes {
|
|
||||||
[key: string]: any
|
|
||||||
"class-name"?: string
|
|
||||||
type: RTEItemType
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface RTEAssetAttrs extends Attributes {
|
|
||||||
alt: string
|
|
||||||
"asset-alt": string
|
|
||||||
"asset-link": string
|
|
||||||
"asset-name": string
|
|
||||||
"asset-type": "image/png" | "image/jpg" | "image/jpeg"
|
|
||||||
"asset-uid": string
|
|
||||||
"display-type": EmbedTypesEnum.display
|
|
||||||
"content-type-uid": "sys_assets"
|
|
||||||
inline: false
|
|
||||||
type: RTEItemTypeEnum.asset
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface RTEAnchorAttrs extends Attributes {
|
|
||||||
target: string
|
|
||||||
url: string
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface RTELinkAttrs extends Attributes {
|
|
||||||
"display-type": EmbedTypesEnum.link
|
|
||||||
"class-name": string
|
|
||||||
"content-type-uid": string
|
|
||||||
"entry-uid": string
|
|
||||||
locale: Lang
|
|
||||||
href: string
|
|
||||||
target: HTMLAnchorElement["target"]
|
|
||||||
type: RTEItemTypeEnum.entry
|
|
||||||
}
|
|
||||||
|
|
||||||
export type RTEImageVaultAttrs = Attributes & {
|
|
||||||
height: string
|
|
||||||
style: string[]
|
|
||||||
width: string
|
|
||||||
} & (ImageVaultAssetResponse | ImageVaultAsset)
|
|
||||||
@@ -1,98 +0,0 @@
|
|||||||
import type { RTETypeEnum } from "@scandic-hotels/trpc/types/RTEenums"
|
|
||||||
import type { JSX } from "react"
|
|
||||||
|
|
||||||
import type { EmbedByUid } from "../components/deprecatedjsontohtml"
|
|
||||||
import type {
|
|
||||||
Attributes,
|
|
||||||
RTEAnchorAttrs,
|
|
||||||
RTEAssetAttrs,
|
|
||||||
RTEImageVaultAttrs,
|
|
||||||
RTELinkAttrs,
|
|
||||||
} from "./attrs"
|
|
||||||
import type { RenderOptions } from "./option"
|
|
||||||
|
|
||||||
export interface RTEDefaultNode {
|
|
||||||
attrs: Attributes
|
|
||||||
children: RTENode[]
|
|
||||||
type: RTETypeEnum
|
|
||||||
uid: string
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface RTELinkNode {
|
|
||||||
attrs: Attributes
|
|
||||||
children: RTENode[]
|
|
||||||
type: RTETypeEnum
|
|
||||||
uid: string
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface RTEReferenceAssetNode extends RTEDefaultNode {
|
|
||||||
attrs: RTEAssetAttrs
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface RTEAnchorNode extends RTEDefaultNode {
|
|
||||||
attrs: RTEAnchorAttrs
|
|
||||||
type: RTETypeEnum.a
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface RTEReferenceLinkNode extends RTEDefaultNode {
|
|
||||||
attrs: RTELinkAttrs
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface RTEImageVaultNode extends RTEDefaultNode {
|
|
||||||
attrs: RTEImageVaultAttrs
|
|
||||||
type: RTETypeEnum.ImageVault
|
|
||||||
}
|
|
||||||
|
|
||||||
export enum RTEMarkType {
|
|
||||||
bold = "bold",
|
|
||||||
break = "break",
|
|
||||||
classnameOrId = "classnameOrId",
|
|
||||||
inlineCode = "inlineCode",
|
|
||||||
italic = "italic",
|
|
||||||
strikethrough = "strikethrough",
|
|
||||||
subscript = "subscript",
|
|
||||||
superscript = "superscript",
|
|
||||||
underline = "underline",
|
|
||||||
}
|
|
||||||
|
|
||||||
type RTETextNodeOptionalKeys = {
|
|
||||||
[key in RTEMarkType]?: boolean
|
|
||||||
}
|
|
||||||
|
|
||||||
export type RTETextNode = RTETextNodeOptionalKeys & {
|
|
||||||
classname?: string
|
|
||||||
id?: string
|
|
||||||
text: string
|
|
||||||
}
|
|
||||||
|
|
||||||
export type RTERegularNode = RTEDefaultNode | RTEAnchorNode | RTEImageVaultNode
|
|
||||||
|
|
||||||
export type RTEImageNode = RTEDefaultNode | RTEImageVaultNode
|
|
||||||
|
|
||||||
export type RTEReferenceNode = RTEAnchorNode
|
|
||||||
|
|
||||||
export type RTENode = RTERegularNode | RTEReferenceNode | RTETextNode
|
|
||||||
|
|
||||||
export type RTERenderMark = (
|
|
||||||
children: React.ReactNode,
|
|
||||||
classname?: string,
|
|
||||||
id?: string
|
|
||||||
) => JSX.Element
|
|
||||||
|
|
||||||
export interface RTEDocument extends RTEDefaultNode {
|
|
||||||
type: RTETypeEnum.doc
|
|
||||||
_version: number
|
|
||||||
}
|
|
||||||
|
|
||||||
export type RTERenderOptionComponent = (
|
|
||||||
node: RTERegularNode,
|
|
||||||
embeds: EmbedByUid,
|
|
||||||
next: RTENext,
|
|
||||||
fullRenderOptions: RenderOptions
|
|
||||||
) => React.ReactNode
|
|
||||||
|
|
||||||
export type RTENext = (
|
|
||||||
nodes: RTENode[],
|
|
||||||
embeds: EmbedByUid,
|
|
||||||
fullRenderOptions: RenderOptions
|
|
||||||
) => string
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
import type { RTERenderMark, RTERenderOptionComponent } from "./node"
|
|
||||||
|
|
||||||
export type RenderOptions = {
|
|
||||||
[type: string]: RTERenderOptionComponent | RTERenderMark
|
|
||||||
}
|
|
||||||
@@ -1,5 +1,3 @@
|
|||||||
export enum SidePeekEnum {
|
export enum SidePeekEnum {
|
||||||
hotelDetails = "hotel-detail-side-peek",
|
|
||||||
roomDetails = "room-detail-side-peek",
|
|
||||||
bookedRoomDetails = "booked-room-detail-side-peek",
|
bookedRoomDetails = "booked-room-detail-side-peek",
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,12 +20,6 @@ interface Actions {
|
|||||||
setIsLoading: (isLoading: boolean) => void
|
setIsLoading: (isLoading: boolean) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SubmitCallbackData {
|
|
||||||
sort: HotelSortOption
|
|
||||||
defaultSort: HotelSortOption
|
|
||||||
filters: string[]
|
|
||||||
basePath: string
|
|
||||||
}
|
|
||||||
export interface DestinationDataState {
|
export interface DestinationDataState {
|
||||||
actions: Actions
|
actions: Actions
|
||||||
allCities: DestinationCityListItem[]
|
allCities: DestinationCityListItem[]
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user