From 66bc1cb167bd58133df74554e1d6fc2e1c7f651a Mon Sep 17 00:00:00 2001 From: Aaryan Khandelwal <65252264+aaryan610@users.noreply.github.com> Date: Wed, 29 Nov 2023 13:48:07 +0530 Subject: [PATCH] chore: update profile settings layout (#2925) * chore: update profile layout * fix: multiple workspaces * chore: removed breadcrumbs * chore: fix sidebar collapsed state --- space/package.json | 2 +- web/layouts/settings-layout/profile/index.ts | 1 - .../settings-layout/profile/layout.tsx | 11 +- .../profile/settings-sidebar.tsx | 75 ----- .../settings-layout/profile/sidebar.tsx | 293 ++++++++---------- web/package.json | 2 +- web/pages/profile/activity.tsx | 9 +- web/pages/profile/change-password.tsx | 12 +- web/pages/profile/index.tsx | 34 +- web/pages/profile/preferences.tsx | 7 +- web/types/users.d.ts | 1 + yarn.lock | 13 +- 12 files changed, 176 insertions(+), 284 deletions(-) delete mode 100644 web/layouts/settings-layout/profile/settings-sidebar.tsx diff --git a/space/package.json b/space/package.json index ddab959ab..6bd61d41b 100644 --- a/space/package.json +++ b/space/package.json @@ -25,7 +25,7 @@ "clsx": "^2.0.0", "js-cookie": "^3.0.1", "lowlight": "^2.9.0", - "lucide-react": "^0.263.1", + "lucide-react": "^0.293.0", "mobx": "^6.10.0", "mobx-react-lite": "^4.0.3", "next": "12.3.2", diff --git a/web/layouts/settings-layout/profile/index.ts b/web/layouts/settings-layout/profile/index.ts index 3b5b08062..c4bfd4db3 100644 --- a/web/layouts/settings-layout/profile/index.ts +++ b/web/layouts/settings-layout/profile/index.ts @@ -1,3 +1,2 @@ export * from "./layout"; -export * from "./settings-sidebar"; export * from "./sidebar"; diff --git a/web/layouts/settings-layout/profile/layout.tsx b/web/layouts/settings-layout/profile/layout.tsx index 86ce5f577..fae706d24 100644 --- a/web/layouts/settings-layout/profile/layout.tsx +++ b/web/layouts/settings-layout/profile/layout.tsx @@ -1,13 +1,13 @@ import { FC, ReactNode } from "react"; // layout import { UserAuthWrapper } from "layouts/auth-layout"; +import { ProfileLayoutSidebar } from "layouts/settings-layout"; // components -import { ProfileLayoutSidebar, ProfileSettingsSidebar } from "layouts/settings-layout"; import { CommandPalette } from "components/command-palette"; interface IProfileSettingsLayout { children: ReactNode; - header: ReactNode; + header?: ReactNode; } export const ProfileSettingsLayout: FC = (props) => { @@ -21,12 +21,7 @@ export const ProfileSettingsLayout: FC = (props) => {
{header} -
-
- -
- {children} -
+
{children}
diff --git a/web/layouts/settings-layout/profile/settings-sidebar.tsx b/web/layouts/settings-layout/profile/settings-sidebar.tsx deleted file mode 100644 index 534a69b4f..000000000 --- a/web/layouts/settings-layout/profile/settings-sidebar.tsx +++ /dev/null @@ -1,75 +0,0 @@ -import React from "react"; -import { useRouter } from "next/router"; -import Link from "next/link"; -import { observer } from "mobx-react-lite"; -// mobx -import { useMobxStore } from "lib/mobx/store-provider"; - -const PROFILE_LINKS: Array<{ - key: string; - label: string; - href: string; -}> = [ - { - key: "profile", - label: "Profile", - href: `/profile`, - }, - { - key: "change-password", - label: "Change password", - href: `/profile/change-password`, - }, - { - key: "activity", - label: "Activity", - href: `/profile/activity`, - }, - { - key: "preferences", - label: "Preferences", - href: `/profile/preferences`, - }, -]; - -export const ProfileSettingsSidebar = observer(() => { - const router = useRouter(); - const { - appConfig: { envConfig }, - } = useMobxStore(); - const enableEmailPassword = - envConfig && - (envConfig?.email_password_login || - !( - envConfig?.email_password_login || - envConfig?.magic_login || - envConfig?.google_client_id || - envConfig?.github_client_id - )); - - return ( -
- My Account -
- {PROFILE_LINKS.map((link) => { - if (link.key === "change-password" && !enableEmailPassword) return; - return ( - - -
- {link.label} -
-
- - ); - })} -
-
- ); -}); diff --git a/web/layouts/settings-layout/profile/sidebar.tsx b/web/layouts/settings-layout/profile/sidebar.tsx index 0a322e43f..ba223ff9b 100644 --- a/web/layouts/settings-layout/profile/sidebar.tsx +++ b/web/layouts/settings-layout/profile/sidebar.tsx @@ -1,50 +1,73 @@ -import { Fragment, useEffect, useRef, useState } from "react"; import { mutate } from "swr"; import Link from "next/link"; import { useRouter } from "next/router"; import { observer } from "mobx-react-lite"; import { useTheme } from "next-themes"; -import { Menu, Transition } from "@headlessui/react"; -// icons -import { LogIn, LogOut, MoveLeft, Plus, User, UserPlus } from "lucide-react"; +import { Activity, ChevronLeft, CircleUser, KeyRound, LogOut, MoveLeft, Plus, Settings2, UserPlus } from "lucide-react"; // mobx store import { useMobxStore } from "lib/mobx/store-provider"; // ui -import { Avatar, Tooltip } from "@plane/ui"; +import { Tooltip } from "@plane/ui"; // hooks import useToast from "hooks/use-toast"; +import { useState } from "react"; -const SIDEBAR_LINKS = [ +const PROFILE_ACTION_LINKS = [ + { + key: "profile", + label: "Profile", + href: `/profile`, + Icon: CircleUser, + }, + { + key: "change-password", + label: "Change password", + href: `/profile/change-password`, + Icon: KeyRound, + }, + { + key: "activity", + label: "Activity", + href: `/profile/activity`, + Icon: Activity, + }, + { + key: "preferences", + label: "Preferences", + href: `/profile/preferences`, + Icon: Settings2, + }, +]; + +const WORKSPACE_ACTION_LINKS = [ { key: "create-workspace", Icon: Plus, - name: "Create workspace", + label: "Create workspace", href: "/create-workspace", }, { key: "invitations", Icon: UserPlus, - name: "Invitations", + label: "Invitations", href: "/invitations", }, ]; export const ProfileLayoutSidebar = observer(() => { // states - const [isScrolled, setIsScrolled] = useState(false); // scroll animation state - // refs - const containerRef = useRef(null); - + const [isSigningOut, setIsSigningOut] = useState(false); + // router const router = useRouter(); - + // next themes const { setTheme } = useTheme(); - + // toast const { setToastAlert } = useToast(); const { theme: { sidebarCollapsed, toggleSidebar }, workspace: { workspaces }, - user: { currentUser, currentUserSettings, isUserInstanceAdmin, signOut }, + user: { currentUser, currentUserSettings, signOut }, } = useMobxStore(); // redirect url for normal mode @@ -54,6 +77,8 @@ export const ProfileLayoutSidebar = observer(() => { ""; const handleSignOut = async () => { + setIsSigningOut(true); + await signOut() .then(() => { mutate("CURRENT_USER_DETAILS", null); @@ -66,144 +91,67 @@ export const ProfileLayoutSidebar = observer(() => { title: "Error!", message: "Failed to sign out. Please try again.", }) - ); + ) + .finally(() => setIsSigningOut(false)); }; - /** - * Implementing scroll animation styles based on the scroll length of the container - */ - useEffect(() => { - const handleScroll = () => { - if (containerRef.current) { - const scrollTop = containerRef.current.scrollTop; - setIsScrolled(scrollTop > 0); - } - }; - const currentContainerRef = containerRef.current; - if (currentContainerRef) { - currentContainerRef.addEventListener("scroll", handleScroll); - } - return () => { - if (currentContainerRef) { - currentContainerRef.removeEventListener("scroll", handleScroll); - } - }; - }, []); - return (
-
-
-
-
-
- -
- - {!sidebarCollapsed &&

My Profile

} -
-
+
+ +
{!sidebarCollapsed && ( - - - - - - - - {currentUser?.email} - - - Sign out - - {isUserInstanceAdmin && ( - - )} - - - +
Workspaces
)} -
- -
- {SIDEBAR_LINKS.map((link) => ( - - - -
- {} - {!sidebarCollapsed && link.name} -
-
-
- - ))} -
- {workspaces && workspaces.length > 0 && ( -
- {!sidebarCollapsed && ( -
Your workspaces
- )} -
+ {workspaces && workspaces.length > 0 && ( + + )} + - )} -
- - + + + +
diff --git a/web/package.json b/web/package.json index 4044be2ae..1c68d8aa1 100644 --- a/web/package.json +++ b/web/package.json @@ -39,7 +39,7 @@ "js-cookie": "^3.0.1", "lodash": "^4.17.21", "lodash.debounce": "^4.0.8", - "lucide-react": "^0.274.0", + "lucide-react": "^0.293.0", "mobx": "^6.10.0", "mobx-react-lite": "^4.0.3", "next": "12.3.2", diff --git a/web/pages/profile/activity.tsx b/web/pages/profile/activity.tsx index 29e37e646..5cd2c194d 100644 --- a/web/pages/profile/activity.tsx +++ b/web/pages/profile/activity.tsx @@ -9,7 +9,6 @@ import { ProfileSettingsLayout } from "layouts/settings-layout"; // components import { ActivityIcon, ActivityMessage } from "components/core"; import { RichReadOnlyEditor } from "@plane/rich-text-editor"; -import { ProfileSettingsHeader } from "components/headers"; // icons import { History, MessageSquare } from "lucide-react"; // ui @@ -30,12 +29,12 @@ const ProfileActivityPage: NextPageWithLayout = () => { const { data: userActivity } = useSWR(USER_ACTIVITY, () => userService.getUserActivity()); return ( -
-
+
+

Activity

{userActivity ? ( -
+
    {userActivity.results.map((activityItem: any) => { if (activityItem.field === "comment") { @@ -191,7 +190,7 @@ const ProfileActivityPage: NextPageWithLayout = () => { }; ProfileActivityPage.getLayout = function getLayout(page: ReactElement) { - return }>{page}; + return {page}; }; export default ProfileActivityPage; diff --git a/web/pages/profile/change-password.tsx b/web/pages/profile/change-password.tsx index 509837b55..67dc85999 100644 --- a/web/pages/profile/change-password.tsx +++ b/web/pages/profile/change-password.tsx @@ -10,8 +10,6 @@ import { UserService } from "services/user.service"; import useToast from "hooks/use-toast"; // layout import { ProfileSettingsLayout } from "layouts/settings-layout"; -// components -import { ProfileSettingsHeader } from "components/headers"; // ui import { Button, Input, Spinner } from "@plane/ui"; // types @@ -99,7 +97,11 @@ const ChangePasswordPage: NextPageWithLayout = observer(() => { ); return ( -
    + +

    Change password

    Current password

    @@ -181,9 +183,7 @@ const ChangePasswordPage: NextPageWithLayout = observer(() => { }); ChangePasswordPage.getLayout = function getLayout(page: ReactElement) { - return ( - }>{page} - ); + return {page}; }; export default ChangePasswordPage; diff --git a/web/pages/profile/index.tsx b/web/pages/profile/index.tsx index 583236f82..8f6b67f75 100644 --- a/web/pages/profile/index.tsx +++ b/web/pages/profile/index.tsx @@ -11,7 +11,6 @@ import useToast from "hooks/use-toast"; import { ProfileSettingsLayout } from "layouts/settings-layout"; // components import { ImagePickerPopover, UserImageUploadModal } from "components/core"; -import { ProfileSettingsHeader } from "components/headers"; import { DeactivateAccountModal } from "components/account"; // ui import { Button, CustomSelect, CustomSearchSelect, Input, Spinner } from "@plane/ui"; @@ -169,10 +168,10 @@ const ProfileSettingsPage: NextPageWithLayout = () => { )} /> setDeactivateAccountModal(false)} /> -
    +
    -
    +
    {
    -

    First Name

    +

    First name

    { ref={ref} hasError={Boolean(errors.first_name)} placeholder="Enter your first name" - className="rounded-md font-medium w-full" + className="rounded-md w-full" /> )} />
    -

    Last Name

    +

    Last name

    { ref={ref} hasError={Boolean(errors.last_name)} placeholder="Enter your last name" - className="rounded-md font-medium w-full" + className="rounded-md w-full" /> )} /> @@ -292,8 +291,8 @@ const ProfileSettingsPage: NextPageWithLayout = () => { onChange={onChange} ref={ref} hasError={Boolean(errors.email)} - placeholder="Enter your last name" - className="rounded-md font-medium w-full" + placeholder="Enter your email" + className="rounded-md w-full" disabled /> )} @@ -312,7 +311,7 @@ const ProfileSettingsPage: NextPageWithLayout = () => { onChange={onChange} label={value ? value.toString() : "Select your role"} buttonClassName={errors.role ? "border-red-500 bg-red-500/10" : "border-none"} - className="rounded-md border !border-custom-border-200" + className="rounded-md border-[0.5px] !border-custom-border-200" width="w-full" input > @@ -328,7 +327,7 @@ const ProfileSettingsPage: NextPageWithLayout = () => {
    -

    Display name

    +

    Display name

    {
    -

    Timezone

    +

    Timezone

    { options={timeZoneOptions} onChange={onChange} optionsClassName="w-full" - buttonClassName={"border-none"} - className="rounded-md border !border-custom-border-200" + buttonClassName="border-none" + className="rounded-md border-[0.5px] !border-custom-border-200" input /> )} @@ -389,7 +388,7 @@ const ProfileSettingsPage: NextPageWithLayout = () => {
    @@ -399,8 +398,7 @@ const ProfileSettingsPage: NextPageWithLayout = () => { {({ open }) => ( <> - Deactivate Account - {/* */} + Deactivate account @@ -437,7 +435,7 @@ const ProfileSettingsPage: NextPageWithLayout = () => { }; ProfileSettingsPage.getLayout = function getLayout(page: ReactElement) { - return }>{page}; + return {page}; }; export default ProfileSettingsPage; diff --git a/web/pages/profile/preferences.tsx b/web/pages/profile/preferences.tsx index 57631488a..1514c7b98 100644 --- a/web/pages/profile/preferences.tsx +++ b/web/pages/profile/preferences.tsx @@ -8,7 +8,6 @@ import useToast from "hooks/use-toast"; import { ProfileSettingsLayout } from "layouts/settings-layout"; // components import { CustomThemeSelector, ThemeSwitch } from "components/core"; -import { ProfileSettingsHeader } from "components/headers"; // ui import { Spinner } from "@plane/ui"; // constants @@ -50,8 +49,8 @@ const ProfilePreferencesPage: NextPageWithLayout = observer(() => { return ( <> {currentUser ? ( -
    -
    +
    +

    Preferences

    @@ -75,7 +74,7 @@ const ProfilePreferencesPage: NextPageWithLayout = observer(() => { }); ProfilePreferencesPage.getLayout = function getLayout(page: ReactElement) { - return }>{page}; + return {page}; }; export default ProfilePreferencesPage; diff --git a/web/types/users.d.ts b/web/types/users.d.ts index 0ac13fd34..ba5527528 100644 --- a/web/types/users.d.ts +++ b/web/types/users.d.ts @@ -14,6 +14,7 @@ export interface IUser { is_email_verified: boolean; is_managed: boolean; is_onboarded: boolean; + is_password_autoset: boolean; is_tour_completed: boolean; mobile_number: string | null; role: string | null; diff --git a/yarn.lock b/yarn.lock index ae75bb269..56d63662f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6049,15 +6049,10 @@ lucide-react@^0.244.0: resolved "https://registry.yarnpkg.com/lucide-react/-/lucide-react-0.244.0.tgz#9626f44881830280012dad23afda7ddbcffff24b" integrity sha512-PeDVbx5PlIRrVvdxiuSxPfBo7sK5qrL3LbvvRoGVNiHYRAkBm/48lKqoioxcmp0bgsyJs9lMw7CdtGFvnMJbVg== -lucide-react@^0.263.1: - version "0.263.1" - resolved "https://registry.yarnpkg.com/lucide-react/-/lucide-react-0.263.1.tgz#a456ee0d171aa373929bd3ee20d6f9fb4429c301" - integrity sha512-keqxAx97PlaEN89PXZ6ki1N8nRjGWtDa4021GFYLNj0RgruM5odbpl8GHTExj0hhPq3sF6Up0gnxt6TSHu+ovw== - -lucide-react@^0.274.0: - version "0.274.0" - resolved "https://registry.yarnpkg.com/lucide-react/-/lucide-react-0.274.0.tgz#d3b54dcb972b12f1292061448d61d422ef2e269d" - integrity sha512-qiWcojRXEwDiSimMX1+arnxha+ROJzZjJaVvCC0rsG6a9pUPjZePXSq7em4ZKMp0NDm1hyzPNkM7UaWC3LU2AA== +lucide-react@^0.293.0: + version "0.293.0" + resolved "https://registry.yarnpkg.com/lucide-react/-/lucide-react-0.293.0.tgz#02703dbcc56bb38779f4e576cc03be8cc0046fcc" + integrity sha512-g3AN0EYITCpAjNgLHrKrFWvIJzZy0Y9OPBaonyKw1cM+nZE6piOM+TiuQdYfha7oa76TMiDaWXQHE44CEqsrzw== magic-string@^0.25.0, magic-string@^0.25.7: version "0.25.9"