From b173c2fb11c521375599a056b0eda66be29e0a9f Mon Sep 17 00:00:00 2001 From: Simon Emanuelsson Date: Mon, 18 Mar 2024 17:24:17 +0100 Subject: [PATCH] feat(WEB-128): desktop and mobile initial wireframe implemented --- .prettierignore | 1 + .../(protected)/my-pages/layout.module.css | 31 +++++++++ .../(live)/(protected)/my-pages/layout.tsx | 23 +++++++ .../(protected)/my-pages/page.module.css | 27 ++++++++ .../(live)/(protected)/my-pages/page.tsx | 25 +++++-- app/[lang]/(live)/fonts.ts | 7 ++ app/[lang]/(live)/layout.tsx | 4 +- app/globals.css | 19 ++++++ auth.ts | 11 ++-- components/Current/Blocks/List/ListItem.tsx | 5 +- components/MyPages/Blocks/Overview/Mobile.tsx | 13 ++++ components/MyPages/Blocks/Overview/index.tsx | 5 ++ .../Blocks/Overview/overview.module.css | 34 ++++++++++ .../Blocks/UpcomingStays/Stay/index.tsx | 66 +++++++++++++++++++ .../Blocks/UpcomingStays/Stay/stay.module.css | 61 +++++++++++++++++ .../MyPages/Blocks/UpcomingStays/index.tsx | 42 ++++++++++++ .../Blocks/UpcomingStays/upcoming.module.css | 30 +++++++++ .../Header/Breadcrumbs/breadcrumbs.module.css | 21 ++++++ .../MyPages/Header/Breadcrumbs/index.tsx | 23 +++++++ .../Header/Hamburger/hamburger.module.css | 16 +++++ components/MyPages/Header/Hamburger/index.tsx | 11 ++++ .../MyPages/Header/LanguageSwitcher/index.tsx | 11 ++++ .../LanguageSwitcher/language.module.css | 15 +++++ components/MyPages/Header/Logo/index.tsx | 33 ++++++++++ .../MyPages/Header/Logo/logo.module.css | 4 ++ components/MyPages/Header/User/index.tsx | 10 +++ .../MyPages/Header/User/user.module.css | 43 ++++++++++++ components/MyPages/Header/header.module.css | 36 ++++++++++ components/MyPages/Header/index.tsx | 25 +++++++ components/MyPages/Sidebar/index.tsx | 40 +++++++++++ components/MyPages/Sidebar/sidebar.module.css | 45 +++++++++++++ components/MyPages/Title/index.tsx | 40 +++++++++++ components/MyPages/Title/title.module.css | 43 ++++++++++++ lib/dt.ts | 60 +++++++++++++++++ lib/graphql/Query/Logo.graphql | 16 +++++ package-lock.json | 21 ++++-- package.json | 4 +- public/calendar_month.svg | 8 +++ public/flower-image.svg | 8 +++ public/person.svg | 8 +++ public/sweden.svg | 8 +++ types/components/myPages/stay.ts | 6 ++ types/components/myPages/title.ts | 7 ++ types/requests/myPages/logo.ts | 10 +++ 44 files changed, 957 insertions(+), 19 deletions(-) create mode 100644 app/[lang]/(live)/(protected)/my-pages/layout.module.css create mode 100644 app/[lang]/(live)/(protected)/my-pages/layout.tsx create mode 100644 app/[lang]/(live)/(protected)/my-pages/page.module.css create mode 100644 app/[lang]/(live)/fonts.ts create mode 100644 components/MyPages/Blocks/Overview/Mobile.tsx create mode 100644 components/MyPages/Blocks/Overview/index.tsx create mode 100644 components/MyPages/Blocks/Overview/overview.module.css create mode 100644 components/MyPages/Blocks/UpcomingStays/Stay/index.tsx create mode 100644 components/MyPages/Blocks/UpcomingStays/Stay/stay.module.css create mode 100644 components/MyPages/Blocks/UpcomingStays/index.tsx create mode 100644 components/MyPages/Blocks/UpcomingStays/upcoming.module.css create mode 100644 components/MyPages/Header/Breadcrumbs/breadcrumbs.module.css create mode 100644 components/MyPages/Header/Breadcrumbs/index.tsx create mode 100644 components/MyPages/Header/Hamburger/hamburger.module.css create mode 100644 components/MyPages/Header/Hamburger/index.tsx create mode 100644 components/MyPages/Header/LanguageSwitcher/index.tsx create mode 100644 components/MyPages/Header/LanguageSwitcher/language.module.css create mode 100644 components/MyPages/Header/Logo/index.tsx create mode 100644 components/MyPages/Header/Logo/logo.module.css create mode 100644 components/MyPages/Header/User/index.tsx create mode 100644 components/MyPages/Header/User/user.module.css create mode 100644 components/MyPages/Header/header.module.css create mode 100644 components/MyPages/Header/index.tsx create mode 100644 components/MyPages/Sidebar/index.tsx create mode 100644 components/MyPages/Sidebar/sidebar.module.css create mode 100644 components/MyPages/Title/index.tsx create mode 100644 components/MyPages/Title/title.module.css create mode 100644 lib/dt.ts create mode 100644 lib/graphql/Query/Logo.graphql create mode 100644 public/calendar_month.svg create mode 100644 public/flower-image.svg create mode 100644 public/person.svg create mode 100644 public/sweden.svg create mode 100644 types/components/myPages/stay.ts create mode 100644 types/components/myPages/title.ts create mode 100644 types/requests/myPages/logo.ts diff --git a/.prettierignore b/.prettierignore index 433d656d1..84dd22b6b 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,5 +1,6 @@ # Directories public/_static +public/*.svg # Files app/core.css diff --git a/app/[lang]/(live)/(protected)/my-pages/layout.module.css b/app/[lang]/(live)/(protected)/my-pages/layout.module.css new file mode 100644 index 000000000..4ad216198 --- /dev/null +++ b/app/[lang]/(live)/(protected)/my-pages/layout.module.css @@ -0,0 +1,31 @@ +.page { + --max-width: 101.4rem; + + display: grid; + font-family: var(--ff-fira-sans); + grid-template-rows: auto 1fr; + min-height: 100dvh; +} + +.content { + display: grid; + padding: 0 0 17.5rem; + padding-bottom: 2.4rem; + padding-left: 0; + padding-right: 0; + padding-top: 0; +} + +@media screen and (min-width: 950px) { + .page { + gap: 4.4rem; + } + + .content { + gap: 10rem; + grid-template-columns: 25rem 1fr; + padding-bottom: 17.5rem; + padding-left: 2.4rem; + padding-right: 2.4rem; + } +} diff --git a/app/[lang]/(live)/(protected)/my-pages/layout.tsx b/app/[lang]/(live)/(protected)/my-pages/layout.tsx new file mode 100644 index 000000000..f0427c12f --- /dev/null +++ b/app/[lang]/(live)/(protected)/my-pages/layout.tsx @@ -0,0 +1,23 @@ +import { firaSans } from "@/app/[lang]/(live)/fonts" + +import Header from "@/components/MyPages/Header" +import Sidebar from "@/components/MyPages/Sidebar" + +import styles from "./layout.module.css" + +import type { LangParams, LayoutArgs } from "@/types/params" + +export default function MyPagesLayout({ + children, + params, +}: React.PropsWithChildren>) { + return ( +
+
+
+ +
{children}
+
+
+ ) +} diff --git a/app/[lang]/(live)/(protected)/my-pages/page.module.css b/app/[lang]/(live)/(protected)/my-pages/page.module.css new file mode 100644 index 000000000..0ad1e0ab7 --- /dev/null +++ b/app/[lang]/(live)/(protected)/my-pages/page.module.css @@ -0,0 +1,27 @@ +.container { + display: grid; + gap: 2.2rem; +} + +.blocks { + display: grid; + gap: 4.2rem; + padding-left: 2rem; + padding-right: 2rem; +} + +.header { + display: none; +} + +@media screen and (min-width: 950px) { + .blocks { + gap: 6.4rem; + padding-left: 0; + padding-right: 0; + } + + .header { + display: block; + } +} diff --git a/app/[lang]/(live)/(protected)/my-pages/page.tsx b/app/[lang]/(live)/(protected)/my-pages/page.tsx index f567c8dbf..bc6b05c65 100644 --- a/app/[lang]/(live)/(protected)/my-pages/page.tsx +++ b/app/[lang]/(live)/(protected)/my-pages/page.tsx @@ -1,12 +1,27 @@ import { auth } from "@/auth" -export default async function MyPages() { +import Overview from "@/components/MyPages/Blocks/Overview" +import OverviewMobile from "@/components/MyPages/Blocks/Overview/Mobile" +import Title from "@/components/MyPages/Title" +import UpcomingStays from "@/components/MyPages/Blocks/UpcomingStays" + +import styles from "./page.module.css" + +import type { LangParams, PageArgs } from "@/types/params" + +export default async function MyPage({ params }: PageArgs) { const session = await auth() console.log({ session }) return ( - <> -

Wilkommen

-
{JSON.stringify(session, null, 2)}
- +
+
+ Good morning {session?.user?.name ?? "[NAME]"} +
+
+ + + +
+
) } diff --git a/app/[lang]/(live)/fonts.ts b/app/[lang]/(live)/fonts.ts new file mode 100644 index 000000000..41b15be86 --- /dev/null +++ b/app/[lang]/(live)/fonts.ts @@ -0,0 +1,7 @@ +import { Fira_Sans } from "next/font/google" + +export const firaSans = Fira_Sans({ + subsets: ["latin"], + weight: ["300", "400", "600", "900"], + variable: "--ff-fira-sans", +}) diff --git a/app/[lang]/(live)/layout.tsx b/app/[lang]/(live)/layout.tsx index 41740e684..9deddef70 100644 --- a/app/[lang]/(live)/layout.tsx +++ b/app/[lang]/(live)/layout.tsx @@ -1,9 +1,11 @@ import AdobeScript from "@/components/Current/AdobeScript" import Script from "next/script" +import VwoScript from "@/components/Current/VwoScript" import type { Metadata } from "next" import type { LangParams, LayoutArgs } from "@/types/params" -import VwoScript from "@/components/Current/VwoScript" + +import "@/app/globals.css" export const metadata: Metadata = { description: "New web", diff --git a/app/globals.css b/app/globals.css index e69de29bb..e6547e169 100644 --- a/app/globals.css +++ b/app/globals.css @@ -0,0 +1,19 @@ +:root { + font-size: 62.5%; +} + +* { + box-sizing: border-box; +} + +html { + margin: 0; + padding: 0; +} + +body { + margin: 0; + min-height: 100dvh; + overflow-x: hidden; + padding: 0; +} diff --git a/auth.ts b/auth.ts index a1d4f9ce2..04cb71491 100644 --- a/auth.ts +++ b/auth.ts @@ -54,6 +54,7 @@ export const config = { return true }, async session(...args) { + console.log("****** SESSION *******") console.log(args) return args[0].session }, @@ -70,14 +71,14 @@ export const config = { } return baseUrl }, - authorized({ auth, request }) { + async authorized({ auth, request }) { console.log("****** AUTHORIZED *******") console.log({ request, auth }) // const { pathname } = request.nextUrl // if (pathname === "/middleware-example") return !!auth return true }, - jwt({ session, token, trigger }) { + async jwt({ session, token, trigger }) { console.log("****** JWT *******") // if (trigger === "update") token.name = session.user.name console.log({ token, trigger, session }) @@ -86,10 +87,12 @@ export const config = { }, events: { async signIn(...args) { - console.log({ args }) + console.log("#### SIGNIN EVENT ARGS ######") + console.log(args) }, async session(...args) { - console.log({ args }) + console.log("#### SESSION EVENT ARGS ######") + console.log(args) }, }, logger: { diff --git a/components/Current/Blocks/List/ListItem.tsx b/components/Current/Blocks/List/ListItem.tsx index 375c4d2b4..a2390c037 100644 --- a/components/Current/Blocks/List/ListItem.tsx +++ b/components/Current/Blocks/List/ListItem.tsx @@ -1,10 +1,11 @@ import { cva } from "class-variance-authority" + import { BlockListItemsEnum } from "@/types/requests/blocks/list" -import type { ListItem } from "@/types/requests/blocks/list" - import styles from "./list.module.css" +import type { ListItem } from "@/types/requests/blocks/list" + const config = { variants: { type: { diff --git a/components/MyPages/Blocks/Overview/Mobile.tsx b/components/MyPages/Blocks/Overview/Mobile.tsx new file mode 100644 index 000000000..65bb9dbd1 --- /dev/null +++ b/components/MyPages/Blocks/Overview/Mobile.tsx @@ -0,0 +1,13 @@ +import Breadcrumbs from "@/components/MyPages/Header/Breadcrumbs" +import Title from "@/components/MyPages/Title" + +import styles from "./overview.module.css" + +export default function OverviewMobile() { + return ( +
+ + Good Morning [NAME] +
+ ) +} diff --git a/components/MyPages/Blocks/Overview/index.tsx b/components/MyPages/Blocks/Overview/index.tsx new file mode 100644 index 000000000..a954da5c4 --- /dev/null +++ b/components/MyPages/Blocks/Overview/index.tsx @@ -0,0 +1,5 @@ +import styles from "./overview.module.css" + +export default function Overview() { + return
+} diff --git a/components/MyPages/Blocks/Overview/overview.module.css b/components/MyPages/Blocks/Overview/overview.module.css new file mode 100644 index 000000000..8b5f0fc88 --- /dev/null +++ b/components/MyPages/Blocks/Overview/overview.module.css @@ -0,0 +1,34 @@ +.overview { + display: none; +} + +.overviewMobile { + background-color: var(--some-grey-color, #f2f2f2); + left: 50%; + margin-left: -50vw; + margin-right: -50vw; + padding: 3.5rem 2rem 2rem; + position: relative; + right: 50%; + width: 100dvw; +} + +@media screen and (min-width: 950px) { + .overview { + background-color: var(--some-grey-color, #f2f2f2); + border-radius: 0.8rem; + display: block; + height: 35rem; + left: unset; + margin-left: unset; + margin-right: unset; + max-width: var(--max-width); + position: static; + right: unset; + width: 100%; + } + + .overviewMobile { + display: none; + } +} diff --git a/components/MyPages/Blocks/UpcomingStays/Stay/index.tsx b/components/MyPages/Blocks/UpcomingStays/Stay/index.tsx new file mode 100644 index 000000000..bbbf2388d --- /dev/null +++ b/components/MyPages/Blocks/UpcomingStays/Stay/index.tsx @@ -0,0 +1,66 @@ +import { dt } from "@/lib/dt" + +import Image from "@/components/Image" +import Title from "@/components/MyPages/Title" + +import styles from "./stay.module.css" + +import type { LangParams } from "@/types/params" +import type { StayProps } from "@/types/components/myPages/stay" + +export default function Stay({ + dateArrive, + dateDepart, + guests, + hotel, + lang, +}: StayProps & LangParams) { + const daysUntilArrival = dt(dateArrive).diff(dt(), "days") + const arrival = dt(dateArrive).locale(lang) + const arrivalDate = arrival.format("DD MMM") + const arrivalDateTime = arrival.format("YYYY-MM-DD") + const depart = dt(dateDepart).locale(lang) + const departDate = depart.format("DD MMM YYYY") + const departDateTime = depart.format("YYYY-MM-DD") + return ( +
+
+
+ +
+ Placeholder image flower +
+
+ + {hotel} + +
+
+ Calendar Icon +

+ + {" - "} + +

+
+
+ Guests Icon + + {guests} guest{guests > 1 ? "s" : ""} + +
+
+
+
+ ) +} diff --git a/components/MyPages/Blocks/UpcomingStays/Stay/stay.module.css b/components/MyPages/Blocks/UpcomingStays/Stay/stay.module.css new file mode 100644 index 000000000..87f9a38c3 --- /dev/null +++ b/components/MyPages/Blocks/UpcomingStays/Stay/stay.module.css @@ -0,0 +1,61 @@ +.stay { + background-color: var(--some-grey-color, #ababab); + border-radius: 0.8rem; + display: grid; + flex-grow: 1; + flex-shrink: 0; + flex-basis: 32rem; + grid-template-rows: 1fr 9rem; + height: 28rem; +} + +.imageContainer { + align-items: center; + display: grid; + justify-content: center; + position: relative; +} + +.badge { + background-color: var(--some-white-color, #fff); + border-radius: 4rem; + left: 1.5rem; + padding: 0.6rem 1.4rem; + position: absolute; + top: 1.5rem; +} + +.time { + color: var(--some-black-color, #000); + font-family: var(--ff-fira-sans); + font-size: 1.2rem; + font-weight: 400; +} + +.footer { + background-color: var(--some-white-color, #fff); + border-bottom: 0.1rem solid var(--some-grey-color, #d9d9d9); + border-left: 0.1rem solid var(--some-grey-color, #d9d9d9); + border-right: 0.1rem solid var(--some-grey-color, #d9d9d9); + border-radius: 0 0 0.8rem 0.8rem; + display: flex; + flex-direction: column; + gap: 0.8rem; + height: 9rem; + padding: 1.5rem 2rem; +} + +.container { + align-items: center; + display: grid; + gap: 2rem; + grid-template-columns: auto 1fr; + justify-content: flex-start; +} + +.date, +.guests { + align-items: center; + display: flex; + gap: 0.6rem; +} diff --git a/components/MyPages/Blocks/UpcomingStays/index.tsx b/components/MyPages/Blocks/UpcomingStays/index.tsx new file mode 100644 index 000000000..3879559e4 --- /dev/null +++ b/components/MyPages/Blocks/UpcomingStays/index.tsx @@ -0,0 +1,42 @@ +import Stay from "./Stay" +import Title from "@/components/MyPages/Title" + +import styles from "./upcoming.module.css" + +import type { LangParams } from "@/types/params" + +const stays = [ + { + dateArrive: new Date("04 27 2024"), + dateDepart: new Date("04 28 2024"), + guests: 2, + hotel: "Scandic Helsinki Hub", + }, + { + dateArrive: new Date("05 27 2024"), + dateDepart: new Date("05 28 2024"), + guests: 2, + hotel: "Scandic Örebro Central", + }, + { + dateArrive: new Date("06 27 2024"), + dateDepart: new Date("06 28 2024"), + guests: 2, + hotel: "Scandic Oslo City", + }, +] + +export default function UpcomingStays({ lang }: LangParams) { + return ( +
+ + Your upcoming stays + +
+ {stays.map((stay) => ( + + ))} +
+
+ ) +} diff --git a/components/MyPages/Blocks/UpcomingStays/upcoming.module.css b/components/MyPages/Blocks/UpcomingStays/upcoming.module.css new file mode 100644 index 000000000..cd15129fe --- /dev/null +++ b/components/MyPages/Blocks/UpcomingStays/upcoming.module.css @@ -0,0 +1,30 @@ +.container { + display: grid; + gap: 2.2rem; + margin-right: -2rem; + max-width: var(--max-width); + overflow: hidden; +} + +.stays { + display: flex; + gap: 2rem; + overflow-x: auto; + padding-right: 2rem; + + /* Hide scrollbar IE and Edge */ + -ms-overflow-style: none; + /* Hide Scrollbar Firefox */ + scrollbar-width: none; +} + +/* Hide Scrollbar Chrome, Safari and Opera */ +.stays::-webkit-scrollbar { + display: none; +} + +@media screen and (min-width: 950px) { + .container { + margin-right: 0; + } +} diff --git a/components/MyPages/Header/Breadcrumbs/breadcrumbs.module.css b/components/MyPages/Header/Breadcrumbs/breadcrumbs.module.css new file mode 100644 index 000000000..640a23c0e --- /dev/null +++ b/components/MyPages/Header/Breadcrumbs/breadcrumbs.module.css @@ -0,0 +1,21 @@ +.list { + align-items: center; + display: flex; + gap: 0.4rem; + justify-content: flex-start; + list-style: none; + margin: 0; + padding: 0; +} + +.listItem, +.link { + color: var(--some-text-color, #000); + font-size: 1.4rem; + font-weight: 400; + line-height: 1.56rem; +} + +.link { + text-decoration: none; +} diff --git a/components/MyPages/Header/Breadcrumbs/index.tsx b/components/MyPages/Header/Breadcrumbs/index.tsx new file mode 100644 index 000000000..53ec7bd0d --- /dev/null +++ b/components/MyPages/Header/Breadcrumbs/index.tsx @@ -0,0 +1,23 @@ +import Link from "next/link" + +import styles from "./breadcrumbs.module.css" + +export default function Breadcrumbs() { + return ( + + ) +} diff --git a/components/MyPages/Header/Hamburger/hamburger.module.css b/components/MyPages/Header/Hamburger/hamburger.module.css new file mode 100644 index 000000000..61086cc08 --- /dev/null +++ b/components/MyPages/Header/Hamburger/hamburger.module.css @@ -0,0 +1,16 @@ +.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; +} diff --git a/components/MyPages/Header/Hamburger/index.tsx b/components/MyPages/Header/Hamburger/index.tsx new file mode 100644 index 000000000..f20374e32 --- /dev/null +++ b/components/MyPages/Header/Hamburger/index.tsx @@ -0,0 +1,11 @@ +import styles from "./hamburger.module.css" + +export default function Hamburger() { + return ( + + ) +} diff --git a/components/MyPages/Header/LanguageSwitcher/index.tsx b/components/MyPages/Header/LanguageSwitcher/index.tsx new file mode 100644 index 000000000..96b05428e --- /dev/null +++ b/components/MyPages/Header/LanguageSwitcher/index.tsx @@ -0,0 +1,11 @@ +import Image from "@/components/Image" +import styles from "./language.module.css" + +export default function LanguageSwitcher() { + return ( +
+ Swedish flag + SV / SEK +
+ ) +} diff --git a/components/MyPages/Header/LanguageSwitcher/language.module.css b/components/MyPages/Header/LanguageSwitcher/language.module.css new file mode 100644 index 000000000..9bd8b7566 --- /dev/null +++ b/components/MyPages/Header/LanguageSwitcher/language.module.css @@ -0,0 +1,15 @@ +.switcher { + align-items: center; + display: none; + font-family: var(--ff-fira-sans); + font-size: 1.4rem; + font-weight: 400; + gap: 0.6rem; + line-height: 1.6rem; +} + +@media screen and (min-width: 950px) { + .switcher { + display: flex; + } +} diff --git a/components/MyPages/Header/Logo/index.tsx b/components/MyPages/Header/Logo/index.tsx new file mode 100644 index 000000000..dd6145b4e --- /dev/null +++ b/components/MyPages/Header/Logo/index.tsx @@ -0,0 +1,33 @@ +import { request } from "@/lib/request" +import { GetMyPagesLogo } from "@/lib/graphql/Query/Logo.graphql" + +import Image from "@/components/Image" +import Link from "next/link" + +import styles from "./logo.module.css" + +import type { LangParams } from "@/types/params" +import type { LogoQueryData } from "@/types/requests/myPages/logo" + +export default async function Logo({ lang }: LangParams) { + const { data } = await request(GetMyPagesLogo, { + 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 ( + + {logo.node.title} + + ) +} diff --git a/components/MyPages/Header/Logo/logo.module.css b/components/MyPages/Header/Logo/logo.module.css new file mode 100644 index 000000000..cdb897b61 --- /dev/null +++ b/components/MyPages/Header/Logo/logo.module.css @@ -0,0 +1,4 @@ +.link { + cursor: pointer; + display: block; +} diff --git a/components/MyPages/Header/User/index.tsx b/components/MyPages/Header/User/index.tsx new file mode 100644 index 000000000..3611c6100 --- /dev/null +++ b/components/MyPages/Header/User/index.tsx @@ -0,0 +1,10 @@ +import styles from "./user.module.css" + +export default function User() { + return ( +
+ FK + 1 +
+ ) +} diff --git a/components/MyPages/Header/User/user.module.css b/components/MyPages/Header/User/user.module.css new file mode 100644 index 000000000..c93b73f11 --- /dev/null +++ b/components/MyPages/Header/User/user.module.css @@ -0,0 +1,43 @@ +.user { + align-items: center; + background-color: var(--some-black-color, #000); + border-radius: 50%; + color: var(--some-white-color, #fff); + display: flex; + font-family: var(--ff-fira-sans); + font-size: 1.2rem; + font-weight: 600; + height: 3.5rem; + justify-content: center; + position: relative; + width: 3.5rem; +} + +.alert { + align-items: center; + background-color: var(--some-red-color, #ed2027); + border-radius: 50%; + display: flex; + font-size: 1rem; + height: 2rem; + justify-content: center; + position: absolute; + right: -1rem; + top: -0.5rem; + width: 2rem; +} + +@media screen and (min-width: 950px) { + .user { + height: 2.8rem; + width: 2.8rem; + } + + .alert { + font-size: 0.6rem; + height: 1rem; + right: -0.2rem; + top: -0.1rem; + width: 1rem; + } +} diff --git a/components/MyPages/Header/header.module.css b/components/MyPages/Header/header.module.css new file mode 100644 index 000000000..5be0db772 --- /dev/null +++ b/components/MyPages/Header/header.module.css @@ -0,0 +1,36 @@ +.container { + position: sticky; + top: 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: 7rem; + padding: 0 2rem; +} + +.breadcrumbs { + display: none; +} + +@media screen and (min-width: 950px) { + .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; + height: 4.5rem; + padding: 0 2.4rem; + } + + .breadcrumbs { + display: block; + padding-left: 2.4rem; + } +} diff --git a/components/MyPages/Header/index.tsx b/components/MyPages/Header/index.tsx new file mode 100644 index 000000000..6b57c4462 --- /dev/null +++ b/components/MyPages/Header/index.tsx @@ -0,0 +1,25 @@ +import Breadcrumbs from "./Breadcrumbs" +import Hamburger from "./Hamburger" +import LanguageSwitcher from "./LanguageSwitcher" +import Logo from "./Logo" +import User from "./User" + +import styles from "./header.module.css" + +import type { LangParams } from "@/types/params" + +export default function Header({ lang }: LangParams) { + return ( +
+
+ + + + +
+
+ +
+
+ ) +} diff --git a/components/MyPages/Sidebar/index.tsx b/components/MyPages/Sidebar/index.tsx new file mode 100644 index 000000000..4007c117f --- /dev/null +++ b/components/MyPages/Sidebar/index.tsx @@ -0,0 +1,40 @@ +import { LogOut } from "react-feather" +import Link from "next/link" + +import styles from "./sidebar.module.css" + +export default function Sidebar() { + return ( + + ) +} diff --git a/components/MyPages/Sidebar/sidebar.module.css b/components/MyPages/Sidebar/sidebar.module.css new file mode 100644 index 000000000..bf8e86bc8 --- /dev/null +++ b/components/MyPages/Sidebar/sidebar.module.css @@ -0,0 +1,45 @@ +.sidebar { + align-self: flex-start; + display: none; + position: sticky; + top: 13.2rem; +} + +.nav { + align-items: flex-start; + display: flex; + flex-direction: column; + gap: 2rem; + padding-left: 4rem; +} + +.link { + align-items: center; + color: var(--some-text-color, #111); + display: flex; + font-size: 1.6rem; + font-weight: 400; + gap: 0.6rem; + line-height: 1.9rem; + position: relative; + text-decoration: none; +} + +.active { + font-weight: 600; +} + +.active::before { + bottom: -0.4rem; + background-color: var(--some-text-color, #000); + content: ""; + height: 0.2rem; + position: absolute; + width: 100%; +} + +@media screen and (min-width: 950px) { + .sidebar { + display: block; + } +} diff --git a/components/MyPages/Title/index.tsx b/components/MyPages/Title/index.tsx new file mode 100644 index 000000000..0da643b28 --- /dev/null +++ b/components/MyPages/Title/index.tsx @@ -0,0 +1,40 @@ +import { cva } from "class-variance-authority" + +import styles from "./title.module.css" + +import type { HeadingProps } from "@/types/components/myPages/title" + +const config = { + variants: { + text: { + uppercase: styles.uppercase, + }, + type: { + h1: styles.h1, + h2: styles.h2, + h3: styles.h3, + h4: styles.h4, + h5: styles.h5, + h6: styles.h6, + }, + }, + defaultVariants: { + type: "h1", + }, +} as const + +const headingStyles = cva(styles.heading, config) + +export default function Title({ + as, + children, + level = "h1", + uppercase = false, +}: HeadingProps) { + const Hx = level + const className = headingStyles({ + text: uppercase ? "uppercase" : undefined, + type: as ?? level, + }) + return {children} +} diff --git a/components/MyPages/Title/title.module.css b/components/MyPages/Title/title.module.css new file mode 100644 index 000000000..244eda2da --- /dev/null +++ b/components/MyPages/Title/title.module.css @@ -0,0 +1,43 @@ +.heading { + font-weight: 900; + margin: 0; + padding: 0; +} + +.uppercase { + text-transform: uppercase; +} + +.h1 { + font-size: 2.4rem; + line-height: 2.8rem; +} + +.h2 { + font-size: 2.4rem; + line-height: 2.8rem; +} + +.h3 { + font-size: 1.6rem; + line-height: 1.8rem; +} + +.h4 { + font-size: 1.4rem; +} + +.h5 { + font-size: 1.2rem; +} + +.h6 { + font-size: 1rem; +} + +@media screen and (min-width: 950px) { + .h1 { + font-size: 3.8rem; + line-height: 4.5rem; + } +} diff --git a/lib/dt.ts b/lib/dt.ts new file mode 100644 index 000000000..ad7bc7f9f --- /dev/null +++ b/lib/dt.ts @@ -0,0 +1,60 @@ +import d from "dayjs" +import isToday from "dayjs/plugin/isToday" +import relativeTime from "dayjs/plugin/relativeTime" + +import "dayjs/locale/da" +import "dayjs/locale/de" +import "dayjs/locale/fi" +import "dayjs/locale/sv" + +/** + * dayjs export Norwegian as nb [Norwegian Bokmål] so here we create the same + * setup as nb has. + * https://day.js.org/docs/en/customization/customization + * https://github.com/iamkun/dayjs/blob/dev/src/locale/nb.js + */ +d.locale("no", { + name: "no", + weekdays: "søndag_mandag_tirsdag_onsdag_torsdag_fredag_lørdag".split("_"), + weekdaysShort: "sø._ma._ti._on._to._fr._lø.".split("_"), + weekdaysMin: "sø_ma_ti_on_to_fr_lø".split("_"), + months: + "januar_februar_mars_april_mai_juni_juli_august_september_oktober_november_desember".split( + "_" + ), + monthsShort: + "jan._feb._mars_april_mai_juni_juli_aug._sep._okt._nov._des.".split("_"), + ordinal: (n: any) => `${n}.`, + weekStart: 1, + formats: { + LT: "HH:mm", + LTS: "HH:mm:ss", + L: "DD.MM.YYYY", + LL: "D. MMMM YYYY", + LLL: "D. MMMM YYYY [kl.] HH:mm", + LLLL: "dddd D. MMMM YYYY [kl.] HH:mm", + }, + relativeTime: { + future: "om %s", + past: "%s siden", + s: "noen sekunder", + m: "ett minutt", + mm: "%d minutter", + h: "en time", + hh: "%d timer", + d: "en dag", + dd: "%d dager", + M: "en måned", + MM: "%d måneder", + y: "ett år", + yy: "%d år", + }, +}) + +/** + * If more plugins are needed https://day.js.org/docs/en/plugin/plugin + */ +d.extend(isToday) +d.extend(relativeTime) + +export const dt = d diff --git a/lib/graphql/Query/Logo.graphql b/lib/graphql/Query/Logo.graphql new file mode 100644 index 000000000..831238481 --- /dev/null +++ b/lib/graphql/Query/Logo.graphql @@ -0,0 +1,16 @@ +#import "../Fragments/Image.graphql" + +query GetMyPagesLogo($locale: String!) { + all_header(limit: 1, locale: $locale) { + items { + logoConnection { + edges { + node { + ...Image + } + } + totalCount + } + } + } +} diff --git a/package-lock.json b/package-lock.json index 04d7c91af..3edbb099a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,6 +14,7 @@ "@scandic-hotels/design-system": "git+https://x-token-auth:$DESIGN_SYSTEM_ACCESS_TOKEN@bitbucket.org/scandic-swap/design-system.git#v0.1.0-rc.2", "@t3-oss/env-nextjs": "^0.9.2", "class-variance-authority": "^0.7.0", + "dayjs": "^1.11.10", "graphql": "^16.8.1", "graphql-request": "^6.1.0", "graphql-tag": "^2.12.6", @@ -21,6 +22,7 @@ "next-auth": "^5.0.0-beta.15", "react": "^18", "react-dom": "^18", + "react-feather": "^2.0.10", "server-only": "^0.0.1", "zod": "^3.22.4" }, @@ -4222,8 +4224,7 @@ "node_modules/dayjs": { "version": "1.11.10", "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.10.tgz", - "integrity": "sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==", - "dev": true + "integrity": "sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==" }, "node_modules/debug": { "version": "4.3.4", @@ -7926,7 +7927,6 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -8489,7 +8489,6 @@ "version": "15.8.1", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", - "dev": true, "dependencies": { "loose-envify": "^1.4.0", "object-assign": "^4.1.1", @@ -8800,11 +8799,21 @@ "react": "^18.2.0" } }, + "node_modules/react-feather": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/react-feather/-/react-feather-2.0.10.tgz", + "integrity": "sha512-BLhukwJ+Z92Nmdcs+EMw6dy1Z/VLiJTzEQACDUEnWMClhYnFykJCGWQx+NmwP/qQHGX/5CzQ+TGi8ofg2+HzVQ==", + "dependencies": { + "prop-types": "^15.7.2" + }, + "peerDependencies": { + "react": ">=16.8.6" + } + }, "node_modules/react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", - "dev": true + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, "node_modules/react-stately": { "version": "3.30.1", diff --git a/package.json b/package.json index c148072e8..c69c19d2f 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,7 @@ "@scandic-hotels/design-system": "git+https://x-token-auth:$DESIGN_SYSTEM_ACCESS_TOKEN@bitbucket.org/scandic-swap/design-system.git#v0.1.0-rc.2", "@t3-oss/env-nextjs": "^0.9.2", "class-variance-authority": "^0.7.0", + "dayjs": "^1.11.10", "graphql": "^16.8.1", "graphql-request": "^6.1.0", "graphql-tag": "^2.12.6", @@ -29,6 +30,7 @@ "next-auth": "^5.0.0-beta.15", "react": "^18", "react-dom": "^18", + "react-feather": "^2.0.10", "server-only": "^0.0.1", "zod": "^3.22.4" }, @@ -51,4 +53,4 @@ "engines": { "node": "18" } -} \ No newline at end of file +} diff --git a/public/calendar_month.svg b/public/calendar_month.svg new file mode 100644 index 000000000..eb109863d --- /dev/null +++ b/public/calendar_month.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/public/flower-image.svg b/public/flower-image.svg new file mode 100644 index 000000000..392c1091e --- /dev/null +++ b/public/flower-image.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/public/person.svg b/public/person.svg new file mode 100644 index 000000000..281c00793 --- /dev/null +++ b/public/person.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/public/sweden.svg b/public/sweden.svg new file mode 100644 index 000000000..24f510186 --- /dev/null +++ b/public/sweden.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/types/components/myPages/stay.ts b/types/components/myPages/stay.ts new file mode 100644 index 000000000..1c529048c --- /dev/null +++ b/types/components/myPages/stay.ts @@ -0,0 +1,6 @@ +export type StayProps = { + dateArrive: Date + dateDepart: Date + guests: number + hotel: string +} diff --git a/types/components/myPages/title.ts b/types/components/myPages/title.ts new file mode 100644 index 000000000..f73b774a0 --- /dev/null +++ b/types/components/myPages/title.ts @@ -0,0 +1,7 @@ +type HeadingLevel = "h1" | "h2" | "h3" | "h4" | "h5" | "h6" + +export interface HeadingProps extends React.HTMLAttributes { + as?: HeadingLevel + level?: HeadingLevel + uppercase?: boolean +} diff --git a/types/requests/myPages/logo.ts b/types/requests/myPages/logo.ts new file mode 100644 index 000000000..5b922a6d2 --- /dev/null +++ b/types/requests/myPages/logo.ts @@ -0,0 +1,10 @@ +import type { Edges } from "../utils/edges" +import type { Image } from "../../image" + +export type LogoQueryData = { + all_header: { + items: { + logoConnection: Edges + }[] + } +}