From 82e4d402037f7e4a99296d3816ccea9edf4bf9f5 Mon Sep 17 00:00:00 2001 From: Simon Emanuelsson Date: Fri, 5 Apr 2024 08:28:20 +0200 Subject: [PATCH] feat(WEB-154): my profile view --- .../(live)/(protected)/my-pages/_constants.ts | 28 +++++ .../(protected)/my-pages/layout.module.css | 15 +-- .../(live)/(protected)/my-pages/layout.tsx | 7 +- .../(protected)/my-pages/page.module.css | 3 +- .../(live)/(protected)/my-pages/page.tsx | 16 +-- .../my-pages/profile/@edit/default.tsx | 3 + .../my-pages/profile/@edit/edit/default.tsx | 10 ++ .../profile/@verifyCode/(.)verify/page.tsx | 11 ++ .../my-pages/profile/@verifyCode/default.tsx | 3 + .../my-pages/profile/@view/default.tsx | 22 ++++ .../my-pages/profile/@view/view.module.css | 3 + .../(protected)/my-pages/profile/layout.tsx | 16 +++ .../my-pages/profile/page.module.css | 10 ++ .../(protected)/my-pages/profile/page.tsx | 36 ++++++ .../my-pages/profile/verify/page.tsx | 9 ++ components/MaxWidth/index.tsx | 17 +++ components/MaxWidth/maxWidth.module.css | 3 + components/Modal/Header/header.module.css | 1 + components/Modal/Header/index.tsx | 9 ++ components/Modal/Modal/index.tsx | 22 ++++ components/Modal/Modal/modal.module.css | 11 ++ components/Modal/Overlay/index.tsx | 44 +++++++ components/Modal/Overlay/overlay.module.css | 9 ++ components/Modal/Portal.tsx | 9 ++ components/Modal/Title/index.tsx | 9 ++ components/Modal/Title/title.module.css | 1 + components/Modal/index.tsx | 20 ++++ .../MyPages/Blocks/Challenges/index.tsx | 2 +- .../MyPages/Blocks/Overview/Friend/index.tsx | 2 +- .../Overview/Stats/QualifyingPoints/index.tsx | 2 +- .../Overview/Stats/TotalPoints/index.tsx | 2 +- .../MyPages/Blocks/Overview/Stats/index.tsx | 2 +- components/MyPages/Blocks/Overview/index.tsx | 2 +- components/MyPages/Blocks/Shortcuts/index.tsx | 2 +- .../Blocks/UpcomingStays/Stay/index.tsx | 2 +- .../MyPages/Blocks/UpcomingStays/index.tsx | 2 +- components/MyPages/Breadcrumbs/Client.tsx | 49 ++++++++ .../Breadcrumbs/breadcrumbs.module.css | 40 +++++++ components/MyPages/Breadcrumbs/index.tsx | 21 ++++ .../Header/Breadcrumbs/breadcrumbs.module.css | 25 ---- .../MyPages/Header/Breadcrumbs/index.tsx | 23 ---- components/MyPages/Header/header.module.css | 29 +---- components/MyPages/Header/index.tsx | 18 +-- components/MyPages/Sidebar/Client.tsx | 46 ++++++++ components/MyPages/Sidebar/index.tsx | 28 ++--- components/MyPages/Sidebar/sidebar.module.css | 29 +---- components/MyPages/Title/index.tsx | 28 +---- components/MyPages/Title/title.module.css | 28 ++++- components/MyPages/Title/variants.ts | 33 ++++++ components/MyProfile/Card/Title/index.tsx | 21 ++++ .../MyProfile/Card/Title/title.module.css | 68 +++++++++++ components/MyProfile/Card/Title/variants.ts | 33 ++++++ components/MyProfile/Card/card.module.css | 6 + components/MyProfile/Card/index.tsx | 16 +++ .../CommunicationPreferences/com.module.css | 5 + .../CommunicationPreferences/index.tsx | 11 ++ .../CreditCards/creditCards.module.css | 5 + components/MyProfile/CreditCards/index.tsx | 11 ++ components/MyProfile/LabelAndIcon/index.tsx | 25 ++++ .../MyProfile/LabelAndIcon/lai.module.css | 45 ++++++++ components/MyProfile/MembershipCard/index.tsx | 11 ++ .../MembershipCard/membershipCard.module.css | 5 + components/MyProfile/Password/index.tsx | 11 ++ .../MyProfile/Password/password.module.css | 5 + components/MyProfile/Profile/index.tsx | 108 ++++++++++++++++++ .../MyProfile/Profile/profile.module.css | 19 +++ components/MyProfile/Wishes/index.tsx | 11 ++ components/MyProfile/Wishes/wishes.module.css | 5 + .../TempDesignSystem/Button/button.module.css | 76 ++++++++++++ components/TempDesignSystem/Button/index.tsx | 20 ++-- .../TempDesignSystem/Button/variants.ts | 22 +++- .../TempDesignSystem/Link/link.module.css | 2 +- components/TempDesignSystem/Link/link.ts | 2 +- constants/myPages.js | 17 +++ constants/myPages.ts | 19 +++ hooks/useHandleKeyPress.ts | 11 ++ public/account_circle.svg | 3 + public/alternate_email.svg | 8 ++ public/home.svg | 8 ++ public/phone.svg | 8 ++ routes/protected.ts | 16 +++ types/components/max-width.ts | 3 + types/components/myPages/breadcrumbs.ts | 10 ++ .../myPages/{ => myPage}/challenges.ts | 0 .../components/myPages/{ => myPage}/friend.ts | 0 .../myPages/{ => myPage}/overview.ts | 0 .../myPages/{ => myPage}/qualifyingPoints.ts | 0 .../myPages/{ => myPage}/shortcuts.ts | 0 .../components/myPages/{ => myPage}/stats.ts | 0 .../components/myPages/{ => myPage}/stays.ts | 0 .../myPages/{ => myPage}/totalPoints.ts | 0 .../components/myPages/myProfile/card/card.ts | 3 + .../myPages/myProfile/card/title.ts | 11 ++ types/components/myPages/myProfile/profile.ts | 5 + types/components/myPages/title.ts | 8 +- 95 files changed, 1239 insertions(+), 196 deletions(-) create mode 100644 app/[lang]/(live)/(protected)/my-pages/profile/@edit/default.tsx create mode 100644 app/[lang]/(live)/(protected)/my-pages/profile/@edit/edit/default.tsx create mode 100644 app/[lang]/(live)/(protected)/my-pages/profile/@verifyCode/(.)verify/page.tsx create mode 100644 app/[lang]/(live)/(protected)/my-pages/profile/@verifyCode/default.tsx create mode 100644 app/[lang]/(live)/(protected)/my-pages/profile/@view/default.tsx create mode 100644 app/[lang]/(live)/(protected)/my-pages/profile/@view/view.module.css create mode 100644 app/[lang]/(live)/(protected)/my-pages/profile/layout.tsx create mode 100644 app/[lang]/(live)/(protected)/my-pages/profile/page.module.css create mode 100644 app/[lang]/(live)/(protected)/my-pages/profile/page.tsx create mode 100644 app/[lang]/(live)/(protected)/my-pages/profile/verify/page.tsx create mode 100644 components/MaxWidth/index.tsx create mode 100644 components/MaxWidth/maxWidth.module.css create mode 100644 components/Modal/Header/header.module.css create mode 100644 components/Modal/Header/index.tsx create mode 100644 components/Modal/Modal/index.tsx create mode 100644 components/Modal/Modal/modal.module.css create mode 100644 components/Modal/Overlay/index.tsx create mode 100644 components/Modal/Overlay/overlay.module.css create mode 100644 components/Modal/Portal.tsx create mode 100644 components/Modal/Title/index.tsx create mode 100644 components/Modal/Title/title.module.css create mode 100644 components/Modal/index.tsx create mode 100644 components/MyPages/Breadcrumbs/Client.tsx create mode 100644 components/MyPages/Breadcrumbs/breadcrumbs.module.css create mode 100644 components/MyPages/Breadcrumbs/index.tsx delete mode 100644 components/MyPages/Header/Breadcrumbs/breadcrumbs.module.css delete mode 100644 components/MyPages/Header/Breadcrumbs/index.tsx create mode 100644 components/MyPages/Sidebar/Client.tsx create mode 100644 components/MyPages/Title/variants.ts create mode 100644 components/MyProfile/Card/Title/index.tsx create mode 100644 components/MyProfile/Card/Title/title.module.css create mode 100644 components/MyProfile/Card/Title/variants.ts create mode 100644 components/MyProfile/Card/card.module.css create mode 100644 components/MyProfile/Card/index.tsx create mode 100644 components/MyProfile/CommunicationPreferences/com.module.css create mode 100644 components/MyProfile/CommunicationPreferences/index.tsx create mode 100644 components/MyProfile/CreditCards/creditCards.module.css create mode 100644 components/MyProfile/CreditCards/index.tsx create mode 100644 components/MyProfile/LabelAndIcon/index.tsx create mode 100644 components/MyProfile/LabelAndIcon/lai.module.css create mode 100644 components/MyProfile/MembershipCard/index.tsx create mode 100644 components/MyProfile/MembershipCard/membershipCard.module.css create mode 100644 components/MyProfile/Password/index.tsx create mode 100644 components/MyProfile/Password/password.module.css create mode 100644 components/MyProfile/Profile/index.tsx create mode 100644 components/MyProfile/Profile/profile.module.css create mode 100644 components/MyProfile/Wishes/index.tsx create mode 100644 components/MyProfile/Wishes/wishes.module.css create mode 100644 constants/myPages.js create mode 100644 constants/myPages.ts create mode 100644 hooks/useHandleKeyPress.ts create mode 100644 public/account_circle.svg create mode 100644 public/alternate_email.svg create mode 100644 public/home.svg create mode 100644 public/phone.svg create mode 100644 routes/protected.ts create mode 100644 types/components/max-width.ts create mode 100644 types/components/myPages/breadcrumbs.ts rename types/components/myPages/{ => myPage}/challenges.ts (100%) rename types/components/myPages/{ => myPage}/friend.ts (100%) rename types/components/myPages/{ => myPage}/overview.ts (100%) rename types/components/myPages/{ => myPage}/qualifyingPoints.ts (100%) rename types/components/myPages/{ => myPage}/shortcuts.ts (100%) rename types/components/myPages/{ => myPage}/stats.ts (100%) rename types/components/myPages/{ => myPage}/stays.ts (100%) rename types/components/myPages/{ => myPage}/totalPoints.ts (100%) create mode 100644 types/components/myPages/myProfile/card/card.ts create mode 100644 types/components/myPages/myProfile/card/title.ts create mode 100644 types/components/myPages/myProfile/profile.ts diff --git a/app/[lang]/(live)/(protected)/my-pages/_constants.ts b/app/[lang]/(live)/(protected)/my-pages/_constants.ts index a0669b48b..bb3b03dc8 100644 --- a/app/[lang]/(live)/(protected)/my-pages/_constants.ts +++ b/app/[lang]/(live)/(protected)/my-pages/_constants.ts @@ -1,3 +1,20 @@ +export const breadcrumbs = { + "/my-pages": [ + { + title: "My Pages" + } + ], + "/my-pages/profile": [ + { + href: "/my-pages", + title: "My Pages" + }, + { + title: "My Profile", + }, + ], +} + export const challenges = { journeys: [ { @@ -84,3 +101,14 @@ export const stays = [ hotel: "Scandic Oslo City", }, ] + +export const extendedUser = { + journeys: challenges.journeys, + membershipId: 30812404844732, + nights: 14, + points: 20720, + qualifyingPoints: 5000, + shortcuts, + stays, + victories: challenges.victories, +} diff --git a/app/[lang]/(live)/(protected)/my-pages/layout.module.css b/app/[lang]/(live)/(protected)/my-pages/layout.module.css index bc8621afb..bc197d5f7 100644 --- a/app/[lang]/(live)/(protected)/my-pages/layout.module.css +++ b/app/[lang]/(live)/(protected)/my-pages/layout.module.css @@ -1,31 +1,28 @@ -.page { +.layout { --max-width: 101.4rem; + --header-height: 4.5rem; display: grid; font-family: var(--ff-fira-sans); - grid-template-rows: auto 1fr; + grid-template-rows: var(--header-height) auto 1fr; min-height: 100dvh; } .content { display: grid; - padding: 0 0 17.5rem; padding-bottom: 7.7rem; padding-left: 0; padding-right: 0; - padding-top: 0; + position: relative; } @media screen and (min-width: 950px) { - .page { - gap: 5.8rem; - } - .content { gap: 10rem; grid-template-columns: 25rem 1fr; padding-bottom: 17.5rem; padding-left: 2.4rem; padding-right: 2.4rem; + padding-top: 5.8rem; } -} +} \ No newline at end of file diff --git a/app/[lang]/(live)/(protected)/my-pages/layout.tsx b/app/[lang]/(live)/(protected)/my-pages/layout.tsx index 829ee1cd0..62d99018d 100644 --- a/app/[lang]/(live)/(protected)/my-pages/layout.tsx +++ b/app/[lang]/(live)/(protected)/my-pages/layout.tsx @@ -1,5 +1,7 @@ import { firaMono, firaSans } from "@/app/[lang]/(live)/fonts" +import { breadcrumbs } from "./_constants" +import Breadcrumbs from "@/components/MyPages/Breadcrumbs" import Header from "@/components/MyPages/Header" import Sidebar from "@/components/MyPages/Sidebar" @@ -54,8 +56,11 @@ export default async function MyPagesLayout({ const menuItems = mapMenuItems(navigation.items) return ( -
+
+
{children} diff --git a/app/[lang]/(live)/(protected)/my-pages/page.module.css b/app/[lang]/(live)/(protected)/my-pages/page.module.css index 3e1bb051a..94d971d2d 100644 --- a/app/[lang]/(live)/(protected)/my-pages/page.module.css +++ b/app/[lang]/(live)/(protected)/my-pages/page.module.css @@ -1,7 +1,6 @@ .blocks { display: grid; gap: 4.2rem; - max-width: var(--max-width); padding-left: 2rem; padding-right: 2rem; } @@ -12,4 +11,4 @@ padding-left: 0; padding-right: 0; } -} +} \ No newline at end of file diff --git a/app/[lang]/(live)/(protected)/my-pages/page.tsx b/app/[lang]/(live)/(protected)/my-pages/page.tsx index f6a5210cd..e29ded786 100644 --- a/app/[lang]/(live)/(protected)/my-pages/page.tsx +++ b/app/[lang]/(live)/(protected)/my-pages/page.tsx @@ -1,7 +1,8 @@ import { serverClient } from "@/lib/trpc/server" -import { challenges, shortcuts, stays } from "./_constants" +import { extendedUser } from "./_constants" +import MaxWidth from "@/components/MaxWidth" import Overview from "@/components/MyPages/Blocks/Overview" import Shortcuts from "@/components/MyPages/Blocks/Shortcuts" import UpcomingStays from "@/components/MyPages/Blocks/UpcomingStays" @@ -14,17 +15,10 @@ export default async function MyPage({ params }: PageArgs) { const data = await serverClient().user.get() const user = { ...data, - journeys: challenges.journeys, - membershipId: 30812404844732, - nights: 14, - points: 20720, - qualifyingPoints: 5000, - shortcuts, - stays, - victories: challenges.victories, + ...extendedUser, } return ( -
+ ) { title="Handy Shortcuts" subtitle="The community at your fingertips" /> -
+ ) } diff --git a/app/[lang]/(live)/(protected)/my-pages/profile/@edit/default.tsx b/app/[lang]/(live)/(protected)/my-pages/profile/@edit/default.tsx new file mode 100644 index 000000000..ddef0b3e6 --- /dev/null +++ b/app/[lang]/(live)/(protected)/my-pages/profile/@edit/default.tsx @@ -0,0 +1,3 @@ +export default function DefaultEdit() { + return null +} diff --git a/app/[lang]/(live)/(protected)/my-pages/profile/@edit/edit/default.tsx b/app/[lang]/(live)/(protected)/my-pages/profile/@edit/edit/default.tsx new file mode 100644 index 000000000..8252fdf0f --- /dev/null +++ b/app/[lang]/(live)/(protected)/my-pages/profile/@edit/edit/default.tsx @@ -0,0 +1,10 @@ +import Button from "@/components/TempDesignSystem/Button"; + +export default function EditProfile() { + return ( + <> + + + + ) +} diff --git a/app/[lang]/(live)/(protected)/my-pages/profile/@verifyCode/(.)verify/page.tsx b/app/[lang]/(live)/(protected)/my-pages/profile/@verifyCode/(.)verify/page.tsx new file mode 100644 index 000000000..a177b8d41 --- /dev/null +++ b/app/[lang]/(live)/(protected)/my-pages/profile/@verifyCode/(.)verify/page.tsx @@ -0,0 +1,11 @@ +import Modal from "@/components/Modal"; + +export default function VerifyCode() { + return ( + + + Verify Code + + + ) +} diff --git a/app/[lang]/(live)/(protected)/my-pages/profile/@verifyCode/default.tsx b/app/[lang]/(live)/(protected)/my-pages/profile/@verifyCode/default.tsx new file mode 100644 index 000000000..827ef624b --- /dev/null +++ b/app/[lang]/(live)/(protected)/my-pages/profile/@verifyCode/default.tsx @@ -0,0 +1,3 @@ +export default function Default() { + return null +} \ No newline at end of file diff --git a/app/[lang]/(live)/(protected)/my-pages/profile/@view/default.tsx b/app/[lang]/(live)/(protected)/my-pages/profile/@view/default.tsx new file mode 100644 index 000000000..def44df05 --- /dev/null +++ b/app/[lang]/(live)/(protected)/my-pages/profile/@view/default.tsx @@ -0,0 +1,22 @@ +import Button from "@/components/TempDesignSystem/Button"; +import Link from "@/components/TempDesignSystem/Link"; + +import styles from "./view.module.css" + +import type { LangParams, PageArgs } from "@/types/params"; + +export default function ProfileView({ params }: PageArgs) { + return ( + + ) +} diff --git a/app/[lang]/(live)/(protected)/my-pages/profile/@view/view.module.css b/app/[lang]/(live)/(protected)/my-pages/profile/@view/view.module.css new file mode 100644 index 000000000..136a638cf --- /dev/null +++ b/app/[lang]/(live)/(protected)/my-pages/profile/@view/view.module.css @@ -0,0 +1,3 @@ +.btn { + position: absolute; +} \ No newline at end of file diff --git a/app/[lang]/(live)/(protected)/my-pages/profile/layout.tsx b/app/[lang]/(live)/(protected)/my-pages/profile/layout.tsx new file mode 100644 index 000000000..d2504b779 --- /dev/null +++ b/app/[lang]/(live)/(protected)/my-pages/profile/layout.tsx @@ -0,0 +1,16 @@ +type ProfileLayoutProps = React.PropsWithChildren<{ + edit: React.ReactNode + verifyCode: React.ReactNode + view: React.ReactNode +}> + +export default function ProfileLayout({ children, edit, verifyCode, view }: ProfileLayoutProps) { + return ( + <> + {edit} + {view} + {children} + {verifyCode} + + ) +} diff --git a/app/[lang]/(live)/(protected)/my-pages/profile/page.module.css b/app/[lang]/(live)/(protected)/my-pages/profile/page.module.css new file mode 100644 index 000000000..aa1e27153 --- /dev/null +++ b/app/[lang]/(live)/(protected)/my-pages/profile/page.module.css @@ -0,0 +1,10 @@ +.page { + display: grid; + gap: 3rem; +} + +.cards { + display: grid; + gap: 0.4rem; + grid-template-columns: 1fr 1fr; +} \ No newline at end of file diff --git a/app/[lang]/(live)/(protected)/my-pages/profile/page.tsx b/app/[lang]/(live)/(protected)/my-pages/profile/page.tsx new file mode 100644 index 000000000..bd11b2244 --- /dev/null +++ b/app/[lang]/(live)/(protected)/my-pages/profile/page.tsx @@ -0,0 +1,36 @@ +import { serverClient } from "@/lib/trpc/server"; +import { extendedUser } from "../_constants"; + +import CommunicationPreferences from "@/components/MyProfile/CommunicationPreferences"; +import CreditCards from "@/components/MyProfile/CreditCards"; +import MaxWidth from "@/components/MaxWidth"; +import MembershipCard from "@/components/MyProfile/MembershipCard"; +import Password from "@/components/MyProfile/Password"; +import Profile from "@/components/MyProfile/Profile"; +import Wishes from "@/components/MyProfile/Wishes"; + +import styles from "./page.module.css" +import Modal from "@/components/Modal"; + +export default async function MyProfile() { + const data = await serverClient().user.get() + const user = { + ...data, + ...extendedUser, + } + return ( + + +

HALLĂ… ELLER!?!

+
+ +
+ + + + + +
+
+ ) +} diff --git a/app/[lang]/(live)/(protected)/my-pages/profile/verify/page.tsx b/app/[lang]/(live)/(protected)/my-pages/profile/verify/page.tsx new file mode 100644 index 000000000..0be0d64a0 --- /dev/null +++ b/app/[lang]/(live)/(protected)/my-pages/profile/verify/page.tsx @@ -0,0 +1,9 @@ +export default function VerifyPage() { + return ( +
+
+

Verify that code already!

+
+
+ ) +} diff --git a/components/MaxWidth/index.tsx b/components/MaxWidth/index.tsx new file mode 100644 index 000000000..806c06358 --- /dev/null +++ b/components/MaxWidth/index.tsx @@ -0,0 +1,17 @@ +import { cva } from "class-variance-authority" + +import styles from "./maxWidth.module.css" + +import type { MaxWidthProps } from "@/types/components/max-width" + +const maxWidthVariants = cva(styles.container) + +export default function MaxWidth({ + className, + tag = "section", + ...props +}: MaxWidthProps +) { + const Cmp = tag + return +} diff --git a/components/MaxWidth/maxWidth.module.css b/components/MaxWidth/maxWidth.module.css new file mode 100644 index 000000000..9985ce86d --- /dev/null +++ b/components/MaxWidth/maxWidth.module.css @@ -0,0 +1,3 @@ +.container { + max-width: var(--max-width); +} \ No newline at end of file diff --git a/components/Modal/Header/header.module.css b/components/Modal/Header/header.module.css new file mode 100644 index 000000000..6e25c1cb9 --- /dev/null +++ b/components/Modal/Header/header.module.css @@ -0,0 +1 @@ +.header {} \ No newline at end of file diff --git a/components/Modal/Header/index.tsx b/components/Modal/Header/index.tsx new file mode 100644 index 000000000..404ae1c35 --- /dev/null +++ b/components/Modal/Header/index.tsx @@ -0,0 +1,9 @@ +import styles from "./header.module.css" + +export default function Header({ children }: React.PropsWithChildren) { + return ( +
+ {children} +
+ ) +} diff --git a/components/Modal/Modal/index.tsx b/components/Modal/Modal/index.tsx new file mode 100644 index 000000000..d31e0b659 --- /dev/null +++ b/components/Modal/Modal/index.tsx @@ -0,0 +1,22 @@ +import { forwardRef } from "react" + +import styles from "./modal.module.css" + +const Modal = forwardRef( + function ({ children }, ref) { + return ( +
+ {children} +
+ ) + } +) + +Modal.displayName = "Modal" + +export default Modal diff --git a/components/Modal/Modal/modal.module.css b/components/Modal/Modal/modal.module.css new file mode 100644 index 000000000..51ad05b35 --- /dev/null +++ b/components/Modal/Modal/modal.module.css @@ -0,0 +1,11 @@ +.modal { + background-color: var(--some-white-color, #F2F2F2); + border-radius: 0.4rem; + left: 50%; + outline: none; + overflow: auto; + padding: 3.5rem 7rem; + position: absolute; + top: 50%; + transform: translate(-50%, -50%); +} \ No newline at end of file diff --git a/components/Modal/Overlay/index.tsx b/components/Modal/Overlay/index.tsx new file mode 100644 index 000000000..df6ac5287 --- /dev/null +++ b/components/Modal/Overlay/index.tsx @@ -0,0 +1,44 @@ +"use client" +import { useCallback, useLayoutEffect } from "react"; +import { useRouter } from "next/navigation"; + +import { useHandleKeyPress } from "@/hooks/useHandleKeyPress"; + +import styles from "./overlay.module.css" + +export default function Overlay({ children }: React.PropsWithChildren) { + const router = useRouter() + + const handleOnClose = useCallback(() => { + return router.back() + }, [router]) + + const handleOnEscape = useCallback((evt: KeyboardEvent) => { + if (evt.code === "Escape") { + handleOnClose() + } + }, [handleOnClose]) + + useHandleKeyPress(handleOnEscape) + + useLayoutEffect(() => { + // Get original body overflow + const originalStyle = window.getComputedStyle(document.body).overflow; + // Prevent scrolling on mount + document.body.style.overflow = 'hidden'; + // Re-enable scrolling when component unmounts + return () => { + document.body.style.overflow = originalStyle; + }; + }, []); + + return ( +
+ {children} +
+ ); +}; \ No newline at end of file diff --git a/components/Modal/Overlay/overlay.module.css b/components/Modal/Overlay/overlay.module.css new file mode 100644 index 000000000..d1eaa333a --- /dev/null +++ b/components/Modal/Overlay/overlay.module.css @@ -0,0 +1,9 @@ +.overlay { + background-color: rgba(0, 0, 0, 0.3); + bottom: 0; + left: 0; + position: fixed; + right: 0; + top: 0; + z-index: 9999; +} \ No newline at end of file diff --git a/components/Modal/Portal.tsx b/components/Modal/Portal.tsx new file mode 100644 index 000000000..c3ef90464 --- /dev/null +++ b/components/Modal/Portal.tsx @@ -0,0 +1,9 @@ +"use client" +import { createPortal } from 'react-dom'; + +export default function Portal({ children }: React.PropsWithChildren) { + return createPortal( + children, + document.body + ); +}; diff --git a/components/Modal/Title/index.tsx b/components/Modal/Title/index.tsx new file mode 100644 index 000000000..a5bf60d1c --- /dev/null +++ b/components/Modal/Title/index.tsx @@ -0,0 +1,9 @@ +import styles from "./title.module.css" + +export default function Title({ children }: React.PropsWithChildren) { + return ( +

+ {children} +

+ ) +} diff --git a/components/Modal/Title/title.module.css b/components/Modal/Title/title.module.css new file mode 100644 index 000000000..0eb961927 --- /dev/null +++ b/components/Modal/Title/title.module.css @@ -0,0 +1 @@ +.heading {} \ No newline at end of file diff --git a/components/Modal/index.tsx b/components/Modal/index.tsx new file mode 100644 index 000000000..c042e8e5a --- /dev/null +++ b/components/Modal/index.tsx @@ -0,0 +1,20 @@ +import Header from "./Header" +import UiModal from "./Modal" +import Overlay from "./Overlay" +import Portal from "./Portal" +import Title from "./Title" + +export default function Modal({ children }: React.PropsWithChildren) { + return ( + + + + {children} + + + + ) +} + +Modal.Header = Header +Modal.Title = Title diff --git a/components/MyPages/Blocks/Challenges/index.tsx b/components/MyPages/Blocks/Challenges/index.tsx index 52f82e0bb..a3a265e7f 100644 --- a/components/MyPages/Blocks/Challenges/index.tsx +++ b/components/MyPages/Blocks/Challenges/index.tsx @@ -3,7 +3,7 @@ import Title from "@/components/MyPages/Title" import styles from "./challenges.module.css" -import type { ChallengesProps } from "@/types/components/myPages/challenges" +import type { ChallengesProps } from "@/types/components/myPages/myPage/challenges" export default function Challenges({ journeys, victories }: ChallengesProps) { return ( diff --git a/components/MyPages/Blocks/Overview/Friend/index.tsx b/components/MyPages/Blocks/Overview/Friend/index.tsx index 798e92264..6e08f8f45 100644 --- a/components/MyPages/Blocks/Overview/Friend/index.tsx +++ b/components/MyPages/Blocks/Overview/Friend/index.tsx @@ -2,7 +2,7 @@ import Image from "@/components/Image" import styles from "./friend.module.css" -import type { FriendProps } from "@/types/components/myPages/friend" +import type { FriendProps } from "@/types/components/myPages/myPage/friend" export default function Friend({ user }: FriendProps) { return ( diff --git a/components/MyPages/Blocks/Overview/Stats/QualifyingPoints/index.tsx b/components/MyPages/Blocks/Overview/Stats/QualifyingPoints/index.tsx index d7e6ffd25..ce3a29ace 100644 --- a/components/MyPages/Blocks/Overview/Stats/QualifyingPoints/index.tsx +++ b/components/MyPages/Blocks/Overview/Stats/QualifyingPoints/index.tsx @@ -3,7 +3,7 @@ import Image from "@/components/Image" import styles from "./points.module.css" -import type { QualifyingPointsProps } from "@/types/components/myPages/qualifyingPoints" +import type { QualifyingPointsProps } from "@/types/components/myPages/myPage/qualifyingPoints" export default function QualifyingPoints({ user }: QualifyingPointsProps) { return ( diff --git a/components/MyPages/Blocks/Overview/Stats/TotalPoints/index.tsx b/components/MyPages/Blocks/Overview/Stats/TotalPoints/index.tsx index abc52bb61..61f992d7e 100644 --- a/components/MyPages/Blocks/Overview/Stats/TotalPoints/index.tsx +++ b/components/MyPages/Blocks/Overview/Stats/TotalPoints/index.tsx @@ -3,7 +3,7 @@ import Title from "../Title" import styles from "./totalPoints.module.css" -import type { TotalPointsProps } from "@/types/components/myPages/totalPoints" +import type { TotalPointsProps } from "@/types/components/myPages/myPage/totalPoints" export default function TotalPoints({ user }: TotalPointsProps) { return ( diff --git a/components/MyPages/Blocks/Overview/Stats/index.tsx b/components/MyPages/Blocks/Overview/Stats/index.tsx index 22a69bc3e..ea86f6443 100644 --- a/components/MyPages/Blocks/Overview/Stats/index.tsx +++ b/components/MyPages/Blocks/Overview/Stats/index.tsx @@ -3,7 +3,7 @@ import TotalPoints from "./TotalPoints" import styles from "./stats.module.css" -import type { StatsProps } from "@/types/components/myPages/stats" +import type { StatsProps } from "@/types/components/myPages/myPage/stats" export default function Stats({ user }: StatsProps) { return ( diff --git a/components/MyPages/Blocks/Overview/index.tsx b/components/MyPages/Blocks/Overview/index.tsx index 891a477f1..7e7108dbc 100644 --- a/components/MyPages/Blocks/Overview/index.tsx +++ b/components/MyPages/Blocks/Overview/index.tsx @@ -4,7 +4,7 @@ import Title from "@/components/MyPages/Title" import styles from "./overview.module.css" -import type { OverviewProps } from "@/types/components/myPages/overview" +import type { OverviewProps } from "@/types/components/myPages/myPage/overview" export default function Overview({ user }: OverviewProps) { return ( diff --git a/components/MyPages/Blocks/Shortcuts/index.tsx b/components/MyPages/Blocks/Shortcuts/index.tsx index 010821865..615d1223b 100644 --- a/components/MyPages/Blocks/Shortcuts/index.tsx +++ b/components/MyPages/Blocks/Shortcuts/index.tsx @@ -4,7 +4,7 @@ import Title from "@/components/MyPages/Title" import styles from "./shortcuts.module.css" -import type { ShortcutsProps } from "@/types/components/myPages/shortcuts" +import type { ShortcutsProps } from "@/types/components/myPages/myPage/shortcuts" export default function Shortcuts({ shortcuts, diff --git a/components/MyPages/Blocks/UpcomingStays/Stay/index.tsx b/components/MyPages/Blocks/UpcomingStays/Stay/index.tsx index 0cb99c760..a2cd5fdaa 100644 --- a/components/MyPages/Blocks/UpcomingStays/Stay/index.tsx +++ b/components/MyPages/Blocks/UpcomingStays/Stay/index.tsx @@ -6,7 +6,7 @@ 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/stays" +import type { StayProps } from "@/types/components/myPages/myPage/stays" export default function Stay({ dateArrive, diff --git a/components/MyPages/Blocks/UpcomingStays/index.tsx b/components/MyPages/Blocks/UpcomingStays/index.tsx index 338140828..cb5a04919 100644 --- a/components/MyPages/Blocks/UpcomingStays/index.tsx +++ b/components/MyPages/Blocks/UpcomingStays/index.tsx @@ -4,7 +4,7 @@ import Title from "@/components/MyPages/Title" import styles from "./upcoming.module.css" import type { LangParams } from "@/types/params" -import type { StaysProps } from "@/types/components/myPages/stays" +import type { StaysProps } from "@/types/components/myPages/myPage/stays" import Link from "next/link" export default function UpcomingStays({ diff --git a/components/MyPages/Breadcrumbs/Client.tsx b/components/MyPages/Breadcrumbs/Client.tsx new file mode 100644 index 000000000..c678216e7 --- /dev/null +++ b/components/MyPages/Breadcrumbs/Client.tsx @@ -0,0 +1,49 @@ +"use client" +import { Fragment } from "react" +import { usePathname } from "next/navigation" + +import Link from "@/components/TempDesignSystem/Link" + +import styles from "./breadcrumbs.module.css" + +import type { BreadcrumbsProps } from "@/types/components/myPages/breadcrumbs" + +export default function ClientBreadcrumbs({ breadcrumbs, lang }: BreadcrumbsProps) { + const pathname = usePathname() + /** Temp solution until we can get breadcrumbs from CS */ + const path = pathname.replace(`/${lang}`, '') + const currentBreadcrumbs = breadcrumbs?.[path] + if (!currentBreadcrumbs?.length) { + return null + } + + return ( + <> +
  • + / +
  • + {currentBreadcrumbs.map(breadcrumb => { + if (breadcrumb.href) { + return ( + +
  • + + {breadcrumb.title} + +
  • +
  • + / +
  • +
    + ) + } + + return ( +
  • +

    {breadcrumb.title}

    +
  • + ) + })} + + ) +} diff --git a/components/MyPages/Breadcrumbs/breadcrumbs.module.css b/components/MyPages/Breadcrumbs/breadcrumbs.module.css new file mode 100644 index 000000000..746a35a12 --- /dev/null +++ b/components/MyPages/Breadcrumbs/breadcrumbs.module.css @@ -0,0 +1,40 @@ +.breadcrumbs { + background-color: var(--some-grey-color, #f2f2f2); + display: block; + padding-bottom: 0.8rem; + padding-left: 2rem; + padding-top: 3rem; + position: sticky; + top: var(--header-height); + z-index: 999; +} + +.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; +} + +.currentPage { + margin: 0; +} + +@media screen and (min-width: 950px) { + .breadcrumbs { + background-color: var(--some-white-color, #fff); + padding-left: 2.4rem; + padding-top: 2rem; + } +} \ No newline at end of file diff --git a/components/MyPages/Breadcrumbs/index.tsx b/components/MyPages/Breadcrumbs/index.tsx new file mode 100644 index 000000000..3933f4de7 --- /dev/null +++ b/components/MyPages/Breadcrumbs/index.tsx @@ -0,0 +1,21 @@ +import ClientBreadcrumbs from "./Client" +import Link from "@/components/TempDesignSystem/Link" + +import styles from "./breadcrumbs.module.css" + +import type { BreadcrumbsProps } from "@/types/components/myPages/breadcrumbs" + +export default function Breadcrumbs({ breadcrumbs, lang }: BreadcrumbsProps) { + return ( + + ) +} diff --git a/components/MyPages/Header/Breadcrumbs/breadcrumbs.module.css b/components/MyPages/Header/Breadcrumbs/breadcrumbs.module.css deleted file mode 100644 index f2f6baf4c..000000000 --- a/components/MyPages/Header/Breadcrumbs/breadcrumbs.module.css +++ /dev/null @@ -1,25 +0,0 @@ -.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; -} - -.currentPage { - margin: 0; -} diff --git a/components/MyPages/Header/Breadcrumbs/index.tsx b/components/MyPages/Header/Breadcrumbs/index.tsx deleted file mode 100644 index 5ed7979ea..000000000 --- a/components/MyPages/Header/Breadcrumbs/index.tsx +++ /dev/null @@ -1,23 +0,0 @@ -import Link from "next/link" - -import styles from "./breadcrumbs.module.css" - -export default function Breadcrumbs() { - return ( - - ) -} diff --git a/components/MyPages/Header/header.module.css b/components/MyPages/Header/header.module.css index bdbc2d57c..33d969802 100644 --- a/components/MyPages/Header/header.module.css +++ b/components/MyPages/Header/header.module.css @@ -1,9 +1,3 @@ -.container { - position: sticky; - top: 0; - z-index: 999; -} - .header { align-items: center; background-color: var(--some-white-color, #fff); @@ -11,16 +5,12 @@ display: grid; gap: 3rem; grid-template-columns: 1fr auto auto; - height: 7rem; - padding: 0 2rem; -} + height: var(--header-height); -.breadcrumbs { - background-color: var(--some-grey-color, #f2f2f2); - display: block; - padding-bottom: 0.8rem; - padding-left: 2rem; - padding-top: 3rem; + padding: 0 2rem; + position: sticky; + top: 0; + z-index: 999; } @media screen and (min-width: 950px) { @@ -30,13 +20,6 @@ box-shadow: none; gap: 3.2rem; grid-template-columns: 1fr 19rem auto auto; - height: 4.5rem; padding: 0 2.4rem; } - - .breadcrumbs { - background-color: var(--some-white-color, #fff); - padding-left: 2.4rem; - padding-top: 2rem; - } -} +} \ No newline at end of file diff --git a/components/MyPages/Header/index.tsx b/components/MyPages/Header/index.tsx index 6b57c4462..64deb14ed 100644 --- a/components/MyPages/Header/index.tsx +++ b/components/MyPages/Header/index.tsx @@ -1,4 +1,3 @@ -import Breadcrumbs from "./Breadcrumbs" import Hamburger from "./Hamburger" import LanguageSwitcher from "./LanguageSwitcher" import Logo from "./Logo" @@ -10,16 +9,11 @@ import type { LangParams } from "@/types/params" export default function Header({ lang }: LangParams) { return ( -
    -
    - - - - -
    -
    - -
    -
    +
    + + + + +
    ) } diff --git a/components/MyPages/Sidebar/Client.tsx b/components/MyPages/Sidebar/Client.tsx new file mode 100644 index 000000000..2b377072b --- /dev/null +++ b/components/MyPages/Sidebar/Client.tsx @@ -0,0 +1,46 @@ +"use client" +import { usePathname } from "next/navigation" + +import Link from "@/components/TempDesignSystem/Link" + +import type { LangParams } from "@/types/params" + +export default function ClientSidebar({ lang }: LangParams) { + const pathname = usePathname() + return ( + <> + + My Pages + + + My Stays + + + My Points + + + My Benefits + + {/* + My Challenges + + + My Favourites + */} + + About Scandic Friends + + + My Profile + + + ) +} diff --git a/components/MyPages/Sidebar/index.tsx b/components/MyPages/Sidebar/index.tsx index be9c8e42e..6d6a69085 100644 --- a/components/MyPages/Sidebar/index.tsx +++ b/components/MyPages/Sidebar/index.tsx @@ -1,10 +1,10 @@ -"use client" +import { Fragment } from "react" import { LogOut } from "react-feather" -import Link from "../../TempDesignSystem/Link" +import Link from "@/components/TempDesignSystem/Link" import styles from "./sidebar.module.css" -import { SidebarProps } from "@/types/requests/myPages/navigation" -import { Fragment } from "react" + +import type { SidebarProps } from "@/types/requests/myPages/navigation" export default function Sidebar({ menuItems }: SidebarProps) { return ( @@ -17,16 +17,16 @@ export default function Sidebar({ menuItems }: SidebarProps) { {item.subItems ? item.subItems.map((subItem) => { - return ( - - {subItem.linkText} - - ) - }) + return ( + + {subItem.linkText} + + ) + }) : null} ))} diff --git a/components/MyPages/Sidebar/sidebar.module.css b/components/MyPages/Sidebar/sidebar.module.css index bf8e86bc8..ef5cca417 100644 --- a/components/MyPages/Sidebar/sidebar.module.css +++ b/components/MyPages/Sidebar/sidebar.module.css @@ -2,7 +2,7 @@ align-self: flex-start; display: none; position: sticky; - top: 13.2rem; + top: 14.6rem; } .nav { @@ -13,33 +13,8 @@ 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; } -} +} \ No newline at end of file diff --git a/components/MyPages/Title/index.tsx b/components/MyPages/Title/index.tsx index afcfde778..e77237071 100644 --- a/components/MyPages/Title/index.tsx +++ b/components/MyPages/Title/index.tsx @@ -1,41 +1,21 @@ -import { cva } from "class-variance-authority" - -import styles from "./title.module.css" +import { headingVariants } from "./variants" 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, - }, - }, - defaultVariants: { - type: "h1", - }, -} as const - -const headingStyles = cva(styles.heading, config) - export default function Title({ as, children, className = "", level = "h1", uppercase = false, + weight, }: HeadingProps) { const Hx = level - const classNames = headingStyles({ + const classNames = headingVariants({ className, text: uppercase ? "uppercase" : undefined, type: as ?? level, + weight, }) return {children} } diff --git a/components/MyPages/Title/title.module.css b/components/MyPages/Title/title.module.css index 0601b3d78..b8b2490f7 100644 --- a/components/MyPages/Title/title.module.css +++ b/components/MyPages/Title/title.module.css @@ -1,5 +1,5 @@ .heading { - font-weight: 900; + /* font-family: var(--ff-brandon-text); */ margin: 0; padding: 0; } @@ -33,6 +33,30 @@ line-height: var(--typography-Title5-Mobile-lineHeight); } +.light { + font-weight: 300; +} + +.regular { + font-weight: 400; +} + +.medium { + font-weight: 500; +} + +.semiBold { + font-weight: 600; +} + +.bold { + font-weight: 700; +} + +.black { + font-weight: 900; +} + @media screen and (min-width: 950px) { .h1 { font-size: var(--typography-Title1-Desktop-fontSize); @@ -58,4 +82,4 @@ font-size: var(--typography-Title5-Desktop-fontSize); line-height: var(--typography-Title5-Desktop-lineHeight); } -} +} \ No newline at end of file diff --git a/components/MyPages/Title/variants.ts b/components/MyPages/Title/variants.ts new file mode 100644 index 000000000..0540f83a6 --- /dev/null +++ b/components/MyPages/Title/variants.ts @@ -0,0 +1,33 @@ +import { cva } from "class-variance-authority" + +import styles from "./title.module.css" + +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, + }, + weight: { + light: styles.light, + regular: styles.regular, + medium: styles.medium, + semiBold: styles.semiBold, + bold: styles.bold, + black: styles.black, + }, + }, + defaultVariants: { + type: "h1", + weight: "black", + }, +} as const + +export const headingVariants = cva(styles.heading, config) diff --git a/components/MyProfile/Card/Title/index.tsx b/components/MyProfile/Card/Title/index.tsx new file mode 100644 index 000000000..576cc7ba6 --- /dev/null +++ b/components/MyProfile/Card/Title/index.tsx @@ -0,0 +1,21 @@ +import { headingVariants } from "./variants" + +import type { HeadingProps } from "@/types/components/myPages/myProfile/card/title" + +export default function Title({ + as, + children, + className = "", + level = "h1", + uppercase = false, + weight, +}: HeadingProps) { + const Hx = level + const classNames = headingVariants({ + className, + text: uppercase ? "uppercase" : undefined, + type: as ?? level, + weight, + }) + return {children} +} diff --git a/components/MyProfile/Card/Title/title.module.css b/components/MyProfile/Card/Title/title.module.css new file mode 100644 index 000000000..61dcb0610 --- /dev/null +++ b/components/MyProfile/Card/Title/title.module.css @@ -0,0 +1,68 @@ +.heading { + color: var(--some-black-color, #2E2E2E); + /* font-family: var(--ff-brandon-text); */ + letter-spacing: 6%; + margin: 0; + padding: 0; +} + +.uppercase { + text-transform: uppercase; +} + +.h1 { + font-size: 2.5rem; + line-height: 3.5rem; +} + +.h2 { + font-size: 1.3rem; + line-height: 1.6rem; +} + +.h3 { + font-size: 1.8rem; +} + +.h4 { + font-size: 1.6rem; +} + +.h5 { + font-size: 1.3rem; +} + +.h6 { + font-size: 1rem; +} + +.light { + font-weight: 300; +} + +.regular { + font-weight: 400; +} + +.medium { + font-weight: 500; +} + +.semiBold { + font-weight: 600; +} + +.bold { + font-weight: 700; +} + +.black { + font-weight: 900; +} + +/* @media screen and (min-width: 950px) { + .h1 { + font-size: 3.8rem; + line-height: 4.5rem; + } +} */ \ No newline at end of file diff --git a/components/MyProfile/Card/Title/variants.ts b/components/MyProfile/Card/Title/variants.ts new file mode 100644 index 000000000..c4c2ee202 --- /dev/null +++ b/components/MyProfile/Card/Title/variants.ts @@ -0,0 +1,33 @@ +import { cva } from "class-variance-authority" + +import styles from "./title.module.css" + +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, + }, + weight: { + light: styles.light, + regular: styles.regular, + medium: styles.medium, + semiBold: styles.semiBold, + bold: styles.bold, + black: styles.black, + }, + }, + defaultVariants: { + type: "h1", + weight: "medium", + }, +} as const + +export const headingVariants = cva(styles.heading, config) diff --git a/components/MyProfile/Card/card.module.css b/components/MyProfile/Card/card.module.css new file mode 100644 index 000000000..8c09c8422 --- /dev/null +++ b/components/MyProfile/Card/card.module.css @@ -0,0 +1,6 @@ +.card { + background-color: var(--some-grey-color, #F2F2F2); + border-radius: 0.4rem; + min-height: 15.6rem; + padding: 3.8rem; +} \ No newline at end of file diff --git a/components/MyProfile/Card/index.tsx b/components/MyProfile/Card/index.tsx new file mode 100644 index 000000000..27ba0dd30 --- /dev/null +++ b/components/MyProfile/Card/index.tsx @@ -0,0 +1,16 @@ +import { cva } from "class-variance-authority" + +import Title from "./Title" + +import styles from "./card.module.css" + +import type { CardProps } from "@/types/components/myPages/myProfile/card/card" + +const cardStyles = cva(styles.card) + +export default function Card({ className, tag = "section", ...props }: CardProps) { + const Cmp = tag + return +} + +Card.Title = Title diff --git a/components/MyProfile/CommunicationPreferences/com.module.css b/components/MyProfile/CommunicationPreferences/com.module.css new file mode 100644 index 000000000..fd51a93d0 --- /dev/null +++ b/components/MyProfile/CommunicationPreferences/com.module.css @@ -0,0 +1,5 @@ +.container { + align-items: center; + display: flex; + justify-content: center; +} \ No newline at end of file diff --git a/components/MyProfile/CommunicationPreferences/index.tsx b/components/MyProfile/CommunicationPreferences/index.tsx new file mode 100644 index 000000000..703408364 --- /dev/null +++ b/components/MyProfile/CommunicationPreferences/index.tsx @@ -0,0 +1,11 @@ +import Card from "@/components/MyProfile/Card" + +import styles from "./com.module.css" + +export default function CommunicationPreferences() { + return ( + + My communication preferences + + ) +} diff --git a/components/MyProfile/CreditCards/creditCards.module.css b/components/MyProfile/CreditCards/creditCards.module.css new file mode 100644 index 000000000..fd51a93d0 --- /dev/null +++ b/components/MyProfile/CreditCards/creditCards.module.css @@ -0,0 +1,5 @@ +.container { + align-items: center; + display: flex; + justify-content: center; +} \ No newline at end of file diff --git a/components/MyProfile/CreditCards/index.tsx b/components/MyProfile/CreditCards/index.tsx new file mode 100644 index 000000000..25fe3d123 --- /dev/null +++ b/components/MyProfile/CreditCards/index.tsx @@ -0,0 +1,11 @@ +import Card from "@/components/MyProfile/Card" + +import styles from "./creditCards.module.css" + +export default function CreditCards() { + return ( + + My credit cards + + ) +} diff --git a/components/MyProfile/LabelAndIcon/index.tsx b/components/MyProfile/LabelAndIcon/index.tsx new file mode 100644 index 000000000..5d73b21a8 --- /dev/null +++ b/components/MyProfile/LabelAndIcon/index.tsx @@ -0,0 +1,25 @@ +import styles from "./lai.module.css" + +export default function LabelAndIcon({ children }: React.PropsWithChildren) { + return ( +
    + {children} +
    + ) +} + +function Icon({ children }: React.PropsWithChildren) { + return {children} +} + +function Label({ children }: React.PropsWithChildren) { + return {children} +} + +function Content({ children }: React.PropsWithChildren) { + return {children} +} + +LabelAndIcon.Icon = Icon +LabelAndIcon.Label = Label +LabelAndIcon.Content = Content diff --git a/components/MyProfile/LabelAndIcon/lai.module.css b/components/MyProfile/LabelAndIcon/lai.module.css new file mode 100644 index 000000000..b8bcd43aa --- /dev/null +++ b/components/MyProfile/LabelAndIcon/lai.module.css @@ -0,0 +1,45 @@ +.container { + align-content: flex-start; + align-items: center; + display: grid; + gap: 0.4rem 1.7rem; + grid-template-areas: + "icon label" + "icon content"; + justify-content: flex-start; +} + +.icon { + align-items: center; + background-color: var(--some-white-color, #FFF); + border-radius: 50%; + display: flex; + font-family: var(--ff-fira-sans); + font-size: 1.6rem; + font-weight: 400; + grid-area: icon; + height: 3rem; + justify-content: center; + line-height: 1.9rem; + width: 3rem; +} + +.label, +.content { + font-family: var(--ff-fira-sans); + font-weight: 400; + letter-spacing: -1.5%; + line-height: 2.4rem; +} + +.label { + color: var(--some-black-color, #404040); + grid-area: label; + font-size: 1.6rem; +} + +.content { + color: var(--some-black-color, #000); + grid-area: content; + font-size: 1.8rem; +} \ No newline at end of file diff --git a/components/MyProfile/MembershipCard/index.tsx b/components/MyProfile/MembershipCard/index.tsx new file mode 100644 index 000000000..3cb5c2f2c --- /dev/null +++ b/components/MyProfile/MembershipCard/index.tsx @@ -0,0 +1,11 @@ +import Card from "@/components/MyProfile/Card" + +import styles from "./membershipCard.module.css" + +export default function MembershipCard() { + return ( + + Membership cards + + ) +} diff --git a/components/MyProfile/MembershipCard/membershipCard.module.css b/components/MyProfile/MembershipCard/membershipCard.module.css new file mode 100644 index 000000000..fd51a93d0 --- /dev/null +++ b/components/MyProfile/MembershipCard/membershipCard.module.css @@ -0,0 +1,5 @@ +.container { + align-items: center; + display: flex; + justify-content: center; +} \ No newline at end of file diff --git a/components/MyProfile/Password/index.tsx b/components/MyProfile/Password/index.tsx new file mode 100644 index 000000000..e3e85e573 --- /dev/null +++ b/components/MyProfile/Password/index.tsx @@ -0,0 +1,11 @@ +import Card from "@/components/MyProfile/Card" + +import styles from "./password.module.css" + +export default function Password() { + return ( + + Password + + ) +} diff --git a/components/MyProfile/Password/password.module.css b/components/MyProfile/Password/password.module.css new file mode 100644 index 000000000..fd51a93d0 --- /dev/null +++ b/components/MyProfile/Password/password.module.css @@ -0,0 +1,5 @@ +.container { + align-items: center; + display: flex; + justify-content: center; +} \ No newline at end of file diff --git a/components/MyProfile/Profile/index.tsx b/components/MyProfile/Profile/index.tsx new file mode 100644 index 000000000..f8c6736d7 --- /dev/null +++ b/components/MyProfile/Profile/index.tsx @@ -0,0 +1,108 @@ +import { cva } from "class-variance-authority" + +import Card from "@/components/MyProfile/Card" +import Image from "@/components/Image" +import LabelAndIcon from "../LabelAndIcon" + +import styles from "./profile.module.css" + +import type { ProfileProps } from "@/types/components/myPages/myProfile/profile" + +const profileStyles = cva(styles.profile) + +export default function Profile({ className, user, ...props }: ProfileProps) { + return ( + +
    + Account Icon + + {user.name} + +
    +
    + + SE + Country + Sweden + + + + Calendar Icon + + Date of Birth + 27/05/1977 + + + + Email Icon + + Email + f*********@g****.com + + + + Cellphone Icon + + Phone number + +46 ******00 + + + + House Icon + + Address + T*************** + + + + House Icon + + City/State + S******* + + + + House Icon + + Zip code + 1**** + +
    +
    + ) +} diff --git a/components/MyProfile/Profile/profile.module.css b/components/MyProfile/Profile/profile.module.css new file mode 100644 index 000000000..0e5461461 --- /dev/null +++ b/components/MyProfile/Profile/profile.module.css @@ -0,0 +1,19 @@ +.profile { + display: grid; + gap: 3.4rem; + grid-template-rows: auto 1fr; + min-height: 46rem; +} + +.header { + align-items: center; + display: grid; + gap: 1.4rem; + grid-template-columns: auto 1fr; +} + +.info { + display: grid; + gap: 1.8rem; + grid-template-columns: 1fr 1fr; +} \ No newline at end of file diff --git a/components/MyProfile/Wishes/index.tsx b/components/MyProfile/Wishes/index.tsx new file mode 100644 index 000000000..8f437a1e0 --- /dev/null +++ b/components/MyProfile/Wishes/index.tsx @@ -0,0 +1,11 @@ +import Card from "@/components/MyProfile/Card" + +import styles from "./wishes.module.css" + +export default function Wishes() { + return ( + + My wishes + + ) +} diff --git a/components/MyProfile/Wishes/wishes.module.css b/components/MyProfile/Wishes/wishes.module.css new file mode 100644 index 000000000..fd51a93d0 --- /dev/null +++ b/components/MyProfile/Wishes/wishes.module.css @@ -0,0 +1,5 @@ +.container { + align-items: center; + display: flex; + justify-content: center; +} \ No newline at end of file diff --git a/components/TempDesignSystem/Button/button.module.css b/components/TempDesignSystem/Button/button.module.css index c6b9368e4..8a8f7d7aa 100644 --- a/components/TempDesignSystem/Button/button.module.css +++ b/components/TempDesignSystem/Button/button.module.css @@ -72,3 +72,79 @@ color: var(--some-grey-color, #444343); cursor: not-allowed; } + +.small { + border-radius: 3rem; + font-size: 1.4rem; + height: 2.6rem; + line-height: 1.7rem; + padding: 0.8rem 2.2rem; +} + +.average { + border-radius: 4.7rem; + font-size: 1.4rem; + height: 3.2rem; + letter-spacing: 1%; + line-height: 1.6rem; + padding: 0.65rem 1.3rem; +} + +.light { + font-weight: 300; +} + +.regular { + font-weight: 400; +} + +.medium { + font-weight: 500; +} + +.semiBold { + font-weight: 600; +} + +.bold { + font-weight: 700; +} + +.black { + font-weight: 900; +} + +.primary { + background-color: var(--scandic-blue, #02838E); + border: 0.1rem solid var(--scandic-blue, #02838E); + color: var(--some-white-color, #FFF); +} + +.secondary { + background-color: var(--some-black-color, #000); + border: 0.1rem solid var(--some-black-color, #000); + color: var(--some-white-color, #FFF); +} + +.tertiary { + background-color: var(--some-red-color, #D60728); + border: 0.1rem solid var(--some-red-color, #D60728); + color: var(--some-white-color, #FFF); +} + +.quarternary { + background-color: var(--some-grey-color, #727272); + border: 0.1rem solid var(--some-black-color, #727272); + color: var(--some-white-color, #FFF); +} + +.white { + background-color: var(--some-white-color, #FFF); + border: 0.1rem solid var(--some-black-color, #000); + color: var(--some-black-color, #000); +} + +.disabled { + background-color: var(--some-grey-color, #D9D9D9); + color: var(--some-grey-color, #757575); +} \ No newline at end of file diff --git a/components/TempDesignSystem/Button/index.tsx b/components/TempDesignSystem/Button/index.tsx index 1c09b6f63..67d2812a2 100644 --- a/components/TempDesignSystem/Button/index.tsx +++ b/components/TempDesignSystem/Button/index.tsx @@ -8,16 +8,22 @@ import type { ButtonProps } from "./button" export default function Button({ asChild = false, + bgcolor, className, + disabled, + size, variant, - intent, + weight, ...props }: ButtonProps) { const Comp = asChild ? Slot : "button" - return ( - - ) + const classNames = buttonVariants({ + bgcolor, + className, + disabled, + size, + variant, + weight, + }) + return } diff --git a/components/TempDesignSystem/Button/variants.ts b/components/TempDesignSystem/Button/variants.ts index 81d90eeba..0a174b333 100644 --- a/components/TempDesignSystem/Button/variants.ts +++ b/components/TempDesignSystem/Button/variants.ts @@ -4,16 +4,32 @@ import styles from "./button.module.css" export const buttonVariants = cva(styles.btn, { variants: { + bgcolor: { + primary: styles.primary, + secondary: styles.secondary, + tertiary: styles.tertiary, + quarternary: styles.quarternary, + white: styles.white, + }, + size: { + small: styles.small, + regular: styles.average, + }, variant: { default: styles.default, icon: styles.icon, }, - intent: { - primary: styles.primary, - secondary: styles.secondary, + weight: { + light: styles.light, + regular: styles.regular, + medium: styles.medium, + semiBold: styles.semiBold, + bold: styles.bold, + black: styles.black, }, }, defaultVariants: { variant: "default", + weight: "regular", }, }) diff --git a/components/TempDesignSystem/Link/link.module.css b/components/TempDesignSystem/Link/link.module.css index 088a78934..a6ebb9f6e 100644 --- a/components/TempDesignSystem/Link/link.module.css +++ b/components/TempDesignSystem/Link/link.module.css @@ -28,4 +28,4 @@ height: 0.2rem; position: absolute; width: 100%; -} +} \ No newline at end of file diff --git a/components/TempDesignSystem/Link/link.ts b/components/TempDesignSystem/Link/link.ts index 51c70e5a6..64476aa44 100644 --- a/components/TempDesignSystem/Link/link.ts +++ b/components/TempDesignSystem/Link/link.ts @@ -4,6 +4,6 @@ import type { VariantProps } from "class-variance-authority" export interface LinkProps extends React.AnchorHTMLAttributes, - VariantProps { + VariantProps { href: string } diff --git a/constants/myPages.js b/constants/myPages.js new file mode 100644 index 000000000..dd19bb2ad --- /dev/null +++ b/constants/myPages.js @@ -0,0 +1,17 @@ +export const pageNames = { + da: "mine-sider", + de: "mein-profil", + en: "my-pages", + fi: "minun-sivujani", + no: "mine-sider", + sv: "mina-sidor", +} + +export const profilePageNames = { + da: "mine-sider/profil", + de: "mein-profil/profil", + en: "my-pages/profile", + fi: "minun-sivujani/profil", + no: "mine-sider/profil", + sv: "mina-sidor/profil", +} diff --git a/constants/myPages.ts b/constants/myPages.ts new file mode 100644 index 000000000..17f9f3beb --- /dev/null +++ b/constants/myPages.ts @@ -0,0 +1,19 @@ +import type { Lang } from "@/types/lang" + +export const pageNames: Record = { + da: "mine-sider", + de: "mein-profil", + en: "my-pages", + fi: "minun-sivujani", + no: "mine-sider", + sv: "mina-sidor", +} + +export const profilePageNames: Record = { + da: "mine-sider/profil", + de: "mein-profil/profil", + en: "my-pages/profile", + fi: "minun-sivujani/profil", + no: "mine-sider/profil", + sv: "mina-sidor/profil", +} diff --git a/hooks/useHandleKeyPress.ts b/hooks/useHandleKeyPress.ts new file mode 100644 index 000000000..d9fdc0ea2 --- /dev/null +++ b/hooks/useHandleKeyPress.ts @@ -0,0 +1,11 @@ +"use client" +import { useEffect } from 'react'; + +export function useHandleKeyPress(callback: (event: KeyboardEvent) => void) { + useEffect(() => { + window.addEventListener('keydown', callback); + return () => { + window.removeEventListener('keydown', callback); + }; + }, [callback]); +} \ No newline at end of file diff --git a/public/account_circle.svg b/public/account_circle.svg new file mode 100644 index 000000000..fcb2c8d1b --- /dev/null +++ b/public/account_circle.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/alternate_email.svg b/public/alternate_email.svg new file mode 100644 index 000000000..d6a9e29b9 --- /dev/null +++ b/public/alternate_email.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/public/home.svg b/public/home.svg new file mode 100644 index 000000000..e8859f979 --- /dev/null +++ b/public/home.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/public/phone.svg b/public/phone.svg new file mode 100644 index 000000000..91a4801ff --- /dev/null +++ b/public/phone.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/routes/protected.ts b/routes/protected.ts new file mode 100644 index 000000000..fdd8c174f --- /dev/null +++ b/routes/protected.ts @@ -0,0 +1,16 @@ +import { pageNames, profilePageNames } from "@/constants/myPages" + +import type { Lang } from "@/types/lang" + +/* Authenticated routes */ +export const protectedRoutes: string[] = [ + ...Object.keys(pageNames).map( + (locale) => `/${locale}/${pageNames[locale as Lang]}` + ), + ...Object.keys(profilePageNames).map( + (locale) => `/${locale}/${profilePageNames[locale as Lang]}` + ), + ...Object.keys(profilePageNames).map( + (locale) => `/${locale}/${profilePageNames[locale as Lang]}/verify` + ), +] diff --git a/types/components/max-width.ts b/types/components/max-width.ts new file mode 100644 index 000000000..e1327b581 --- /dev/null +++ b/types/components/max-width.ts @@ -0,0 +1,3 @@ +export interface MaxWidthProps extends React.HTMLAttributes { + tag?: "article" | "div" | "main" | "section" +} diff --git a/types/components/myPages/breadcrumbs.ts b/types/components/myPages/breadcrumbs.ts new file mode 100644 index 000000000..953a2a5f8 --- /dev/null +++ b/types/components/myPages/breadcrumbs.ts @@ -0,0 +1,10 @@ +import type { LangParams } from "@/types/params" + +type Breadcrumb = { + href?: string + title: string +} + +export type BreadcrumbsProps = LangParams & { + breadcrumbs: Record +} \ No newline at end of file diff --git a/types/components/myPages/challenges.ts b/types/components/myPages/myPage/challenges.ts similarity index 100% rename from types/components/myPages/challenges.ts rename to types/components/myPages/myPage/challenges.ts diff --git a/types/components/myPages/friend.ts b/types/components/myPages/myPage/friend.ts similarity index 100% rename from types/components/myPages/friend.ts rename to types/components/myPages/myPage/friend.ts diff --git a/types/components/myPages/overview.ts b/types/components/myPages/myPage/overview.ts similarity index 100% rename from types/components/myPages/overview.ts rename to types/components/myPages/myPage/overview.ts diff --git a/types/components/myPages/qualifyingPoints.ts b/types/components/myPages/myPage/qualifyingPoints.ts similarity index 100% rename from types/components/myPages/qualifyingPoints.ts rename to types/components/myPages/myPage/qualifyingPoints.ts diff --git a/types/components/myPages/shortcuts.ts b/types/components/myPages/myPage/shortcuts.ts similarity index 100% rename from types/components/myPages/shortcuts.ts rename to types/components/myPages/myPage/shortcuts.ts diff --git a/types/components/myPages/stats.ts b/types/components/myPages/myPage/stats.ts similarity index 100% rename from types/components/myPages/stats.ts rename to types/components/myPages/myPage/stats.ts diff --git a/types/components/myPages/stays.ts b/types/components/myPages/myPage/stays.ts similarity index 100% rename from types/components/myPages/stays.ts rename to types/components/myPages/myPage/stays.ts diff --git a/types/components/myPages/totalPoints.ts b/types/components/myPages/myPage/totalPoints.ts similarity index 100% rename from types/components/myPages/totalPoints.ts rename to types/components/myPages/myPage/totalPoints.ts diff --git a/types/components/myPages/myProfile/card/card.ts b/types/components/myPages/myProfile/card/card.ts new file mode 100644 index 000000000..cece9fef6 --- /dev/null +++ b/types/components/myPages/myProfile/card/card.ts @@ -0,0 +1,3 @@ +export interface CardProps extends React.HTMLAttributes { + tag?: "article" | "div" | "section" +} diff --git a/types/components/myPages/myProfile/card/title.ts b/types/components/myPages/myProfile/card/title.ts new file mode 100644 index 000000000..bfe8269bb --- /dev/null +++ b/types/components/myPages/myProfile/card/title.ts @@ -0,0 +1,11 @@ +import { headingVariants } from "@/components/MyProfile/Card/Title/variants" + +import type { VariantProps } from "class-variance-authority" + +type HeadingLevel = "h1" | "h2" | "h3" | "h4" | "h5" | "h6" + +export interface HeadingProps extends React.HTMLAttributes, VariantProps { + as?: HeadingLevel + level?: HeadingLevel + uppercase?: boolean +} diff --git a/types/components/myPages/myProfile/profile.ts b/types/components/myPages/myProfile/profile.ts new file mode 100644 index 000000000..7cd4d7752 --- /dev/null +++ b/types/components/myPages/myProfile/profile.ts @@ -0,0 +1,5 @@ +import type { User } from "@/types/user" + +export interface ProfileProps extends React.HTMLAttributes { + user: User +} diff --git a/types/components/myPages/title.ts b/types/components/myPages/title.ts index 82e464079..fa73698bf 100644 --- a/types/components/myPages/title.ts +++ b/types/components/myPages/title.ts @@ -1,6 +1,10 @@ -type HeadingLevel = "h1" | "h2" | "h3" | "h4" | "h5" +import { headingVariants } from "@/components/MyPages/Title/variants" -export interface HeadingProps extends React.HTMLAttributes { +import type { VariantProps } from "class-variance-authority" + +type HeadingLevel = "h1" | "h2" | "h3" | "h4" | "h5" | "h6" + +export interface HeadingProps extends React.HTMLAttributes, VariantProps { as?: HeadingLevel level?: HeadingLevel uppercase?: boolean