feat: sync design of header with current web

This commit is contained in:
Christel Westerberg
2024-05-29 15:36:19 +02:00
parent 88dde3def4
commit 0ec6d58d6a
22 changed files with 122 additions and 225 deletions

View File

@@ -0,0 +1,42 @@
.button {
background-color: #02838e;
color: #fff;
padding: 5px 15px;
display: inline-block;
line-height: 20px;
border: 1px solid transparent;
border-radius: 50px;
height: 32px;
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;
}
.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: 950px) {
.button {
font-weight: 600;
font-size: 16px;
line-height: 24px;
height: auto;
padding: 12px 32px;
}
}

View File

@@ -0,0 +1,11 @@
import "@scandic-hotels/design-system/current/style.css"
import styles from "./bookingButton.module.css"
export default function BookingButton() {
return (
<a className={styles.button} href="/">
Book
</a>
)
}

View File

@@ -2,7 +2,8 @@
import { useState } from "react" import { useState } from "react"
import Image from "@/components/Image" import Image from "@/components/Image"
import Button from "@/components/TempDesignSystem/Button"
import BookingButton from "../BookingButton"
import styles from "./mainMenu.module.css" import styles from "./mainMenu.module.css"
@@ -82,9 +83,9 @@ export function MainMenu({
<li className={styles.mobileLi}>{languageSwitcher}</li> <li className={styles.mobileLi}>{languageSwitcher}</li>
) : null} ) : null}
</ul> </ul>
{/* <div className={styles.buttonContainer}> <div className={styles.buttonContainer}>
<Button>Book</Button> <BookingButton />
</div> */} </div>
</nav> </nav>
</div> </div>
</div> </div>

View File

@@ -25,7 +25,7 @@
.navBar { .navBar {
display: grid; display: grid;
grid-template-columns: 1fr 80px 1fr; grid-template-columns: 1fr 80px 1fr;
padding-bottom: 1.5px; height: 52.39px;
} }
.expanderBtn { .expanderBtn {
@@ -33,8 +33,7 @@
border: none; border: none;
cursor: pointer; cursor: pointer;
justify-self: flex-start; justify-self: flex-start;
left: 0; padding: 11px 8px 16px;
padding: 12px 8px 16px;
transition: 0.3s; transition: 0.3s;
user-select: none; user-select: none;
} }
@@ -45,7 +44,7 @@
background: #757575; background: #757575;
border-radius: 2.3px; border-radius: 2.3px;
display: inline-block; display: inline-block;
height: 4.6px; height: 5px;
position: relative; position: relative;
transition: 0.3s; transition: 0.3s;
width: 32px; width: 32px;
@@ -178,6 +177,8 @@
.buttonContainer { .buttonContainer {
display: flex; display: flex;
justify-content: flex-end; justify-content: flex-end;
align-items: center;
margin-right: 8px;
} }
@media screen and (min-width: 1367px) { @media screen and (min-width: 1367px) {
@@ -200,6 +201,7 @@
.navBar { .navBar {
grid-template-columns: 132.18px 1fr auto; grid-template-columns: 132.18px 1fr auto;
align-content: center; align-content: center;
height: 85.09px;
} }
.expanderBtn { .expanderBtn {
@@ -261,6 +263,7 @@
@media (min-width: 1200px) { @media (min-width: 1200px) {
.navBar { .navBar {
grid-template-columns: 140px auto 1fr; grid-template-columns: 140px auto 1fr;
height: 82.4px;
} }
.logoLink { .logoLink {

View File

@@ -1,13 +1,18 @@
import { auth } from "@/auth"
import styles from "./topMenu.module.css" import styles from "./topMenu.module.css"
import type { TopMenuProps } from "@/types/components/current/header/topMenu" import type { TopMenuProps } from "@/types/components/current/header/topMenu"
export default function TopMenu({ export default async function TopMenu({
frontpageLinkText, frontpageLinkText,
homeHref, homeHref,
links, links,
languageSwitcher, languageSwitcher,
lang,
}: TopMenuProps) { }: TopMenuProps) {
const session = await auth()
return ( return (
<div className={styles.topMenu}> <div className={styles.topMenu}>
<div className={styles.container}> <div className={styles.container}>
@@ -25,6 +30,17 @@ export default function TopMenu({
</a> </a>
</li> </li>
))} ))}
<li className={styles.loginContainer}>
{session ? (
<a href={`${lang}/logout`} className={styles.loginLink}>
Log out
</a>
) : (
<a href={`${lang}/login`} className={styles.loginLink}>
Log in
</a>
)}
</li>
</ul> </ul>
</div> </div>
</div> </div>

View File

@@ -37,12 +37,15 @@
Arial, Arial,
sans-serif; sans-serif;
font-size: 13px; font-size: 13px;
font-weight: 400;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-rendering: optimizeLegibility;
} }
.langSwitcher { .langSwitcher {
text-align: center; text-align: center;
position: relative; position: relative;
display: block; display: block;
padding: 3px 15px;
} }
@media screen and (min-width: 768px) { @media screen and (min-width: 768px) {
@@ -63,6 +66,16 @@
.link { .link {
padding-top: 4px; padding-top: 4px;
padding-bottom: 4px; padding-bottom: 4px;
font-weight: 300; }
.loginContainer {
margin-left: 10px;
background-color: #f3f2f1;
}
.loginLink {
padding-left: 30px;
padding-right: 30px;
color: #000;
} }
} }

View File

@@ -14,7 +14,7 @@ export default async function Header({
lang, lang,
languageSwitcher, languageSwitcher,
}: LangParams & { languageSwitcher: React.ReactNode }) { }: LangParams & { languageSwitcher: React.ReactNode }) {
const data = await serverClient().contentstack.config.header() const data = await serverClient().contentstack.config.header({ lang })
const homeHref = homeHrefs[env.NODE_ENV][lang] const homeHref = homeHrefs[env.NODE_ENV][lang]
const { frontpage_link_text, logo, menu, top_menu } = data const { frontpage_link_text, logo, menu, top_menu } = data
@@ -31,6 +31,7 @@ export default async function Header({
homeHref={homeHref} homeHref={homeHref}
links={top_menu.links} links={top_menu.links}
languageSwitcher={languageSwitcher} languageSwitcher={languageSwitcher}
lang={lang}
/> />
<MainMenu <MainMenu
frontpageLinkText={frontpage_link_text} frontpageLinkText={frontpage_link_text}

View File

@@ -1,16 +0,0 @@
.hamburger {
background: none;
border: none;
cursor: pointer;
display: flex;
flex-direction: column;
gap: 0.5rem;
padding: 0;
}
.line {
background-color: var(--some-black-color, #1c1b1f);
border-radius: 0.8rem;
height: 0.2rem;
width: 2.5rem;
}

View File

@@ -1,11 +0,0 @@
import styles from "./hamburger.module.css"
export default function Hamburger() {
return (
<button className={styles.hamburger} type="button">
<div className={styles.line} />
<div className={styles.line} />
<div className={styles.line} />
</button>
)
}

View File

@@ -1,17 +0,0 @@
import Image from "@/components/Image"
import styles from "./language.module.css"
export default function LanguageSwitcher() {
return (
<div className={styles.switcher}>
<Image
alt="Swedish flag"
height={21}
src="/_static/icons/sweden.svg"
width={21}
/>
<span>SV / SEK</span>
</div>
)
}

View File

@@ -1,15 +0,0 @@
.switcher {
align-items: center;
display: none;
font-family: var(--typography-Body-Regular-fontFamily);
font-size: 1.4rem;
font-weight: 400;
gap: 0.6rem;
line-height: 1.6rem;
}
@media screen and (min-width: 1367px) {
.switcher {
display: flex;
}
}

View File

@@ -1,15 +0,0 @@
import Link from "next/link"
import Image from "@/components/Image"
import styles from "./logo.module.css"
import { LogoProps } from "@/types/components/header/logo"
export default async function Logo({ title, height, width, src }: LogoProps) {
return (
<Link className={styles.link} href="#">
<Image alt={title} height={height} src={src} width={width} />
</Link>
)
}

View File

@@ -1,4 +0,0 @@
.link {
cursor: pointer;
display: block;
}

View File

@@ -1,25 +0,0 @@
.header {
align-items: center;
background-color: var(--some-white-color, #fff);
box-shadow: 0px 1.0006656646728516px 1.0006656646728516px 0px #0000000d;
display: grid;
gap: 3rem;
grid-template-columns: 1fr auto auto;
height: var(--header-height);
padding: 0 2rem;
position: sticky;
top: 0;
z-index: 999;
}
@media screen and (min-width: 1367px) {
.header {
background-color: var(--some-grey-color, #ececec);
border-bottom: 0.1rem solid var(--some-grey-color, #ccc);
box-shadow: none;
gap: 3.2rem;
grid-template-columns: 1fr 19rem auto auto;
padding: 0 2.4rem;
}
}

View File

@@ -1,35 +0,0 @@
import { GetHeader } from "@/lib/graphql/Query/Header.graphql"
import { request } from "@/lib/graphql/request"
import Logo from "./Logo"
import styles from "./header.module.css"
import type { LangParams } from "@/types/params"
import { HeaderQueryData } from "@/types/requests/header"
export default async function Header({ lang }: LangParams) {
const { data } = await request<HeaderQueryData>(GetHeader, {
locale: lang,
})
if (
!data.all_header.items.length ||
!data.all_header.items?.[0].logoConnection.totalCount
) {
return null
}
const logo = data.all_header.items[0].logoConnection.edges[0]
return (
<header className={styles.header}>
<Logo
title={logo.node.title}
height={logo.node.dimension.height}
width={logo.node.dimension.width}
src={logo.node.url}
/>
</header>
)
}

View File

@@ -1,32 +0,0 @@
#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
}
}
}
}
}

View File

@@ -0,0 +1,9 @@
import z from "zod"
import { Lang } from "@/constants/languages"
export const headerInput = z
.object({
lang: z.nativeEnum(Lang),
})
.optional()

View File

@@ -4,6 +4,7 @@ import { request } from "@/lib/graphql/request"
import { internalServerError, notFound } from "@/server/errors/trpc" import { internalServerError, notFound } from "@/server/errors/trpc"
import { contentstackProcedure, publicProcedure, router } from "@/server/trpc" import { contentstackProcedure, publicProcedure, router } from "@/server/trpc"
import { headerInput } from "./input"
import { import {
type ContactConfigData, type ContactConfigData,
HeaderData, HeaderData,
@@ -34,11 +35,12 @@ export const configQueryRouter = router({
return validatedContactConfigConfig.data.all_contact_config.items[0] return validatedContactConfigConfig.data.all_contact_config.items[0]
}), }),
header: publicProcedure.query(async ({ ctx }) => { header: publicProcedure.input(headerInput).query(async ({ input, ctx }) => {
const locale = input?.lang || ctx.lang
const response = await request<HeaderDataRaw>( const response = await request<HeaderDataRaw>(
GetCurrentHeader, GetCurrentHeader,
{ locale: ctx.lang }, { locale },
{ next: { tags: [`header-${ctx.lang}`] } } { next: { tags: [`header-${locale}`] } }
) )
if (!response.data) { if (!response.data) {

View File

@@ -1,10 +1,13 @@
import type { Image } from "@/types/image" import type { Image } from "@/types/image"
import type { HeaderLink, TopMenuHeaderLink } from "@/types/requests/header" import type {
CurrentHeaderLink,
TopMenuHeaderLink,
} from "@/types/requests/currentHeader"
export type MainMenuProps = { export type MainMenuProps = {
frontpageLinkText: string frontpageLinkText: string
homeHref: string homeHref: string
links: HeaderLink[] links: CurrentHeaderLink[]
logo: Image logo: Image
topMenuMobileLinks: TopMenuHeaderLink[] topMenuMobileLinks: TopMenuHeaderLink[]
languageSwitcher: React.ReactNode languageSwitcher: React.ReactNode

View File

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

View File

@@ -7,7 +7,7 @@ export type CurrentHeaderLink = {
title: string title: string
} }
export type TopMenuCurrentHeaderLink = { export type TopMenuHeaderLink = {
link: { link: {
href: string href: string
title: string title: string
@@ -21,7 +21,7 @@ export type CurrentHeaderLinks = {
} }
export type TopMenuCurrentHeaderLinks = { export type TopMenuCurrentHeaderLinks = {
links: TopMenuCurrentHeaderLink[] links: TopMenuHeaderLink[]
} }
export type CurrentHeader = { export type CurrentHeader = {

View File

@@ -1,35 +0,0 @@
import type { Image } from "../image"
import type { EdgesWithTotalCount } from "./utils/edges"
export type HeaderLink = {
href: string
title: string
}
export type TopMenuHeaderLink = {
link: {
href: string
title: string
}
show_on_mobile: boolean
sort_order_mobile: number
}
export type HeaderLinks = {
links: HeaderLink[]
}
export type TopMenuHeaderLinks = {
links: TopMenuHeaderLink[]
}
export type HeaderQueryData = {
all_header: {
items: {
frontpage_link_text: string
logoConnection: EdgesWithTotalCount<Image>
menu: HeaderLinks
top_menu: TopMenuHeaderLinks
}[]
}
}