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
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
}
}
+3
View File
@@ -0,0 +1,3 @@
export interface RefreshTokenError {
error?: "RefreshAccessTokenError"
}
@@ -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
}
@@ -0,0 +1,6 @@
import type { Accordion } from "@/server/routers/contentstack/schemas/blocks/accordion"
export type AccordionProps = {
accordion: Accordion["accordion"]["accordions"]
title?: string
}
@@ -0,0 +1,3 @@
import type { CardGallery } from "@/types/trpc/routers/contentstack/blocks"
export interface CardGalleryProps extends Pick<CardGallery, "card_gallery"> {}
@@ -0,0 +1,5 @@
import type { CardsGrid } from "@/types/trpc/routers/contentstack/blocks"
export interface CardsGridProps extends Pick<CardsGrid, "cards_grid"> {
firstItem?: boolean
}
@@ -0,0 +1,4 @@
import type { CarouselCards } from "@/types/trpc/routers/contentstack/blocks"
export interface CarouselCardsProps
extends Pick<CarouselCards, "carousel_cards"> {}
@@ -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 {}
@@ -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"]
}
@@ -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[]
}
@@ -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
}
@@ -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"]
}
@@ -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
}
@@ -0,0 +1,5 @@
import type { TableData } from "@/types/trpc/routers/contentstack/blocks"
export interface TableBlockProps {
data: TableData
}
@@ -0,0 +1,3 @@
import type { TextCols } from "@/types/trpc/routers/contentstack/blocks"
export interface TextColProps extends Pick<TextCols, "text_cols"> { }
@@ -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"]
@@ -0,0 +1,6 @@
export enum ChildBedMapEnum {
IN_ADULTS_BED = 0,
IN_CRIB = 1,
IN_EXTRA_BED = 2,
UNKNOWN = 3,
}
@@ -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
}
@@ -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
}
@@ -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
}
@@ -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[]
}
@@ -0,0 +1,7 @@
import { RegisterOptions } from "react-hook-form"
export interface CheckboxProps
extends React.InputHTMLAttributes<HTMLInputElement> {
name: string
registerOptions?: RegisterOptions
}
@@ -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
}
@@ -0,0 +1,5 @@
export interface CountdownProps {
minutes?: number
seconds?: number
onChange?: (time: number) => void
}
@@ -0,0 +1,5 @@
import type { Asides } from "@/types/requests/currentBlockPage"
export type AsideProps = {
blocks: Asides[]
}
@@ -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>[] }
@@ -0,0 +1,3 @@
import type { Puff } from "@/types/requests/puff"
export type PuffProps = Puff
@@ -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>[]
}
@@ -0,0 +1,5 @@
import type { Blocks } from "@/types/requests/currentBlockPage"
export type BlocksProps = {
blocks: Blocks[]
}
@@ -0,0 +1,3 @@
import type { Text } from "@/types/requests/blocks/text"
export type TextProps = Text
@@ -0,0 +1,7 @@
import type { Breadcrumb } from "@/types/requests/currentBlockPage"
export type BreadcrumbsProps = {
breadcrumbs: Breadcrumb[]
parent?: Breadcrumb
title: string
}
@@ -0,0 +1,5 @@
import type { GetCurrentBlockPageData } from "@/types/requests/currentBlockPage"
export type ContentPageProps = {
data: GetCurrentBlockPageData
}
@@ -0,0 +1,5 @@
import { NavigationItem } from "@/server/routers/contentstack/base/output"
export type FooterNavigationProps = {
linkGroups: NavigationItem[]
}
@@ -0,0 +1,3 @@
export type HeaderProps = {
uid: string
}
@@ -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
}
@@ -0,0 +1,8 @@
import type { TopMenuHeaderLink } from "@/types/requests/currentHeader"
export type TopMenuProps = {
frontpageLinkText: string
homeHref: string
links: TopMenuHeaderLink[]
languageSwitcher: React.ReactNode | null
}
@@ -0,0 +1,7 @@
import type { Image } from "@/types/image"
export type HeroProps = {
images: {
node: Image
}[]
}
@@ -0,0 +1,10 @@
import type { LanguageSwitcherData } from "@/types/requests/languageSwitcher"
export type LanguageSwitcherLink = {
href: string
title: string
}
export type LanguageSwitcherProps = {
urls: LanguageSwitcherData
}
@@ -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
}
@@ -0,0 +1,7 @@
import type { Breadcrumb } from "@/types/requests/currentBlockPage"
export type SubnavMobileProps = {
breadcrumbs: Breadcrumb[]
parent?: Breadcrumb
title: string
}
@@ -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
}
@@ -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>>
@@ -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"]
}
@@ -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
}
@@ -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}`
@@ -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",
}
@@ -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>
@@ -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
}
@@ -0,0 +1,3 @@
export type SocialIconsProps = {
iconName: string
}
@@ -0,0 +1,6 @@
export interface SocialLinkProps {
link: {
href: string
title: string
}
}
@@ -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
}
@@ -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">
@@ -0,0 +1,3 @@
import type { passwordValidators } from "@/utils/zod/passwordValidator"
export type PasswordValidatorKey = keyof typeof passwordValidators
@@ -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
}
@@ -0,0 +1,3 @@
export type SignUpFormProps = {
title: string
}
@@ -0,0 +1,6 @@
import type { ImageProps } from "next/image"
export interface AvatarProps {
image?: ImageProps
initials?: string | null
}
@@ -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
}
@@ -0,0 +1,6 @@
export type LogoProps = {
height: number
src: string
title: string
width: number
}
@@ -0,0 +1,2 @@
export interface MainMenuButtonProps
extends React.ButtonHTMLAttributes<HTMLButtonElement> {}
@@ -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
}
@@ -0,0 +1,6 @@
import type { Header } from "@/types/trpc/routers/contentstack/header"
export interface MobileMenuProps {
topLink: Header["header"]["topLink"]
isLoggedIn: boolean
}
@@ -0,0 +1,3 @@
export interface NavigationMenuProps {
isMobile: boolean
}
@@ -0,0 +1,6 @@
import type { MenuItem } from "@/types/trpc/routers/contentstack/header"
export interface NavigationMenuItemProps {
item: MenuItem
isMobile: boolean
}
@@ -0,0 +1,6 @@
import type { MenuItem } from "@/types/trpc/routers/contentstack/header"
export interface NavigationMenuListProps {
isMobile: boolean
items: MenuItem[]
}
@@ -0,0 +1,7 @@
import type { Header } from "@/types/trpc/routers/contentstack/header"
export interface TopLinkProps {
isLoggedIn: boolean
topLink: Header["header"]["topLink"]
iconSize?: number
}
@@ -0,0 +1,2 @@
export interface TopMenuButtonProps
extends React.ButtonHTMLAttributes<HTMLButtonElement> {}
@@ -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[]
}
@@ -0,0 +1,6 @@
import type { Hotel } from "@/types/hotel"
export type HotelLogoProps = {
hotelId: Hotel["operaId"]
hotelType: Hotel["hotelType"]
}
@@ -0,0 +1,5 @@
import type { Amenities } from "@/types/hotel"
export type AmenitiesListProps = {
detailedFacilities: Amenities
}
@@ -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
@@ -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",
}
@@ -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
}
@@ -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
}
@@ -0,0 +1,6 @@
import type { PointOfInterest } from "@/types/hotel"
export interface MapCardProps {
hotelName: string
pois: PointOfInterest[]
}
@@ -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[]
}
@@ -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
}
@@ -0,0 +1,7 @@
import type { Coordinates } from "../../maps/coordinates"
export type StaticMapProps = {
coordinates: Coordinates
hotelName: string
zoomLevel?: number
}
@@ -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"]
@@ -0,0 +1,6 @@
import type { ApiImage } from "@/types/hotel"
export type PreviewImagesProps = {
images: ApiImage[]
hotelName: string
}
@@ -0,0 +1,10 @@
import type { Room } from "@/types/hotel"
export interface RoomCardProps {
room: Room
}
export type RoomsProps = {
preamble?: string
rooms: Room[]
}
@@ -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"
>
@@ -0,0 +1,4 @@
export type AccessibilityAmenityProps = {
elevatorPitch?: string
accessibilityPageUrl?: string
}
@@ -0,0 +1,8 @@
export type ActivitiesSidePeekProps = {
contentPage: {
href: string
preamble: string
}
sidepeekCTA: string
sidepeekSlug: string
}
@@ -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"]
}
@@ -0,0 +1,5 @@
import type { Hotel } from "@/types/hotel"
export type CheckInAmenityProps = {
checkInInformation: Hotel["hotelFacts"]["checkin"]
}
@@ -0,0 +1,5 @@
import type { Hotel } from "@/types/hotel"
export type FacilityProps = {
data: Hotel["healthFacilities"][number]
}
@@ -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
}
@@ -0,0 +1,8 @@
import type { RestaurantOpeningHours } from "@/types/hotel"
export interface OpeningHoursProps {
openingHours: RestaurantOpeningHours
alternateOpeningHours?: RestaurantOpeningHours
heading?: string
type?: "amenities" | "default"
}
@@ -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"]
}
@@ -0,0 +1,9 @@
import type { Restaurant } from "@/types/hotel"
export interface RestaurantBarSidePeekProps {
restaurants: Restaurant[]
}
export interface RestaurantBarItemProps {
restaurant: Restaurant
}
@@ -0,0 +1,5 @@
import type { Room } from "@/types/hotel"
export interface RoomSidePeekProps {
room: Room
}
@@ -0,0 +1,10 @@
import type { Hotel } from "@/types/hotel"
export type WellnessAndExerciseSidePeekProps = {
healthFacilities: Hotel["healthFacilities"]
wellnessExercisePageUrl?: string
spaPage?: {
buttonCTA: string
url: string
}
}
@@ -0,0 +1,4 @@
export interface HotelSubpageProps {
hotelId: string
subpage: string
}
@@ -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
}
@@ -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
}
@@ -0,0 +1,5 @@
import type { MutableRefObject } from "react"
export interface DownloadInvoiceProps {
mainRef: MutableRefObject<HTMLElement | null>
}
@@ -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"> {}
@@ -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]
}
}
@@ -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>
}
@@ -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