diff --git a/components/Current/Header/Da.tsx b/components/Current/Header/Da.tsx
deleted file mode 100644
index 4bf8164ea..000000000
--- a/components/Current/Header/Da.tsx
+++ /dev/null
@@ -1,198 +0,0 @@
-/* eslint-disable @next/next/no-img-element */
-import {
- currentAboutLinks,
- currentSponsoringLinks,
- currentWifiLinks,
-} from "@/constants/current/links"
-
-import Desktop from "./LanguageSwitcher/Desktop"
-import Mobile from "./LanguageSwitcher/Mobile"
-
-import type { LanguageSwitcherLink } from "@/types/components/current/languageSwitcher"
-import type { HeaderProps } from "@/types/components/current/header"
-
-const paths: Record = {
- "/kundeservice/sporgsmal-og-svar/om-scandics-website": currentAboutLinks,
- "/oplev-scandic/wifi": currentWifiLinks,
- "/sponsorering": currentSponsoringLinks,
-}
-
-const currentLanguage = "Dansk"
-
-export default function DaHeader({ pathname }: HeaderProps) {
- const links = paths?.[pathname] ?? null
- return (
-
- )
-}
diff --git a/components/Current/Header/De.tsx b/components/Current/Header/De.tsx
deleted file mode 100644
index b8d3fb5a9..000000000
--- a/components/Current/Header/De.tsx
+++ /dev/null
@@ -1,209 +0,0 @@
-import {
- currentAboutLinks,
- currentSponsoringLinks,
- currentWifiLinks,
-} from "@/constants/current/links"
-
-import Desktop from "./LanguageSwitcher/Desktop"
-import Mobile from "./LanguageSwitcher/Mobile"
-
-import type { HeaderProps } from "@/types/components/current/header"
-import type { LanguageSwitcherLink } from "@/types/components/current/languageSwitcher"
-
-const paths: Record = {
- "/kundenbetreuung/haufig-gestellte-fragen/nutzung-der-internetseite":
- currentAboutLinks,
- "/scandic-entdecken/wlan": currentWifiLinks,
- "/sponsoring": currentSponsoringLinks,
-}
-
-const currentLanguage = "Deutsch"
-
-export default function DeHeader({ pathname }: HeaderProps) {
- const links = paths?.[pathname] ?? null
-
- return (
-
- )
-}
diff --git a/components/Current/Header/En.tsx b/components/Current/Header/En.tsx
deleted file mode 100644
index 10bc6c983..000000000
--- a/components/Current/Header/En.tsx
+++ /dev/null
@@ -1,196 +0,0 @@
-/* eslint-disable @next/next/no-img-element */
-import {
- currentAboutLinks,
- currentSponsoringLinks,
- currentWifiLinks,
-} from "@/constants/current/links"
-
-import Desktop from "./LanguageSwitcher/Desktop"
-import Mobile from "./LanguageSwitcher/Mobile"
-
-import type { LanguageSwitcherLink } from "@/types/components/current/languageSwitcher"
-import type { HeaderProps } from "@/types/components/current/header"
-
-const paths: Record = {
- "/customer-service/frequently-asked-questions/using-the-website":
- currentAboutLinks,
- "/explore-scandic/wifi": currentWifiLinks,
- "/sponsoring": currentSponsoringLinks,
-}
-
-const currentLanguage = "English"
-
-export default function EnHeader({ pathname }: HeaderProps) {
- const links = paths?.[pathname] ?? null
- return (
-
- )
-}
diff --git a/components/Current/Header/Fi.tsx b/components/Current/Header/Fi.tsx
deleted file mode 100644
index 87ec99599..000000000
--- a/components/Current/Header/Fi.tsx
+++ /dev/null
@@ -1,198 +0,0 @@
-/* eslint-disable @next/next/no-img-element */
-import {
- currentAboutLinks,
- currentSponsoringLinks,
- currentWifiLinks,
-} from "@/constants/current/links"
-
-import Desktop from "./LanguageSwitcher/Desktop"
-import Mobile from "./LanguageSwitcher/Mobile"
-
-import type { LanguageSwitcherLink } from "@/types/components/current/languageSwitcher"
-import type { HeaderProps } from "@/types/components/current/header"
-
-const paths: Record = {
- "/asiakaspalvelu/usein-kysytyt-kysymykset/tietoja-internetsivuista":
- currentAboutLinks,
- "/koe-scandic/maksuton-internetyhteys": currentSponsoringLinks,
- "/scandic-entdecken/wlan": currentWifiLinks,
-}
-
-const currentLanguage = "Suomi"
-
-export default function FiHeader({ pathname }: HeaderProps) {
- const links = paths?.[pathname] ?? null
- return (
-
- )
-}
diff --git a/components/Current/Header/LanguageSwitcher/Desktop.tsx b/components/Current/Header/LanguageSwitcher/Desktop.tsx
deleted file mode 100644
index dbdd288a7..000000000
--- a/components/Current/Header/LanguageSwitcher/Desktop.tsx
+++ /dev/null
@@ -1,37 +0,0 @@
-import type { LanguageSwitcherProps } from "@/types/components/current/languageSwitcher"
-
-export default function Desktop({
- currentLanguage,
- links,
-}: LanguageSwitcherProps) {
- return (
-
-
-
-
- )
-}
diff --git a/components/Current/Header/LanguageSwitcher/Desktop/desktop.module.css b/components/Current/Header/LanguageSwitcher/Desktop/desktop.module.css
new file mode 100644
index 000000000..7d5faa37a
--- /dev/null
+++ b/components/Current/Header/LanguageSwitcher/Desktop/desktop.module.css
@@ -0,0 +1,45 @@
+.dropdown {
+ background-clip: padding-box;
+ background-color: #fff;
+ border: 1px solid rgba(0, 0, 0, .15);
+ border-radius: 4px;
+ box-shadow: 0 6px 12px rgba(0, 0, 0, .175);
+ display: none;
+ float: left;
+ font-size: 1rem;
+ left: 0;
+ list-style: none;
+ margin: 2px 0 0;
+ min-width: 160px;
+ padding: 5px 0;
+ position: absolute;
+ text-align: left;
+ top: 100%;
+ z-index: 11;
+}
+
+.dropdown.isOpen {
+ display: block;
+}
+
+.link {
+ clear: both;
+ color: grey;
+ display: block;
+ font-weight: 400;
+ padding: 3px 20px;
+ white-space: nowrap;
+}
+
+.link:hover {
+ background-color: #f5f5f5;
+ color: #737373;
+ text-decoration: none;
+}
+
+.active>.link {
+ background-color: #00838e;
+ color: #fff;
+ outline: 0;
+ text-decoration: none;
+}
\ No newline at end of file
diff --git a/components/Current/Header/LanguageSwitcher/Desktop/index.tsx b/components/Current/Header/LanguageSwitcher/Desktop/index.tsx
new file mode 100644
index 000000000..b36f3e091
--- /dev/null
+++ b/components/Current/Header/LanguageSwitcher/Desktop/index.tsx
@@ -0,0 +1,83 @@
+"use client"
+import { useCallback, useEffect, useRef, useState } from "react"
+
+import { languages } from "@/constants/languages"
+
+import styles from "./desktop.module.css"
+
+import type { LanguageSwitcherProps } from "@/types/components/current/languageSwitcher"
+
+export default function Desktop({
+ currentLanguage,
+ urls,
+}: LanguageSwitcherProps) {
+ const [isOpen, setIsOpen] = useState(false)
+ const divRef = useRef(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])
+
+ return (
+
+
+
+
+ )
+}
diff --git a/components/Current/Header/LanguageSwitcher/Mobile.tsx b/components/Current/Header/LanguageSwitcher/Mobile.tsx
deleted file mode 100644
index 7344b1d76..000000000
--- a/components/Current/Header/LanguageSwitcher/Mobile.tsx
+++ /dev/null
@@ -1,31 +0,0 @@
-import type { LanguageSwitcherProps } from "@/types/components/current/languageSwitcher"
-
-export default function Mobile({
- currentLanguage,
- links,
-}: LanguageSwitcherProps) {
- return (
-
-
-
-
- )
-}
diff --git a/components/Current/Header/LanguageSwitcher/Mobile/index.tsx b/components/Current/Header/LanguageSwitcher/Mobile/index.tsx
new file mode 100644
index 000000000..c7ae5bee6
--- /dev/null
+++ b/components/Current/Header/LanguageSwitcher/Mobile/index.tsx
@@ -0,0 +1,56 @@
+"use client"
+import { useState } from "react"
+
+import { languages } from "@/constants/languages"
+
+import styles from "./mobile.module.css"
+
+import type { LanguageSwitcherProps } from "@/types/components/current/languageSwitcher"
+
+export default function Mobile({
+ currentLanguage,
+ urls,
+}: LanguageSwitcherProps) {
+ const [isOpen, setIsOpen] = useState(false)
+
+ function toggleOpen() {
+ setIsOpen(prevIsOpen => !prevIsOpen)
+ }
+
+ return (
+
+
+
+
+ )
+}
diff --git a/components/Current/Header/LanguageSwitcher/Mobile/mobile.module.css b/components/Current/Header/LanguageSwitcher/Mobile/mobile.module.css
new file mode 100644
index 000000000..0f678bbd1
--- /dev/null
+++ b/components/Current/Header/LanguageSwitcher/Mobile/mobile.module.css
@@ -0,0 +1,31 @@
+.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;
+}
\ No newline at end of file
diff --git a/components/Current/Header/MainMenu/index.tsx b/components/Current/Header/MainMenu/index.tsx
new file mode 100644
index 000000000..79a7bd6d9
--- /dev/null
+++ b/components/Current/Header/MainMenu/index.tsx
@@ -0,0 +1,107 @@
+"use client"
+import { useState } from "react"
+
+import Image from "@/components/Image"
+import Mobile from "../LanguageSwitcher/Mobile"
+
+import styles from "./mainMenu.module.css"
+
+import type { MainMenuProps } from "@/types/components/current/header/mainMenu"
+
+export default function MainMenu({
+ currentLanguage,
+ frontpageLinkText,
+ homeHref,
+ links,
+ logo,
+ topMenuMobileLinks,
+ urls,
+}: MainMenuProps) {
+ const [isOpen, setIsOpen] = useState(false)
+
+ function toogleIsOpen() {
+ setIsOpen(prevIsOpen => !prevIsOpen)
+ }
+
+ return (
+
+ )
+}
diff --git a/components/Current/Header/MainMenu/mainMenu.module.css b/components/Current/Header/MainMenu/mainMenu.module.css
new file mode 100644
index 000000000..4a2083e3f
--- /dev/null
+++ b/components/Current/Header/MainMenu/mainMenu.module.css
@@ -0,0 +1,225 @@
+.mainMenu {
+ background-color: #fff;
+ background-image: none;
+ box-shadow: 0 0 7px rgba(0, 0, 0, .75);
+ max-height: 100%;
+ overflow: visible;
+ position: fixed;
+ top: 0;
+ width: 100%;
+ z-index: 99999;
+}
+
+.container {
+ box-sizing: content-box;
+ display: grid;
+ /** Third column is Book button */
+ grid-template-columns: repeat(3, 1fr);
+ height: 100%;
+ margin: 0 auto;
+ max-width: 1200px;
+ padding: 0;
+}
+
+.expanderBtn {
+ background-color: transparent;
+ border: none;
+ cursor: pointer;
+ justify-self: flex-start;
+ left: 0;
+ padding: 0.75rem 0.5rem 1rem;
+ transition: .3s;
+ user-select: none;
+}
+
+.iconBars,
+.iconBars::after,
+.iconBars::before {
+ background: #757575;
+ border-radius: 0.1428571429rem;
+ display: inline-block;
+ height: 0.2857142857rem;
+ position: relative;
+ transition: .3s;
+ width: 2rem;
+}
+
+.iconBars::after,
+.iconBars::before {
+ content: "";
+ left: 0;
+ position: absolute;
+ transform-origin: 0.1428571429rem center;
+}
+
+.iconBars::after {
+ top: -0.5rem;
+}
+
+.iconBars::before {
+ top: 0.5rem;
+}
+
+.expanded .iconBars {
+ background: transparent;
+}
+
+.expanded .iconBars::after,
+.expanded .iconBars::before {
+ top: 0;
+ transform-origin: 50% 50%;
+ width: 2rem;
+}
+
+.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 {
+ align-items: center;
+ display: flex;
+ justify-self: center;
+}
+
+.list {
+ background-color: #fff;
+ border-top: 1px solid #e3e0db;
+ display: none;
+ list-style: none;
+ overflow-y: visible;
+ padding-bottom: 20px;
+}
+
+.list.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;
+ display: block;
+ font-family: Helvetica Neue, Helvetica, Arial, sans-serif;
+ font-size: .875rem;
+ font-weight: 700;
+ padding-bottom: 20px;
+ padding-top: 20px;
+ text-transform: uppercase;
+}
+
+.link:hover {
+ color: #7f7369;
+ text-decoration: none;
+}
+
+.mobileList {
+ padding-top: 6px;
+}
+
+.mobileLi {
+ display: block;
+ position: relative;
+ text-align: center;
+}
+
+.mobileLink {
+ color: #000;
+ display: block;
+ font-family: Helvetica;
+ font-size: .875rem;
+ padding: 5px 0;
+}
+
+@media screen and (max-width: 950px) {
+ .logoLink {
+ width: 5rem;
+ }
+
+ .li {
+ background-color: #f3f2f1;
+ }
+}
+
+@media screen and (min-width: 950px) {
+ .mainMenu {
+ background-color: hsla(0, 0%, 100%, .95);
+ position: relative;
+ z-index: unset;
+ }
+
+ .container {
+ gap: 30px;
+ grid-template-columns: minmax(100px, auto) 1fr;
+ padding: 0px 30px;
+ }
+
+ .expanderBtn {
+ display: none;
+ }
+
+ .logo {
+ max-width: none;
+ min-width: 98px;
+ width: auto;
+ }
+
+ .list {
+ border-top: none;
+ display: block;
+ padding-bottom: 0;
+ padding-top: 0;
+ position: static;
+ width: 100%;
+ }
+
+ .list.isOpen {
+ position: static;
+ }
+
+ .li {
+ display: table-cell;
+ float: none;
+ vertical-align: middle;
+ }
+
+ .link {
+ background-image: none;
+ font-family: Helvetica, Arial, sans-serif;
+ font-weight: 700;
+ line-height: 1.15;
+ padding: 30px 15px;
+ }
+
+ .mobileList {
+ display: none;
+ padding-top: 0px;
+ }
+
+ .mobileLi {
+ display: none;
+ }
+}
\ No newline at end of file
diff --git a/components/Current/Header/No.tsx b/components/Current/Header/No.tsx
deleted file mode 100644
index 42399eccf..000000000
--- a/components/Current/Header/No.tsx
+++ /dev/null
@@ -1,203 +0,0 @@
-import {
- currentAboutLinks,
- currentSponsoringLinks,
- currentWifiLinks,
-} from "@/constants/current/links"
-
-import Desktop from "./LanguageSwitcher/Desktop"
-import Mobile from "./LanguageSwitcher/Mobile"
-
-import type { LanguageSwitcherLink } from "@/types/components/current/languageSwitcher"
-import type { HeaderProps } from "@/types/components/current/header"
-
-const paths: Record = {
- "/kundeservice/sporsmal-og-svar/bruk-av-nettsiden": currentAboutLinks,
- "/utforsk-scandic/wifi": currentWifiLinks,
- "/vi-sponser": currentSponsoringLinks,
-}
-
-const currentLanguage = "Norsk"
-
-export default function NoHeader({ pathname }: HeaderProps) {
- const links = paths?.[pathname] ?? null
-
- return (
-
- )
-}
diff --git a/components/Current/Header/OfflineBanner/banner.module.css b/components/Current/Header/OfflineBanner/banner.module.css
new file mode 100644
index 000000000..b6ecf284e
--- /dev/null
+++ b/components/Current/Header/OfflineBanner/banner.module.css
@@ -0,0 +1,23 @@
+.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;
+}
\ No newline at end of file
diff --git a/components/Current/Header/OfflineBanner/index.tsx b/components/Current/Header/OfflineBanner/index.tsx
new file mode 100644
index 000000000..1b98d40a9
--- /dev/null
+++ b/components/Current/Header/OfflineBanner/index.tsx
@@ -0,0 +1,10 @@
+import styles from "./banner.module.css"
+
+export default function OfflineBanner() {
+ return (
+
+ You are offline, some content may be out of date.
+
+
+ )
+}
diff --git a/components/Current/Header/Sv.tsx b/components/Current/Header/Sv.tsx
deleted file mode 100644
index 8f3aca360..000000000
--- a/components/Current/Header/Sv.tsx
+++ /dev/null
@@ -1,198 +0,0 @@
-/* eslint-disable @next/next/no-img-element */
-import {
- currentAboutLinks,
- currentSponsoringLinks,
- currentWifiLinks,
-} from "@/constants/current/links"
-
-import Desktop from "./LanguageSwitcher/Desktop"
-import Mobile from "./LanguageSwitcher/Mobile"
-
-import type { LanguageSwitcherLink } from "@/types/components/current/languageSwitcher"
-import type { HeaderProps } from "@/types/components/current/header"
-
-const paths: Record = {
- "/kundservice/fragor-och-svar/om-scandics-webbplats": currentAboutLinks,
- "/utforska-scandic/wi-fi": currentWifiLinks,
- "/vi-sponsrar": currentSponsoringLinks,
-}
-
-const currentLanguage = "Svenska"
-
-export default function SvHeader({ pathname }: HeaderProps) {
- const links = paths?.[pathname] ?? null
- return (
-
- )
-}
diff --git a/components/Current/Header/TopMenu/index.tsx b/components/Current/Header/TopMenu/index.tsx
new file mode 100644
index 000000000..b73c32c77
--- /dev/null
+++ b/components/Current/Header/TopMenu/index.tsx
@@ -0,0 +1,39 @@
+import Desktop from "../LanguageSwitcher/Desktop"
+
+import styles from "./topMenu.module.css"
+
+import type { TopMenuProps } from "@/types/components/current/header/topMenu"
+
+export default function TopMenu({ currentLanguage, frontpageLinkText, homeHref, links, urls }: TopMenuProps) {
+ return (
+
+ )
+}
diff --git a/components/Current/Header/TopMenu/topMenu.module.css b/components/Current/Header/TopMenu/topMenu.module.css
new file mode 100644
index 000000000..161b00ac5
--- /dev/null
+++ b/components/Current/Header/TopMenu/topMenu.module.css
@@ -0,0 +1,51 @@
+.topMenu {
+ background-color: #8d3a7c;
+ color: #fff;
+ display: none;
+ font-size: .8125rem;
+ 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;
+}
+
+.link {
+ color: #fff;
+ display: inline-block;
+ padding: 3px 10px;
+ text-decoration: none;
+}
+
+@media screen and (min-width: 740px) {
+ .container {
+ padding: 0 30px;
+ }
+}
+
+@media screen and (min-width: 950px) {
+ .topMenu {
+ background-color: #3d3835;
+ display: block;
+ }
+
+ .link {
+ padding-top: 4px;
+ padding-bottom: 4px;
+ }
+}
\ No newline at end of file
diff --git a/components/Current/Header/header.module.css b/components/Current/Header/header.module.css
new file mode 100644
index 000000000..9d72b90f7
--- /dev/null
+++ b/components/Current/Header/header.module.css
@@ -0,0 +1,9 @@
+.header {
+ display: grid;
+}
+
+@media screen and (max-width: 950px) {
+ .header {
+ height: 50px;
+ }
+}
\ No newline at end of file
diff --git a/components/Current/Header/index.tsx b/components/Current/Header/index.tsx
index 52c480605..8e01bd761 100644
--- a/components/Current/Header/index.tsx
+++ b/components/Current/Header/index.tsx
@@ -1,30 +1,77 @@
-import { langEnum } from "@/types/lang"
+import { languages } from "@/constants/languages"
+import { batchRequest } from "@/lib/batchRequest"
+import { request } from "@/lib/request"
+import { GetHeader } from "@/lib/graphql/Query/Header.graphql"
+import { GetDaDeEnUrls, GetFiNoSvUrls } from "@/lib/graphql/Query/LanguageSwitcher.graphql"
+import { homeHrefs } from "@/constants/homeHrefs"
+import { env } from "@/env/server"
-import Da from "./Da"
-import De from "./De"
-import En from "./En"
-import Fi from "./Fi"
-import No from "./No"
-import Sv from "./Sv"
+import MainMenu from "./MainMenu"
+import OfflineBanner from "./OfflineBanner"
+import TopMenu from "./TopMenu"
+
+import styles from "./header.module.css"
-import type { HeaderProps } from "@/types/components/current/header"
import { LangParams } from "@/types/params"
+import type { HeaderQueryData } from "@/types/requests/header"
+import type { HeaderProps } from "@/types/components/current/header"
+import type { LanguageSwitcherQueryData } from "@/types/requests/languageSwitcher"
-export default function Header({ lang, pathname }: LangParams & HeaderProps) {
- switch (lang) {
- case langEnum.sv:
- return
- case langEnum.fi:
- return
- case langEnum.en:
- return
- case langEnum.da:
- return
- case langEnum.de:
- return
- case langEnum.no:
- return
- default:
+export default async function Header({ lang, uid }: LangParams & HeaderProps) {
+ try {
+ const variables = {
+ locale: lang,
+ uid,
+ }
+
+ const { data } = await request(GetHeader, { locale: lang }, { tags: [`header-${lang}`] })
+ const { data: urls } = await batchRequest([
+ {
+ document: GetDaDeEnUrls,
+ tags: [`DA-DE-EN-${uid}`],
+ variables,
+ },
+ {
+ document: GetFiNoSvUrls,
+ tags: [`FI-NO-SV-${uid}`],
+ variables,
+ },
+ ])
+
+ if (!data.all_header.items.length) {
return null
+ }
+
+ const currentLanguage = languages[lang]
+ const homeHref = homeHrefs[env.NODE_ENV][lang]
+ const { frontpage_link_text, logoConnection, menu, top_menu } = data.all_header.items[0]
+ const logo = logoConnection.edges?.[0]?.node
+ const topMenuMobileLinks = top_menu.links.filter(link => link.show_on_mobile)
+ .sort((a, b) => a.sort_order_mobile < b.sort_order_mobile ? 1 : -1)
+
+ return (
+
+ )
+ } catch (error) {
+ console.error(error)
+ return null
}
}
diff --git a/components/Current/Preamble/Breadcrumbs/index.tsx b/components/Current/Preamble/Breadcrumbs/index.tsx
index 631482046..0fbb477c2 100644
--- a/components/Current/Preamble/Breadcrumbs/index.tsx
+++ b/components/Current/Preamble/Breadcrumbs/index.tsx
@@ -1,5 +1,3 @@
-import Link from "next/link"
-
import styles from "./breadcrumbs.module.css"
import type { BreadcrumbsProps } from "@/types/components/current/breadcrumbs"
@@ -14,20 +12,20 @@ export default function Breadcrumbs({
{parent ? (
-
-
- {parent.node.breadcrumbs?.title ?? parent.node.title}
-
+
+ {parent.title}
+
) : null}
- {breadcrumbs.edges.map((breadcrumb) => (
+ {breadcrumbs.map((breadcrumb) => (
-
-
- {breadcrumb.node.breadcrumbs?.title ?? breadcrumb.node.title}
-
+
+ {breadcrumb.title}
+
))}
-
diff --git a/components/Current/SubnavMobile.tsx b/components/Current/SubnavMobile.tsx
index 4dac85716..04eea5fd9 100644
--- a/components/Current/SubnavMobile.tsx
+++ b/components/Current/SubnavMobile.tsx
@@ -1,5 +1,3 @@
-import Link from "next/link"
-
import type { SubnavMobileProps } from "@/types/components/current/subnavMobile"
export default async function SubnavMobile({
@@ -13,16 +11,16 @@ export default async function SubnavMobile({
{parent ? (
-
-
- {parent.node.breadcrumbs?.title ?? parent.node.title}
-
+
+ {parent.title}
+
) : null}
- {breadcrumbs.edges.map((breadcrumb) => (
- -
-
- {breadcrumb.node.breadcrumbs?.title ?? breadcrumb.node.title}
-
+ {breadcrumbs.map((breadcrumb) => (
+
-
+
+ {breadcrumb.title}
+
))}
-
diff --git a/app/[lang]/Tracking.tsx b/components/Current/Tracking.tsx
similarity index 100%
rename from app/[lang]/Tracking.tsx
rename to components/Current/Tracking.tsx
diff --git a/components/JsonToHtml/renderOptions.tsx b/components/JsonToHtml/renderOptions.tsx
index c2061923b..3529017cd 100644
--- a/components/JsonToHtml/renderOptions.tsx
+++ b/components/JsonToHtml/renderOptions.tsx
@@ -263,8 +263,9 @@ export const renderOptions: RenderOptions = {
}
} else {
const props = extractPossibleAttributes(node.attrs)
+ const href = node.attrs?.locale ? `/${node.attrs.locale}${node.attrs.href}` : node.attrs.href
return (
-
+
{next(node.children, embeds, fullRenderOptions)}
)
diff --git a/constants/current/links.ts b/constants/current/links.ts
deleted file mode 100644
index f60a63134..000000000
--- a/constants/current/links.ts
+++ /dev/null
@@ -1,80 +0,0 @@
-export const currentAboutLinks = [
- {
- href: "https://www.scandichotels.com/customer-service/frequently-asked-questions/using-the-website",
- title: "English",
- },
- {
- href: "https://www.scandichotels.se/kundservice/fragor-och-svar/om-scandics-webbplats",
- title: "Svenska",
- },
- {
- href: "https://www.scandichotels.no/kundeservice/sporsmal-og-svar/bruk-av-nettsiden",
- title: "Norsk",
- },
- {
- href: "https://www.scandichotels.dk/kundeservice/sporgsmal-og-svar/om-scandics-website",
- title: "Dansk",
- },
- {
- href: "https://www.scandichotels.fi/asiakaspalvelu/usein-kysytyt-kysymykset/tietoja-internetsivuista",
- title: "Suomi",
- },
- {
- href: "https://www.scandichotels.de/kundenbetreuung/haufig-gestellte-fragen/nutzung-der-internetseite",
- title: "Deutsch",
- },
-]
-
-export const currentSponsoringLinks = [
- {
- href: "https://www.scandichotels.com/sponsoring",
- title: "English",
- },
- {
- href: "https://www.scandichotels.se/vi-sponsrar",
- title: "Svenska",
- },
- {
- href: "https://www.scandichotels.no/vi-sponser",
- title: "Norsk",
- },
- {
- href: "https://www.scandichotels.dk/sponsorering",
- title: "Dansk",
- },
- {
- href: "https://www.scandichotels.fi/sponsorointi",
- title: "Suomi",
- },
- {
- href: "https://www.scandichotels.de/sponsoring",
- title: "Deutsch",
- },
-]
-
-export const currentWifiLinks = [
- {
- href: "https://www.scandichotels.com/explore-scandic/wifi",
- title: "English",
- },
- {
- href: "https://www.scandichotels.se/utforska-scandic/wi-fi",
- title: "Svenska",
- },
- {
- href: "https://www.scandichotels.no/utforsk-scandic/wifi",
- title: "Norsk",
- },
- {
- href: "https://www.scandichotels.dk/oplev-scandic/wifi",
- title: "Dansk",
- },
- {
- href: "https://www.scandichotels.fi/koe-scandic/maksuton-internetyhteys",
- title: "Suomi",
- },
- {
- href: "https://www.scandichotels.de/scandic-entdecken/wlan",
- title: "Deutsch",
- },
-]
diff --git a/constants/homeHrefs.ts b/constants/homeHrefs.ts
new file mode 100644
index 000000000..33fc26087
--- /dev/null
+++ b/constants/homeHrefs.ts
@@ -0,0 +1,27 @@
+
+export const homeHrefs = {
+ development: {
+ da: "https://stage.scandichotels.dk",
+ de: "https://stage.scandichotels.de",
+ en: "https://stage.scandichotels.com",
+ fi: "https://stage.scandichotels.fi",
+ no: "https://stage.scandichotels.no",
+ sv: "https://stage.scandichotels.se",
+ },
+ production: {
+ da: "https://www.scandichotels.dk",
+ de: "https://www.scandichotels.de",
+ en: "https://www.scandichotels.com",
+ fi: "https://www.scandichotels.fi",
+ no: "https://www.scandichotels.no",
+ sv: "https://www.scandichotels.se",
+ },
+ test: {
+ da: "https://test2.scandichotels.dk",
+ de: "https://test2.scandichotels.de",
+ en: "https://test2.scandichotels.com",
+ fi: "https://test2.scandichotels.fi",
+ no: "https://test2.scandichotels.no",
+ sv: "https://test2.scandichotels.se",
+ },
+}
diff --git a/constants/languages.ts b/constants/languages.ts
new file mode 100644
index 000000000..089ded4ba
--- /dev/null
+++ b/constants/languages.ts
@@ -0,0 +1,8 @@
+export const languages = {
+ da: "Dansk",
+ de: "Deutsch",
+ en: "English",
+ fi: "Suomi",
+ no: "Norsk",
+ sv: "Svenska",
+}
diff --git a/env/server.ts b/env/server.ts
index 9e17194a9..c6c658b80 100644
--- a/env/server.ts
+++ b/env/server.ts
@@ -11,6 +11,7 @@ export const env = createEnv({
CMS_PREVIEW_TOKEN: z.string(),
NODE_ENV: z.enum(["development", "test", "production"]),
PRINT_QUERY: z.boolean().default(false),
+ REVALIDATE_SECRET: z.string(),
},
emptyStringAsUndefined: true,
runtimeEnv: {
@@ -22,5 +23,6 @@ export const env = createEnv({
CMS_PREVIEW_TOKEN: process.env.CMS_PREVIEW_TOKEN,
NODE_ENV: process.env.NODE_ENV,
PRINT_QUERY: process.env.PRINT_QUERY,
+ REVALIDATE_SECRET: process.env.REVALIDATE_SECRET,
},
})
diff --git a/lib/batchRequest.ts b/lib/batchRequest.ts
new file mode 100644
index 000000000..319db94bd
--- /dev/null
+++ b/lib/batchRequest.ts
@@ -0,0 +1,28 @@
+import "server-only"
+import { request } from "./request"
+
+import type { Data } from "@/types/request"
+import type { BatchRequestDocument } from "graphql-request"
+
+export async function batchRequest(queries: (BatchRequestDocument & NextFetchRequestConfig)[]): Promise> {
+ try {
+ const response = await Promise.allSettled(
+ queries.map(query => request(query.document, query.variables, { tags: query.tags }))
+ )
+
+ let data = {} as T
+ const reasons = []
+ response.forEach(res => {
+ if (res.status === "fulfilled") {
+ data = Object.assign({}, data, res.value.data)
+ } else {
+ reasons.push(res.reason)
+ }
+ })
+
+ return { data }
+ } catch (error) {
+ console.error(error)
+ throw new Error("Something went wrong")
+ }
+}
diff --git a/lib/graphql/Fragments/Aside/Puff.graphql b/lib/graphql/Fragments/Aside/Puff.graphql
index 1cdc63204..1ed6ba3ca 100644
--- a/lib/graphql/Fragments/Aside/Puff.graphql
+++ b/lib/graphql/Fragments/Aside/Puff.graphql
@@ -2,13 +2,6 @@
fragment PuffAside on CurrentBlocksPageAsidePuff {
puff {
- puffConnection {
- totalCount
- edges {
- node {
- ...Puff
- }
- }
- }
+ ...Puff
}
}
diff --git a/lib/graphql/Fragments/Blocks/List.graphql b/lib/graphql/Fragments/Blocks/List.graphql
index 749416bef..17720ffea 100644
--- a/lib/graphql/Fragments/Blocks/List.graphql
+++ b/lib/graphql/Fragments/Blocks/List.graphql
@@ -1,5 +1,3 @@
-#import "../PageLinks.graphql"
-
fragment ListItem on CurrentBlocksPageBlocksListBlockListItemsListItem {
list_item {
list_item_style
@@ -19,30 +17,12 @@ fragment ListItemExternalLink on CurrentBlocksPageBlocksListBlockListItemsListIt
}
}
-fragment ListItemInternalLink on CurrentBlocksPageBlocksListBlockListItemsListItemInternalLink {
- list_item_internal_link {
- link_text
- list_item_style
- subtitle
- pageConnection {
- totalCount
- edges {
- node {
- __typename
- ...CurrentBlocksPageLink
- }
- }
- }
- }
-}
-
fragment ListBlock on CurrentBlocksPageBlocksList {
list {
list_items {
__typename
...ListItem
...ListItemExternalLink
- ...ListItemInternalLink
}
title
}
diff --git a/lib/graphql/Fragments/Blocks/Puff.graphql b/lib/graphql/Fragments/Blocks/Puff.graphql
index 4c125bceb..f42cf99e0 100644
--- a/lib/graphql/Fragments/Blocks/Puff.graphql
+++ b/lib/graphql/Fragments/Blocks/Puff.graphql
@@ -2,11 +2,9 @@
fragment PuffBlock on CurrentBlocksPageBlocksPuffs {
puffs {
- # We have to manually add a limit since Contentstack handles its complexity calculation in a certain way
- puffsConnection(limit: 9) {
- totalCount
- edges {
- node {
+ puffs {
+ ... on CurrentBlocksPageBlocksPuffsBlockPuffsPuff {
+ puff {
...Puff
}
}
diff --git a/lib/graphql/Fragments/Blocks/Text.graphql b/lib/graphql/Fragments/Blocks/Text.graphql
index 3ee6173a8..25e39b0cb 100644
--- a/lib/graphql/Fragments/Blocks/Text.graphql
+++ b/lib/graphql/Fragments/Blocks/Text.graphql
@@ -1,5 +1,4 @@
#import "../Image.graphql"
-#import "../PageLinks.graphql"
fragment TextBlock on CurrentBlocksPageBlocksText {
text {
@@ -9,7 +8,6 @@ fragment TextBlock on CurrentBlocksPageBlocksText {
edges {
node {
__typename
- ...CurrentBlocksPageLink
...Image
}
}
diff --git a/lib/graphql/Fragments/Breadcrumbs.graphql b/lib/graphql/Fragments/Breadcrumbs.graphql
index 2be6fd10e..585ecbf40 100644
--- a/lib/graphql/Fragments/Breadcrumbs.graphql
+++ b/lib/graphql/Fragments/Breadcrumbs.graphql
@@ -1,18 +1,9 @@
fragment Breadcrumbs on CurrentBlocksPage {
breadcrumbs {
- title
- parentsConnection {
- edges {
- node {
- ... on CurrentBlocksPage {
- breadcrumbs {
- title
- }
- title
- url
- }
- }
- }
+ parents {
+ href
+ title
}
+ title
}
}
diff --git a/lib/graphql/Fragments/Footer/Logo.graphql b/lib/graphql/Fragments/Footer/Logo.graphql
index 730d13a1b..d2ce3cbe6 100644
--- a/lib/graphql/Fragments/Footer/Logo.graphql
+++ b/lib/graphql/Fragments/Footer/Logo.graphql
@@ -1,9 +1,10 @@
+#import "../Image.graphql"
+
fragment Logo on Footer {
logoConnection {
edges {
node {
- title
- url
+ ...Image
}
}
}
diff --git a/lib/graphql/Fragments/Footer/Navigation.graphql b/lib/graphql/Fragments/Footer/Navigation.graphql
index 9274a7048..10a425980 100644
--- a/lib/graphql/Fragments/Footer/Navigation.graphql
+++ b/lib/graphql/Fragments/Footer/Navigation.graphql
@@ -1,33 +1,9 @@
-#import "../PageLinks.graphql"
-
fragment Navigation on Footer {
navigation {
links {
- ... on FooterNavigationLinksInternalLink {
- __typename
- internal_link {
- link_text
- pageConnection {
- edges {
- node {
- __typename
- ...CurrentBlocksPageLink
- }
- }
- }
- }
- }
- ... on FooterNavigationLinksExternalLink {
- __typename
- external_link {
- link {
- href
- title
- }
- }
- }
+ href
+ title
}
-
title
}
}
diff --git a/lib/graphql/Fragments/Hero.graphql b/lib/graphql/Fragments/Hero.graphql
index a96351a54..a232e4bc0 100644
--- a/lib/graphql/Fragments/Hero.graphql
+++ b/lib/graphql/Fragments/Hero.graphql
@@ -1,5 +1,4 @@
#import "./Image.graphql"
-#import "./PageLinks.graphql"
fragment Hero on Hero {
imagesConnection {
diff --git a/lib/graphql/Fragments/PageLinks.graphql b/lib/graphql/Fragments/PageLinks.graphql
index abc9c3920..1b82b2a59 100644
--- a/lib/graphql/Fragments/PageLinks.graphql
+++ b/lib/graphql/Fragments/PageLinks.graphql
@@ -1,7 +1,7 @@
fragment CurrentBlocksPageLink on CurrentBlocksPage {
system {
- uid
locale
+ uid
}
title
url
diff --git a/lib/graphql/Fragments/Preamble.graphql b/lib/graphql/Fragments/Preamble.graphql
index dd6424608..a02586296 100644
--- a/lib/graphql/Fragments/Preamble.graphql
+++ b/lib/graphql/Fragments/Preamble.graphql
@@ -1,5 +1,4 @@
#import "./Image.graphql"
-#import "./PageLinks.graphql"
fragment Preamble on CurrentBlocksPage {
preamble {
@@ -9,7 +8,6 @@ fragment Preamble on CurrentBlocksPage {
edges {
node {
__typename
- ...CurrentBlocksPageLink
...Image
}
}
diff --git a/lib/graphql/Fragments/Puff.graphql b/lib/graphql/Fragments/Puff.graphql
index d99f25346..e63c3a16d 100644
--- a/lib/graphql/Fragments/Puff.graphql
+++ b/lib/graphql/Fragments/Puff.graphql
@@ -1,5 +1,4 @@
#import "./Image.graphql"
-#import "./PageLinks.graphql"
fragment Puff on Puff {
imageConnection {
@@ -9,33 +8,12 @@ fragment Puff on Puff {
}
}
}
- is_internal
link {
href
title
}
- pageConnection {
- edges {
- node {
- __typename
- ...CurrentBlocksPageLink
- }
- }
- }
- system {
- uid
- }
text {
json
- embedded_itemsConnection {
- totalCount
- edges {
- node {
- __typename
- ...Image
- }
- }
- }
}
title
}
diff --git a/lib/graphql/Query/CurrentBlockPage.graphql b/lib/graphql/Query/CurrentBlockPage.graphql
index 8eebebb7a..0a5315f78 100644
--- a/lib/graphql/Query/CurrentBlockPage.graphql
+++ b/lib/graphql/Query/CurrentBlockPage.graphql
@@ -27,13 +27,13 @@ query GetCurrentBlockPage($locale: String!, $url: String!) {
...Hero
}
...Preamble
- title
- url
system {
- uid
created_at
+ uid
updated_at
}
+ title
+ url
}
total
}
diff --git a/lib/graphql/Query/Header.graphql b/lib/graphql/Query/Header.graphql
new file mode 100644
index 000000000..e546f88af
--- /dev/null
+++ b/lib/graphql/Query/Header.graphql
@@ -0,0 +1,32 @@
+#import "../Fragments/Image.graphql"
+
+query GetHeader($locale: String!) {
+ all_header(limit: 1, locale: $locale) {
+ items {
+ frontpage_link_text
+ logoConnection {
+ edges {
+ node {
+ ...Image
+ }
+ }
+ }
+ menu {
+ links {
+ href
+ title
+ }
+ }
+ top_menu {
+ links {
+ link {
+ href
+ title
+ }
+ show_on_mobile
+ sort_order_mobile
+ }
+ }
+ }
+ }
+}
diff --git a/lib/graphql/Query/LanguageSwitcher.graphql b/lib/graphql/Query/LanguageSwitcher.graphql
new file mode 100644
index 000000000..1ca39ed97
--- /dev/null
+++ b/lib/graphql/Query/LanguageSwitcher.graphql
@@ -0,0 +1,21 @@
+query GetDaDeEnUrls($uid: String!) {
+ de: current_blocks_page(uid: $uid, locale: "de") {
+ url: original_url
+ }
+ en: current_blocks_page(uid: $uid, locale: "en") {
+ url: original_url
+ }
+}
+
+query GetFiNoSvUrls($uid: String!) {
+ fi: current_blocks_page(uid: $uid, locale: "fi") {
+ url: original_url
+ }
+ no: current_blocks_page(uid: $uid, locale: "no") {
+ url: original_url
+ }
+ sv: current_blocks_page(uid: $uid, locale: "sv") {
+ url: original_url
+ }
+}
+
diff --git a/lib/request.ts b/lib/request.ts
index cc333dfcb..8562c03a4 100644
--- a/lib/request.ts
+++ b/lib/request.ts
@@ -1,21 +1,31 @@
import "server-only"
-import { request as graphqlRequest } from "graphql-request"
+import { GraphQLClient } from "graphql-request"
import { env } from "@/env/server"
+import { cache } from "react"
import type { Data } from "@/types/request"
import type { DocumentNode } from "graphql"
+const client = new GraphQLClient(env.CMS_URL, {
+ fetch: cache(async function (url: URL | RequestInfo, params: RequestInit | undefined) {
+ return fetch(url, params)
+ }),
+})
+
export async function request(
query: string | DocumentNode,
- variables?: {}
+ variables?: {},
+ next?: NextFetchRequestConfig
): Promise> {
try {
- if (env.PRINT_QUERY) {
- const graphqlRawRequest = (await import("graphql-request")).rawRequest
- const print = (await import("graphql/language/printer")).print
- const rawResponse = await graphqlRawRequest(
- env.CMS_URL,
+ if (next) {
+ client.requestConfig.next = next
+ }
+
+ if (env.PRINT_QUERY) {
+ const print = (await import("graphql/language/printer")).print
+ const rawResponse = await client.rawRequest(
print(query as DocumentNode),
variables,
{
@@ -40,13 +50,12 @@ export async function request(
}
}
- const response = await graphqlRequest({
+ const response = await client.request({
document: query,
requestHeaders: {
access_token: env.CMS_ACCESS_TOKEN,
"Content-Type": "application/json",
},
- url: env.CMS_URL,
variables,
})
diff --git a/next.config.js b/next.config.js
index 526ce8d5e..ef9e4137e 100644
--- a/next.config.js
+++ b/next.config.js
@@ -25,8 +25,14 @@ const nextConfig = {
loader: "graphql-tag/loader",
})
- return config
+ return config;
},
-}
+
+ logging: {
+ fetches: {
+ fullUrl: true,
+ },
+ },
+};
export default nextConfig
diff --git a/public/Static/img/scandic-logotype-white.svg b/public/Static/img/scandic-logotype-white.svg
index e8837b33d..c253c69fa 100644
--- a/public/Static/img/scandic-logotype-white.svg
+++ b/public/Static/img/scandic-logotype-white.svg
@@ -2,7 +2,7 @@