Merged in monorepo-step-1 (pull request #1080)

Migrate to a monorepo setup - step 1

* Move web to subfolder /apps/scandic-web

* Yarn + transitive deps

- Move to yarn
- design-system package removed for now since yarn doesn't
support the parameter for token (ie project currently broken)
- Add missing transitive dependencies as Yarn otherwise
prevents these imports
- VS Code doesn't pick up TS path aliases unless you open
/apps/scandic-web instead of root (will be fixed with monorepo)

* Pin framer-motion to temporarily fix typing issue

https://github.com/adobe/react-spectrum/issues/7494

* Pin zod to avoid typ error

There seems to have been a breaking change in the types
returned by zod where error is now returned as undefined
instead of missing in the type. We should just handle this
but to avoid merge conflicts just pin the dependency for
now.

* Pin react-intl version

Pin version of react-intl to avoid tiny type issue where formatMessage
does not accept a generic any more. This will be fixed in a future
commit, but to avoid merge conflicts just pin for now.

* Pin typescript version

Temporarily pin version as newer versions as stricter and results in
a type error. Will be fixed in future commit after merge.

* Setup workspaces

* Add design-system as a monorepo package

* Remove unused env var DESIGN_SYSTEM_ACCESS_TOKEN

* Fix husky for monorepo setup

* Update netlify.toml

* Add lint script to root package.json

* Add stub readme

* Fix react-intl formatMessage types

* Test netlify.toml in root

* Remove root toml

* Update netlify.toml publish path

* Remove package-lock.json

* Update build for branch/preview builds


Approved-by: Linus Flood
This commit is contained in:
Anton Gunnarsson
2025-02-26 10:36:17 +00:00
committed by Linus Flood
parent 667cab6fb6
commit 80100e7631
2731 changed files with 30986 additions and 23708 deletions

31
apps/scandic-web/types/auth.d.ts vendored Normal file
View File

@@ -0,0 +1,31 @@
import type { JWT } from "next-auth/jwt"
import type { RefreshTokenError } from "./authError"
// Module augmentation
// https://authjs.dev/getting-started/typescript#popular-interfaces-to-augment
declare module "next-auth" {
/**
* The shape of the account object returned in the OAuth providers' `account` callback,
* Usually contains information about the provider being used, like OAuth tokens (`access_token`, etc).
*/
interface Account {}
/**
* Returned by `useSession`, `auth`, contains information about the active session.
*/
interface Session extends RefreshTokenError {
token: JWT
}
/**
* The shape of the user object returned in the OAuth providers' `profile` callback,
* or the second parameter of the `session` callback, when using a database.
*/
interface User {
given_name: string
sub: string
email?: string
login_with: string
}
}

View File

@@ -0,0 +1,3 @@
export interface RefreshTokenError {
error?: "RefreshAccessTokenError"
}

View File

@@ -0,0 +1,27 @@
export interface AncillaryCardProps {
ancillary: {
title: string
imageUrl: string
imageOpacity?: number
price: {
total: number
currency: string
text?: string
included?: boolean
}
points?: number
description?: string
}
}
export interface BreakfastChoiceCardProps extends AncillaryCardProps {
name: string
id?: string
value: string
}
export interface AncillaryChoiceCardProps extends AncillaryCardProps {
name: string
id?: string
value: string
}

View File

@@ -0,0 +1,6 @@
import type { Accordion } from "@/server/routers/contentstack/schemas/blocks/accordion"
export type AccordionProps = {
accordion: Accordion["accordion"]["accordions"]
title?: string
}

View File

@@ -0,0 +1,3 @@
import type { CardGallery } from "@/types/trpc/routers/contentstack/blocks"
export interface CardGalleryProps extends Pick<CardGallery, "card_gallery"> {}

View File

@@ -0,0 +1,5 @@
import type { CardsGrid } from "@/types/trpc/routers/contentstack/blocks"
export interface CardsGridProps extends Pick<CardsGrid, "cards_grid"> {
firstItem?: boolean
}

View File

@@ -0,0 +1,4 @@
import type { CarouselCards } from "@/types/trpc/routers/contentstack/blocks"
export interface CarouselCardsProps
extends Pick<CarouselCards, "carousel_cards"> {}

View File

@@ -0,0 +1,22 @@
import type { DynamicContent } from "@/types/trpc/routers/contentstack/blocks"
interface PartialDynamicContent
extends Pick<DynamicContent, "dynamic_content"> {}
export interface DynamicContentProps extends PartialDynamicContent {
firstItem: boolean
}
export interface HowItWorksProps extends PartialDynamicContent {
firstItem: boolean
}
export interface LoyaltyLevelsProps extends PartialDynamicContent {
firstItem: boolean
}
export interface OverviewTableProps extends PartialDynamicContent {
firstItem: boolean
}
export interface SignupFormWrapperProps extends PartialDynamicContent {}

View File

@@ -0,0 +1,8 @@
import type { HotelListing } from "@/types/trpc/routers/contentstack/blocks"
export interface HotelListingProps {
heading?: string
locationFilter: HotelListing["locationFilter"]
hotelsToInclude: HotelListing["hotelsToInclude"]
contentType: HotelListing["contentType"]
}

View File

@@ -0,0 +1,22 @@
import type { Block as AccountPageBlock } from "@/types/trpc/routers/contentstack/accountPage"
import type { Block as CollectionPageBlock } from "@/types/trpc/routers/contentstack/collectionPage"
import type { Block as ContentPageBlock } from "@/types/trpc/routers/contentstack/contentPage"
import type { Block as DestinationCityPageBlock } from "@/types/trpc/routers/contentstack/destinationCityPage"
import type { Block as DestinationCountryPageBlock } from "@/types/trpc/routers/contentstack/destinationCountryPage"
import type { Block as DestinationOverviewPageBlock } from "@/types/trpc/routers/contentstack/destinationOverviewPage"
import type { Block as LoyaltyPageBlock } from "@/types/trpc/routers/contentstack/loyaltyPage"
import type { Block as StartPageBlock } from "@/types/trpc/routers/contentstack/startPage"
export type Blocks =
| AccountPageBlock
| CollectionPageBlock
| ContentPageBlock
| DestinationCityPageBlock
| DestinationCountryPageBlock
| DestinationOverviewPageBlock
| LoyaltyPageBlock
| StartPageBlock
export interface BlocksProps {
blocks: Blocks[]
}

View File

@@ -0,0 +1,30 @@
import type { VariantProps } from "class-variance-authority"
import type { ImageVaultAsset } from "@/types/components/imageVault"
import type { CardProps } from "@/components/TempDesignSystem/Card/card"
import type { cardVariants } from "@/components/TempDesignSystem/Card/variants"
type CardTheme = Exclude<
NonNullable<VariantProps<typeof cardVariants>["theme"]>,
"image"
>
export const INFO_CARD_THEMES = [
"one",
"two",
"three",
"primaryInverted",
"primaryStrong",
] as const satisfies readonly CardTheme[]
export interface InfoCardProps {
scriptedTopTitle?: string
heading: string
bodyText: string
image?: ImageVaultAsset
imagePosition?: "left" | "right"
primaryButton?: CardProps["primaryButton"]
secondaryButton?: CardProps["secondaryButton"]
theme?: CardTheme
className?: string
}

View File

@@ -0,0 +1,10 @@
import type { Shortcut } from "@/types/trpc/routers/contentstack/blocks"
export interface ShortcutsListProps extends Shortcut {
firstItem?: boolean
}
export type ShortcutsListItemsProps = {
className?: string
shortcutsListItems: ShortcutsListProps["shortcuts"]
}

View File

@@ -0,0 +1,29 @@
import type { Surprise } from "@/server/routers/contentstack/reward/output"
export interface SurprisesProps {
surprises: Surprise[]
membershipNumber?: string
}
export interface NavigationProps {
selectedSurprise: number
totalSurprises: number
showSurprise: (direction: number) => void
}
export interface CardProps extends React.PropsWithChildren {
title?: string
}
export interface InitialProps {
totalSurprises: number
onOpen: VoidFunction
}
export interface SlideProps {
surprise: Surprise
}
export interface HeaderProps extends React.PropsWithChildren {
onClose: VoidFunction
}

View File

@@ -0,0 +1,5 @@
import type { TableData } from "@/types/trpc/routers/contentstack/blocks"
export interface TableBlockProps {
data: TableData
}

View File

@@ -0,0 +1,3 @@
import type { TextCols } from "@/types/trpc/routers/contentstack/blocks"
export interface TextColProps extends Pick<TextCols, "text_cols"> { }

View File

@@ -0,0 +1,4 @@
import type { UspGrid } from "@/types/trpc/routers/contentstack/blocks"
export interface UspGridProps extends Pick<UspGrid, "usp_grid"> {}
export type UspIcon = UspGrid["usp_grid"]["usp_card"][number]["icon"]

View File

@@ -0,0 +1,6 @@
export enum ChildBedMapEnum {
IN_ADULTS_BED = 0,
IN_CRIB = 1,
IN_EXTRA_BED = 2,
UNKNOWN = 3,
}

View File

@@ -0,0 +1,35 @@
import type { Child, Room } from "../hotelReservation/selectRate/selectRate"
export type ChildBed = {
label: string
value: number
}
export type TGuestsRoom = Required<Pick<Room, "adults" | "childrenInRoom">>
export type GuestsRoomPickerProps = {
index: number
}
export type SelectorProps = {
roomIndex: number
currentAdults: number
currentChildren: Child[]
childrenInAdultsBed: number
}
export type ChildInfoSelectorProps = {
child: Child
adults: number
index: number
roomIndex: number
childrenInAdultsBed: number
}
export interface CounterProps {
count: number
handleOnIncrease: () => void
handleOnDecrease: () => void
disableIncrease: boolean
disableDecrease: boolean
}

View File

@@ -0,0 +1,42 @@
import type { VariantProps } from "class-variance-authority"
import type { z } from "zod"
import type { SearchParams } from "@/types/params"
import type { Locations } from "@/types/trpc/routers/hotel/locations"
import type {
bookingCodeSchema,
bookingWidgetSchema,
} from "@/components/Forms/BookingWidget/schema"
import type { bookingWidgetVariants } from "@/components/Forms/BookingWidget/variants"
import type { TGuestsRoom } from "./guestsRoomsPicker"
export type BookingWidgetSchema = z.output<typeof bookingWidgetSchema>
export type BookingCodeSchema = z.output<typeof bookingCodeSchema>
export type BookingWidgetSearchData = {
city?: string
hotel?: string
fromDate?: string
toDate?: string
rooms?: TGuestsRoom[]
bookingCode?: string
}
export type BookingWidgetType = VariantProps<
typeof bookingWidgetVariants
>["type"]
export interface BookingWidgetProps {
type?: BookingWidgetType
bookingWidgetSearchParams: SearchParams<BookingWidgetSearchData>["searchParams"]
}
export interface BookingWidgetClientProps {
locations: Locations
type?: BookingWidgetType
bookingWidgetSearchParams: SearchParams<BookingWidgetSearchData>["searchParams"]
}
export interface BookingWidgetToggleButtonProps {
openMobileSearch: () => void
}

View File

@@ -0,0 +1,10 @@
import type { ButtonPropsSlot } from "@/components/TempDesignSystem/Button/button"
export type ButtonLinkProps = React.PropsWithChildren &
Omit<ButtonPropsSlot, "asChild"> &
Pick<React.AnchorHTMLAttributes<HTMLAnchorElement>, "onClick" | "target"> & {
href: string
trackingId?: string
trackingParams?: Record<string, string>
appendToCurrentPath?: boolean
}

View File

@@ -0,0 +1,8 @@
import { FacilityCard, FacilityImage } from "./hotelPage/facilities"
import type { CardProps } from "@/components/TempDesignSystem/Card/card"
export interface CardImageProps extends React.HTMLAttributes<HTMLDivElement> {
card: FacilityCard | CardProps
imageCards?: FacilityImage[]
}

View File

@@ -0,0 +1,7 @@
import { RegisterOptions } from "react-hook-form"
export interface CheckboxProps
extends React.InputHTMLAttributes<HTMLInputElement> {
name: string
registerOptions?: RegisterOptions
}

View File

@@ -0,0 +1,8 @@
import type { Hotel } from "@/types/hotel"
import type { HotelListing } from "@/types/trpc/routers/contentstack/blocks"
export interface HotelListingItemProps {
hotel: Hotel
contentType: HotelListing["contentType"]
url: string | null
}

View File

@@ -0,0 +1,5 @@
export interface CountdownProps {
minutes?: number
seconds?: number
onChange?: (time: number) => void
}

View File

@@ -0,0 +1,5 @@
import type { Asides } from "@/types/requests/currentBlockPage"
export type AsideProps = {
blocks: Asides[]
}

View File

@@ -0,0 +1,4 @@
import type { ContactNode } from "@/types/requests/asides/contact"
import type { Node } from "@/types/requests/utils/edges"
export type ContactsProps = { contacts: Node<ContactNode>[] }

View File

@@ -0,0 +1,3 @@
import type { Puff } from "@/types/requests/puff"
export type PuffProps = Puff

View File

@@ -0,0 +1,6 @@
import type { Puff } from "@/types/requests/puff"
import type { Node } from "@/types/requests/utils/edges"
export type PuffsProps = {
puffs: Node<Puff>[]
}

View File

@@ -0,0 +1,5 @@
import type { Blocks } from "@/types/requests/currentBlockPage"
export type BlocksProps = {
blocks: Blocks[]
}

View File

@@ -0,0 +1,3 @@
import type { Text } from "@/types/requests/blocks/text"
export type TextProps = Text

View File

@@ -0,0 +1,7 @@
import type { Breadcrumb } from "@/types/requests/currentBlockPage"
export type BreadcrumbsProps = {
breadcrumbs: Breadcrumb[]
parent?: Breadcrumb
title: string
}

View File

@@ -0,0 +1,5 @@
import type { GetCurrentBlockPageData } from "@/types/requests/currentBlockPage"
export type ContentPageProps = {
data: GetCurrentBlockPageData
}

View File

@@ -0,0 +1,5 @@
import { NavigationItem } from "@/server/routers/contentstack/base/output"
export type FooterNavigationProps = {
linkGroups: NavigationItem[]
}

View File

@@ -0,0 +1,3 @@
export type HeaderProps = {
uid: string
}

View File

@@ -0,0 +1,18 @@
import type { Image } from "@/types/image"
import type {
CurrentHeaderLink,
TopMenuHeaderLink,
} from "@/types/requests/currentHeader"
import { User } from "@/types/user"
export type MainMenuProps = {
frontpageLinkText: string
homeHref: string
links: CurrentHeaderLink[]
logo: Image
topMenuMobileLinks: TopMenuHeaderLink[]
languageSwitcher: React.ReactNode | null
myPagesMobileDropdown: React.ReactNode | null
bookingHref: string
user: Pick<User, "firstName" | "lastName"> | null
}

View File

@@ -0,0 +1,8 @@
import type { TopMenuHeaderLink } from "@/types/requests/currentHeader"
export type TopMenuProps = {
frontpageLinkText: string
homeHref: string
links: TopMenuHeaderLink[]
languageSwitcher: React.ReactNode | null
}

View File

@@ -0,0 +1,7 @@
import type { Image } from "@/types/image"
export type HeroProps = {
images: {
node: Image
}[]
}

View File

@@ -0,0 +1,10 @@
import type { LanguageSwitcherData } from "@/types/requests/languageSwitcher"
export type LanguageSwitcherLink = {
href: string
title: string
}
export type LanguageSwitcherProps = {
urls: LanguageSwitcherData
}

View File

@@ -0,0 +1,10 @@
import type { Preamble } from "@/types/requests/preamble"
import type { BreadcrumbsProps } from "./breadcrumbs"
export type PreambleProps = {
breadcrumbs: BreadcrumbsProps["breadcrumbs"]
breadcrumbParent: BreadcrumbsProps["parent"]
breadcrumbTitle: BreadcrumbsProps["title"]
preamble?: Preamble
title: string
}

View File

@@ -0,0 +1,7 @@
import type { Breadcrumb } from "@/types/requests/currentBlockPage"
export type SubnavMobileProps = {
breadcrumbs: Breadcrumb[]
parent?: Breadcrumb
title: string
}

View File

@@ -0,0 +1,17 @@
import { Lang } from "@/constants/languages"
import type { Locale } from "date-fns"
import type { DateRange } from "react-day-picker"
export interface DatePickerFormProps {
name?: string
}
type LangWithoutEn = Lang.da | Lang.de | Lang.fi | Lang.no | Lang.sv
export interface DatePickerProps {
close: () => void
handleOnSelect: (selected: Date) => void
locales: Record<LangWithoutEn, Locale>
selectedDate: DateRange
}

View File

@@ -0,0 +1,12 @@
import type { Embeds } from "@/types/requests/embeds"
import type { Node } from "@/types/requests/utils/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>>

View File

@@ -0,0 +1,27 @@
export type DestinationsData = {
country: string
countryUrl: string | undefined
numberOfHotels: number
cities: {
id: string
name: string
hotelIds: string[] | null
hotelCount: number
url: string | undefined
}[]
}[]
export type HotelsSectionProps = {
destinations: DestinationsData
}
export type DestinationsListProps = {
destinations: DestinationsData
}
export type DestinationProps = {
country: string
countryUrl: string | undefined
numberOfHotels: number
cities: DestinationsData[number]["cities"]
}

View File

@@ -0,0 +1,10 @@
export interface DialogProps {
bodyText: string
cancelButtonText: string
proceedHref?: string
proceedIsPending?: boolean
proceedOnClick?: (close: () => void) => void
proceedText: string
titleText: string
trigger: React.ReactNode
}

View File

@@ -0,0 +1,22 @@
export interface DropdownState {
isHamburgerMenuOpen: boolean
isMyPagesMobileMenuOpen: boolean
isMyPagesMenuOpen: boolean
isHeaderLanguageSwitcherOpen: boolean
isHeaderLanguageSwitcherMobileOpen: boolean
isFooterLanguageSwitcherOpen: boolean
openMegaMenu: string | false
toggleMegaMenu: (menu: string | false) => void
toggleDropdown: (dropdown: DropdownTypeEnum) => void
}
export enum DropdownTypeEnum {
HamburgerMenu = "hamburgerMenu",
MyPagesMobileMenu = "myPagesMobileMenu",
MyPagesMenu = "myPagesMenu",
HeaderLanguageSwitcher = "headerLanguageSwitcher",
HeaderLanguageSwitcherMobile = "headerLanguageSwitcherMobile",
FooterLanguageSwitcher = "footerLanguageSwitcher",
}
export type DropdownType = `${DropdownTypeEnum}`

View File

@@ -0,0 +1,14 @@
export enum AppDownLoadLinks {
Apple_da = "/_static/img/store-badges/app-store-badge-da.svg",
Apple_de = "/_static/img/store-badges/app-store-badge-de.svg",
Apple_en = "/_static/img/store-badges/app-store-badge-en.svg",
Apple_fi = "/_static/img/store-badges/app-store-badge-fi.svg",
Apple_no = "/_static/img/store-badges/app-store-badge-no.svg",
Apple_sv = "/_static/img/store-badges/app-store-badge-sv.svg",
Google_da = "/_static/img/store-badges/google-play-badge-da.svg",
Google_de = "/_static/img/store-badges/google-play-badge-de.svg",
Google_en = "/_static/img/store-badges/google-play-badge-en.svg",
Google_fi = "/_static/img/store-badges/google-play-badge-fi.svg",
Google_no = "/_static/img/store-badges/google-play-badge-no.svg",
Google_sv = "/_static/img/store-badges/google-play-badge-sv.svg",
}

View File

@@ -0,0 +1,11 @@
import { z } from "zod"
import {
validateFooterConfigSchema,
validateFooterRefConfigSchema,
validateLinkItem,
} from "@/server/routers/contentstack/base/output"
export type FooterRefDataRaw = z.infer<typeof validateFooterRefConfigSchema>
export type FooterDataRaw = z.infer<typeof validateFooterConfigSchema>
export type FooterLinkItem = z.infer<typeof validateLinkItem>

View File

@@ -0,0 +1,19 @@
import type {
FooterLink,
FooterLinkWithType,
FooterSecondaryNavGroup,
} from "@/types/trpc/routers/contentstack/footer"
export type FooterMainNavProps = {
mainLinks: FooterLink[]
}
type FooterAppDownloads = {
title: string
links: FooterLinkWithType
}
export type FooterSecondaryNavProps = {
secondaryLinks: FooterSecondaryNavGroup
appDownloads: FooterAppDownloads
}

View File

@@ -0,0 +1,3 @@
export type SocialIconsProps = {
iconName: string
}

View File

@@ -0,0 +1,6 @@
export interface SocialLinkProps {
link: {
href: string
title: string
}
}

View File

@@ -0,0 +1,73 @@
import type { BookingWidgetType } from "@/types/components/bookingWidget"
import type { Location, Locations } from "@/types/trpc/routers/hotel/locations"
export interface BookingWidgetFormProps {
locations: Locations
type?: BookingWidgetType
onClose: () => void
}
export interface BookingWidgetFormContentProps {
locations: Locations
formId: string
onSubmit: () => void
isSearching: boolean
}
export enum ActionType {
CLEAR_HISTORY_LOCATIONS = "CLEAR_HISTORY_LOCATIONS",
CLEAR_SEARCH_LOCATIONS = "CLEAR_SEARCH_LOCATIONS",
SEARCH_LOCATIONS = "SEARCH_LOCATIONS",
SELECT_ITEM = "SELECT_ITEM",
SET_STORAGE_DATA = "SET_STORAGE_DATA",
}
interface ClearHistoryLocationsAction {
type: ActionType.CLEAR_HISTORY_LOCATIONS
}
interface ClearSearchLocationsAction {
type: ActionType.CLEAR_SEARCH_LOCATIONS
}
interface SearchLocationsAction {
payload: {
search: string
}
type: ActionType.SEARCH_LOCATIONS
}
interface SetItemAction {
payload: {
location: Location
searchHistory: Locations
}
type: ActionType.SELECT_ITEM
}
export interface SetStorageData {
payload: {
searchData?: Location
searchHistory?: Locations
}
type: ActionType.SET_STORAGE_DATA
}
export type Action =
| ClearHistoryLocationsAction
| ClearSearchLocationsAction
| SearchLocationsAction
| SetItemAction
| SetStorageData
export interface State {
defaultLocations: Locations
locations: Locations
search: string
searchData: Location | undefined
searchHistory: Locations | null
}
export interface InitState extends Pick<State, "defaultLocations"> {
initialValue?: string
}

View File

@@ -0,0 +1,17 @@
type FilterChipType = "checkbox" | "radio"
export interface FilterChipProps {
Icon?: React.ElementType
iconHeight?: number
iconWidth?: number
id?: string
label: string
name: string
type: FilterChipType
value?: string
selected?: boolean
disabled?: boolean
hasTooltip?: boolean
}
export type FilterChipCheckboxProps = Omit<FilterChipProps, "type">

View File

@@ -0,0 +1,3 @@
import type { passwordValidators } from "@/utils/zod/passwordValidator"
export type PasswordValidatorKey = keyof typeof passwordValidators

View File

@@ -0,0 +1,15 @@
import type { CountryCode } from "libphonenumber-js/min"
import type { RegisterOptions } from "react-hook-form"
export type LowerCaseCountryCode = Lowercase<CountryCode>
export interface PhoneProps {
ariaLabel?: string
className?: string
disabled?: boolean
label: string
name?: string
placeholder?: string
readOnly?: boolean
registerOptions?: RegisterOptions
}

View File

@@ -0,0 +1,3 @@
export type SignUpFormProps = {
title: string
}

View File

@@ -0,0 +1,6 @@
import type { ImageProps } from "next/image"
export interface AvatarProps {
image?: ImageProps
initials?: string | null
}

View File

@@ -0,0 +1,9 @@
import type { LinkProps } from "next/link"
import type { IconName } from "../icon"
export interface HeaderLinkProps extends React.PropsWithChildren {
href: LinkProps["href"]
iconName: IconName | null
iconSize?: number
}

View File

@@ -0,0 +1,6 @@
export type LogoProps = {
height: number
src: string
title: string
width: number
}

View File

@@ -0,0 +1,2 @@
export interface MainMenuButtonProps
extends React.ButtonHTMLAttributes<HTMLButtonElement> {}

View File

@@ -0,0 +1,9 @@
import type { MenuItem } from "@/types/trpc/routers/contentstack/header"
export interface MegaMenuProps {
title: MenuItem["title"]
seeAllLink: MenuItem["seeAllLink"]
submenu: MenuItem["submenu"]
card: MenuItem["card"]
isMobile: boolean
}

View File

@@ -0,0 +1,6 @@
import type { Header } from "@/types/trpc/routers/contentstack/header"
export interface MobileMenuProps {
topLink: Header["header"]["topLink"]
isLoggedIn: boolean
}

View File

@@ -0,0 +1,3 @@
export interface NavigationMenuProps {
isMobile: boolean
}

View File

@@ -0,0 +1,6 @@
import type { MenuItem } from "@/types/trpc/routers/contentstack/header"
export interface NavigationMenuItemProps {
item: MenuItem
isMobile: boolean
}

View File

@@ -0,0 +1,6 @@
import type { MenuItem } from "@/types/trpc/routers/contentstack/header"
export interface NavigationMenuListProps {
isMobile: boolean
items: MenuItem[]
}

View File

@@ -0,0 +1,7 @@
import type { Header } from "@/types/trpc/routers/contentstack/header"
export interface TopLinkProps {
isLoggedIn: boolean
topLink: Header["header"]["topLink"]
iconSize?: number
}

View File

@@ -0,0 +1,2 @@
export interface TopMenuButtonProps
extends React.ButtonHTMLAttributes<HTMLButtonElement> {}

View File

@@ -0,0 +1,17 @@
import type { SortOption } from "../enums/hotelFilterAndSort"
export interface SortItem {
label: string
value: SortOption
}
export interface Filter {
name: string
slug: string
filterType: string
}
export interface CategorizedFilters {
facilityFilters: Filter[]
surroundingsFilters: Filter[]
}

View File

@@ -0,0 +1,6 @@
import type { Hotel } from "@/types/hotel"
export type HotelLogoProps = {
hotelId: Hotel["operaId"]
hotelType: Hotel["hotelType"]
}

View File

@@ -0,0 +1,5 @@
import type { Amenities } from "@/types/hotel"
export type AmenitiesListProps = {
detailedFacilities: Amenities
}

View File

@@ -0,0 +1,82 @@
import type { Amenities, Facility, HealthFacilities } from "@/types/hotel"
import type { ActivitiesCard } from "@/types/trpc/routers/contentstack/hotelPage"
import type { CardProps } from "@/components/TempDesignSystem/Card/card"
export type FacilitiesProps = {
facilities: Facility[]
activitiesCards: ActivitiesCard[]
amenities: Amenities
healthFacilities: HealthFacilities
}
export type FacilityImage = {
backgroundImage: CardProps["backgroundImage"]
theme: CardProps["theme"]
id: string
}
export type FacilityCard = {
secondaryButton: {
href: string
title: string
openInNewTab?: boolean
isExternal: boolean
scrollOnClick: boolean
}
heading: string
scriptedTopTitle?: string
theme: CardProps["theme"]
id: string
}
export type FacilityCardType = FacilityImage | FacilityCard
export type FacilityGrid = FacilityCardType[]
export type Facilities = FacilityGrid[]
export type CardGridProps = {
facilitiesCardGrid: FacilityGrid
}
export enum FacilityCardTypeEnum {
wellness = "wellness-and-exercise",
conference = "meetings-and-conferences",
restaurant = "restaurant-and-bar",
}
export enum RestaurantHeadings {
restaurantAndBar = "Restaurant & Bar",
bar = "Bar",
restaurant = "Restaurant",
breakfastRestaurant = "Breakfast Restaurant",
}
export enum WellnessHeadings {
GymPool = "Gym & Pool",
GymSauna = "Gym & Sauna",
GymPoolSaunaRelax = "Gym, Pool, Sauna & Relax",
GymJacuzziSaunaRelax = "Gym, Jacuzzi, Sauna & Relax",
}
export enum MeetingsHeading {
Default = "Events that make an impression",
}
export type HeadingEnum =
| RestaurantHeadings
| WellnessHeadings
| MeetingsHeading
export enum HealthFacilitiesEnum {
Jacuzzi = "Jacuzzi",
Gym = "Gym",
Sauna = "Sauna",
Relax = "Relax",
IndoorPool = "Indoor pool",
OutdoorPool = "Outdoor pool",
}
export const FacilityCardButtonText = {
RESTAURANT: "Read more & book a table",
MEETINGS: "About meetings & conferences",
WELLNESS: "Read more about wellness & exercise",
} as const

View File

@@ -0,0 +1,12 @@
export interface HotelPageProps {
hotelId: string
}
// Slugs that are not set elsewhere (dynamically or from CS)
export enum SidepeekSlugs {
about = "about",
amenities = "amenities",
restaurant = "restaurant-and-bar",
meetings = "meetings-and-conferences",
wellness = "wellness-and-exercise",
}

View File

@@ -0,0 +1,10 @@
import type { PointOfInterest } from "@/types/hotel"
import type { Coordinates } from "../../maps/coordinates"
export interface DynamicMapProps {
apiKey: string
hotelName: string
coordinates: Coordinates
pointsOfInterest: PointOfInterest[]
mapId: string
}

View File

@@ -0,0 +1,16 @@
import type { ReactElement } from "react"
import type { HotelPin } from "@/types/components/hotelReservation/selectHotel/map"
import type { Coordinates } from "@/types/components/maps/coordinates"
import type { PointOfInterest } from "@/types/hotel"
export interface InteractiveMapProps {
coordinates: Coordinates
pointsOfInterest?: PointOfInterest[]
activePoi?: PointOfInterest["name"] | null
hotelPins?: HotelPin[]
mapId: string
closeButton: ReactElement
onTilesLoaded?: () => void
onActivePoiChange?: (poi: PointOfInterest["name"] | null) => void
}

View File

@@ -0,0 +1,6 @@
import type { PointOfInterest } from "@/types/hotel"
export interface MapCardProps {
hotelName: string
pois: PointOfInterest[]
}

View File

@@ -0,0 +1,8 @@
import type { Coordinates } from "@/types/components/maps/coordinates"
import type { PointOfInterest } from "@/types/hotel"
export interface MapWithCardWrapperProps {
coordinates: Coordinates
hotelName: string
topThreePois: PointOfInterest[]
}

View File

@@ -0,0 +1,10 @@
import type { PointOfInterest } from "@/types/hotel"
import type { Coordinates } from "../../maps/coordinates"
export interface SidebarProps {
hotelName: string
pointsOfInterest: PointOfInterest[]
activePoi: PointOfInterest["name"] | null
onActivePoiChange: (poi: PointOfInterest["name"] | null) => void
coordinates: Coordinates
}

View File

@@ -0,0 +1,7 @@
import type { Coordinates } from "../../maps/coordinates"
export type StaticMapProps = {
coordinates: Coordinates
hotelName: string
zoomLevel?: number
}

View File

@@ -0,0 +1,7 @@
import type { z } from "zod"
import type { meetingRoomsSchema } from "@/server/routers/hotels/schemas/meetingRoom"
export type MeetingRoomData = z.output<typeof meetingRoomsSchema>
export type MeetingRooms = MeetingRoomData["data"]
export type MeetingRoom = MeetingRooms[number]["attributes"]

View File

@@ -0,0 +1,6 @@
import type { ApiImage } from "@/types/hotel"
export type PreviewImagesProps = {
images: ApiImage[]
hotelName: string
}

View File

@@ -0,0 +1,10 @@
import type { Room } from "@/types/hotel"
export interface RoomCardProps {
room: Room
}
export type RoomsProps = {
preamble?: string
rooms: Room[]
}

View File

@@ -0,0 +1,15 @@
import type { Hotel, HotelAddress, HotelLocation } from "@/types/hotel"
export type AboutTheHotelSidePeekProps = {
hotelAddress: HotelAddress
coordinates: HotelLocation
contact: Hotel["contactInformation"]
socials: Hotel["socialMedia"]
ecoLabels: Hotel["hotelFacts"]["ecoLabels"]
descriptions: Hotel["hotelContent"]["texts"]
}
export type ContactInformationProps = Omit<
AboutTheHotelSidePeekProps,
"descriptions"
>

View File

@@ -0,0 +1,4 @@
export type AccessibilityAmenityProps = {
elevatorPitch?: string
accessibilityPageUrl?: string
}

View File

@@ -0,0 +1,8 @@
export type ActivitiesSidePeekProps = {
contentPage: {
href: string
preamble: string
}
sidepeekCTA: string
sidepeekSlug: string
}

View File

@@ -0,0 +1,22 @@
import type { Hotel, Restaurant, RestaurantOpeningHours } from "@/types/hotel"
import type { AccessibilityAmenityProps } from "./accessibility"
import type { ParkingAmenityProps } from "./parking"
export type AmenitiesSidePeekProps = {
amenitiesList: Hotel["detailedFacilities"]
parking: ParkingAmenityProps
checkInInformation: Hotel["hotelFacts"]["checkin"]
accessibility: AccessibilityAmenityProps
restaurants: Restaurant[]
hotelType: Hotel["hotelType"]
}
export type FilteredAmenitiesProps = {
filteredAmenities: Hotel["detailedFacilities"]
}
export interface BreakfastAmenityProps {
openingHours?: RestaurantOpeningHours
alternateOpeningHours?: RestaurantOpeningHours
hotelType: Hotel["hotelType"]
}

View File

@@ -0,0 +1,5 @@
import type { Hotel } from "@/types/hotel"
export type CheckInAmenityProps = {
checkInInformation: Hotel["hotelFacts"]["checkin"]
}

View File

@@ -0,0 +1,5 @@
import type { Hotel } from "@/types/hotel"
export type FacilityProps = {
data: Hotel["healthFacilities"][number]
}

View File

@@ -0,0 +1,9 @@
import type { Hotel } from "@/types/hotel"
import type { MeetingRooms } from "../meetingRooms"
export type MeetingsAndConferencesSidePeekProps = {
meetingFacilities: Hotel["conferencesAndMeetings"]
descriptions: Hotel["hotelContent"]["texts"]["meetingDescription"]
meetingRooms: MeetingRooms
meetingPageUrl: string | undefined
}

View File

@@ -0,0 +1,8 @@
import type { RestaurantOpeningHours } from "@/types/hotel"
export interface OpeningHoursProps {
openingHours: RestaurantOpeningHours
alternateOpeningHours?: RestaurantOpeningHours
heading?: string
type?: "amenities" | "default"
}

View File

@@ -0,0 +1,29 @@
import type { Hotel, Parking } from "@/types/hotel"
export enum Periods {
allDay = "AllDay",
day = "Day",
night = "Night",
}
export type ParkingAmenityProps = {
parkingPageUrl?: string
parking: Hotel["parking"]
parkingElevatorPitch?: string
}
export interface ParkingListProps
extends Pick<
Parking,
| "address"
| "canMakeReservation"
| "distanceToHotel"
| "numberOfChargingSpaces"
| "numberOfParkingSpots"
> {}
export interface ParkingPricesProps
extends Pick<Parking["pricing"], "freeParking">,
Pick<NonNullable<Parking["pricing"]["localCurrency"]>, "currency"> {
pricing: NonNullable<Parking["pricing"]["localCurrency"]>["ordinary"]
}

View File

@@ -0,0 +1,9 @@
import type { Restaurant } from "@/types/hotel"
export interface RestaurantBarSidePeekProps {
restaurants: Restaurant[]
}
export interface RestaurantBarItemProps {
restaurant: Restaurant
}

View File

@@ -0,0 +1,5 @@
import type { Room } from "@/types/hotel"
export interface RoomSidePeekProps {
room: Room
}

View File

@@ -0,0 +1,10 @@
import type { Hotel } from "@/types/hotel"
export type WellnessAndExerciseSidePeekProps = {
healthFacilities: Hotel["healthFacilities"]
wellnessExercisePageUrl?: string
spaPage?: {
buttonCTA: string
url: string
}
}

View File

@@ -0,0 +1,4 @@
export interface HotelSubpageProps {
hotelId: string
subpage: string
}

View File

@@ -0,0 +1,29 @@
export enum HotelHashValues {
overview = "overview",
rooms = "rooms-section",
restaurant = "restaurant-and-bar",
meetings = "meetings-and-conferences",
wellness = "wellness-and-exercise",
activities = "activities",
faq = "faq",
}
type Tabs = {
overview?: string
rooms?: string
restaurant_bar?: string
conferences_meetings?: string
health_wellness?: string
activities?: string
offers?: string
faq?: string
}
export type TabNavigationProps = {
hasActivities: boolean
hasFAQ: boolean
hasWellness: boolean
hasRestaurants: boolean
hasMeetingRooms: boolean
tabValues?: Tabs | null
}

View File

@@ -0,0 +1,14 @@
import type { EventAttributes } from "ics"
import type { RouterOutput } from "@/lib/trpc/client"
export interface AddToCalendarProps {
checkInDate: NonNullable<
RouterOutput["booking"]["confirmation"]
>["booking"]["checkInDate"]
event: EventAttributes
hotelName: NonNullable<
RouterOutput["booking"]["confirmation"]
>["hotel"]["name"]
renderButton: (onPress: () => Promise<void>) => React.ReactNode
}

View File

@@ -0,0 +1,5 @@
import type { MutableRefObject } from "react"
export interface DownloadInvoiceProps {
mainRef: MutableRefObject<HTMLElement | null>
}

View File

@@ -0,0 +1,5 @@
import type { BookingConfirmation } from "@/types/trpc/routers/booking/confirmation"
export interface ManageBookingProps
extends Pick<BookingConfirmation["booking"], "confirmationNumber">,
Pick<BookingConfirmation["booking"]["guest"], "lastName"> {}

View File

@@ -0,0 +1,12 @@
import type { Room } from "@/types/hotel"
import type { BookingConfirmation } from "@/types/trpc/routers/booking/confirmation"
export interface BookingConfirmationProps {
confirmationNumber: string
}
export interface ConfirmationProps extends BookingConfirmation {
room: Room & {
bedType: Room["roomTypes"][number]
}
}

View File

@@ -0,0 +1,8 @@
import type { MutableRefObject } from "react"
import type { BookingConfirmation } from "@/types/trpc/routers/booking/confirmation"
export interface BookingConfirmationHeaderProps
extends Pick<BookingConfirmation, "booking" | "hotel"> {
mainRef: MutableRefObject<HTMLElement | null>
}

View File

@@ -0,0 +1,5 @@
import type { BookingConfirmation } from "@/types/trpc/routers/booking/confirmation"
export interface BookingConfirmationHotelDetailsProps {
hotel: BookingConfirmation["hotel"]
}

Some files were not shown because too many files have changed in this diff Show More