Merged in feat/SW-2999-cleanup (pull request #2810)

feat(SW-2999): cleanup current web

* feat(SW-2999): cleanup current web

* Merge master

* Removed unused fonts


Approved-by: Joakim Jäderberg
This commit is contained in:
Linus Flood
2025-09-16 11:28:57 +00:00
parent 48324ef935
commit fd0198f57b
137 changed files with 5 additions and 146805 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +1,3 @@
ADOBE_SCRIPT_SRC=""
API_BASEURL="https://tstapi.scandichotels.com" API_BASEURL="https://tstapi.scandichotels.com"
CMS_ACCESS_TOKEN="" CMS_ACCESS_TOKEN=""
CMS_BRANCH="development" CMS_BRANCH="development"

View File

@@ -1,4 +1,3 @@
ADOBE_SCRIPT_SRC="test"
API_BASEURL="test" API_BASEURL="test"
CMS_ENVIRONMENT="test" CMS_ENVIRONMENT="test"
CMS_ACCESS_TOKEN="test" CMS_ACCESS_TOKEN="test"

View File

@@ -1,4 +1,4 @@
import NotFound from "@/components/Current/NotFound" import NotFound from "@/components/NotFound"
import type { LangParams, PageArgs } from "@/types/params" import type { LangParams, PageArgs } from "@/types/params"

View File

@@ -1,4 +1,4 @@
import NotFound from "@/components/Current/NotFound" import NotFound from "@/components/NotFound"
export default function NotFoundPage() { export default function NotFoundPage() {
return <NotFound /> return <NotFound />

View File

@@ -1,7 +0,0 @@
import Header from "@/components/Current/Header"
import type { LangParams, PageArgs } from "@/types/params"
export default async function HeaderPage({}: PageArgs<LangParams>) {
return <Header />
}

View File

@@ -1,21 +0,0 @@
"use client"
import * as Sentry from "@sentry/nextjs"
import { useEffect } from "react"
import { logger } from "@scandic-hotels/common/logger"
export default function Error({
error,
}: {
error: Error & { digest?: string }
}) {
useEffect(() => {
if (!error) return
logger.error("header", error)
Sentry.captureException(error)
}, [error])
return null
}

View File

@@ -1,76 +0,0 @@
import { notFound } from "next/navigation"
import { logger } from "@scandic-hotels/common/logger"
import { GetCurrentBlockPage } from "@scandic-hotels/trpc/graphql/Query/Current/CurrentBlockPage.graphql"
import { GetCurrentBlockPageTrackingData } from "@scandic-hotels/trpc/graphql/Query/Current/CurrentBlockPageTrackingData.graphql"
import { request } from "@scandic-hotels/trpc/graphql/request"
import ContentPage from "@/components/Current/ContentPage"
import Tracking from "@/components/Current/Tracking"
import type { LangParams, PageArgs, UriParams } from "@/types/params"
import type { GetCurrentBlockPageData } from "@/types/requests/currentBlockPage"
import type { TrackingData } from "@/types/requests/trackingData"
export default async function CurrentContentPage(
props: PageArgs<LangParams, UriParams>
) {
const searchParams = await props.searchParams
const params = await props.params
try {
if (!searchParams.uri) {
throw new Error("Bad URI")
}
const response = await request<GetCurrentBlockPageData>(
GetCurrentBlockPage,
{
locale: params.lang,
url: searchParams.uri,
},
{
key: `${params.lang}:current-block-page:${searchParams.uri}`,
ttl: "max",
}
)
if (!response.data?.all_current_blocks_page?.total) {
logger.debug(
"#### DATA ####",
response.data,
"SearchParams URI: ",
searchParams.uri
)
throw new Error("Not found")
}
// This is currently to be considered a temporary solution to provide the tracking with a few values in english to align with existing reports
const pageDataForTracking = await request<TrackingData>(
GetCurrentBlockPageTrackingData,
{ uid: response.data.all_current_blocks_page.items[0].system.uid },
{
key: `${params.lang}:current-block-page-tracking:${searchParams.uri}`,
ttl: "max",
}
)
const pageData = response.data.all_current_blocks_page.items[0]
const trackingData = {
lang: params.lang,
publishedDate: pageData.system.updated_at,
createdDate: pageData.system.created_at,
pageId: pageData.system.uid,
englishUrl: pageDataForTracking.data?.current_blocks_page.url,
}
return (
<>
<ContentPage data={response.data} />
<Tracking pageData={trackingData} />
</>
)
} catch {
return notFound()
}
}

View File

@@ -1,88 +0,0 @@
/* eslint-disable formatjs/no-literal-string-in-jsx */
import "@scandic-hotels/design-system/fonts.css"
import "@/app/globals.css"
import "@/public/_static/css/design-system-current-deprecated.css"
import "@scandic-hotels/design-system/style.css"
import Script from "next/script"
import { Lang } from "@scandic-hotels/common/constants/language"
import TokenRefresher from "@/components/Auth/TokenRefresher"
import CookieBotConsent from "@/components/CookieBot"
import AdobeScript from "@/components/Current/AdobeScript"
import Footer from "@/components/Current/Footer"
import LangPopup from "@/components/Current/LangPopup"
import RouteChange from "@/components/RouteChange"
import SkipToMainContent from "@/components/SkipToMainContent"
import { getMessages } from "@/i18n"
import ClientIntlProvider from "@/i18n/Provider"
import { setLang } from "@/i18n/serverContext"
import type { Metadata } from "next"
import type { LangParams, LayoutArgs } from "@/types/params"
export const fetchCache = "default-no-store"
export const metadata: Metadata = {
title: "Scandic Hotels",
}
export default async function RootLayout(
props: React.PropsWithChildren<
LayoutArgs<LangParams> & { header: React.ReactNode }
>
) {
const params = await props.params
const { children, header } = props
setLang(params.lang)
const messages = await getMessages(params.lang)
return (
<html lang={params.lang}>
<head>
{/* eslint-disable-next-line @next/next/no-css-tags */}
<link rel="stylesheet" href="/_static/css/core.css" />
{/* eslint-disable-next-line @next/next/no-css-tags */}
<link rel="stylesheet" href="/_static/css/scandic.css" />
<Script
strategy="beforeInteractive"
data-blockingmode="auto"
data-cbid="6d539de8-3e67-4f0f-a0df-8cef9070f712"
data-culture={params.lang}
id="Cookiebot"
src="https://consent.cookiebot.com/uc.js"
/>
<Script id="ensure-datalayer">{`
window.datalayer = window.datalayer || {}
`}</Script>
<AdobeScript />
</head>
<body className="theme-00Corecolours theme-X0Oldcorecolours">
<LangPopup />
<SkipToMainContent />
<ClientIntlProvider
defaultLocale={Lang.en}
locale={params.lang}
messages={messages}
>
<RouteChange />
{header}
{children}
<Footer />
<TokenRefresher />
<CookieBotConsent />
</ClientIntlProvider>
<Script id="page-tracking">{`
if (typeof _satellite !== "undefined" && typeof _satellite.pageBottom === "function") {
_satellite.pageBottom();
}
`}</Script>
</body>
</html>
)
}

View File

@@ -1,5 +0,0 @@
import NotFound from "@/components/Current/NotFound"
export default function NotFoundPage() {
return <NotFound />
}

View File

@@ -1,9 +0,0 @@
import Script from "next/script"
import { env } from "@/env/server"
export default function AdobeScript() {
return env.ADOBE_SCRIPT_SRC ? (
<Script data-cookieconsent="statistics" src={env.ADOBE_SCRIPT_SRC} />
) : null
}

View File

@@ -1,99 +0,0 @@
/* eslint-disable formatjs/no-literal-string-in-jsx */
import { Lang } from "@scandic-hotels/common/constants/language"
import styles from "./contact.module.css"
import { type ContactNode, Section } from "@/types/requests/asides/contact"
export default function Contact({ sections, system: { locale } }: ContactNode) {
if (!sections.length) {
return null
}
const visitingAddressMessage = getVisitingAddressMessage(locale)
return (
<section>
{sections.map((section, idx) => {
switch (section.__typename) {
case Section.ContactBlockSectionsExtraInfo:
return <p>{section.extra_info.text}</p>
case Section.ContactBlockSectionsMailingAddress:
return (
<p key={`section-mail-${idx}`}>
{section.mailing_address.name}
<br />
{section.mailing_address.street}
<br />
{section.mailing_address.zip} {section.mailing_address.city}
<br />
{section.mailing_address.country}
</p>
)
case Section.ContactBlockSectionsPhone:
return (
<div
className={styles.highlightBlock}
key={`section-phone-${idx}`}
>
<h3>{section.phone.title}</h3>
<div className={styles.phoneContainer}>
<svg
focusable="false"
className={styles.phoneIcon}
viewBox="0 0 32 32"
>
<use
xmlnsXlink="http://www.w3.org/1999/xlink"
xlinkHref="/_static/img/icons/sprites.svg#icon-phone"
></use>
</svg>
<a
href={`tel:+${section.phone.number}`}
itemProp="telephone"
className={styles.phoneNumberLink}
>
+{section.phone.number}
</a>
</div>
</div>
)
case Section.ContactBlockSectionsTitle:
return (
<h2 className={styles.heading} key={`section-heading-${idx}`}>
{section.title.text}
</h2>
)
case Section.ContactBlockSectionsVisitingAddress:
return (
<p key={`section-visiting-address-${idx}`}>
{visitingAddressMessage}: {section.visiting_address.street}{" "}
</p>
)
default:
return null
}
})}
</section>
)
}
function getVisitingAddressMessage(lang: Lang) {
switch (lang) {
case Lang.sv:
return "Besöksadress"
case Lang.en:
return "Visiting address"
case Lang.da:
return "Besøgsadresse"
case Lang.de:
return "Besuchsadresse"
case Lang.fi:
return "Vierailuosoite"
case Lang.no:
return "Besøksadresse"
default:
return ""
}
}

View File

@@ -1,63 +0,0 @@
.highlightBlock {
padding: 10px 10px 15px;
background: #fff;
overflow: hidden;
}
.heading {
font-family: BrandonText-Bold, Arial, Helvetica, sans-serif;
font-size: 1.375rem;
line-height: 1.1em;
text-transform: uppercase;
font-weight: 400;
color: #483729;
margin-bottom: 1rem;
}
.phoneContainer {
display: flex;
gap: 10px;
align-items: center;
}
.phoneNumberLink {
line-height: 1.1em;
font-family: Helvetica, Arial, sans-serif;
font-weight: 400;
text-transform: none;
font-size: 1.125rem;
color: #00838e;
text-decoration: none;
cursor: pointer;
}
.phoneIcon {
width: 42px;
height: 42px;
fill: #00838e;
}
.p {
color: #333;
line-height: 1.3;
margin-bottom: 1em;
padding-top: 7px;
text-decoration: none;
}
.phoneNumberLink:active,
.phoneNumberLink:hover {
outline: 0;
text-decoration: underline;
}
@media screen and (min-width: 1367px) {
.heading {
font-size: 1.625rem;
}
.phoneNumberLink {
line-height: 1.1em;
font-size: 1.375rem;
}
}

View File

@@ -1,9 +0,0 @@
import Contact from "./Contact"
import type { ContactsProps } from "@/types/components/current/asides/contact"
export default function Contacts({ contacts }: ContactsProps) {
return contacts.map((contact) => (
<Contact key={contact.node.system.uid} {...contact.node} />
))
}

View File

@@ -1,84 +0,0 @@
"use client"
import { useRouter } from "next/navigation"
import Image from "@scandic-hotels/design-system/Image"
import { OldDSButton as Button } from "@scandic-hotels/design-system/OldDSButton"
import { renderOptions as currentRenderOptions } from "@/components/Current/currentRenderOptions"
import DeprecatedJsonToHtml from "@/components/DeprecatedJsonToHtml"
import { renderOptions } from "./renderOptions"
import styles from "./puff.module.css"
import type { PuffProps } from "@/types/components/current/asides/puff"
import { PuffStyleEnum } from "@/types/requests/puff"
export default function Puff({
imageConnection,
link,
text,
puff_style,
title,
}: PuffProps) {
const router = useRouter()
switch (puff_style) {
case PuffStyleEnum.button:
function onClick() {
router.push(link.href)
}
return (
<article>
{imageConnection.edges.map((image) => (
<Image
alt={image.node.title}
className={styles.image}
height={image.node.dimension.height}
key={image.node.system.uid}
src={image.node.url}
width={image.node.dimension.width}
/>
))}
<section className={styles.content}>
<DeprecatedJsonToHtml
embeds={[]}
nodes={text.json.children}
renderOptions={{ ...currentRenderOptions, ...renderOptions }}
/>
<div>
<Button onPress={onClick}>{link.title || title}</Button>
</div>
</section>
</article>
)
case PuffStyleEnum.default:
return (
<a className={styles.link} href={link.href}>
<article>
{imageConnection.edges.map((image) => (
<Image
alt={image.node.title}
className={styles.image}
height={image.node.dimension.height}
key={image.node.system.uid}
src={image.node.url}
width={image.node.dimension.width}
/>
))}
<section className={styles.content}>
<header>
<h3 className={styles.heading}>{title}</h3>
</header>
<DeprecatedJsonToHtml
embeds={[]}
nodes={text.json.children}
renderOptions={{ ...currentRenderOptions, ...renderOptions }}
/>
</section>
</article>
</a>
)
}
}

View File

@@ -1,56 +0,0 @@
.link {
display: inline-block;
transition: 200ms ease;
}
.link:hover {
text-decoration: none;
transform: scale(1.01);
}
.image {
height: auto;
object-fit: contain;
object-position: center;
width: 100%;
}
.content {
display: grid;
padding: 10px;
background-color: #fff;
gap: 27px;
}
.heading {
color: #00838e;
font-family: Helvetica, Arial, sans-serif;
font-weight: 400;
line-height: normal;
margin-bottom: 0;
text-decoration: none;
text-transform: none;
}
.link:hover .heading {
text-decoration: underline;
}
.p {
color: #333;
line-height: 1.3;
margin-bottom: 0;
text-decoration: none;
}
@media screen and (min-width: 768px) {
.content {
padding: 20px 0px;
}
}
@media screen and (min-width: 1367px) {
.heading {
font-size: 1.375rem;
}
}

View File

@@ -1,22 +0,0 @@
import { RTETypeEnum } from "@scandic-hotels/trpc/types/RTEenums"
import styles from "./puff.module.css"
import type { EmbedByUid } from "@/types/components/deprecatedjsontohtml"
import type { RTEDefaultNode, RTENext } from "@/types/rte/node"
import type { RenderOptions } from "@/types/rte/option"
export const renderOptions: RenderOptions = {
[RTETypeEnum.p]: (
node: RTEDefaultNode,
embeds: EmbedByUid,
next: RTENext,
fullRenderOptions: RenderOptions
) => {
return (
<p key={node.uid} className={styles.p}>
{next(node.children, embeds, fullRenderOptions)}
</p>
)
},
}

View File

@@ -1,3 +0,0 @@
.wrapper {
padding: 20px 10px 5px;
}

View File

@@ -1,34 +0,0 @@
import Contacts from "./Contacts"
import Puff from "./Puff"
import styles from "./aside.module.css"
import type { AsideProps } from "@/types/components/current/aside"
import { AsideTypenameEnum } from "@/types/requests/utils/typename"
export default function Aside({ blocks }: AsideProps) {
if (!blocks?.length) {
return null
}
return (
<aside className={styles.wrapper}>
{blocks.map((block, idx) => {
const type = block.__typename
switch (type) {
case AsideTypenameEnum.CurrentBlocksPageAsideContact:
return (
<Contacts
contacts={block.contact.contactConnection.edges}
key={`block-${idx}`}
/>
)
case AsideTypenameEnum.CurrentBlocksPageAsidePuff:
return <Puff key={`block-${idx}`} {...block.puff} />
default:
return null
}
})}
</aside>
)
}

View File

@@ -1,68 +0,0 @@
import { cva } from "class-variance-authority"
import styles from "./list.module.css"
import { BlockListItemsEnum, type ListItem } from "@/types/requests/blocks/list"
const config = {
variants: {
type: {
default: styles.disc,
checkmark: styles.checkmark,
},
},
defaultVariants: {
type: "default",
},
} as const
const listItemStyle = cva(styles.listItem, config)
export default function ListItem({ listItem }: { listItem: ListItem }) {
const typeName = listItem.__typename
switch (typeName) {
case BlockListItemsEnum.CurrentBlocksPageBlocksListBlockListItemsListItem:
return (
<li
className={listItemStyle({
type: listItem.list_item.list_item_style,
})}
>
{listItem.list_item.subtitle ? (
<>
<strong>{listItem.list_item.title}</strong>
<br />
<span>{listItem.list_item.subtitle}</span>
</>
) : (
listItem.list_item.title
)}
</li>
)
case BlockListItemsEnum.CurrentBlocksPageBlocksListBlockListItemsListItemExternalLink:
return (
<li
className={listItemStyle({
type: listItem.list_item_external_link.list_item_style,
})}
>
<a
className={styles.link}
href={listItem.list_item_external_link.link.href}
>
<strong>{listItem.list_item_external_link.link.title}</strong>
</a>
{listItem.list_item_external_link.subtitle && (
<span>
<br />
{listItem.list_item_external_link.subtitle}
</span>
)}
</li>
)
default:
return null
}
}

View File

@@ -1,18 +0,0 @@
import ListItem from "./ListItem"
import styles from "./list.module.css"
import type { ListProps } from "@/types/requests/blocks/list"
export default function List({ list }: ListProps) {
return (
<>
{list.title ? <h2 className={styles.title}>{list.title}</h2> : null}
<ul className={styles.ul}>
{list.list_items.map((item, i) => (
<ListItem listItem={item} key={`list-item-${i}`} />
))}
</ul>
</>
)
}

View File

@@ -1,72 +0,0 @@
.title {
color: #483729;
font-family: BrandonText-Bold, Arial, Helvetica, sans-serif;
font-size: 1.375rem;
font-weight: 400;
line-height: 1.1em;
margin-bottom: 1rem;
margin-top: 2rem;
text-transform: uppercase;
}
.title:first-child {
margin-top: 0;
}
.ul {
margin-bottom: 15px;
}
.listItem {
margin-bottom: 8px;
padding-left: 1.3em;
}
.checkmark {
padding-left: 1.6em;
}
.checkmark::before,
.disc::before {
position: relative;
top: 4px;
display: inline-block;
height: 0px;
width: 0px;
}
.checkmark::before {
content: url("/_static/img/bullet-list-tick-birch-v2.svg");
transform: scale(0.9);
left: -1.2em;
}
.disc::before {
content: "•";
color: rgb(157, 160, 161);
font-size: 26px;
left: -0.7em;
}
.link {
border-bottom: 1px dotted #00838e;
color: #00838e;
text-decoration: none;
background-color: transparent;
}
.link:active,
.link:hover {
text-decoration: underline;
outline: 0;
}
.link:hover {
border-bottom: none;
}
@media screen and (min-width: 1367px) {
.title {
font-size: 1.625rem;
}
}

View File

@@ -1,3 +0,0 @@
export default function Puffs() {
return <></>
}

View File

@@ -1,15 +0,0 @@
import DeprecatedJsonToHtml from "@/components/DeprecatedJsonToHtml"
import { renderOptions } from "./../currentRenderOptions"
import type { TextProps } from "@/types/components/current/blocks/text"
export default function Text({ text }: TextProps) {
return (
<DeprecatedJsonToHtml
embeds={text.content.embedded_itemsConnection.edges}
nodes={text.content.json.children}
renderOptions={renderOptions}
/>
)
}

View File

@@ -1,10 +0,0 @@
.wrapper {
background-color: #fff;
padding: 20px 10px 5px;
}
@media screen and (min-width: 1367px) {
.wrapper {
padding: 20px 0 0;
}
}

View File

@@ -1,36 +0,0 @@
import { logger } from "@scandic-hotels/common/logger"
import List from "./List"
import Puffs from "./Puffs"
import Text from "./Text"
import styles from "./blocks.module.css"
import type { BlocksProps } from "@/types/components/current/blocks"
import { BlocksTypenameEnum } from "@/types/requests/utils/typename"
export default function Blocks({ blocks }: BlocksProps) {
if (!blocks?.length) {
return null
}
return (
<section className={styles.wrapper}>
{blocks.map((block, idx) => {
const type = block.__typename
switch (type) {
case BlocksTypenameEnum.CurrentBlocksPageBlocksList:
return <List key={`${block.__typename}-${idx}`} {...block} />
case BlocksTypenameEnum.CurrentBlocksPageBlocksPuffs:
return <Puffs key={`${block.__typename}-${idx}`} {...block} />
case BlocksTypenameEnum.CurrentBlocksPageBlocksText:
return <Text key={`${block.__typename}-${idx}`} {...block} />
default:
logger.error(`Unknown type: (${type})`)
return null
}
})}
<div id="mainarea_personalized"></div>
</section>
)
}

View File

@@ -1,7 +0,0 @@
.wrapper {
position: relative;
background: #f3f2f1;
display: block;
padding-bottom: 50px;
width: 100%;
}

View File

@@ -1,47 +0,0 @@
import Aside from "@/components/Current/Aside"
import Blocks from "@/components/Current/Blocks"
import Hero from "@/components/Current/Hero"
import Preamble from "@/components/Current/Preamble"
import Section from "@/components/Current/Section"
import SubnavMobile from "@/components/Current/SubnavMobile"
import styles from "./contentPage.module.css"
import type { ContentPageProps } from "@/types/components/current/contentPage"
export default function ContentPage({ data }: ContentPageProps) {
const page = data.all_current_blocks_page.items[0]
const images = page.hero?.imagesConnection
const breadcrumbs = page.breadcrumbs.parents
const parent = breadcrumbs.at(-1)
return (
<>
{images?.totalCount ? <Hero images={images.edges} /> : null}
<main className={styles.wrapper} id="maincontent" role="main">
<input
id="lbl-personalized-areas"
name="lbl-personalized-areas"
type="hidden"
value=""
/>
<SubnavMobile
breadcrumbs={breadcrumbs}
parent={parent}
title={page.breadcrumbs.title}
/>
<Preamble
breadcrumbs={breadcrumbs}
breadcrumbParent={parent}
breadcrumbTitle={page.breadcrumbs.title}
preamble={page.preamble}
title={page.title}
/>
<Section>
<Blocks blocks={page.blocks} />
<Aside blocks={page.aside} />
</Section>
</main>
</>
)
}

View File

@@ -1,26 +0,0 @@
import styles from "./navigation.module.css"
import type { FooterNavigationProps } from "@/types/components/current/footer"
export default function Navigation({ linkGroups }: FooterNavigationProps) {
return (
<ul className={styles.container}>
{linkGroups.map((group) => (
<li className={styles.section} key={group.title}>
<div className={styles.linkList}>
<h3 className={styles.linkListTitle}>{group.title}</h3>
<ul className={styles.listPages}>
{group.links.map((link) => (
<li className={styles.li} key={link.href}>
<a className={styles.listLink} href={link.href}>
{link.title}
</a>
</li>
))}
</ul>
</div>
</li>
))}
</ul>
)
}

View File

@@ -1,166 +0,0 @@
.container {
position: relative;
background: #000;
color: #fff;
z-index: 9;
overflow: hidden;
border-top: 1px solid #868686;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-rendering: optimizeLegibility;
}
.container::before {
content: "";
position: absolute;
top: -10px;
left: 0;
width: 100%;
height: 10px;
z-index: 3;
-webkit-box-shadow: rgba(0, 0, 0, 0.85) 0 0 10px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.85);
}
.content {
position: relative;
box-sizing: content-box;
max-width: 1200px;
margin: 0 auto;
padding: 30px 10px 0 10px;
}
.contentHeading {
text-align: center;
color: #fff;
font-family: BrandonText-Bold, Arial, Helvetica, sans-serif;
font-size: 22px;
line-height: 17.6px;
text-transform: uppercase;
font-weight: 400;
color: #483729;
margin-bottom: 16px;
margin-top: 0;
}
.hiddenAccessible {
display: block;
position: absolute;
left: -100000px;
top: auto;
width: 1px;
height: 1px;
overflow: hidden;
}
.footerSections {
display: block;
padding: 0;
margin: -10px;
list-style: none;
}
.footerLink {
clear: both;
padding: 0 0 3px;
}
.footerLinkHeader {
display: none;
padding: 0 20px;
border-bottom: 1px solid #e3e0db;
font-weight: 700;
text-transform: uppercase;
margin-bottom: 15px;
}
.contentBottom {
max-width: 700px;
margin: 0 auto;
text-align: center;
}
.contentBottomTitle {
margin: 16px 0;
font-weight: 700;
font-size: 16px;
line-height: 22.4px;
font-family: Helvetica, Arial, sans-serif;
text-align: center;
}
.footerAboutText {
margin-bottom: 16px;
line-height: 22.4px;
font-family: Helvetica, Arial, sans-serif;
font-size: 16px;
}
.appDownloadTable {
height: 62px;
width: 100%;
border-collapse: collapse;
}
.tableRow {
height: 62px;
}
.tableData {
width: 50px;
height: 62px;
padding: 1px;
}
.sectionContainer {
text-align: center;
margin-top: 32px;
margin-bottom: 16px;
padding-bottom: 3px;
}
.sectionTitle {
font-family: Helvetica, Arial, sans-serif;
font-weight: 400;
line-height: normal;
font-size: 16px;
font-weight: 700;
margin: 16px 0;
color: #fff;
}
.socialMediaIconsContainer {
display: flex;
gap: 8px;
justify-content: center;
align-items: center;
padding-right: 4px;
padding-bottom: 4px;
}
.socialMediaIconLink {
border-bottom: 3px solid transparent;
}
.socialMediaIcon {
width: 42px;
height: 42px;
overflow: hidden;
display: block;
text-indent: -9999px;
fill: #fff;
}
@media screen and (min-width: 950px) {
.container {
padding: 0 20px;
}
.contentHeading {
margin: 0;
margin-bottom: 25px;
}
.socialMediaIconsContainer {
gap: 9px;
}
}

View File

@@ -1,170 +0,0 @@
/* eslint-disable formatjs/no-literal-string-in-jsx */
import Image from "@scandic-hotels/design-system/Image"
import { getCurrentFooter } from "@/lib/trpc/memoizedRequests"
import { getLang } from "@/i18n/serverContext"
import Navigation from "./Navigation"
import styles from "./footer.module.css"
export default async function Footer() {
const lang = await getLang()
const footerData = await getCurrentFooter(lang)
if (!footerData) {
return null
}
return (
<footer className={styles.container}>
<div className={styles.content}>
<h2 className={styles.contentHeading}>
<Image
alt={footerData.logoConnection.edges[0].node.title}
data-nosvgsrc="/_static/img/scandic-logotype-white.png" // what here?
height={23}
src={footerData.logoConnection.edges[0].node.url}
width={102.17}
/>
<span className={styles.hiddenAccessible}>Scandic</span>
</h2>
<ul className={styles.footerSections}>
{footerData.navigation.map((group) => (
<li className={styles.footerLink} key={group.title}>
<div className={styles.footerLinkHeader}>{group.title}</div>
</li>
))}
</ul>
<div>
<Navigation linkGroups={footerData.navigation} />
<div className={styles.contentBottom}>
<p className={styles.contentBottomTitle}>
{footerData.about.title}
</p>
<div>
<p className={styles.footerAboutText}>{footerData.about.text}</p>
<p className={styles.contentBottomTitle}>
{footerData.app_downloads.title}
</p>
<table className={styles.appDownloadTable}>
<tbody>
<tr className={styles.tableRow}>
<td
className={styles.tableData}
style={{ textAlign: "right" }}
>
<a
title="Appstore"
href={footerData.app_downloads.app_store.href}
target="_blank"
rel="noopener"
>
<Image
alt={
footerData.app_downloads.app_store.imageConnection
.edges[0].node.title
}
height={45}
src={
footerData.app_downloads.app_store.imageConnection
.edges[0].node.url
}
width={135}
/>
</a>
</td>
<td
className={styles.tableData}
style={{ textAlign: "left" }}
>
<a
title="Google Play"
href={footerData.app_downloads.google_play.href}
target="_blank"
rel="noopener"
>
<Image
alt={
footerData.app_downloads.google_play.imageConnection
.edges[0].node.title
}
height={45}
src={
footerData.app_downloads.google_play.imageConnection
.edges[0].node.url
}
width={135}
/>
</a>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div className={styles.sectionContainer}>
<h3 className={styles.sectionTitle}>
{footerData.social_media.title}
</h3>
<section className={styles.socialMediaIconsContainer}>
<a
href={footerData.social_media.facebook.href}
rel="noopener"
target="_blank"
className={styles.socialMediaIconLink}
title="Scandic on Facebook"
>
<svg
focusable="false"
className={styles.socialMediaIcon}
viewBox="0 0 150 150"
role="img"
aria-labelledby="social-icons facebook-icon"
>
<title id="facebook-icon">
{footerData.social_media.facebook.title}
</title>
<use xlinkHref="/_static/img/icons/sprites.svg#icon-facebook"></use>
</svg>
</a>
<a
href={footerData.social_media.instagram.href}
rel="noopener"
target="_blank"
className={styles.socialMediaIconLink}
title="Scandic on Instagram"
>
<svg
focusable="false"
className={styles.socialMediaIcon}
viewBox="0 0 150 150"
role="img"
aria-labelledby="social-icons instagram-icon"
>
<title id="instagram-icon">
{footerData.social_media.instagram.title}
</title>
<use xlinkHref="/_static/img/icons/sprites.svg#icon-instagram"></use>
</svg>
</a>
</section>
</div>
<div className={styles.sectionContainer}>
<h3 className={styles.sectionTitle}>
{footerData.trip_advisor.title}
</h3>
<Image
alt="Trip Advisor logotype"
height={24}
src={footerData.trip_advisor.logoConnection.edges[0].node.url}
width={160}
/>
</div>
</div>
</div>
</footer>
)
}

View File

@@ -1,93 +0,0 @@
.container {
display: block;
padding: 0;
margin: -10px;
list-style: none;
}
.section {
padding: 0 0 3px;
display: block;
height: auto;
float: left;
width: 100%;
list-style: none;
}
.linkList {
padding: 10px 20px 20px;
}
.linkListTitle {
color: #fff;
font-family:
Helvetica Neue,
Roboto,
Helvetica,
Arial,
sans-serif;
font-size: 16px;
line-height: 22px;
border-bottom: 1px solid #e3e0db;
font-weight: 700;
text-transform: uppercase;
padding-bottom: 3px;
margin-bottom: 15px;
margin-top: 0;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-rendering: optimizeLegibility;
}
.listPages {
list-style: none;
}
.li {
padding-left: 38px;
margin-bottom: 8px;
background-image: url(/_static/img/bullet-list-arrow-circle-white.svg);
background-repeat: no-repeat;
background-position: 0 7px;
background-size: 19px;
}
.listLink {
text-decoration: none;
color: #fff;
font-family: Helvetica, Arial, sans-serif;
font-size: 16px;
line-height: 32px;
}
.listLink:hover,
.listLink:active,
.listLink:focus {
text-decoration: underline;
}
@media screen and (min-width: 950px) {
.container {
display: flex;
}
.section {
margin-bottom: 4px;
padding: 0 0 20px;
}
.linkList {
padding: 0 10px;
}
.linkListTitle {
padding: 0 20px;
}
.listPages {
padding: 10px 20px;
}
.linkListTitle {
padding-bottom: 2px;
line-height: 24px;
}
}

View File

@@ -1,43 +0,0 @@
.button {
background-color: #02838e;
color: #fff;
padding: 5px 15px;
display: inline-block;
line-height: 20px;
border: 1px solid transparent;
border-radius: 50px;
height: 38px;
line-height: 20px;
font-size: 14px;
font-family: Helvetica, Arial, sans-serif;
font-weight: 400;
font-size: 16px;
cursor: pointer;
text-decoration: none;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-rendering: optimizeLegibility;
align-content: center;
}
.button:hover {
text-decoration: underline;
}
.button:focus,
.button:active {
box-shadow: 0 0 1px 2px #b4defa;
outline: none;
border: 1px solid hsl(0, 0%, 80%);
text-decoration: underline;
}
@media screen and (min-width: 1367px) {
.button {
font-weight: 600;
font-size: 16px;
line-height: 24px;
height: auto;
padding: 12px 32px;
}
}

View File

@@ -1,18 +0,0 @@
"use client"
import "@/public/_static/css/design-system-current-deprecated.css"
import { useIntl } from "react-intl"
import styles from "./bookingButton.module.css"
export default function BookingButton({ href }: { href: string }) {
const intl = useIntl()
return (
<a className={styles.button} href={href}>
{intl.formatMessage({
defaultMessage: "Book",
})}
</a>
)
}

View File

@@ -1,13 +0,0 @@
import { MainMenuSkeleton } from "../MainMenu"
import { TopMenuSkeleton } from "../TopMenu"
import styles from "../header.module.css"
export default async function HeaderFallback() {
return (
<header className={styles.header} role="banner">
<TopMenuSkeleton />
<MainMenuSkeleton />
</header>
)
}

View File

@@ -1,113 +0,0 @@
.desktop {
display: none;
}
.container {
position: relative;
font-family:
Helvetica Neue,
Helvetica,
Arial,
sans-serif;
}
.toggle {
display: flex;
color: #fff;
padding: 3px 15px;
font-size: 14px;
border: none;
background-color: transparent;
margin: 0 auto;
cursor: pointer;
gap: 4px;
align-items: center;
}
.hiddenAccessible {
display: block;
position: absolute;
left: -100000em;
top: auto;
width: 1px;
height: 1px;
overflow: hidden;
}
.caret {
display: inline-block;
width: 0;
height: 0;
margin-left: 2px;
vertical-align: middle;
border-top: 5px dashed;
border-right: 5px solid transparent;
border-left: 5px solid transparent;
}
.icon {
width: 18px;
height: 18px;
vertical-align: -4px;
margin-right: 3px;
fill: #fff;
}
.dropdown {
position: absolute;
top: 100%;
left: 0;
z-index: 100;
display: none;
float: left;
min-width: 160px;
padding: 5px 0;
margin: 2px 0 0;
list-style: none;
font-size: 16px;
text-align: left;
background-color: #fff;
border: 1px solid rgba(0, 0, 0, 0.15);
border-radius: 4px;
-webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);
box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);
background-clip: padding-box;
}
.li {
cursor: pointer;
}
.dropdown.isOpen {
display: block;
}
.link {
clear: both;
color: grey;
display: block;
font-weight: 400;
padding: 3px 20px;
white-space: nowrap;
text-decoration: none;
}
.link:hover {
background-color: #f5f5f5;
color: #737373;
text-decoration: none;
}
.active > .link {
background-color: #00838e;
color: #fff;
outline: 0;
text-decoration: none;
}
@media (min-width: 1367px) {
.desktop {
display: block;
}
}

View File

@@ -1,103 +0,0 @@
/* eslint-disable formatjs/no-literal-string-in-jsx */
"use client"
import { useCallback, useEffect, useRef, useState } from "react"
import Link from "@scandic-hotels/design-system/Link"
import { languages } from "@/constants/languages"
import useLang from "@/hooks/useLang"
import styles from "./desktop.module.css"
import type { Lang } from "@scandic-hotels/common/constants/language"
import type { LanguageSwitcherProps } from "@/types/components/current/languageSwitcher"
export default function Desktop({ urls }: LanguageSwitcherProps) {
const currentLanguage = useLang()
const [isOpen, setIsOpen] = useState(false)
const divRef = useRef<HTMLDivElement>(null)
function toggleOpen() {
setIsOpen((prevIsOpen) => !prevIsOpen)
}
const close = useCallback(() => {
setIsOpen(false)
}, [setIsOpen])
useEffect(() => {
function handleClickOutside(evt: Event) {
const target = evt.target as HTMLElement
if (divRef.current && target && !divRef.current.contains(target)) {
close()
}
}
if (divRef.current) {
document.addEventListener("click", handleClickOutside, false)
}
return () => {
document.removeEventListener("click", handleClickOutside, false)
}
}, [close])
const urlKeys = Object.keys(urls)
if (urlKeys.length === 1 && urlKeys[0] === currentLanguage) {
return (
<div className={styles.container} ref={divRef}>
<section className={styles.languageSwitcher}>
<svg focusable="false" className={styles.icon} viewBox="0 0 32 32">
<use xlinkHref="/_static/img/icons/sprites.svg#icon-globe"></use>
</svg>
{languages[currentLanguage]}
</section>
</div>
)
}
return (
<section className={styles.desktop}>
<div className={styles.container} ref={divRef}>
<button
aria-pressed="false"
className={styles.toggle}
onClick={toggleOpen}
>
<svg focusable="false" className={styles.icon} viewBox="0 0 32 32">
<use xlinkHref="/_static/img/icons/sprites.svg#icon-globe"></use>
</svg>
{languages[currentLanguage]}
<span className={styles.hiddenAccessible}>Choose language</span>
<span className={styles.caret}></span>
</button>
<ul className={`${styles.dropdown} ${isOpen ? styles.isOpen : ""}`}>
{urlKeys.map((key) => {
const url = urls[key as Lang]?.url
if (url) {
return (
<li
key={key}
className={`${styles.li} ${currentLanguage === key ? styles.active : ""}`}
>
{urls[key as Lang]?.isExternal ? (
<Link className={styles.link} href={url}>
{languages[key as Lang]}
</Link>
) : (
<a className={styles.link} href={url}>
{languages[key as Lang]}
</a>
)}
</li>
)
}
})}
</ul>
</div>
</section>
)
}

View File

@@ -1,60 +0,0 @@
/* eslint-disable formatjs/no-literal-string-in-jsx */
"use client"
import { useState } from "react"
import { languages } from "@/constants/languages"
import useLang from "@/hooks/useLang"
import styles from "./mobile.module.css"
import type { Lang } from "@scandic-hotels/common/constants/language"
import type { LanguageSwitcherProps } from "@/types/components/current/languageSwitcher"
export default function Mobile({ urls }: LanguageSwitcherProps) {
const currentLanguage = useLang()
const [isOpen, setIsOpen] = useState(false)
function toggleOpen() {
setIsOpen((prevIsOpen) => !prevIsOpen)
}
const urlKeys = Object.keys(urls)
if (urlKeys.length === 1 && urlKeys[0] === currentLanguage) {
return <div className={styles.toggle}>{languages[currentLanguage]}</div>
}
return (
<section className={styles.mobile}>
<div>
<button
aria-pressed="false"
className={styles.toggle}
onClick={toggleOpen}
>
{languages[currentLanguage]}{" "}
<span
className={`${styles.arrow} ${isOpen ? styles.open : ""}`}
></span>
<span className={styles.hiddenAccessible}>Choose language</span>
</button>
<ul className={`${styles.dropdown} ${isOpen ? styles.isOpen : ""}`}>
{urlKeys.map((key) => {
const url = urls[key as Lang]?.url
if (url) {
return (
<li key={key} className={styles.li}>
<a href={url} className={styles.link}>
{languages[key as Lang]}
</a>
</li>
)
}
})}
</ul>
</div>
</section>
)
}

View File

@@ -1,74 +0,0 @@
.mobile {
display: block;
font-family: Helvetica, Arial, sans-serif;
}
.toggle {
font-size: 14px;
padding: 5px 0;
display: block;
border: none;
background-color: transparent;
margin: 0 auto;
color: #333;
}
.hiddenAccessible {
display: block;
position: absolute;
left: -100000em;
top: auto;
width: 1px;
height: 1px;
overflow: hidden;
}
.li {
list-style: none;
font-size: 14px;
font-family: Helvetica, Arial, sans-serif;
}
.link {
color: #333;
text-decoration: none;
line-height: 22.4px;
}
.dropdown {
display: none;
}
.dropdown.isOpen {
display: block;
}
.arrow {
background-image: url("/_static/img/icons/arrows/arrow-down-grey.png");
background-position: 50%;
background-repeat: no-repeat;
display: inline-block;
margin-left: 5px;
padding: 5px 10px;
}
.arrow.open {
background-image: url("/_static/img/icons/arrows/arrow-up-grey.png");
}
.link {
color: grey;
display: block;
text-transform: capitalize;
}
.link:hover {
color: #7f7369;
text-decoration: none;
}
@media (min-width: 1367px) {
.mobile {
display: none;
}
}

View File

@@ -1,37 +0,0 @@
"use client"
import { usePathname } from "next/navigation"
import SkeletonShimmer from "@scandic-hotels/design-system/SkeletonShimmer"
import { trpc } from "@scandic-hotels/trpc/client"
import useLang from "@/hooks/useLang"
import Desktop from "./Desktop"
import Mobile from "./Mobile"
export default function LanguageSwitcher() {
const currentLanguage = useLang()
const pathName = usePathname()
const { data: languagesResponse, isLoading } =
trpc.contentstack.languageSwitcher.get.useQuery({
pathName,
lang: currentLanguage,
})
if (isLoading) {
return <SkeletonShimmer width="12ch" />
}
if (!languagesResponse?.urls) {
return null
}
return (
<>
<Desktop urls={languagesResponse.urls} />
<Mobile urls={languagesResponse.urls} />
</>
)
}

View File

@@ -1,307 +0,0 @@
/* eslint-disable formatjs/no-literal-string-in-jsx */
"use client"
import { usePathname } from "next/navigation"
import { useIntl } from "react-intl"
import { findMyBookingCurrentWebPath } from "@scandic-hotels/common/constants/routes/findMyBookingRoutes"
import { logout } from "@scandic-hotels/common/constants/routes/handleAuth"
import { myPages } from "@scandic-hotels/common/constants/routes/myPages"
import { useLazyPathname } from "@scandic-hotels/common/hooks/useLazyPathname"
import { getCurrentWebUrl } from "@scandic-hotels/common/utils/url"
import Image from "@scandic-hotels/design-system/Image"
import Link from "@scandic-hotels/design-system/Link"
import { LoginButton } from "@scandic-hotels/design-system/LoginButton"
import SkeletonShimmer from "@scandic-hotels/design-system/SkeletonShimmer"
import { env } from "@/env/client"
import useDropdownStore from "@/stores/main-menu"
import Avatar from "@/components/MyPages/Avatar"
import useLang from "@/hooks/useLang"
import { trackClick, trackLoginClick } from "@/utils/tracking"
import BookingButton from "../BookingButton"
import styles from "./mainMenu.module.css"
import type { MainMenuProps } from "@/types/components/current/header/mainMenu"
import { DropdownTypeEnum } from "@/types/components/dropdown/dropdown"
export function MainMenu({
frontpageLinkText,
homeHref,
links,
logo,
topMenuMobileLinks,
languageSwitcher,
myPagesMobileDropdown,
bookingHref,
user,
}: MainMenuProps) {
const intl = useIntl()
const lang = useLang()
const pathname = usePathname()
const baseUrl = env.NEXT_PUBLIC_PUBLIC_URL || "https://www.scandichotels.com"
const loginPathname = useLazyPathname({ includeSearchParams: true })
const isThreeStaticPagesPathnames = [
"/de/sponsoring",
"/en/sponsoring",
"/da/sponsorering",
"/fi/sponsorointi",
"/no/vi-sponser",
"/sv/vi-sponsrar",
"/de/scandic-entdecken/wlan",
"/en/explore-scandic/wifi",
"/da/oplev-scandic/wifi",
"/fi/koe-scandic/maksuton-internetyhteys",
"/no/utforsk-scandic/wifi",
"/sv/utforska-scandic/wi-fi",
"/de/kundenbetreuung/haufig-gestellte-fragen/nutzung-der-internetseite",
"/en/customer-service/frequently-asked-questions/using-the-website",
"/da/kundeservice/sporgsmal-og-svar/om-scandics-website",
"/fi/asiakaspalvelu/usein-kysytyt-kysymykset/tietoja-internetsivuista",
"/no/kundeservice/sporsmal-og-svar/bruk-av-nettsiden",
"/sv/kundservice/fragor-och-svar/om-scandics-webbplats",
"/de/current-content-page",
"/en/current-content-page",
"/da/current-content-page",
"/fi/current-content-page",
"/no/current-content-page",
"/sv/current-content-page",
].includes(pathname)
const { toggleDropdown, isMyPagesMobileMenuOpen, isHamburgerMenuOpen } =
useDropdownStore()
function handleMyPagesMobileMenuClick() {
// Only track click when opening it
if (!isMyPagesMobileMenuOpen) {
trackClick("profile picture icon")
}
toggleDropdown(DropdownTypeEnum.MyPagesMobileMenu)
}
const trackHamburgerMenuClick = (title: string) => {
if (isHamburgerMenuOpen) {
trackClick(`hamburger - ${title}`)
}
}
return (
<div className={styles.mainMenu}>
<div
className={styles.container}
itemScope
itemType="http://schema.org/Organization"
>
<meta itemProp="name" content="Scandic" />
<nav className={styles.navBar}>
<button
aria-pressed="false"
className={`${styles.expanderBtn} ${isHamburgerMenuOpen ? styles.expanded : ""}`}
onClick={() => toggleDropdown(DropdownTypeEnum.HamburgerMenu)}
type="button"
>
<span className={styles.iconBars}></span>
<span className={styles.hiddenAccessible}>Menu</span>
</button>
<a className={styles.logoLink} href={homeHref}>
<span className={styles.hiddenAccessible}>{frontpageLinkText}</span>
<Image
alt="Scandic Hotels logo"
className={styles.logo}
data-js="scandiclogoimg"
data-nosvgsrc="/_static/img/scandic-logotype.png"
itemProp="logo"
height={22}
src={logo.url}
width={logo.dimension.width}
priority
/>
</a>
<ul
className={`${styles.listWrapper} ${isHamburgerMenuOpen ? styles.isOpen : ""}`}
>
<ul className={styles.linkRow}>
{user ? (
<li className={styles.mobileLinkRow}>
<Link
className={styles.mobileLinkButton}
href={myPages[lang]}
>
{intl.formatMessage({
defaultMessage: "My pages",
})}
</Link>
</li>
) : (
<>
<li>
<Image
src="/_static/img/icon-scandic-friends.svg"
alt="Scanidc Friends Logo"
height={35}
width={35}
className={styles.scandicFriendsLogo}
/>
</li>
<li className={styles.mobileLinkRow}>
<LoginButton
lang={lang}
redirectTo={loginPathname}
trackingId="loginStartHamburgerMenu"
className={styles.mobileLinkButton}
onClick={() => {
trackLoginClick("hamburger menu")
}}
>
{intl.formatMessage({
defaultMessage: "Log in",
})}
</LoginButton>
</li>
</>
)}
<li className={styles.mobileLinkRow}>
<span className={styles.mobileSeparator} />
</li>
<li className={styles.mobileLinkRow}>
<Link
className={styles.mobileLinkButton}
href={getCurrentWebUrl({
path: findMyBookingCurrentWebPath[lang],
lang,
baseUrl,
})}
>
{intl.formatMessage({
defaultMessage: "Find booking",
})}
</Link>
</li>
</ul>
<ul className={styles.mainLinks}>
{links.map((link, i) => (
<li className={styles.li} key={link.href + i}>
<Link
id={`hamburger - ${link.title}`}
className={styles.link}
href={link.href}
onClick={() => trackHamburgerMenuClick(link.title)}
>
{link.title}
</Link>
</li>
))}
</ul>
<ul className={styles.mobileList}>
{topMenuMobileLinks.map(({ link }, i) => (
<li className={styles.mobileLi} key={link.href + i}>
<Link
id={`hamburger - ${link.title}`}
className={styles.mobileLink}
href={link.href}
onClick={() => trackHamburgerMenuClick(link.title)}
>
{link.title}
</Link>
</li>
))}
</ul>
{languageSwitcher ? (
<li className={styles.mobileLi}>{languageSwitcher}</li>
) : null}
{!!user ? (
<li className={`${styles.mobileLi} ${styles.logout}`}>
<Link
href={logout[lang]}
className={styles.mobileLink}
prefetch={false}
>
{intl.formatMessage({
defaultMessage: "Log out",
})}
</Link>
</li>
) : null}
</ul>
<div className={styles.buttonContainer}>
<div className={styles.myPagesDesktopLink}>
{!isThreeStaticPagesPathnames && user ? (
<Link className={styles.link} href={myPages[lang]}>
{intl.formatMessage({
defaultMessage: "My pages",
})}
</Link>
) : null}
</div>
<BookingButton href={bookingHref} />
{!isThreeStaticPagesPathnames && myPagesMobileDropdown && user ? (
<div
role="button"
onClick={handleMyPagesMobileMenuClick}
className={styles.avatarButton}
>
<Avatar firstName={user.firstName} lastName={user.lastName} />
</div>
) : null}
</div>
{isMyPagesMobileMenuOpen ? myPagesMobileDropdown : null}
</nav>
</div>
</div>
)
}
export function MainMenuSkeleton() {
return (
<div className={styles.mainMenu}>
<div
className={styles.container}
itemScope
itemType="http://schema.org/Organization"
>
<meta itemProp="name" content="Scandic" />
<nav className={styles.navBar}>
<button
aria-pressed="false"
className={styles.expanderBtn}
type="button"
>
<span className={styles.iconBars}></span>
<span className={styles.hiddenAccessible}>Menu</span>
</button>
<a className={styles.logoLink} href={""}>
<Image
alt="Scandic Hotels logo"
className={styles.logo}
data-js="scandiclogoimg"
itemProp="logo"
height={20}
src={"/_static/img/scandic-logotype.png"}
width={200}
/>
</a>
<ul className={styles.listWrapper}>
{Array.from({ length: 5 }, () => "").map((_, i) => (
<li className={`${styles.li} ${styles.skeletonWrapper}`} key={i}>
<SkeletonShimmer height="22px" width="130px" />
</li>
))}
</ul>
<div className={styles.buttonContainer}>
<BookingButton href={""} />
</div>
</nav>
</div>
</div>
)
}

View File

@@ -1,348 +0,0 @@
.mainMenu {
background-color: var(--Main-Grey-White);
background-image: none;
box-shadow: 0px 1.001px 1.001px 0px rgba(0, 0, 0, 0.05);
max-height: 100%;
overflow: visible;
width: 100%;
height: var(--current-mobile-site-header-height);
max-width: var(--max-width-navigation);
margin: 0 auto;
}
.container {
box-sizing: content-box;
height: 100%;
margin: 0 auto;
padding: 0;
}
.mainLinks {
background-color: #f3f2f1;
}
.navBar {
display: grid;
grid-template-columns: 1fr 80px 1fr;
grid-template-areas: "expanderBtn logoLink . buttonContainer";
grid-template-rows: 100%;
height: 100%;
}
.expanderBtn {
background-color: transparent;
border: none;
cursor: pointer;
justify-self: flex-start;
padding: 11px 8px 16px;
transition: 0.3s;
user-select: none;
}
.iconBars,
.iconBars::after,
.iconBars::before {
background: #757575;
border-radius: 2.3px;
display: inline-block;
height: 5px;
position: relative;
transition: 0.3s;
width: 32px;
}
.iconBars::after,
.iconBars::before {
content: "";
left: 0;
position: absolute;
transform-origin: 2.286px center;
}
.iconBars::after {
top: -8px;
}
.iconBars::before {
top: 8px;
}
.expanded .iconBars {
background: transparent;
}
.expanded .iconBars::after,
.expanded .iconBars::before {
top: 0;
transform-origin: 50% 50%;
width: 32px;
}
.expanded .iconBars::after {
transform: rotate(-45deg);
}
.expanded .iconBars::before {
transform: rotate(45deg);
}
.hiddenAccessible {
display: block;
height: 1px;
left: -100000em;
overflow: hidden;
position: absolute;
top: auto;
width: 1px;
}
.logoLink {
/*padding: 16px 0 8px;*/
display: inline-flex;
align-items: center;
height: 100%;
width: 80px;
}
.logo {
width: 80px;
object-fit: fill;
}
.listWrapper {
background-color: #fff;
border-top: 1px solid #e3e0db;
display: none;
list-style: none;
overflow-y: visible;
padding-bottom: 20px;
margin: 0;
padding-inline-start: 0;
}
.listWrapper.isOpen {
display: block;
left: 0;
position: absolute;
right: 0;
top: 100%;
}
.li {
border-bottom: none;
display: block;
line-height: 17px;
position: relative;
text-align: center;
}
.link {
color: #000;
text-decoration: none;
display: block;
font-family:
Helvetica Neue,
Helvetica,
Arial,
sans-serif;
font-size: 14px;
font-weight: 700;
padding-bottom: 20px;
padding-top: 20px;
text-transform: uppercase;
}
.link:hover {
color: #7f7369;
text-decoration: none;
}
.linkRow {
display: flex;
align-items: center;
justify-content: center;
border-bottom: 1px solid #e3e0db;
background-color: #f3f2f1 !important;
list-style: none;
}
.scandicFriendsLogo {
margin-right: 4px;
margin-left: -4px;
}
.mobileLinkRow {
margin: 6px 0;
padding: 15px 15px 15px 5px;
}
.mobileLinkButton {
font-size: 14px;
font-family:
Helvetica Neue,
Helvetica,
Arial,
sans-serif !important;
font-weight: 700;
background-color: transparent !important;
text-decoration: none;
color: #000;
outline-color: transparent;
}
.mobileSeparator {
border-left: 1px solid #e3e0db;
height: 35px;
margin-bottom: -12px;
margin-left: -1px;
margin-top: -12px;
display: block;
}
.mobileList {
padding-top: 6px;
}
.mobileLi {
display: block;
position: relative;
text-align: center;
line-height: 22.4px;
padding: 5px 0;
}
.mobileLi.logout {
padding: 0;
}
.mobileLink {
color: #000;
display: block;
font-family: Helvetica !important;
font-size: 14px;
text-decoration: none;
}
.buttonContainer {
display: inline-flex;
justify-content: flex-end;
align-items: center;
margin-right: 8px;
gap: var(--Spacing-x3);
}
.myPagesDesktopLink {
display: none;
}
.skeletonWrapper {
padding: 4px 10px;
height: 100%;
align-content: center;
}
@media (min-width: 1367px) {
.navBar {
grid-template-columns: 140px auto 1fr;
height: 82.4px;
align-content: center;
padding: 0px 0px var(--Spacing-x-quarter) 0px;
overflow: hidden;
}
.logoLink {
display: inline-block;
width: 100%;
padding: 27px 30px 26px 0;
text-align: center;
align-items: center;
}
.mainMenu {
box-shadow: none;
background-color: hsla(0, 0%, 100%, 0.95);
position: relative;
z-index: unset;
height: 82.4px;
}
.container {
padding: 0 var(--Spacing-x5) 0 120px;
}
.mainLinks {
padding-top: 2.5px;
background-color: transparent;
height: 100%;
}
.expanderBtn {
display: none;
}
.logo {
width: 102.17px;
height: 100%;
padding-bottom: 4px;
}
.listWrapper {
border-top: none;
display: flex;
align-items: center;
padding-top: 0;
position: static;
width: 100%;
padding-bottom: 0px;
height: 100%;
}
.listWrapper.isOpen {
position: static;
}
.li {
display: inline-grid;
float: none;
vertical-align: middle;
line-height: 1.15;
}
.link {
background-image: none;
font-family: var(--typography-Body-Regular-fontFamily);
font-size: var(--typography-Body-Regular-fontSize);
font-feature-settings:
"clig" off,
"liga" off;
font-weight: 600;
line-height: 125%;
padding: 30px 15px;
text-transform: uppercase;
color: var(--text-black); /* Design system should return #404040 */
}
.linkRow {
display: none;
}
.mobileList {
display: none;
padding-top: 0px;
}
.mobileLi {
display: none;
}
.buttonContainer {
margin-right: 0;
}
.avatarButton {
display: none;
}
.myPagesDesktopLink {
display: block;
}
}

View File

@@ -1,145 +0,0 @@
"use client"
import { useIntl } from "react-intl"
import { logout } from "@scandic-hotels/common/constants/routes/handleAuth"
import { Divider } from "@scandic-hotels/design-system/Divider"
import Link from "@scandic-hotels/design-system/Link"
import SkeletonShimmer from "@scandic-hotels/design-system/SkeletonShimmer"
import Title from "@scandic-hotels/design-system/Title"
import useDropdownStore from "@/stores/main-menu"
import { useMyPagesNavigation } from "@/components/Header/MainMenu/MyPagesMenuContent"
import useLang from "@/hooks/useLang"
import styles from "./my-pages-mobile-dropdown.module.css"
import type { ReactNode } from "react"
import { DropdownTypeEnum } from "@/types/components/dropdown/dropdown"
export default function MyPagesMobileDropdown() {
const intl = useIntl()
const { toggleDropdown, isMyPagesMobileMenuOpen } = useDropdownStore()
const handleOnClick = () => toggleDropdown(DropdownTypeEnum.MyPagesMobileMenu)
return (
<nav
className={`${styles.navigationMenu} ${isMyPagesMobileMenuOpen ? styles.navigationMenuIsOpen : ""}`}
>
<Title textTransform="capitalize" level="h5">
<div className={styles.heading}>
{intl.formatMessage({
defaultMessage: "My pages",
})}
</div>
</Title>
<List>
<PrimaryLinks handleOnClick={handleOnClick} />
</List>
<List>
<SecondaryLinks handleOnClick={handleOnClick} />
</List>
</nav>
)
}
function List({ children }: { children: ReactNode }) {
return (
<>
<div className={styles.dividerWrapper}>
<Divider />
</div>
<ul className={styles.dropdownWrapper}>
<ul className={styles.dropdownLinks}>{children}</ul>
</ul>
</>
)
}
function PrimaryLinks({ handleOnClick }: { handleOnClick: () => void }) {
const {
data: myPagesNavigation,
isLoading,
isSuccess,
} = useMyPagesNavigation()
const primaryLinks = myPagesNavigation?.primaryLinks ?? []
return (
<>
{isLoading && <Skeletons count={4} />}
{isSuccess &&
primaryLinks.map((link, i) => (
<li key={link.href + i}>
<Link
href={link.href}
partialMatch
size="large"
variant="myPageMobileDropdown"
onClick={handleOnClick}
>
{link.text}
</Link>
</li>
))}
</>
)
}
function SecondaryLinks({ handleOnClick }: { handleOnClick: () => void }) {
const {
data: myPagesNavigation,
isLoading,
isSuccess,
} = useMyPagesNavigation()
const secondaryLinks = myPagesNavigation?.secondaryLinks ?? []
const intl = useIntl()
const lang = useLang()
return (
<>
{isLoading && <Skeletons count={3} />}
{isSuccess &&
secondaryLinks.map((link, i) => (
<li key={link.href + i}>
<Link
href={link.href}
partialMatch
size="small"
variant="myPageMobileDropdown"
onClick={handleOnClick}
>
{link.text}
</Link>
</li>
))}
<li>
<Link
href={logout[lang]}
prefetch={false}
size="small"
variant="myPageMobileDropdown"
>
{intl.formatMessage({
defaultMessage: "Log out",
})}
</Link>
</li>
</>
)
}
function Skeletons({ count }: { count: number }) {
return (
<>
{Array.from({ length: count }).map((_, i) => (
<li key={i} className={styles.skeletonItem}>
<SkeletonShimmer width="100px" height="20px" />
</li>
))}
</>
)
}

View File

@@ -1,67 +0,0 @@
.navigationMenu {
background-color: #fff;
border-top: 1px solid #e3e0db;
display: none;
list-style: none;
overflow-y: visible;
margin: 0;
padding-inline-start: 0;
}
.navigationMenu.navigationMenuIsOpen {
display: block;
left: 0;
position: absolute;
right: 0;
top: 100%;
}
.dropdownWrapper {
display: flex;
width: 100%;
padding: 20px var(--Spacing-x2);
flex-direction: column;
justify-content: center;
align-items: flex-start;
background-color: var(--Main-Grey-White);
box-shadow:
0px 276px 77px 0px rgba(0, 0, 0, 0),
0px 177px 71px 0px rgba(0, 0, 0, 0.01),
0px 99px 60px 0px rgba(0, 0, 0, 0.05),
0px 44px 44px 0px rgba(0, 0, 0, 0.09),
0px 11px 24px 0px rgba(0, 0, 0, 0.1);
}
.dividerWrapper {
background-color: var(--Main-Grey-White);
padding: 0 var(--Spacing-x2);
margin: auto;
place-content: center;
display: flex;
}
.heading {
padding: 20px var(--Spacing-x2);
}
.dropdownLinks {
display: flex;
flex-direction: column;
gap: var(--Spacing-x-half);
width: 100%;
list-style: none;
}
@media screen and (min-width: 1367px) {
.navigationMenu {
display: none;
}
.navigationMenu.navigationMenuIsOpen {
display: none;
}
}
.skeletonItem {
padding: var(--Spacing-x1);
}

View File

@@ -1,23 +0,0 @@
.banner {
align-items: center;
background: #606060;
color: #fff;
display: flex;
justify-content: space-between;
padding: 10px;
position: relative;
z-index: 10;
}
.hidden {
display: none;
}
.reloadBtn {
color: #fff;
background-color: #00838e;
border: 0;
border-radius: 18px;
outline: 0 none;
padding: 5px 15px;
}

View File

@@ -1,14 +0,0 @@
/* eslint-disable formatjs/no-literal-string-in-jsx */
import styles from "./banner.module.css"
export default function OfflineBanner() {
return (
<div className={`${styles.banner} ${styles.hidden}`}>
You are offline, some content may be out of date.
<button className={styles.reloadBtn} type="button">
Reload
</button>
</div>
)
}

View File

@@ -1,132 +0,0 @@
import { logout } from "@scandic-hotels/common/constants/routes/handleAuth"
import { overview } from "@scandic-hotels/common/constants/routes/myPages"
import Link from "@scandic-hotels/design-system/Link"
import { LoginButton } from "@scandic-hotels/design-system/LoginButton"
import SkeletonShimmer from "@scandic-hotels/design-system/SkeletonShimmer"
import { getName } from "@/lib/trpc/memoizedRequests"
import { getIntl } from "@/i18n"
import { getLang } from "@/i18n/serverContext"
import { getPathname } from "@/utils/getPathname"
import { trackLoginClick } from "@/utils/tracking"
import styles from "./topMenu.module.css"
import type { TopMenuProps } from "@/types/components/current/header/topMenu"
function capitalize(str: string) {
return str.charAt(0).toUpperCase().toUpperCase() + str.slice(1).toLowerCase()
}
export default async function TopMenu({
frontpageLinkText,
homeHref,
links,
languageSwitcher,
}: TopMenuProps) {
const intl = await getIntl()
const user = await getName()
const lang = await getLang()
const pathname = await getPathname()
return (
<div className={styles.topMenu}>
<div className={styles.container}>
<a className={styles.homeLink} href={homeHref}>
{frontpageLinkText}
</a>
<ul className={styles.list}>
{languageSwitcher ? (
<li className={styles.langSwitcher}>{languageSwitcher}</li>
) : null}
{links.map(({ link }, i) => (
<li key={link.href + i}>
<a className={styles.link} href={link.href}>
{link.title}
</a>
</li>
))}
<li className={styles.sessionContainer}>
{user ? (
<>
{user ? (
<Link
href={overview[lang]}
className={styles.sessionLink}
prefetch={false}
>
<span data-hj-suppress>{capitalize(user.firstName)}</span>
</Link>
) : null}
<div className={styles.loginSeparator} />
<Link
href={logout[lang]}
className={styles.sessionLink}
prefetch={false}
>
{intl.formatMessage({
defaultMessage: "Log out",
})}
</Link>
</>
) : (
<LoginButton
lang={lang}
redirectTo={pathname}
trackingId="loginStartTopMenu"
className={`${styles.sessionLink} ${styles.loginLink}`}
size="small"
onClick={() => {
trackLoginClick("hamburger menu")
}}
>
{intl.formatMessage({
defaultMessage: "Log in",
})}
</LoginButton>
)}
</li>
</ul>
</div>
</div>
)
}
export async function TopMenuSkeleton() {
const intl = await getIntl()
const links = new Array(5).fill("")
const lang = await getLang()
const pathname = await getPathname()
return (
<div className={styles.topMenu}>
<div className={styles.container}>
<ul className={styles.list}>
{links.map((_link, i) => (
<li key={i} className={styles.skeletonWrapper}>
<SkeletonShimmer width="100px" height="16px" />
</li>
))}
<li className={styles.sessionContainer}>
<LoginButton
lang={lang}
redirectTo={pathname}
trackingId="loginStartTopMenu"
className={`${styles.sessionLink} ${styles.loginLink}`}
size="small"
onClick={() => {
trackLoginClick("hamburger menu")
}}
>
{intl.formatMessage({
defaultMessage: "Log in",
})}
</LoginButton>
</li>
</ul>
</div>
</div>
)
}

View File

@@ -1,129 +0,0 @@
.topMenu {
background-color: #8d3a7c;
color: #fff;
display: none;
font-size: 14px;
padding: 0;
position: relative;
z-index: 1;
}
.container {
box-sizing: content-box;
display: flex;
justify-content: flex-end;
margin: 0 auto;
max-width: 1200px;
padding: 0 10px;
}
.homeLink {
display: none;
}
.list {
display: flex;
list-style: none;
line-height: 22.4px;
}
.link {
color: #fff;
display: inline-block;
padding: 3px 10px;
text-decoration: none;
font-family:
Helvetica Neue,
Helvetica,
Arial,
sans-serif;
font-size: 13px;
font-weight: 400;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-rendering: optimizeLegibility;
}
.langSwitcher {
text-align: center;
position: relative;
display: block;
}
.skeletonWrapper {
padding: 4px 10px;
height: 30px;
align-content: center;
}
@media screen and (min-width: 768px) {
.container {
padding: 0 30px;
}
}
@media screen and (min-width: 950px) {
.topMenu {
background-color: #3d3835;
display: block;
}
.list {
align-items: center;
}
.link {
padding-top: 4px;
padding-bottom: 4px;
}
.loginContainer {
margin-left: 10px;
background-color: #f3f2f1;
}
.loginLink {
padding-left: 30px;
padding-right: 30px;
color: #000;
font-family:
Helvetica Neue,
Helvetica,
Arial,
sans-serif !important;
}
.sessionContainer {
margin-left: 10px;
background-color: #f3f2f1;
height: 100%;
display: flex;
align-items: center;
}
.loginSeparator {
height: 15px;
border-right: 1px solid #000;
}
.sessionLink {
padding: 4px 15px;
color: #000;
font-family:
Helvetica Neue,
Helvetica,
Arial,
sans-serif !important;
font-size: 13px;
font-weight: 400;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-rendering: optimizeLegibility;
cursor: pointer;
text-align: center;
text-decoration: none;
}
.sessionLink.loginLink {
padding-left: 30px;
padding-right: 30px;
}
}

View File

@@ -1,14 +0,0 @@
.header {
display: grid;
background-color: var(--Main-Grey-White);
position: relative;
z-index: var(--header-z-index);
}
@media screen and (max-width: 950px) {
.header {
position: sticky;
top: 0;
z-index: var(--header-z-index);
}
}

View File

@@ -1,52 +0,0 @@
import { homeHrefs } from "@/constants/homeHrefs"
import { env } from "@/env/server"
import { getCurrentHeader, getName } from "@/lib/trpc/memoizedRequests"
import { getLang } from "@/i18n/serverContext"
import LanguageSwitcher from "./LanguageSwitcher"
import { MainMenu } from "./MainMenu"
import MyPagesMobileDropdown from "./MyPagesMobileDropdown"
import OfflineBanner from "./OfflineBanner"
import TopMenu from "./TopMenu"
import styles from "./header.module.css"
export default async function Header() {
const lang = await getLang()
const [data, user] = await Promise.all([getCurrentHeader(lang), getName()])
if (!data?.header) {
return null
}
const homeHref = homeHrefs[env.NODE_ENV][lang]
const { frontpageLinkText, logo, menu, topMenu } = data.header
const topMenuMobileLinks = topMenu.links
.filter((link) => link.show_on_mobile)
.sort((a, b) => (a.sort_order_mobile < b.sort_order_mobile ? 1 : -1))
return (
<header className={styles.header} role="banner">
<OfflineBanner />
<TopMenu
frontpageLinkText={frontpageLinkText}
homeHref={homeHref}
links={topMenu.links}
languageSwitcher={<LanguageSwitcher />}
/>
<MainMenu
frontpageLinkText={frontpageLinkText}
homeHref={homeHref}
links={menu.links}
logo={logo}
topMenuMobileLinks={topMenuMobileLinks}
languageSwitcher={<LanguageSwitcher />}
myPagesMobileDropdown={<MyPagesMobileDropdown />}
bookingHref={homeHref}
user={user}
/>
</header>
)
}

View File

@@ -1,34 +0,0 @@
.wrapper {
z-index: -1;
}
.picture {
visibility: visible;
opacity: 1;
transition: opacity 400ms ease-in-out 0s;
transform: translate(-50%, -50%) !important;
}
.heroImage {
width: 100%;
height: auto;
max-height: 600px;
min-height: 100px;
object-fit: cover;
object-position: center;
aspect-ratio: 1/1;
}
@media screen and (min-width: 768px) {
.heroImage {
aspect-ratio: auto;
}
}
@media screen and (min-width: 1367px) {
.wrapper {
overflow: hidden;
position: sticky;
top: 0px;
}
}

View File

@@ -1,25 +0,0 @@
/* eslint-disable formatjs/no-literal-string-in-jsx */
import Image from "@scandic-hotels/design-system/Image"
import styles from "./hero.module.css"
import type { HeroProps } from "@/types/components/current/hero"
export default function Hero({ images }: HeroProps) {
return (
<div className={styles.wrapper} aria-label="Hero" tabIndex={0}>
{images.map(({ node: image }) => (
<picture className={styles.picture} key={image.title}>
<Image
alt={image.title}
className={styles.heroImage}
height={image.dimension.height}
src={image.url}
width={image.dimension.width}
/>
</picture>
))}
</div>
)
}

View File

@@ -1,99 +0,0 @@
/* eslint-disable formatjs/no-literal-string-in-jsx */
import { headers } from "next/headers"
import { Lang } from "@scandic-hotels/common/constants/language"
import { localeToLang } from "@/constants/languages"
import { getLang } from "@/i18n/serverContext"
export default async function LangPopup() {
const headersList = await headers()
const preferedLang = headersList.get("Accept-Language") ?? ""
const possibleLangs = Object.keys(localeToLang)
if (!possibleLangs.includes(preferedLang)) {
return null
}
const langOfChoice: Lang = localeToLang[preferedLang as Lang]
const lang = await getLang()
if (langOfChoice === lang) {
return null
}
let language = ""
let viewIn = ""
switch (langOfChoice) {
case Lang.de:
language = "Deutsch"
viewIn = "Ansicht in"
break
case Lang.da:
language = "Dansk"
viewIn = "Se in"
break
case Lang.fi:
language = "Suomi"
viewIn = "Katso in"
break
case Lang.no:
language = "Norsk"
viewIn = "Se in"
break
case Lang.sv:
language = "Svenska"
viewIn = "Visa in"
break
}
return (
<div className="lang-popup hidden" id="lang-popup">
<a
href="#"
className="lang-popup__close"
title="Close language change popup"
>
<svg
xmlns="http://www.w3.org/2000/svg"
xmlnsXlink="http://www.w3.org/1999/xlink"
width="16px"
height="16px"
viewBox="0 0 16 16"
version="1.1"
style={{
stroke: "#757575",
width: "14px",
height: "14px",
display: "block",
strokeWidth: "2px",
}}
>
<title>Close</title>
<g id="web-close" fillRule="evenodd">
<line x1="0" y1="0" x2="100%" y2="100%" />
<line x1="0" y1="100%" x2="100%" y2="0" />
</g>
</svg>
</a>
<div className="lang-popup__body">
<p className="lang-popup__msg">
You are viewing our website in English, would you like to change to{" "}
{language}?
</p>
</div>
<div className="lang-popup__footer">
<a href="" className="lang-popup__cta btn btn--primary">
{viewIn} {language}
</a>
<a href="#" className="lang-popup__cancel btn btn--link">
No thanks
</a>
</div>
</div>
)
}

View File

@@ -1,22 +0,0 @@
import styles from "./loading.module.css"
export default function LoadingSpinner() {
return (
<div className={styles.container}>
<div className={styles.spinner}>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
</div>
)
}

View File

@@ -1,89 +0,0 @@
.container {
display: flex;
justify-content: center;
align-items: center;
height: 200px;
}
.spinner {
display: inline-block;
position: relative;
width: 80px;
height: 80px;
}
.spinner div {
transform-origin: 40px 40px;
animation: spinnerAnimation 1.2s linear infinite;
}
.spinner div::after {
content: " ";
display: block;
position: absolute;
top: 3px;
left: 37px;
width: 6px;
height: 18px;
border-radius: 20%;
background: red;
}
.spinner div:nth-child(1) {
transform: rotate(0deg);
animation-delay: -1.1s;
}
.spinner div:nth-child(2) {
transform: rotate(30deg);
animation-delay: -1s;
}
.spinner div:nth-child(3) {
transform: rotate(60deg);
animation-delay: -0.9s;
}
.spinner div:nth-child(4) {
transform: rotate(90deg);
animation-delay: -0.8s;
}
.spinner div:nth-child(5) {
transform: rotate(120deg);
animation-delay: -0.7s;
}
.spinner div:nth-child(6) {
transform: rotate(150deg);
animation-delay: -0.6s;
}
.spinner div:nth-child(7) {
transform: rotate(180deg);
animation-delay: -0.5s;
}
.spinner div:nth-child(8) {
transform: rotate(210deg);
animation-delay: -0.4s;
}
.spinner div:nth-child(9) {
transform: rotate(240deg);
animation-delay: -0.3s;
}
.spinner div:nth-child(10) {
transform: rotate(270deg);
animation-delay: -0.2s;
}
.spinner div:nth-child(11) {
transform: rotate(300deg);
animation-delay: -0.1s;
}
.spinner div:nth-child(12) {
transform: rotate(330deg);
animation-delay: 0s;
}
@keyframes spinnerAnimation {
0% {
opacity: 1;
}
100% {
opacity: 0;
}
}

View File

@@ -1,43 +0,0 @@
.nav {
display: none;
padding-bottom: 8px;
}
.parent {
display: none;
}
.list {
align-items: center;
display: grid;
gap: 7px;
grid-auto-flow: column;
justify-content: flex-start;
}
.link {
color: #333;
}
.currentPage {
color: #7f7369;
margin-bottom: 0px;
}
.currentPage,
.li {
font-size: 0.875rem;
line-height: 1.4em;
}
.li::before,
.currentPage::before {
content: "";
margin-right: 4px;
}
@media (min-width: 740px) {
.nav {
display: block;
}
}

View File

@@ -1,31 +0,0 @@
import styles from "./breadcrumbs.module.css"
import type { BreadcrumbsProps } from "@/types/components/current/breadcrumbs"
export default function Breadcrumbs({
breadcrumbs,
parent,
title,
}: BreadcrumbsProps) {
return (
<nav className={styles.nav}>
<ul className={styles.list}>
{parent ? (
<li className={styles.parent}>
<a href={parent.href}>{parent.title}</a>
</li>
) : null}
{breadcrumbs.map((breadcrumb) => (
<li className={styles.li} itemProp="breadcrumb" key={breadcrumb.href}>
<a className={styles.link} href={breadcrumb.href}>
{breadcrumb.title}
</a>
</li>
))}
<li className={styles.currentPage}>
<span>{title}</span>
</li>
</ul>
</nav>
)
}

View File

@@ -1,37 +0,0 @@
import DeprecatedJsonToHtml from "@/components/DeprecatedJsonToHtml"
import { renderOptions as currentRenderOptions } from "./../currentRenderOptions"
import Breadcrumbs from "./Breadcrumbs"
import { renderOptions } from "./renderOptions"
import styles from "./preamble.module.css"
import type { PreambleProps } from "@/types/components/current/preamble"
export default function Preamble({
breadcrumbs,
breadcrumbParent,
breadcrumbTitle,
preamble,
title,
}: PreambleProps) {
return (
<section className={styles.container}>
<section>
<Breadcrumbs
breadcrumbs={breadcrumbs}
parent={breadcrumbParent}
title={breadcrumbTitle}
/>
<h1>{title}</h1>
{preamble?.text ? (
<DeprecatedJsonToHtml
embeds={preamble.text.embedded_itemsConnection.edges}
nodes={preamble.text.json.children}
renderOptions={{ ...currentRenderOptions, ...renderOptions }}
/>
) : null}
</section>
</section>
)
}

View File

@@ -1,43 +0,0 @@
.container {
display: grid;
gap: 60px;
margin: 0 auto;
padding: 20px 10px 25px;
background: #fff;
box-sizing: content-box;
}
.preamble {
color: #333;
font-family:
Helvetica Neue,
Roboto,
Helvetica,
Arial,
sans-serif;
font-size: 1.25rem;
font-weight: 300;
line-height: normal;
text-transform: none;
margin-bottom: 0;
}
@media screen and (min-width: 768px) {
.container {
background: transparent;
padding: 30px 30px 15px;
grid-template-columns: 2fr 1fr;
max-width: 1200px;
}
}
@media screen and (min-width: 1367px) {
.container {
padding: 50px 30px 35px;
}
.preamble {
font-size: 1.5rem;
line-height: 2.25rem;
}
}

View File

@@ -1,22 +0,0 @@
import { RTETypeEnum } from "@scandic-hotels/trpc/types/RTEenums"
import styles from "./preamble.module.css"
import type { EmbedByUid } from "@/types/components/deprecatedjsontohtml"
import type { RTEDefaultNode, RTENext } from "@/types/rte/node"
import type { RenderOptions } from "@/types/rte/option"
export const renderOptions: RenderOptions = {
[RTETypeEnum.p]: (
node: RTEDefaultNode,
embeds: EmbedByUid,
next: RTENext,
fullRenderOptions: RenderOptions
) => {
return (
<p key={node.uid} className={styles.preamble}>
{next(node.children, embeds, fullRenderOptions)}
</p>
)
},
}

View File

@@ -1,9 +0,0 @@
import styles from "./section.module.css"
export default function Section({ children }: React.PropsWithChildren) {
return (
<div className={styles.wrapper}>
<section className={styles.section}>{children}</section>
</div>
)
}

View File

@@ -1,24 +0,0 @@
.section {
box-sizing: content-box;
margin: 0 auto;
}
@media screen and (min-width: 768px) {
.section {
padding: 30px 30px 15px;
grid-template-columns: 2fr 1fr;
display: grid;
gap: 70px;
max-width: 1200px;
}
.wrapper {
background-color: #fff;
}
}
@media screen and (min-width: 1367px) {
.section {
padding: 50px 30px 35px;
}
}

View File

@@ -1,29 +0,0 @@
import type { SubnavMobileProps } from "@/types/components/current/subnavMobile"
export default async function SubnavMobile({
breadcrumbs,
parent,
title,
}: SubnavMobileProps) {
return (
<div className="subnav-mobile hidden-small hidden-medium hidden-large">
<nav className="u-flex">
<ul className="breadcrumb-list hidden-small hidden-medium hidden-large">
{parent ? (
<li className="breadcrumb-list__parent hidden-medium hidden-large">
<a href={parent.href}>{parent.title}</a>
</li>
) : null}
{breadcrumbs.map((breadcrumb) => (
<li className="breadcrumb-list__body" key={breadcrumb.href}>
<a href={breadcrumb.href}>{breadcrumb.title}</a>
</li>
))}
<li className="breadcrumb-list__body">
<span>{title}</span>
</li>
</ul>
</nav>
</div>
)
}

View File

@@ -1,122 +0,0 @@
"use client"
import { usePathname, useSearchParams } from "next/navigation"
import { useEffect } from "react"
import { logger } from "@scandic-hotels/common/logger"
import type {
SiteSectionObject,
TrackingData,
TrackingProps,
} from "@scandic-hotels/tracking/types"
function createPageObject(trackingData: TrackingData) {
const englishSegments = trackingData.englishUrl
? trackingData.englishUrl.split("/").filter((seg?: string) => seg)
: null
const [lang, ...segments] = trackingData.pathName
.split("/")
.filter((seg: string) => seg)
function getSiteSections(segments: string[]): SiteSectionObject {
/*
Adobe expects the properties sitesection1 - sitessection6, hence the for-loop below
The segments ['explore-scandic', 'wifi'] should result in:
{
sitesection1: "explore-scandic",
sitesection2: "explore-scandic|wifi",
sitesection3: "explore-scandic|wifi|",
sitesection4: "explore-scandic|wifi||",
sitesection5: "explore-scandic|wifi|||",
sitesection6: "explore-scandic|wifi||||",
}
*/
const sitesections = {} as SiteSectionObject
for (let i = 0; i < 6; i++) {
const key = ("sitesection" + (i + 1)) as keyof SiteSectionObject
sitesections[key] = segments.slice(0, i + 1).join("|")
if (i > 0 && !segments[i]) {
sitesections[key] = sitesections[key].concat(
"|".repeat(i + 1 - segments.length)
)
}
}
return sitesections
}
const sitesections = englishSegments
? getSiteSections(englishSegments)
: getSiteSections(segments)
const { host: domain, href: fullurl, origin } = window.location
const page_obj = {
pagename: englishSegments ? englishSegments.join("|") : segments.join("|"),
pagetype: "contentpage",
pageurl: origin + trackingData.pathName,
fullurl,
createDate: trackingData.createdDate,
publishDate: trackingData.publishedDate,
domain,
errorcode: null, // handle
querystring: trackingData.queryString || "",
pageid: trackingData.pageId,
// sessionid: "<unique identifier of session>", // base on what?
domainlanguage: trackingData.lang ? trackingData.lang : lang,
hotelbrand: "scandic",
siteversion: "new-web",
...sitesections,
}
return page_obj
}
export default function Tracking({ pageData }: TrackingProps) {
const pathName = usePathname()
const queryString = useSearchParams().toString()
function CookiebotCallbackOnAccept() {
const cookie = window._satellite.cookie.get("CookieConsent")
if (window.Cookiebot?.changed && window.adobe) {
if (cookie?.includes("statistics:true")) {
window.adobe.optIn.approve(window.adobe.OptInCategories.ANALYTICS, true)
} else {
window.adobe.optIn.deny(window.adobe.OptInCategories.ANALYTICS, true)
}
window.adobe.optIn.complete()
logger.warn("window.load event explicitly dispatched.")
window.dispatchEvent(new Event("load"))
}
}
function CookebotCallbackOnDecline() {
if (window.Cookiebot?.changed && window.adobe) {
window.adobe.optIn.deny(window.adobe.OptInCategories.ANALYTICS, true)
}
}
useEffect(() => {
if (window.dataLayer) {
const trackingData = { ...pageData, pathName, queryString }
const pageObject = createPageObject(trackingData)
window.dataLayer.page = pageObject
}
}, [pathName, queryString, pageData])
useEffect(() => {
// handle consent
window.addEventListener("CookiebotOnAccept", CookiebotCallbackOnAccept)
window.addEventListener("CookiebotOnDecline", CookebotCallbackOnDecline)
return () => {
window.removeEventListener("CookiebotOnAccept", CookiebotCallbackOnAccept)
window.removeEventListener(
"CookiebotOnDecline",
CookebotCallbackOnDecline
)
}
}, [])
return null
}

View File

@@ -1,6 +0,0 @@
.image {
height: auto;
margin-bottom: var(--Spacing-x2);
max-width: 100%;
object-fit: cover;
}

View File

@@ -1,477 +0,0 @@
import Image from "@scandic-hotels/design-system/Image"
import Link from "@scandic-hotels/design-system/Link"
import {
RTEItemTypeEnum,
RTETypeEnum,
} from "@scandic-hotels/trpc/types/RTEenums"
import styles from "./currentRenderOptions.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,
RTEMarkType,
type RTENext,
type RTENode,
type RTERegularNode,
} from "@/types/rte/node"
import type { RenderOptions } from "@/types/rte/option"
function extractPossibleAttributes(attrs: Attributes | undefined) {
if (!attrs) return {}
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 (
<a
{...props}
href={node.attrs.url}
target={node.attrs.target ?? "_blank"}
key={node.uid}
>
{next(node.children, embeds, fullRenderOptions)}
</a>
)
}
return null
},
[RTETypeEnum.blockquote]: (
node: RTEDefaultNode,
embeds: EmbedByUid,
next: RTENext,
fullRenderOptions: RenderOptions
) => {
const props = extractPossibleAttributes(node.attrs)
return (
<blockquote key={node.uid} {...props}>
{next(node.children, embeds, fullRenderOptions)}
</blockquote>
)
},
[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 (
<h1 key={node.uid} {...props}>
{next(node.children, embeds, fullRenderOptions)}
</h1>
)
},
[RTETypeEnum.h2]: (
node: RTEDefaultNode,
embeds: EmbedByUid,
next: RTENext,
fullRenderOptions: RenderOptions
) => {
const props = extractPossibleAttributes(node.attrs)
return (
<h2 key={node.uid} {...props}>
{next(node.children, embeds, fullRenderOptions)}
</h2>
)
},
[RTETypeEnum.h3]: (
node: RTEDefaultNode,
embeds: EmbedByUid,
next: RTENext,
fullRenderOptions: RenderOptions
) => {
const props = extractPossibleAttributes(node.attrs)
return (
<h3 key={node.uid} {...props}>
{next(node.children, embeds, fullRenderOptions)}
</h3>
)
},
[RTETypeEnum.h4]: (
node: RTEDefaultNode,
embeds: EmbedByUid,
next: RTENext,
fullRenderOptions: RenderOptions
) => {
const props = extractPossibleAttributes(node.attrs)
return (
<h4 key={node.uid} {...props}>
{next(node.children, embeds, fullRenderOptions)}
</h4>
)
},
[RTETypeEnum.h5]: (
node: RTEDefaultNode,
embeds: EmbedByUid,
next: RTENext,
fullRenderOptions: RenderOptions
) => {
const props = extractPossibleAttributes(node.attrs)
return (
<h5 key={node.uid} {...props}>
{next(node.children, embeds, fullRenderOptions)}
</h5>
)
},
[RTETypeEnum.h6]: (
node: RTEDefaultNode,
embeds: EmbedByUid,
next: RTENext,
fullRenderOptions: RenderOptions
) => {
const props = extractPossibleAttributes(node.attrs)
return (
<h6 key={node.uid} {...props}>
{next(node.children, embeds, fullRenderOptions)}
</h6>
)
},
[RTETypeEnum.hr]: () => {
return <hr />
},
[RTETypeEnum.li]: (
node: RTEDefaultNode,
embeds: EmbedByUid,
next: RTENext,
fullRenderOptions: RenderOptions
) => {
const props = extractPossibleAttributes(node.attrs)
return (
<li key={node.uid} {...props}>
{next(node.children, embeds, fullRenderOptions)}
</li>
)
},
[RTETypeEnum.ol]: (
node: RTEDefaultNode,
embeds: EmbedByUid,
next: RTENext,
fullRenderOptions: RenderOptions
) => {
const props = extractPossibleAttributes(node.attrs)
return (
<ol key={node.uid} {...props}>
{next(node.children, embeds, fullRenderOptions)}
</ol>
)
},
[RTETypeEnum.p]: (
node: RTEDefaultNode,
embeds: EmbedByUid,
next: RTENext,
fullRenderOptions: RenderOptions
) => {
const props = extractPossibleAttributes(node.attrs)
return (
<p {...props} key={node.uid}>
{next(node.children, embeds, fullRenderOptions)}
</p>
)
},
[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 alignment = node.attrs?.style?.["text-align"]
? {
alignSelf: node.attrs?.style?.["text-align"],
}
: {}
return (
<Image
key={node.uid}
alt={alt}
className={styles.image}
height={image.node.dimension.height}
src={image?.node?.url}
width={image.node.dimension.width}
style={alignment}
/>
)
}
} else {
const props = extractPossibleAttributes(node.attrs)
const href = node.attrs?.locale
? `/${node.attrs.locale}${node.attrs.href}`
: node.attrs.href
return (
<Link {...props} href={href} key={node.uid}>
{next(node.children, embeds, fullRenderOptions)}
</Link>
)
}
}
return null
},
[RTETypeEnum.table]: (
node: RTEDefaultNode,
embeds: EmbedByUid,
next: RTENext,
fullRenderOptions: RenderOptions
) => {
const props = extractPossibleAttributes(node.attrs)
return (
<table key={node.uid} {...props}>
{next(node.children, embeds, fullRenderOptions)}
</table>
)
},
[RTETypeEnum.thead]: (
node: RTEDefaultNode,
embeds: EmbedByUid,
next: RTENext,
fullRenderOptions: RenderOptions
) => {
const props = extractPossibleAttributes(node.attrs)
return (
<thead key={node.uid} {...props}>
{next(node.children, embeds, fullRenderOptions)}
</thead>
)
},
[RTETypeEnum.tbody]: (
node: RTEDefaultNode,
embeds: EmbedByUid,
next: RTENext,
fullRenderOptions: RenderOptions
) => {
const props = extractPossibleAttributes(node.attrs)
return (
<tbody key={node.uid} {...props}>
{next(node.children, embeds, fullRenderOptions)}
</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.tr]: (
node: RTEDefaultNode,
embeds: EmbedByUid,
next: RTENext,
fullRenderOptions: RenderOptions
) => {
const props = extractPossibleAttributes(node.attrs)
return (
<tr key={node.uid} {...props}>
{next(node.children, embeds, fullRenderOptions)}
</tr>
)
},
[RTETypeEnum.th]: (
node: RTEDefaultNode,
embeds: EmbedByUid,
next: RTENext,
fullRenderOptions: RenderOptions
) => {
const props = extractPossibleAttributes(node.attrs)
return (
<th key={node.uid} {...props}>
{next(node.children, embeds, fullRenderOptions)}
</th>
)
},
[RTETypeEnum.td]: (
node: RTEDefaultNode,
embeds: EmbedByUid,
next: RTENext,
fullRenderOptions: RenderOptions
) => {
const props = extractPossibleAttributes(node.attrs)
return (
<td key={node.uid} {...props}>
{next(node.children, embeds, fullRenderOptions)}
</td>
)
},
[RTETypeEnum.ul]: (
node: RTEDefaultNode,
embeds: EmbedByUid,
next: RTENext,
fullRenderOptions: RenderOptions
) => {
const props = extractPossibleAttributes(node.attrs)
return (
<ul key={node.uid} {...props}>
{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
) => {
let props = {
className,
id,
}
if (!className) {
delete props.className
}
if (!id) {
delete props.id
}
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)
},
}

View File

@@ -1,6 +1,6 @@
import { Suspense } from "react" import { Suspense } from "react"
import { getHeader, getName } from "@/lib/trpc/memoizedRequests" import { getHeader } from "@/lib/trpc/memoizedRequests"
import MainMenu from "./MainMenu" import MainMenu from "./MainMenu"
import TopMenu, { TopMenuSkeleton } from "./TopMenu" import TopMenu, { TopMenuSkeleton } from "./TopMenu"
@@ -8,7 +8,6 @@ import TopMenu, { TopMenuSkeleton } from "./TopMenu"
import styles from "./header.module.css" import styles from "./header.module.css"
export default async function Header() { export default async function Header() {
void getName()
void getHeader() void getHeader()
return ( return (

View File

@@ -37,7 +37,6 @@
.text { .text {
font-family: font-family:
Helvetica Neue, Helvetica Neue,
Roboto,
Helvetica, Helvetica,
Arial, Arial,
sans-serif; sans-serif;

View File

@@ -1,14 +0,0 @@
import { getIntl } from "@/i18n"
export default async function SkipToMainContent() {
const intl = await getIntl()
return (
<div className="navigation--skip-to-content">
<a data-js="skip-to-content" href="#maincontent">
{intl.formatMessage({
defaultMessage: "Skip to main content",
})}
</a>
</div>
)
}

View File

@@ -37,7 +37,6 @@
.text { .text {
font-family: font-family:
Helvetica Neue, Helvetica Neue,
Roboto,
Helvetica, Helvetica,
Arial, Arial,
sans-serif; sans-serif;

View File

@@ -20,11 +20,6 @@ export const getProfile = cache(async function getMemoizedProfile() {
return caller.user.get() return caller.user.get()
}) })
export const getName = cache(async function getMemoizedName() {
const caller = await serverClient()
return caller.user.name()
})
export const getProfileSafely = cache( export const getProfileSafely = cache(
async function getMemoizedProfileSafely() { async function getMemoizedProfileSafely() {
const caller = await serverClient() const caller = await serverClient()
@@ -101,20 +96,6 @@ export const getHeader = cache(async function getMemoizedHeader() {
return caller.contentstack.base.header() return caller.contentstack.base.header()
}) })
export const getCurrentHeader = cache(async function getMemoizedCurrentHeader(
lang: Lang
) {
const caller = await serverClient()
return caller.contentstack.base.currentHeader({ lang })
})
export const getCurrentFooter = cache(async function getMemoizedCurrentFooter(
lang: Lang
) {
const caller = await serverClient()
return caller.contentstack.base.currentFooter({ lang })
})
export const getSiteConfig = cache(async function getMemoizedSiteConfig( export const getSiteConfig = cache(async function getMemoizedSiteConfig(
lang: Lang lang: Lang
) { ) {

View File

@@ -76,8 +76,6 @@ export const middleware: NextMiddleware = async (request) => {
headers.set("x-uid", uid) headers.set("x-uid", uid)
headers.set("x-contenttype", contentType) headers.set("x-contenttype", contentType)
const isCurrent = contentType ? contentType.indexOf("current") >= 0 : false
if (isPreview) { if (isPreview) {
searchParams.set("isPreview", "true") searchParams.set("isPreview", "true")
return NextResponse.rewrite( return NextResponse.rewrite(
@@ -93,23 +91,6 @@ export const middleware: NextMiddleware = async (request) => {
) )
} }
if (isCurrent) {
const contentTypePathName = pathWithoutTrailingSlash.replace(`/${lang}`, "")
searchParams.set("uid", uid)
searchParams.set("uri", contentTypePathName)
return NextResponse.rewrite(
new URL(
`/${lang}/current-content-page?${searchParams.toString()}`,
nextUrl
),
{
request: {
headers,
},
}
)
}
return NextResponse.rewrite( return NextResponse.rewrite(
new URL( new URL(
`/${lang}/${contentType}/${uid}?${searchParams.toString()}`, `/${lang}/${contentType}/${uid}?${searchParams.toString()}`,

View File

@@ -1,213 +0,0 @@
body #CybotCookiebotDialog * {
font-family: Helvetica, Arial, sans-serif !important
}
body #CybotCookiebotDialog,
body #CybotCookiebotDialog * {
-webkit-box-sizing: border-box;
box-sizing: border-box
}
body #CybotCookiebotDialog {
border-radius: 0;
border: 0;
-webkit-box-shadow: 0 0 transparent;
box-shadow: 0 0 transparent;
top: 50%;
left: 50%;
-webkit-transform: translate(-50%, -50%) !important;
transform: translate(-50%, -50%) !important;
margin: 0 !important;
padding: 15px;
max-height: 90%;
-webkit-transform-origin: unset !important;
transform-origin: unset !important;
overflow-y: auto
}
body #CybotCookiebotDialog div,
body #CybotCookiebotDialog h2 {
color: #333
}
body #CybotCookiebotDialogBodyContent {
padding: 0 !important
}
body #CybotCookiebotDialogBodyContentTitle {
font-size: 1.375rem;
font-family: BrandonText-Black, Arial, Helvetica, sans-serif !important
}
body div#CybotCookiebotDialogBodyContentText {
font-size: 1rem;
line-height: 1.4rem;
margin: 15px 0
}
body #CybotCookiebotDialogDetailBody {
max-width: 100%;
padding: 0
}
body #CybotCookiebotDialogDetailBodyContent {
height: 160px
}
body #CybotCookiebotDialogDetailBodyContentTextOverview {
max-width: 100%
}
body #CybotCookiebotDialogDetailBodyContentCookieContainerTypeDetails {
height: 155px;
max-height: 155px
}
body #CybotCookiebotDialogBodyLevelButtonsSelectPane {
border: none;
padding: 0 0 30px
}
body .CybotCookiebotDialogBodyLevelButtonWrapper {
margin: 20px 0 0 !important;
padding-right: 25px
}
body .CybotCookiebotDialogBodyLevelButtonWrapper label {
font-size: 13px !important;
padding-left: 20px !important;
background: url(/_static/img/icons/shared/checkbox_unselected.svg) no-repeat left 0 !important
}
body input[type=checkbox].CybotCookiebotDialogBodyLevelButton:checked+label {
background: url(/_static/img/icons/shared/checkbox_selected.svg) no-repeat left 0 !important
}
body input[type=checkbox].CybotCookiebotDialogBodyLevelButton.CybotCookiebotDialogBodyLevelButtonDisabled+label {
background: url(/_static/img/icons/shared/checkbox_disabled.svg) no-repeat left 0 !important
}
body #CybotCookiebotDialogBodyLevelWrapper {
display: -ms-flexbox !important;
display: flex !important;
-ms-flex-direction: column-reverse;
flex-direction: column-reverse;
text-align: left;
padding: 0 0 5px
}
body #CybotCookiebotDialogBodyLevelWrapper>div {
padding: 0
}
body #CybotCookiebotDialogBodyLevelButtons {
margin: 0 0 20px !important
}
body #CybotCookiebotDialogBodyLevelButtonsTable {
width: auto !important;
margin: 0 !important
}
body #CybotCookiebotDialogBodyLevelDetailsWrapper {
background: none;
border: 0;
width: auto;
display: inline-block;
padding: 0 20px 0 0;
height: auto
}
body a#CybotCookiebotDialogBodyLevelDetailsButton {
background: none !important;
outline: 0 none;
padding: 0 10px 0 0;
color: #00838e;
font-size: 1rem;
line-height: 1.4rem;
height: auto
}
body a#CybotCookiebotDialogBodyLevelDetailsButton:focus,
body a#CybotCookiebotDialogBodyLevelDetailsButton:hover {
text-decoration: none;
color: #00838e
}
body #CybotCookiebotDialogBodyLevelDetailsWrapper:after {
margin-top: -7px;
background-position: 50%;
height: 14px
}
body #CybotCookiebotDialogBodyLevelDetailsWrapper.active:after {
-webkit-transform: rotate(180deg);
transform: rotate(180deg)
}
body a.CybotCookiebotDialogBodyButton {
width: auto !important;
padding: 5px 15px !important;
border-radius: 25px;
height: auto !important;
font-weight: 400 !important;
font-size: 1rem !important;
margin: 0 !important;
border: 0 !important;
line-height: 1.375rem !important
}
body #CybotCookiebotDialogBodyUnderlay {
position: fixed;
bottom: 0;
top: 0;
left: 0;
right: 0;
opacity: .4 !important
}
@media(max-width: 739px) {
body #CybotCookiebotDialog {
width: 90% !important
}
body a.CybotCookiebotDialogBodyButton {
width: 100% !important
}
}
@media(min-width: 740px) {
body #CybotCookiebotDialogBody {
padding: 15px;
min-width: 560px
}
body #CybotCookiebotDialogBodyContentTitle {
font-size: 1.625rem
}
body #CybotCookiebotDialogBodyLevelDetailsButton {
font-size: 1rem
}
body #CybotCookiebotDialogBodyLevelWrapper {
-ms-flex-direction: row-reverse;
flex-direction: row-reverse;
-ms-flex-pack: justify;
justify-content: space-between;
-ms-flex-align: center;
align-items: center;
padding: 0
}
body #CybotCookiebotDialogBodyLevelButtons {
margin: 0 !important
}
}
@media(min-width: 940px) {
body #CybotCookiebotDialog {
max-width: 810px;
width: 810px !important
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,666 +0,0 @@
:root {
--typography-Body-Bold-Desktop-fontSize: 16px;
--typography-Body-Bold-fontFamily: "fira sans";
--typography-Body-Bold-fontSize: 16px;
--typography-Body-Bold-fontWeight: "medium";
--typography-Body-Bold-letterSpacing: 1.2000000476837158%;
--typography-Body-Bold-lineHeight: 150%;
--typography-Body-Bold-Mobile-fontSize: 16px;
--typography-Body-Bold-Tablet-estimate-fontSize: 16px;
--typography-Body-Bold-textCase: "original";
--typography-Body-Bold-textDecoration: "none";
--typography-Body-Inline-Desktop-fontSize: 16px;
--typography-Body-Inline-fontFamily: "fira sans";
--typography-Body-Inline-fontSize: 16px;
--typography-Body-Inline-fontWeight: "regular";
--typography-Body-Inline-letterSpacing: 1.2000000476837158%;
--typography-Body-Inline-lineHeight: 150%;
--typography-Body-Inline-Mobile-fontSize: 16px;
--typography-Body-Inline-Tablet-estimate-fontSize: 16px;
--typography-Body-Inline-textCase: "original";
--typography-Body-Inline-textDecoration: "underline";
--typography-Body-Link-Desktop-fontSize: 16px;
--typography-Body-Link-Mobile-fontSize: 16px;
--typography-Body-Link-Tablet-estimate-fontSize: 16px;
--typography-Body-Regular-Desktop-fontSize: 16px;
--typography-Body-Regular-fontFamily: "fira sans";
--typography-Body-Regular-fontSize: 16px;
--typography-Body-Regular-fontWeight: "regular";
--typography-Body-Regular-letterSpacing: 1.2000000476837158%;
--typography-Body-Regular-lineHeight: 150%;
--typography-Body-Regular-Mobile-fontSize: 16px;
--typography-Body-Regular-Tablet-estimate-fontSize: 16px;
--typography-Body-Regular-textCase: "original";
--typography-Body-Regular-textDecoration: "none";
--typography-Body-Underline-fontFamily: "fira sans";
--typography-Body-Underline-fontSize: 16px;
--typography-Body-Underline-fontWeight: "medium";
--typography-Body-Underline-letterSpacing: 1.2000000476837158%;
--typography-Body-Underline-lineHeight: 150%;
--typography-Body-Underline-textCase: "original";
--typography-Body-Underline-textDecoration: "underline";
--typography-Caption-Bold-Desktop-fontSize: 14px;
--typography-Caption-Bold-fontFamily: "fira sans";
--typography-Caption-Bold-fontSize: 14px;
--typography-Caption-Bold-fontWeight: "medium";
--typography-Caption-Bold-letterSpacing: 1.399999976158142%;
--typography-Caption-Bold-lineHeight: 139.9999976158142%;
--typography-Caption-Bold-Mobile-fontSize: 14px;
--typography-Caption-Bold-Tablet-estimate-fontSize: 14px;
--typography-Caption-Bold-textCase: "original";
--typography-Caption-Bold-textDecoration: "none";
--typography-Caption-Inline-Desktop-fontSize: 14px;
--typography-Caption-Inline-fontFamily: "fira sans";
--typography-Caption-Inline-fontSize: 14px;
--typography-Caption-Inline-fontWeight: "regular";
--typography-Caption-Inline-letterSpacing: 1.399999976158142%;
--typography-Caption-Inline-lineHeight: 139.9999976158142%;
--typography-Caption-Inline-Mobile-fontSize: 14px;
--typography-Caption-Inline-Tablet-estimate-fontSize: 14px;
--typography-Caption-Inline-textCase: "original";
--typography-Caption-Inline-textDecoration: "underline";
--typography-Caption-Labels-fontFamily: "brandon text";
--typography-Caption-Labels-fontSize: 14px;
--typography-Caption-Labels-fontWeight: "bold";
--typography-Caption-Labels-letterSpacing: 1.399999976158142%;
--typography-Caption-Labels-lineHeight: 150%;
--typography-Caption-Labels-textCase: "upper";
--typography-Caption-Labels-textDecoration: "none";
--typography-Caption-Link-Desktop-fontSize: 14px;
--typography-Caption-Link-Mobile-fontSize: 14px;
--typography-Caption-Link-Tablet-estimate-fontSize: 14px;
--typography-Caption-Regular-Desktop-fontSize: 14px;
--typography-Caption-Regular-fontFamily: "fira sans";
--typography-Caption-Regular-fontSize: 14px;
--typography-Caption-Regular-fontWeight: "regular";
--typography-Caption-Regular-letterSpacing: 1.399999976158142%;
--typography-Caption-Regular-lineHeight: 139.9999976158142%;
--typography-Caption-Regular-Mobile-fontSize: 14px;
--typography-Caption-Regular-Tablet-estimate-fontSize: 14px;
--typography-Caption-Regular-textCase: "original";
--typography-Caption-Regular-textDecoration: "none";
--typography-Caption-Underline-fontFamily: "fira sans";
--typography-Caption-Underline-fontSize: 14px;
--typography-Caption-Underline-fontWeight: "medium";
--typography-Caption-Underline-letterSpacing: 1.399999976158142%;
--typography-Caption-Underline-lineHeight: 139.9999976158142%;
--typography-Caption-Underline-textCase: "original";
--typography-Caption-Underline-textDecoration: "underline";
--typography-Foot-note-Bold-Desktop-fontSize: 12px;
--typography-Foot-note-Bold-Mobile-fontSize: 12px;
--typography-Foot-note-Bold-Tablet-estimate-fontSize: 12px;
--typography-Foot-note-Regular-Desktop-fontSize: 12px;
--typography-Foot-note-Regular-Mobile-fontSize: 12px;
--typography-Foot-note-Regular-Tablet-estimate-fontSize: 12px;
--typography-Footnote-Bold-fontFamily: "fira sans";
--typography-Footnote-Bold-fontSize: 12px;
--typography-Footnote-Bold-fontWeight: "medium";
--typography-Footnote-Bold-letterSpacing: 1.399999976158142%;
--typography-Footnote-Bold-lineHeight: 150%;
--typography-Footnote-Bold-textCase: "original";
--typography-Footnote-Bold-textDecoration: "none";
--typography-Footnote-Labels-fontFamily: "brandon text";
--typography-Footnote-Labels-fontSize: 12px;
--typography-Footnote-Labels-fontWeight: "bold";
--typography-Footnote-Labels-letterSpacing: 1.399999976158142%;
--typography-Footnote-Labels-lineHeight: 150%;
--typography-Footnote-Labels-textCase: "upper";
--typography-Footnote-Labels-textDecoration: "none";
--typography-Footnote-Regular-fontFamily: "fira sans";
--typography-Footnote-Regular-fontSize: 12px;
--typography-Footnote-Regular-fontWeight: "regular";
--typography-Footnote-Regular-letterSpacing: 1.399999976158142%;
--typography-Footnote-Regular-lineHeight: 150%;
--typography-Footnote-Regular-textCase: "original";
--typography-Footnote-Regular-textDecoration: "none";
--typography-Preamble-Desktop-fontSize: 20px;
--typography-Preamble-fontFamily: "fira sans";
--typography-Preamble-fontSize: 20px;
--typography-Preamble-fontWeight: "regular";
--typography-Preamble-letterSpacing: 1%;
--typography-Preamble-lineHeight: 139.9999976158142%;
--typography-Preamble-Mobile-fontSize: 18px;
--typography-Preamble-Tablet-estimate-fontSize: 19px;
--typography-Preamble-textCase: "original";
--typography-Preamble-textDecoration: "none";
--typography-Script-1-Desktop-fontSize: 32px;
--typography-Script-1-fontFamily: "biro script plus";
--typography-Script-1-fontSize: 32px;
--typography-Script-1-fontWeight: "regular";
--typography-Script-1-letterSpacing: 2%;
--typography-Script-1-lineHeight: 110.00000238418579%;
--typography-Script-1-Mobile-fontSize: 24px;
--typography-Script-1-Tablet-estimate-fontSize: 29px;
--typography-Script-1-textCase: "original";
--typography-Script-1-textDecoration: "none";
--typography-Script-2-Desktop-fontSize: 24px;
--typography-Script-2-fontFamily: "biro script plus";
--typography-Script-2-fontSize: 24px;
--typography-Script-2-fontWeight: "regular";
--typography-Script-2-letterSpacing: 2%;
--typography-Script-2-lineHeight: 110.00000238418579%;
--typography-Script-2-Mobile-fontSize: 20px;
--typography-Script-2-Tablet-estimate-fontSize: 22px;
--typography-Script-2-textCase: "original";
--typography-Script-2-textDecoration: "none";
--typography-Subtitle-1-Desktop-fontSize: 24px;
--typography-Subtitle-1-fontFamily: "fira sans";
--typography-Subtitle-1-fontSize: 24px;
--typography-Subtitle-1-fontWeight: "medium";
--typography-Subtitle-1-letterSpacing: 1%;
--typography-Subtitle-1-lineHeight: 120.00000476837158%;
--typography-Subtitle-1-Mobile-fontSize: 20px;
--typography-Subtitle-1-Tablet-estimate-fontSize: 22px;
--typography-Subtitle-1-textCase: "original";
--typography-Subtitle-1-textDecoration: "none";
--typography-Subtitle-2-Desktop-fontSize: 20px;
--typography-Subtitle-2-fontFamily: "fira sans";
--typography-Subtitle-2-fontSize: 20px;
--typography-Subtitle-2-fontWeight: "medium";
--typography-Subtitle-2-letterSpacing: 1%;
--typography-Subtitle-2-lineHeight: 120.00000476837158%;
--typography-Subtitle-2-Mobile-fontSize: 18px;
--typography-Subtitle-2-Tablet-estimate-fontSize: 19px;
--typography-Subtitle-2-textCase: "original";
--typography-Subtitle-2-textDecoration: "none";
--typography-Title-1-Desktop-fontSize: 64px;
--typography-Title-1-fontFamily: "brandon text";
--typography-Title-1-fontSize: 64px;
--typography-Title-1-fontWeight: "black";
--typography-Title-1-letterSpacing: 0.25%;
--typography-Title-1-lineHeight: 110.00000238418579%;
--typography-Title-1-Mobile-fontSize: 48px;
--typography-Title-1-Tablet-estimate-fontSize: 60px;
--typography-Title-1-textCase: "upper";
--typography-Title-1-textDecoration: "none";
--typography-Title-2-Desktop-fontSize: 48px;
--typography-Title-2-fontFamily: "brandon text";
--typography-Title-2-fontSize: 48px;
--typography-Title-2-fontWeight: "black";
--typography-Title-2-letterSpacing: 0.25%;
--typography-Title-2-lineHeight: 110.00000238418579%;
--typography-Title-2-Mobile-fontSize: 36px;
--typography-Title-2-Tablet-estimate-fontSize: 44px;
--typography-Title-2-textCase: "upper";
--typography-Title-2-textDecoration: "none";
--typography-Title-3-Desktop-fontSize: 36px;
--typography-Title-3-fontFamily: "brandon text";
--typography-Title-3-fontSize: 36px;
--typography-Title-3-fontWeight: "black";
--typography-Title-3-letterSpacing: 0.25%;
--typography-Title-3-lineHeight: 110.00000238418579%;
--typography-Title-3-Mobile-fontSize: 30px;
--typography-Title-3-Tablet-estimate-fontSize: 34px;
--typography-Title-3-textCase: "upper";
--typography-Title-3-textDecoration: "none";
--typography-Title-4-Desktop-fontSize: 28px;
--typography-Title-4-fontFamily: "brandon text";
--typography-Title-4-fontSize: 28px;
--typography-Title-4-fontWeight: "bold";
--typography-Title-4-letterSpacing: 0.25%;
--typography-Title-4-lineHeight: 110.00000238418579%;
--typography-Title-4-Mobile-fontSize: 24px;
--typography-Title-4-Tablet-estimate-fontSize: 26px;
--typography-Title-4-textCase: "original";
--typography-Title-4-textDecoration: "none";
--typography-Title-5-Desktop-fontSize: 24px;
--typography-Title-5-fontFamily: "brandon text";
--typography-Title-5-fontSize: 24px;
--typography-Title-5-fontWeight: "black";
--typography-Title-5-letterSpacing: 0.25%;
--typography-Title-5-lineHeight: 110.00000238418579%;
--typography-Title-5-Mobile-fontSize: 20px;
--typography-Title-5-Tablet-estimate-fontSize: 21px;
--typography-Title-5-textCase: "upper";
--typography-Title-5-textDecoration: "none";
}
:root {
--Base-Background-Primary-Elevated: var(--Scandic-Beige-00);
--Base-Background-Primary-Normal: var(--Scandic-Beige-00);
--Base-Border-Hover: var(--Scandic-Peach-80);
--Base-Border-Inverted: var(--UI-Opacity-White-100);
--Base-Border-Normal: var(--Scandic-Beige-40);
--Base-Border-Subtle: var(--Scandic-Beige-20);
--Base-Button-Inverted-Border-Disabled: var(--UI-Opacity-White-0);
--Base-Button-Inverted-Border-Hover: var(--UI-Opacity-White-0);
--Base-Button-Inverted-Border-Normal: var(--UI-Opacity-White-0);
--Base-Button-Inverted-Fill-Disabled: var(--UI-Grey-20);
--Base-Button-Inverted-Fill-Hover: var(--Scandic-Beige-10);
--Base-Button-Inverted-Fill-Hover-alt: var(--Scandic-Peach-10);
--Base-Button-Inverted-Fill-Normal: var(--UI-Opacity-White-100);
--Base-Button-Inverted-On-Fill-Disabled: var(--UI-Grey-40);
--Base-Button-Inverted-On-Fill-Hover: var(--Scandic-Red-90);
--Base-Button-Inverted-On-Fill-Normal: var(--Scandic-Red-100);
--Base-Button-Primary-Border-Disabled: var(--UI-Opacity-White-0);
--Base-Button-Primary-Border-Hover: var(--UI-Opacity-White-0);
--Base-Button-Primary-Border-Normal: var(--UI-Opacity-White-0);
--Base-Button-Primary-Fill-Disabled: var(--UI-Grey-20);
--Base-Button-Primary-Fill-Hover: var(--Scandic-Red-70);
--Base-Button-Primary-Fill-Normal: var(--Scandic-Red-60);
--Base-Button-Primary-On-Fill-Disabled: var(--UI-Grey-40);
--Base-Button-Primary-On-Fill-Hover: var(--UI-Opacity-White-100);
--Base-Button-Primary-On-Fill-Normal: var(--UI-Opacity-White-100);
--Base-Button-Secondary-Border-Disabled: var(--UI-Grey-30);
--Base-Button-Secondary-Border-Hover: var(--Scandic-Peach-80);
--Base-Button-Secondary-Border-Normal: var(--Scandic-Red-100);
--Base-Button-Secondary-Fill-Disabled: var(--UI-Opacity-White-0);
--Base-Button-Secondary-Fill-Hover: var(--UI-Opacity-White-0);
--Base-Button-Secondary-Fill-Normal: var(--UI-Opacity-White-0);
--Base-Button-Secondary-On-Fill-Disabled: var(--UI-Grey-40);
--Base-Button-Secondary-On-Fill-Hover: var(--Scandic-Peach-80);
--Base-Button-Secondary-On-Fill-Normal: var(--Scandic-Red-100);
--Base-Button-Tertiary-Border-Disabled: var(--UI-Opacity-White-0);
--Base-Button-Tertiary-Border-Hover: var(--UI-Opacity-White-0);
--Base-Button-Tertiary-Border-Normal: var(--UI-Opacity-White-0);
--Base-Button-Tertiary-Fill-Disabled: var(--UI-Grey-20);
--Base-Button-Tertiary-Fill-Hover: var(--Scandic-Red-90);
--Base-Button-Tertiary-Fill-Normal: var(--Scandic-Red-100);
--Base-Button-Tertiary-On-Fill-Disabled: var(--UI-Grey-40);
--Base-Button-Tertiary-On-Fill-Hover: var(--UI-Opacity-White-100);
--Base-Button-Tertiary-On-Fill-Normal: var(--UI-Opacity-White-100);
--Base-Button-Text-Border-Disabled: var(--UI-Opacity-White-0);
--Base-Button-Text-Border-Hover: var(--UI-Opacity-White-0);
--Base-Button-Text-Border-Normal: var(--UI-Opacity-White-0);
--Base-Button-Text-Fill-Disabled: var(--UI-Opacity-White-0);
--Base-Button-Text-Fill-Hover: var(--UI-Opacity-White-0);
--Base-Button-Text-Fill-Normal: var(--UI-Opacity-White-0);
--Base-Button-Text-On-Fill-Disabled: var(--UI-Grey-40);
--Base-Button-Text-On-Fill-Hover: var(--Scandic-Peach-80);
--Base-Button-Text-On-Fill-Normal: var(--Scandic-Red-100);
--Base-Icon-Low-contrast: var(--Scandic-Peach-70);
--Base-Interactive-Surface-Primary-normal: var(--Scandic-Red-80);
--Base-Interactive-Surface-Secondary-normal: var(--Scandic-Green-70);
--Base-Interactive-Surface-Tertiary-normal: var(--Scandic-Blue-60);
--Base-Surface-Primary-dark-Hover: var(--Scandic-Peach-20);
--Base-Surface-Primary-dark-Normal: var(--Scandic-Peach-10);
--Base-Surface-Primary-light-Hover: var(--UI-Grey-00);
--Base-Surface-Primary-light-Hover-alt: var(--Scandic-Beige-10);
--Base-Surface-Primary-light-Normal: var(--UI-Opacity-White-100);
--Base-Surface-Secondary-light-Hover: var(--Scandic-Peach-10);
--Base-Surface-Secondary-light-Hover-alt: var(--Scandic-Peach-20);
--Base-Surface-Secondary-light-Normal: var(--Scandic-Beige-00);
--Base-Surface-Subtle-Hover: var(--Scandic-Beige-20);
--Base-Surface-Subtle-Normal: var(--Scandic-Beige-10);
--Base-Text-Accent: var(--Scandic-Red-60);
--Base-Text-Disabled: var(--UI-Grey-40);
--Base-Text-High-contrast: var(--Scandic-Red-100);
--Base-Text-Inverted: var(--UI-Opacity-White-100);
--Base-Text-Medium-contrast: var(--Scandic-Peach-80);
--Primary-Dark-Button-Primary-Border-Disabled: var(--UI-Opacity-White-0);
--Primary-Dark-Button-Primary-Border-Hover: var(--UI-Opacity-White-0);
--Primary-Dark-Button-Primary-Border-Normal: var(--UI-Opacity-White-0);
--Primary-Dark-Button-Primary-Fill-Disabled: var(--UI-Opacity-White-20);
--Primary-Dark-Button-Primary-Fill-Hover: var(--Scandic-Peach-20);
--Primary-Dark-Button-Primary-Fill-Normal: var(--Scandic-Peach-10);
--Primary-Dark-Button-Primary-On-Fill-Disabled: var(--UI-Opacity-White-30);
--Primary-Dark-Button-Primary-On-Fill-Hover: var(--Scandic-Red-80);
--Primary-Dark-Button-Primary-On-Fill-Normal: var(--Scandic-Red-100);
--Primary-Dark-Button-Secondary-Border-Disabled: var(--UI-Opacity-White-20);
--Primary-Dark-Button-Secondary-Border-Hover: var(--Scandic-Peach-30);
--Primary-Dark-Button-Secondary-Border-Normal: var(--Scandic-Peach-10);
--Primary-Dark-Button-Secondary-Fill-Disabled: var(--UI-Opacity-White-0);
--Primary-Dark-Button-Secondary-Fill-Hover: var(--UI-Opacity-White-0);
--Primary-Dark-Button-Secondary-Fill-Normal: var(--UI-Opacity-White-0);
--Primary-Dark-Button-Secondary-On-Fill-Disabled: var(--UI-Opacity-White-30);
--Primary-Dark-Button-Secondary-On-Fill-Hover: var(--Scandic-Peach-30);
--Primary-Dark-Button-Secondary-On-Fill-Normal: var(--Scandic-Peach-10);
--Primary-Dark-On-Surface-Accent: var(--Scandic-Peach-50);
--Primary-Dark-On-Surface-Divider: var(--Scandic-Peach-80);
--Primary-Dark-On-Surface-Text: var(--Scandic-Peach-10);
--Primary-Dark-Surface-Hover: var(--Scandic-Red-90);
--Primary-Dark-Surface-Normal: var(--Scandic-Red-100);
--Primary-Dim-Button-Primary-Border-Disabled: var(--UI-Opacity-White-0);
--Primary-Dim-Button-Primary-Border-Hover: var(--UI-Opacity-White-0);
--Primary-Dim-Button-Primary-Border-Normal: var(--UI-Opacity-White-0);
--Primary-Dim-Button-Primary-Fill-Disabled: var(--UI-Opacity-Almost-Black-10);
--Primary-Dim-Button-Primary-Fill-Hover: var(--Scandic-Red-80);
--Primary-Dim-Button-Primary-Fill-Normal: var(--Scandic-Red-100);
--Primary-Dim-Button-Primary-On-Fill-Disabled: var(
--UI-Opacity-Almost-Black-20
);
--Primary-Dim-Button-Primary-On-Fill-Hover: var(--Scandic-Peach-30);
--Primary-Dim-Button-Primary-On-Fill-Normal: var(--Scandic-Peach-10);
--Primary-Dim-Button-Secondary-Border-Disabled: var(
--UI-Opacity-Almost-Black-20
);
--Primary-Dim-Button-Secondary-Border-Hover: var(--Scandic-Red-80);
--Primary-Dim-Button-Secondary-Border-Normal: var(--Scandic-Red-100);
--Primary-Dim-Button-Secondary-Fill-Disabled: var(--UI-Opacity-White-0);
--Primary-Dim-Button-Secondary-Fill-Hover: var(--UI-Opacity-White-0);
--Primary-Dim-Button-Secondary-Fill-Normal: var(--UI-Opacity-White-0);
--Primary-Dim-Button-Secondary-On-Fill-Disabled: var(
--UI-Opacity-Almost-Black-20
);
--Primary-Dim-Button-Secondary-On-Fill-Hover: var(--Scandic-Red-80);
--Primary-Dim-Button-Secondary-On-Fill-Normal: var(--Scandic-Red-100);
--Primary-Dim-On-Surface-Accent: var(--Scandic-Peach-80);
--Primary-Dim-On-Surface-Divider: var(--Scandic-Peach-40);
--Primary-Dim-On-Surface-Text: var(--Scandic-Red-100);
--Primary-Dim-Surface-Hover: var(--Scandic-Peach-40);
--Primary-Dim-Surface-Normal: var(--Scandic-Peach-30);
--Primary-Light-Button-Primary-Border-Disabled: var(--UI-Opacity-White-0);
--Primary-Light-Button-Primary-Border-Hover: var(--UI-Opacity-White-0);
--Primary-Light-Button-Primary-Border-Normal: var(--UI-Opacity-White-0);
--Primary-Light-Button-Primary-Fill-Disabled: var(
--UI-Opacity-Almost-Black-10
);
--Primary-Light-Button-Primary-Fill-Hover: var(--Scandic-Red-80);
--Primary-Light-Button-Primary-Fill-Normal: var(--Scandic-Red-100);
--Primary-Light-Button-Primary-On-Fill-Disabled: var(
--UI-Opacity-Almost-Black-20
);
--Primary-Light-Button-Primary-On-Fill-Hover: var(--Scandic-Peach-30);
--Primary-Light-Button-Primary-On-Fill-Normal: var(--Scandic-Peach-10);
--Primary-Light-Button-Secondary-Border-Disabled: var(
--UI-Opacity-Almost-Black-20
);
--Primary-Light-Button-Secondary-Border-Hover: var(--Scandic-Red-80);
--Primary-Light-Button-Secondary-Border-Normal: var(--Scandic-Red-100);
--Primary-Light-Button-Secondary-Fill-Disabled: var(--UI-Opacity-White-0);
--Primary-Light-Button-Secondary-Fill-Hover: var(--UI-Opacity-White-0);
--Primary-Light-Button-Secondary-Fill-Normal: var(--UI-Opacity-White-0);
--Primary-Light-Button-Secondary-On-Fill-Disabled: var(
--UI-Opacity-Almost-Black-20
);
--Primary-Light-Button-Secondary-On-Fill-Hover: var(--Scandic-Red-80);
--Primary-Light-Button-Secondary-On-Fill-Normal: var(--Scandic-Red-100);
--Primary-Light-On-Surface-Accent: var(--Scandic-Red-60);
--Primary-Light-On-Surface-Divider: var(--Scandic-Peach-30);
--Primary-Light-On-Surface-Divider-subtle: var(--Scandic-Beige-10);
--Primary-Light-On-Surface-Text: var(--Scandic-Red-100);
--Primary-Light-Surface-Hover: var(--Scandic-Peach-20);
--Primary-Light-Surface-Normal: var(--Scandic-Peach-10);
--Primary-Strong-Button-Primary-Border-Disabled: var(--UI-Opacity-White-0);
--Primary-Strong-Button-Primary-Border-Hover: var(--UI-Opacity-White-0);
--Primary-Strong-Button-Primary-Border-Normal: var(--UI-Opacity-White-0);
--Primary-Strong-Button-Primary-Fill-Disabled: var(--UI-Opacity-White-20);
--Primary-Strong-Button-Primary-Fill-Hover: var(--Scandic-Red-00);
--Primary-Strong-Button-Primary-Fill-Normal: var(--UI-Opacity-White-100);
--Primary-Strong-Button-Primary-On-Fill-Disabled: var(--UI-Opacity-White-20);
--Primary-Strong-Button-Primary-On-Fill-Hover: var(--Scandic-Red-70);
--Primary-Strong-Button-Primary-On-Fill-Normal: var(--Scandic-Red-70);
--Primary-Strong-Button-Secondary-Border-Disabled: var(--UI-Opacity-White-20);
--Primary-Strong-Button-Secondary-Border-Hover: var(--Scandic-Peach-00);
--Primary-Strong-Button-Secondary-Border-Normal: var(--UI-Opacity-White-100);
--Primary-Strong-Button-Secondary-Fill-Disabled: var(--UI-Opacity-White-0);
--Primary-Strong-Button-Secondary-Fill-Hover: var(--UI-Opacity-White-0);
--Primary-Strong-Button-Secondary-Fill-Normal: var(--UI-Opacity-White-0);
--Primary-Strong-Button-Secondary-On-Fill-Disabled: var(
--UI-Opacity-White-20
);
--Primary-Strong-Button-Secondary-On-Fill-Hover: var(--Scandic-Red-00);
--Primary-Strong-Button-Secondary-On-Fill-Normal: var(--UI-Opacity-White-100);
--Primary-Strong-On-Surface-Accent: var(--Scandic-Peach-10);
--Primary-Strong-On-Surface-Divider: var(--Scandic-Red-70);
--Primary-Strong-On-Surface-Text: var(--UI-Opacity-White-100);
--Primary-Strong-Surface-Hover: var(--Scandic-Red-70);
--Primary-Strong-Surface-Normal: var(--Scandic-Red-60);
--Secondary-Dark-Button-Primary-Border-Disabled: var(--UI-Opacity-White-0);
--Secondary-Dark-Button-Primary-Border-Hover: var(--UI-Opacity-White-0);
--Secondary-Dark-Button-Primary-Border-Normal: var(--UI-Opacity-White-0);
--Secondary-Dark-Button-Primary-Fill-Disabled: var(--UI-Opacity-White-10);
--Secondary-Dark-Button-Primary-Fill-Hover: var(--Scandic-Green-30);
--Secondary-Dark-Button-Primary-Fill-Normal: var(--Scandic-Green-20);
--Secondary-Dark-Button-Primary-On-Fill-Disabled: var(--UI-Opacity-White-20);
--Secondary-Dark-Button-Primary-On-Fill-Hover: var(--Scandic-Green-80);
--Secondary-Dark-Button-Primary-On-Fill-Normal: var(--Scandic-Green-90);
--Secondary-Dark-Button-Secondary-Border-Disabled: var(--UI-Opacity-White-20);
--Secondary-Dark-Button-Secondary-Border-Hover: var(--Scandic-Green-30);
--Secondary-Dark-Button-Secondary-Border-Normal: var(--Scandic-Green-20);
--Secondary-Dark-Button-Secondary-Fill-Disabled: var(--UI-Opacity-White-0);
--Secondary-Dark-Button-Secondary-Fill-Hover: var(--UI-Opacity-White-0);
--Secondary-Dark-Button-Secondary-Fill-Normal: var(--UI-Opacity-White-0);
--Secondary-Dark-Button-Secondary-On-Fill-Disabled: var(
--UI-Opacity-White-20
);
--Secondary-Dark-Button-Secondary-On-Fill-Hover: var(--Scandic-Green-30);
--Secondary-Dark-Button-Secondary-On-Fill-Normal: var(--Scandic-Green-20);
--Secondary-Dark-On-Surface-Accent: var(--Scandic-Green-40);
--Secondary-Dark-On-Surface-Divider: var(--Scandic-Green-80);
--Secondary-Dark-On-Surface-Text: var(--Scandic-Green-20);
--Secondary-Dark-Surface-Hover: var(--Scandic-Green-80);
--Secondary-Dark-Surface-Normal: var(--Scandic-Green-90);
--Secondary-Light-Button-Primary-Border-Disabled: var(--UI-Opacity-White-0);
--Secondary-Light-Button-Primary-Border-Hover: var(--UI-Opacity-White-0);
--Secondary-Light-Button-Primary-Border-Normal: var(--UI-Opacity-White-0);
--Secondary-Light-Button-Primary-Fill-Disabled: var(
--UI-Opacity-Almost-Black-10
);
--Secondary-Light-Button-Primary-Fill-Hover: var(--Scandic-Green-80);
--Secondary-Light-Button-Primary-Fill-Normal: var(--Scandic-Green-90);
--Secondary-Light-Button-Primary-On-Fill-Disabled: var(
--UI-Opacity-Almost-Black-20
);
--Secondary-Light-Button-Primary-On-Fill-Hover: var(--Scandic-Green-30);
--Secondary-Light-Button-Primary-On-Fill-Normal: var(--Scandic-Green-20);
--Secondary-Light-Button-Secondary-Border-Disabled: var(
--UI-Opacity-Almost-Black-20
);
--Secondary-Light-Button-Secondary-Border-Hover: var(--Scandic-Green-80);
--Secondary-Light-Button-Secondary-Border-Normal: var(--Scandic-Green-90);
--Secondary-Light-Button-Secondary-Fill-Disabled: var(--UI-Opacity-White-0);
--Secondary-Light-Button-Secondary-Fill-Hover: var(--UI-Opacity-White-0);
--Secondary-Light-Button-Secondary-Fill-Normal: var(--UI-Opacity-White-0);
--Secondary-Light-Button-Secondary-On-Fill-Disabled: var(
--UI-Opacity-Almost-Black-20
);
--Secondary-Light-Button-Secondary-On-Fill-Hover: var(--Scandic-Green-80);
--Secondary-Light-Button-Secondary-On-Fill-Normal: var(--Scandic-Green-90);
--Secondary-Light-On-Surface-Accent: var(--Scandic-Green-50);
--Secondary-Light-On-Surface-Divider: var(--Scandic-Green-30);
--Secondary-Light-On-Surface-Text: var(--Scandic-Green-90);
--Secondary-Light-Surface-Hover: var(--Scandic-Green-20);
--Secondary-Light-Surface-Normal: var(--Scandic-Green-20);
--Tertiary-Dark-Button-Primary-Border-Disabled: var(--UI-Opacity-White-0);
--Tertiary-Dark-Button-Primary-Border-Hover: var(--UI-Opacity-White-0);
--Tertiary-Dark-Button-Primary-Border-Normal: var(--UI-Opacity-White-0);
--Tertiary-Dark-Button-Primary-Fill-Disabled: var(--UI-Opacity-White-10);
--Tertiary-Dark-Button-Primary-Fill-Hover: var(--Scandic-Yellow-20);
--Tertiary-Dark-Button-Primary-Fill-Normal: var(--Scandic-Yellow-10);
--Tertiary-Dark-Button-Primary-On-Fill-Disabled: var(--UI-Opacity-White-20);
--Tertiary-Dark-Button-Primary-On-Fill-Hover: var(--Scandic-Blue-80);
--Tertiary-Dark-Button-Primary-On-Fill-Normal: var(--Scandic-Blue-100);
--Tertiary-Dark-Button-Secondary-Border-Disabled: var(--UI-Opacity-White-20);
--Tertiary-Dark-Button-Secondary-Border-Hover: var(--Scandic-Yellow-20);
--Tertiary-Dark-Button-Secondary-Border-Normal: var(--Scandic-Yellow-10);
--Tertiary-Dark-Button-Secondary-Fill-Disabled: var(--UI-Opacity-White-0);
--Tertiary-Dark-Button-Secondary-Fill-Hover: var(--UI-Opacity-White-0);
--Tertiary-Dark-Button-Secondary-Fill-Normal: var(--UI-Opacity-White-0);
--Tertiary-Dark-Button-Secondary-On-Fill-Disabled: var(--UI-Opacity-White-20);
--Tertiary-Dark-Button-Secondary-On-Fill-Hover: var(--Scandic-Yellow-20);
--Tertiary-Dark-Button-Secondary-On-Fill-Normal: var(--Scandic-Yellow-10);
--Tertiary-Dark-On-Surface-Accent: var(--Scandic-Blue-40);
--Tertiary-Dark-On-Surface-Divider: var(--Scandic-Blue-80);
--Tertiary-Dark-On-Surface-Text: var(--Scandic-Yellow-10);
--Tertiary-Dark-Surface-Hover: var(--Scandic-Blue-90);
--Tertiary-Dark-Surface-Normal: var(--Scandic-Blue-100);
--Tertiary-Light-Button-Primary-Border-Disabled: var(
--UI-Opacity-Almost-Black-20
);
--Tertiary-Light-Button-Primary-Border-Hover: var(--Scandic-Yellow-00);
--Tertiary-Light-Button-Primary-Border-Normal: var(--Scandic-Yellow-10);
--Tertiary-Light-Button-Primary-Fill-Disabled: var(
--UI-Opacity-Almost-Black-10
);
--Tertiary-Light-Button-Primary-Fill-Hover: var(--Scandic-Blue-90);
--Tertiary-Light-Button-Primary-Fill-Normal: var(--Scandic-Blue-100);
--Tertiary-Light-Button-Primary-On-Fill-Disabled: var(
--UI-Opacity-Almost-Black-20
);
--Tertiary-Light-Button-Primary-On-Fill-Hover: var(--Scandic-Yellow-00);
--Tertiary-Light-Button-Primary-On-Fill-Normal: var(--Scandic-Yellow-10);
--Tertiary-Light-Button-Secondary-Border-Disabled: var(
--UI-Opacity-Almost-Black-20
);
--Tertiary-Light-Button-Secondary-Border-Hover: var(--Scandic-Blue-90);
--Tertiary-Light-Button-Secondary-Border-Normal: var(--Scandic-Blue-100);
--Tertiary-Light-Button-Secondary-Fill-Disabled: var(--UI-Opacity-White-0);
--Tertiary-Light-Button-Secondary-Fill-Hover: var(--UI-Opacity-White-0);
--Tertiary-Light-Button-Secondary-Fill-Normal: var(--UI-Opacity-White-0);
--Tertiary-Light-Button-Secondary-On-Fill-Disabled: var(
--UI-Opacity-Almost-Black-20
);
--Tertiary-Light-Button-Secondary-On-Fill-Hover: var(--Scandic-Blue-90);
--Tertiary-Light-Button-Secondary-On-Fill-Normal: var(--Scandic-Blue-100);
--Tertiary-Light-On-Surface-Accent: var(--Scandic-Yellow-50);
--Tertiary-Light-On-Surface-Divider: var(--Scandic-Yellow-20);
--Tertiary-Light-On-Surface-Text: var(--Scandic-Blue-100);
--Tertiary-Light-Surface-Hover: var(--Scandic-Yellow-00);
--Tertiary-Light-Surface-Normal: var(--Scandic-Yellow-10);
--UI-Input-Controls-Border-Disabled: var(--UI-Grey-40);
--UI-Input-Controls-Border-Error: var(--Scandic-Red-70);
--UI-Input-Controls-Border-Focus: var(--Scandic-Blue-80);
--UI-Input-Controls-Border-Hover: var(--Scandic-Beige-70);
--UI-Input-Controls-Border-KeyboardFocus: var(--Scandic-Blue-50);
--UI-Input-Controls-Border-Normal: var(--Scandic-Beige-50);
--UI-Input-Controls-Fill-Disabled: var(--UI-Grey-60);
--UI-Input-Controls-Fill-Normal: var(--UI-Opacity-White-100);
--UI-Input-Controls-Fill-Selected: var(--Scandic-Blue-80);
--UI-Input-Controls-Fill-Selected-hover: var(--Scandic-Blue-70);
--UI-Input-Controls-On-Fill-Normal: var(--UI-Opacity-White-100);
--UI-Input-Controls-Surface-Disabled: var(--UI-Grey-10);
--UI-Input-Controls-Surface-Hover: var(--Scandic-Beige-10);
--UI-Input-Controls-Surface-Normal: var(--UI-Opacity-White-100);
--UI-Semantic-Error: var(--Scandic-Red-70);
--UI-Semantic-Information: var(--Scandic-Blue-70);
--UI-Semantic-Success: var(--Scandic-Green-60);
--UI-Semantic-Warning: var(--Scandic-Yellow-60);
--UI-Text-Active: var(--Scandic-Blue-90);
--UI-Text-Error: var(--Scandic-Red-70);
--UI-Text-High-contrast: var(--UI-Grey-100);
--UI-Text-Medium-contrast: var(--UI-Grey-80);
--UI-Text-Placeholder: var(--UI-Grey-60);
}
:root {
--Go-Beige-00: #faf8f2;
--Go-Beige-10: #f0ede4;
--Go-Beige-20: #e0dcce;
--Go-Beige-30: #c8c4b6;
--Go-Beige-40: #b0aca0;
--Go-Beige-50: #918f83;
--Go-Beige-60: #78766d;
--Go-Beige-70: #63615a;
--Go-Beige-80: #4f4d49;
--Go-Beige-90: #373633;
--Go-Beige-100: #1f1e1d;
--Go-Brand-Aqua: #73fcee;
--Go-Brand-Chartreuse: #85ff52;
--Go-Brand-Coral: #fa3737;
--Go-Brand-Lavender: #dcd7ff;
--Go-Brand-Lemon: #f5ff73;
--Go-Brand-Linen: #e0dcce;
--Go-Brand-Obsidian: #2d163a;
--Go-Brand-Pine: #21331f;
--Go-Brand-Powderrose: #ecc8c9;
--Go-Green-00: #edffe5;
--Go-Green-10: #cdffb8;
--Go-Green-20: #a7ff82;
--Go-Green-30: #85ff52;
--Go-Green-40: #66e03a;
--Go-Green-50: #45b222;
--Go-Green-60: #2e7f18;
--Go-Green-70: #2a601e;
--Go-Green-80: #26461f;
--Go-Green-90: #21331f;
--Go-Green-100: #162115;
--Go-Purple-00: #f4f2ff;
--Go-Purple-10: #dcd7ff;
--Go-Purple-20: #cabffc;
--Go-Purple-30: #baa7f7;
--Go-Purple-40: #ab8ef0;
--Go-Purple-50: #9c75e6;
--Go-Purple-60: #8c5bd5;
--Go-Purple-70: #733cb2;
--Go-Purple-80: #5e2a8c;
--Go-Purple-90: #451f61;
--Go-Purple-100: #2d163a;
--Go-Yellow-00: #fdffe8;
--Go-Yellow-10: #faffc4;
--Go-Yellow-20: #f8ff9c;
--Go-Yellow-30: #f5ff73;
--Go-Yellow-40: #edea39;
--Go-Yellow-50: #dec614;
--Go-Yellow-60: #ba8d07;
--Go-Yellow-70: #966400;
--Go-Yellow-80: #754403;
--Go-Yellow-90: #572701;
--Go-Yellow-100: #3b1300;
--Main-Blue-00: #eaf2fc;
--Main-Blue-10: #c7d9f5;
--Main-Blue-20: #a5c2ee;
--Main-Blue-30: #84ace7;
--Main-Blue-40: #6697df;
--Main-Blue-50: #4983d8;
--Main-Blue-60: #2e70d1;
--Main-Blue-70: #1555b4;
--Main-Blue-80: #023d96;
--Main-Blue-90: #002a69;
--Main-Blue-100: #001b42;
--Main-Brand-Burgundy: #4d001b;
--Main-Brand-DarkBlue: #0d1440;
--Main-Brand-DarkGreen: #093021;
--Main-Brand-DarkGrey: #291710;
--Main-Brand-LightBlue: #b5e0ff;
--Main-Brand-LightGreen: #d2edaf;
--Main-Brand-PalePeach: #f7e1d5;
--Main-Brand-PaleYellow: #fff0c2;
--Main-Brand-ScandicRed: #cd0921;
--Main-Brand-WarmWhite: #faf6f2;
--Main-Green-00: #e7f5e1;
--Main-Green-10: #badda8;
--Main-Green-20: #99ca7e;
--Main-Green-30: #7ab859;
--Main-Green-40: #5fa53a;
--Main-Green-50: #47931f;
--Main-Green-60: #33800a;
--Main-Green-70: #286806;
--Main-Green-80: #1e4f03;
--Main-Green-90: #143701;
--Main-Green-100: #0e2600;
--Main-Grey-00: #f2f2f2;
--Main-Grey-10: #e7e7e8;
--Main-Grey-20: #d8d8da;
--Main-Grey-30: #ceced2;
--Main-Grey-40: #c5c5ca;
--Main-Grey-50: #a7a7ad;
--Main-Grey-60: #7e7e84;
--Main-Grey-70: #535358;
--Main-Grey-80: #2f2f32;
--Main-Grey-90: #1b1b1c;
--Main-Grey-100: #111112;
--Main-Grey-Almostblack: #1f1c1b;
--Main-Grey-White: #ffffff;
--Main-Red-00: #ffebeb;
--Main-Red-10: #f7c1c2;
--Main-Red-20: #f79499;
--Main-Red-30: #f26b74;
--Main-Red-40: #ed4251;
--Main-Red-50: #e32034;
--Main-Red-60: #cd0921;
--Main-Red-70: #ad0015;
--Main-Red-80: #8d0011;
--Main-Red-90: #6d000d;
--Main-Red-100: #4d001b;
--Main-Scandic-00: #edf7f7;
--Main-Scandic-10: #c5e3e5;
--Main-Scandic-20: #97d3d9;
--Main-Scandic-30: #74cbd2;
--Main-Scandic-40: #53c3cc;
--Main-Scandic-50: #26a7b2;
--Main-Scandic-60: #00838e;
--Main-Scandic-70: #055b62;
--Main-Scandic-80: #08393d;
--Main-Scandic-90: #082022;
--Main-Scandic-100: #061112;
--Main-Yellow-00: #fff8e3;
--Main-Yellow-10: #fff0c2;
--Main-Yellow-20: #fade89;
--Main-Yellow-30: #f7ce52;
--Main-Yellow-40: #edb532;
--Main-Yellow-50: #e59515;
--Main-Yellow-60: #d17308;
--Main-Yellow-70: #a85211;
--Main-Yellow-80: #7d370f;
--Main-Yellow-90: #4f2313;
--Main-Yellow-100: #301508;
}

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,19 +0,0 @@
import type { Image } from "@scandic-hotels/trpc/types/image"
import type { User } from "@scandic-hotels/trpc/types/user"
import type {
CurrentHeaderLink,
TopMenuHeaderLink,
} from "@/types/requests/currentHeader"
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

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

View File

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

View File

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

View File

@@ -1,10 +0,0 @@
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

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

View File

@@ -1,49 +0,0 @@
import { BlocksTypenameEnum } from "./utils/typename"
import type { Contact } from "./asides/contact"
import type { PuffAside } from "./asides/puff"
import type { List } from "./blocks/list"
import type { PuffBlock } from "./blocks/puff"
import type { Text } from "./blocks/text"
import type { Hero } from "./hero"
import type { Preamble } from "./preamble"
import type { AllRequestResponseWithTotal } from "./utils/all"
import type { AsideTypenameEnum, Typename } from "./utils/typename"
export type Asides =
| Typename<Contact, AsideTypenameEnum.CurrentBlocksPageAsideContact>
| Typename<PuffAside, AsideTypenameEnum.CurrentBlocksPageAsidePuff>
export type Blocks =
| Typename<List, BlocksTypenameEnum.CurrentBlocksPageBlocksList>
| Typename<PuffBlock, BlocksTypenameEnum.CurrentBlocksPageBlocksPuffs>
| Typename<Text, BlocksTypenameEnum.CurrentBlocksPageBlocksText>
export type Breadcrumb = {
href: string
title: string
}
export type Breadcrumbs = {
parents: Breadcrumb[]
title: string
}
export type BlockPage = {
aside: Asides[]
blocks: Blocks[]
breadcrumbs: Breadcrumbs
hero: Hero
preamble: Preamble
system: {
created_at: string
uid: string
updated_at: string
}
title: string
url: string
}
export type GetCurrentBlockPageData = {
all_current_blocks_page: AllRequestResponseWithTotal<BlockPage>
}

View File

@@ -1,37 +0,0 @@
import type { Edges } from "@scandic-hotels/trpc/types/edges"
import type { Image } from "@scandic-hotels/trpc/types/image"
import type { AllRequestResponse } from "./utils/all"
export type CurrentHeaderLink = {
href: string
title: string
}
export type TopMenuHeaderLink = {
link: {
href: string
title: string
}
show_on_mobile: boolean
sort_order_mobile: number
}
export type CurrentHeaderLinks = {
links: CurrentHeaderLink[]
}
export type TopMenuCurrentHeaderLinks = {
links: TopMenuHeaderLink[]
}
export type CurrentHeader = {
frontpage_link_text: string
logoConnection: Edges<Image>
menu: CurrentHeaderLinks
top_menu: TopMenuCurrentHeaderLinks
}
export type GetCurrentHeaderData = {
all_current_header: AllRequestResponse<CurrentHeader>
}

View File

@@ -1,39 +0,0 @@
#import "../../Fragments/Aside/Contact.graphql"
#import "../../Fragments/Aside/Puff.graphql"
#import "../../Fragments/Blocks/List.graphql"
#import "../../Fragments/Blocks/Puff.graphql"
#import "../../Fragments/Blocks/Text.graphql"
#import "../../Fragments/Breadcrumbs/CurrentBlocksPage.graphql"
#import "../../Fragments/Hero.graphql"
#import "../../Fragments/Preamble.graphql"
query GetCurrentBlockPage($locale: String!, $url: String!) {
all_current_blocks_page(limit: 1, locale: $locale, where: { url: $url }) {
items {
aside {
__typename
...ContactAside
...PuffAside
}
blocks {
__typename
...ListBlock
...PuffBlock
...TextBlock
}
...CurrentBlocksPageBreadcrumbs
hero {
...Hero
}
...Preamble
system {
created_at
uid
updated_at
}
title
url
}
total
}
}

View File

@@ -1,5 +0,0 @@
query GetCurrentBlockPageTrackingData($uid: String!) {
current_blocks_page(uid: $uid, locale: "en") {
url
}
}

View File

@@ -1,36 +0,0 @@
#import "../../Fragments/CurrentFooter/AppDownloads.graphql"
#import "../../Fragments/CurrentFooter/Logo.graphql"
#import "../../Fragments/CurrentFooter/Navigation.graphql"
#import "../../Fragments/CurrentFooter/SocialMedia.graphql"
#import "../../Fragments/CurrentFooter/TripAdvisor.graphql"
#import "../../Fragments/System.graphql"
query GetCurrentFooter($locale: String!) {
all_current_footer(limit: 1, locale: $locale) {
items {
...CurrentFooterAppDownloads
...CurrentFooterSocialMedia
...Logo
...Navigation
...TripAdvisor
title
about {
text
title
}
system {
...System
}
}
}
}
query GetCurrentFooterRef($locale: String!) {
all_current_footer(limit: 1, locale: $locale) {
items {
system {
...System
}
}
}
}

View File

@@ -1,43 +0,0 @@
#import "../../Fragments/SysAsset.graphql"
#import "../../Fragments/System.graphql"
query GetCurrentHeader($locale: String!) {
all_current_header(limit: 1, locale: $locale) {
items {
frontpage_link_text
logoConnection {
edges {
node {
...SysAsset
}
}
}
menu {
links {
href
title
}
}
top_menu {
links {
link {
href
title
}
show_on_mobile
sort_order_mobile
}
}
}
}
}
query GetCurrentHeaderRef($locale: String!) {
all_current_header(limit: 1, locale: $locale) {
items {
system {
...System
}
}
}
}

View File

@@ -1,35 +0,0 @@
query GetDaDeEnUrlsCurrentBlocksPage($uid: String!) {
de: all_current_blocks_page(where: { uid: $uid }, locale: "de") {
items {
url
}
}
en: all_current_blocks_page(where: { uid: $uid }, locale: "en") {
items {
url
}
}
da: all_current_blocks_page(where: { uid: $uid }, locale: "da") {
items {
url
}
}
}
query GetFiNoSvUrlsCurrentBlocksPage($uid: String!) {
fi: all_current_blocks_page(where: { uid: $uid }, locale: "fi") {
items {
url
}
}
no: all_current_blocks_page(where: { uid: $uid }, locale: "no") {
items {
url
}
}
sv: all_current_blocks_page(where: { uid: $uid }, locale: "sv") {
items {
url
}
}
}

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