feat(WEB-170): edit profile view
This commit is contained in:
@@ -1,114 +1,16 @@
|
||||
export const breadcrumbs = {
|
||||
"/my-pages": [
|
||||
{
|
||||
title: "My Pages"
|
||||
}
|
||||
title: "My Pages",
|
||||
},
|
||||
],
|
||||
"/my-pages/profile": [
|
||||
{
|
||||
href: "/my-pages",
|
||||
title: "My Pages"
|
||||
title: "My Pages",
|
||||
},
|
||||
{
|
||||
title: "My Profile",
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
export const challenges = {
|
||||
journeys: [
|
||||
{
|
||||
tag: "After work queen",
|
||||
title: "Try 3 Hotel Bars, Pocket 200 Points",
|
||||
},
|
||||
{
|
||||
tag: "Dine & Shine",
|
||||
title: "Visit 3 scandic Restaurants, Earn 150 Points",
|
||||
},
|
||||
],
|
||||
victories: [
|
||||
{
|
||||
tag: "Capital Explorer",
|
||||
title: "Stay in 3 scandic hotels, in three Capitals, Gain 2000 Points",
|
||||
},
|
||||
{
|
||||
tag: "Friends Feast",
|
||||
title: "Dine with 3 Buddies, Snag a Free Breakfast",
|
||||
},
|
||||
{
|
||||
tag: "Eco Warrior",
|
||||
title: "Choose Green, Get 500 Points",
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
export const shortcuts = [
|
||||
{
|
||||
href: "#",
|
||||
title: "My Benefit",
|
||||
},
|
||||
{
|
||||
href: "#",
|
||||
title: "Program overview",
|
||||
},
|
||||
// {
|
||||
// href: "#",
|
||||
// title: "Scandic Friends shop",
|
||||
// },
|
||||
// {
|
||||
// href: "#",
|
||||
// title: "Fire and safety",
|
||||
// },
|
||||
// {
|
||||
// href: "#",
|
||||
// title: "Our sustainability work",
|
||||
// },
|
||||
// {
|
||||
// href: "#",
|
||||
// title: "How you earn points",
|
||||
// },
|
||||
// {
|
||||
// href: "#",
|
||||
// title: "How you use points",
|
||||
// },
|
||||
// {
|
||||
// href: "#",
|
||||
// title: "Missing points",
|
||||
// },
|
||||
// {
|
||||
// href: "#",
|
||||
// title: "Our term and conditions",
|
||||
// },
|
||||
]
|
||||
|
||||
export 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 const extendedUser = {
|
||||
journeys: challenges.journeys,
|
||||
membershipId: 30812404844732,
|
||||
nights: 14,
|
||||
points: 20720,
|
||||
qualifyingPoints: 5000,
|
||||
shortcuts,
|
||||
stays,
|
||||
victories: challenges.victories,
|
||||
}
|
||||
|
||||
@@ -8,53 +8,11 @@ import Sidebar from "@/components/MyPages/Sidebar"
|
||||
import styles from "./layout.module.css"
|
||||
|
||||
import type { LangParams, LayoutArgs } from "@/types/params"
|
||||
import { request } from "@/lib/graphql/request"
|
||||
import {
|
||||
GetNavigationMyPagesData,
|
||||
NavigationItem,
|
||||
MenuItem,
|
||||
PageLink,
|
||||
PageLinkEnum,
|
||||
} from "@/types/requests/myPages/navigation"
|
||||
import { GetNavigationMyPages } from "@/lib/graphql/Query/NavigationMyPages.graphql"
|
||||
|
||||
function getURL(node: PageLink) {
|
||||
switch (node.__typename) {
|
||||
case PageLinkEnum.ContentPage:
|
||||
return node.web.url
|
||||
case PageLinkEnum.AccountPage:
|
||||
case PageLinkEnum.LoyaltyPage:
|
||||
return node.url
|
||||
}
|
||||
}
|
||||
|
||||
function mapMenuItems(navigationItems: NavigationItem[]) {
|
||||
return navigationItems.map(({ item }): MenuItem => {
|
||||
const { node } = item.pageConnection.edges[0]
|
||||
|
||||
return {
|
||||
uid: node.system.uid,
|
||||
url: getURL(node),
|
||||
linkText: item.link_text || node.title,
|
||||
subItems: item.sub_items ? mapMenuItems(item.sub_items) : null,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export default async function MyPagesLayout({
|
||||
children,
|
||||
params,
|
||||
}: React.PropsWithChildren<LayoutArgs<LangParams>>) {
|
||||
const response = await request<GetNavigationMyPagesData>(
|
||||
GetNavigationMyPages,
|
||||
{
|
||||
locale: params.lang,
|
||||
}
|
||||
)
|
||||
// navigation_my_pages is of type Single, hence the hard [0]
|
||||
const navigation = response.data.all_navigation_my_pages.items[0]
|
||||
const menuItems = mapMenuItems(navigation.items)
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`${firaMono.variable} ${firaSans.variable} ${styles.layout}`}
|
||||
@@ -62,7 +20,7 @@ export default async function MyPagesLayout({
|
||||
<Header lang={params.lang} />
|
||||
<Breadcrumbs breadcrumbs={breadcrumbs} lang={params.lang} />
|
||||
<div className={styles.content}>
|
||||
<Sidebar menuItems={menuItems} />
|
||||
<Sidebar lang={params.lang} />
|
||||
{children}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { _ } from "@/lib/translation"
|
||||
import { serverClient } from "@/lib/trpc/server"
|
||||
|
||||
import { extendedUser } from "./_constants"
|
||||
|
||||
import MaxWidth from "@/components/MaxWidth"
|
||||
import Overview from "@/components/MyPages/Blocks/Overview"
|
||||
import Shortcuts from "@/components/MyPages/Blocks/Shortcuts"
|
||||
@@ -12,19 +11,15 @@ import styles from "./page.module.css"
|
||||
import type { LangParams, PageArgs } from "@/types/params"
|
||||
|
||||
export default async function MyPage({ params }: PageArgs<LangParams>) {
|
||||
const data = await serverClient().user.get()
|
||||
const user = {
|
||||
...data,
|
||||
...extendedUser,
|
||||
}
|
||||
const user = await serverClient().user.get()
|
||||
return (
|
||||
<MaxWidth className={styles.blocks} tag="main">
|
||||
<Overview user={user} />
|
||||
<UpcomingStays lang={params.lang} stays={user.stays} />
|
||||
<Shortcuts
|
||||
shortcuts={user.shortcuts}
|
||||
title="Handy Shortcuts"
|
||||
subtitle="The community at your fingertips"
|
||||
subtitle={_("The community at your fingertips")}
|
||||
title={_("Handy Shortcuts")}
|
||||
/>
|
||||
</MaxWidth>
|
||||
)
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
export default function Default() {
|
||||
return null
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
import CommunicationPreferences from "@/components/MyProfile/CommunicationPreferences"
|
||||
|
||||
export default function Communication() {
|
||||
return <CommunicationPreferences />
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
export default function Default() {
|
||||
return null
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
import CreditCards from "@/components/MyProfile/CreditCards"
|
||||
|
||||
export default function CreditCardSlot() {
|
||||
return <CreditCards />
|
||||
}
|
||||
@@ -1,3 +1,3 @@
|
||||
export default function DefaultEdit() {
|
||||
export default function Default() {
|
||||
return null
|
||||
}
|
||||
|
||||
@@ -1,10 +1,3 @@
|
||||
import Button from "@/components/TempDesignSystem/Button";
|
||||
|
||||
export default function EditProfile() {
|
||||
return (
|
||||
<>
|
||||
<Button form="edit-profile" type="reset">Cancel</Button>
|
||||
<Button form="edit-profile" type="submit">Save</Button>
|
||||
</>
|
||||
)
|
||||
export default function Default() {
|
||||
return null
|
||||
}
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
"use client"
|
||||
import { _ } from "@/lib/translation"
|
||||
import { profile } from "@/constants/routes/myPages"
|
||||
import { useProfileStore } from "@/stores/edit-profile"
|
||||
|
||||
import Button from "@/components/TempDesignSystem/Button"
|
||||
import Link from "@/components/TempDesignSystem/Link"
|
||||
|
||||
import type { LangParams, PageArgs } from "@/types/params"
|
||||
|
||||
export default function EditProfile({ params }: PageArgs<LangParams>) {
|
||||
const isPending = useProfileStore((store) => store.pending)
|
||||
const isValid = useProfileStore((store) => store.valid)
|
||||
return (
|
||||
<>
|
||||
<Button
|
||||
aria-label="Cancel"
|
||||
asChild
|
||||
bgcolor="white"
|
||||
form="edit-profile"
|
||||
size="small"
|
||||
type="reset"
|
||||
>
|
||||
<Link href={profile[params.lang]}>{_("Cancel")}</Link>
|
||||
</Button>
|
||||
<Button
|
||||
bgcolor="quarternary"
|
||||
disabled={!isValid || isPending}
|
||||
form="edit-profile"
|
||||
size="small"
|
||||
type="submit"
|
||||
weight="regular"
|
||||
>
|
||||
{_("Save")}
|
||||
</Button>
|
||||
</>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
export default function Page() {
|
||||
return null
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
export default function Default() {
|
||||
return null
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
import MembershipCard from "@/components/MyProfile/MembershipCard"
|
||||
|
||||
export default function MembershipCardSlot() {
|
||||
return <MembershipCard />
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
export default function Default() {
|
||||
return null
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
import Password from "@/components/MyProfile/Password"
|
||||
|
||||
export default function PasswordSlot() {
|
||||
return <Password />
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
export default function Default() {
|
||||
return null
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
export default function Default() {
|
||||
return null
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
import { serverClient } from "@/lib/trpc/server"
|
||||
|
||||
import EditProfile from "@/components/MyProfile/Profile/Edit"
|
||||
|
||||
export default async function EditProfileSlot() {
|
||||
const user = await serverClient().user.get()
|
||||
return <EditProfile user={user} />
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
import { serverClient } from "@/lib/trpc/server"
|
||||
|
||||
import Profile from "@/components/MyProfile/Profile"
|
||||
|
||||
export default async function ProfileInfo() {
|
||||
const user = await serverClient().user.get()
|
||||
return <Profile user={user} />
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
import Modal from "@/components/Modal";
|
||||
|
||||
export default function VerifyCode() {
|
||||
return (
|
||||
<Modal>
|
||||
<Modal.Header>
|
||||
<Modal.Title>Verify Code</Modal.Title>
|
||||
</Modal.Header>
|
||||
</Modal>
|
||||
)
|
||||
}
|
||||
@@ -1,22 +1,3 @@
|
||||
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<LangParams>) {
|
||||
return (
|
||||
<Button
|
||||
asChild
|
||||
bgcolor="quarternary"
|
||||
className={styles.btn}
|
||||
size="small"
|
||||
weight="regular"
|
||||
>
|
||||
<Link href={`/${params.lang}/my-pages/profile/verify`}>
|
||||
Edit
|
||||
</Link>
|
||||
</Button>
|
||||
)
|
||||
export default function Default() {
|
||||
return null
|
||||
}
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
export default function Default() {
|
||||
return null
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
import { _ } from "@/lib/translation"
|
||||
import { profileEdit } from "@/constants/routes/myPages"
|
||||
|
||||
import Button from "@/components/TempDesignSystem/Button"
|
||||
import Link from "@/components/TempDesignSystem/Link"
|
||||
|
||||
import type { LangParams, PageArgs } from "@/types/params"
|
||||
|
||||
export default function ProfileView({ params }: PageArgs<LangParams>) {
|
||||
return (
|
||||
<Button asChild bgcolor="quarternary" size="small" weight="regular">
|
||||
<Link href={profileEdit[params.lang]}>{_("Edit")}</Link>
|
||||
</Button>
|
||||
)
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
.btn {
|
||||
position: absolute;
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
export default function Default() {
|
||||
return null
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
import Wishes from "@/components/MyProfile/Wishes"
|
||||
|
||||
export default function WishesSlot() {
|
||||
return <Wishes />
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
export default function EditPage() {
|
||||
return null
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
.page {
|
||||
display: grid;
|
||||
gap: 3rem;
|
||||
}
|
||||
|
||||
.btns {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
gap: 1rem;
|
||||
justify-content: flex-end;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
/* Creates the 16px gap from design */
|
||||
top: -1.6rem;
|
||||
/* Moves itself to top of container to avoid calc */
|
||||
transform: translateY(-100%);
|
||||
}
|
||||
|
||||
.cards {
|
||||
display: grid;
|
||||
gap: 0.4rem;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
}
|
||||
@@ -1,16 +1,33 @@
|
||||
type ProfileLayoutProps = React.PropsWithChildren<{
|
||||
edit: React.ReactNode
|
||||
verifyCode: React.ReactNode
|
||||
view: React.ReactNode
|
||||
}>
|
||||
import MaxWidth from "@/components/MaxWidth"
|
||||
|
||||
export default function ProfileLayout({ children, edit, verifyCode, view }: ProfileLayoutProps) {
|
||||
import styles from "./layout.module.css"
|
||||
|
||||
import type { ProfileLayoutProps } from "@/types/components/myPages/myProfile/layout"
|
||||
|
||||
export default function ProfileLayout({
|
||||
communication,
|
||||
creditCards,
|
||||
edit,
|
||||
membershipCard,
|
||||
password,
|
||||
profile,
|
||||
view,
|
||||
wishes,
|
||||
}: React.PropsWithChildren<ProfileLayoutProps>) {
|
||||
return (
|
||||
<>
|
||||
{edit}
|
||||
{view}
|
||||
{children}
|
||||
{verifyCode}
|
||||
</>
|
||||
<MaxWidth className={styles.page} tag="main">
|
||||
<div className={styles.btns}>
|
||||
{edit}
|
||||
{view}
|
||||
</div>
|
||||
{profile}
|
||||
<section className={styles.cards}>
|
||||
{communication}
|
||||
{wishes}
|
||||
{membershipCard}
|
||||
{creditCards}
|
||||
{password}
|
||||
</section>
|
||||
</MaxWidth>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
.page {
|
||||
display: grid;
|
||||
gap: 3rem;
|
||||
}
|
||||
|
||||
.cards {
|
||||
display: grid;
|
||||
gap: 0.4rem;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
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 (
|
||||
<MaxWidth className={styles.page} tag="main">
|
||||
<Modal>
|
||||
<h1>HALLÅ ELLER!?!</h1>
|
||||
</Modal>
|
||||
<Profile user={user} />
|
||||
<section className={styles.cards}>
|
||||
<CommunicationPreferences />
|
||||
<Wishes />
|
||||
<MembershipCard />
|
||||
<CreditCards />
|
||||
<Password />
|
||||
</section>
|
||||
</MaxWidth>
|
||||
)
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
export default function VerifyPage() {
|
||||
return (
|
||||
<section>
|
||||
<header>
|
||||
<h1>Verify that code already!</h1>
|
||||
</header>
|
||||
</section>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user