From 709d3a115b60fd78443d1764d633cc606753f156 Mon Sep 17 00:00:00 2001 From: Ramesh Kumar Chandra <31303617+rameshkumarchandra@users.noreply.github.com> Date: Mon, 29 Apr 2024 12:59:49 +0530 Subject: [PATCH] [WEB-711] style: profile and its settings pages responsiveness (#4022) * [WEB-711] style: profile and its settings pages responsiveness * chore: linting issues fix * fix: mobile-view padding --------- Co-authored-by: LAKHAN BAHETI --- .../preferences/preferences-mobile-header.tsx | 38 ++++ .../profile/profile-issues-mobile-header.tsx | 177 ++++++++++++++++++ .../profile/preferences/layout.tsx | 62 +----- web/layouts/user-profile-layout/layout.tsx | 8 +- .../profile/[userId]/assigned.tsx | 7 +- .../profile/[userId]/created.tsx | 7 +- .../profile/[userId]/subscribed.tsx | 7 +- web/pages/profile/change-password.tsx | 2 +- web/pages/profile/index.tsx | 8 +- web/pages/profile/preferences/email.tsx | 2 +- web/pages/profile/preferences/theme.tsx | 2 +- 11 files changed, 248 insertions(+), 72 deletions(-) create mode 100644 web/components/profile/preferences/preferences-mobile-header.tsx create mode 100644 web/components/profile/profile-issues-mobile-header.tsx diff --git a/web/components/profile/preferences/preferences-mobile-header.tsx b/web/components/profile/preferences/preferences-mobile-header.tsx new file mode 100644 index 000000000..41ad464ae --- /dev/null +++ b/web/components/profile/preferences/preferences-mobile-header.tsx @@ -0,0 +1,38 @@ +import Link from "next/link"; +import router from "next/router"; +// helpers +import { cn } from "@/helpers/common.helper"; + +export const PreferencesMobileHeader = () => { + const profilePreferenceLinks: Array<{ + label: string; + href: string; + }> = [ + { + label: "Theme", + href: `/profile/preferences/theme`, + }, + { + label: "Email", + href: `/profile/preferences/email`, + }, + ]; + + return ( +
+ {profilePreferenceLinks.map((link, index) => ( + console.log(router.asPath)} + className={cn( + "flex justify-around py-2 w-full", + router.asPath.includes(link.label.toLowerCase()) ? "border-b-2 border-custom-primary-100" : "" + )} + > +
{link.label}
+ + ))} +
+ ); +}; diff --git a/web/components/profile/profile-issues-mobile-header.tsx b/web/components/profile/profile-issues-mobile-header.tsx new file mode 100644 index 000000000..6880f6b4b --- /dev/null +++ b/web/components/profile/profile-issues-mobile-header.tsx @@ -0,0 +1,177 @@ +import { useCallback } from "react"; +import { observer } from "mobx-react"; +import { useRouter } from "next/router"; +// icons +import { ChevronDown } from "lucide-react"; +// types +import { IIssueDisplayFilterOptions, IIssueDisplayProperties, IIssueFilterOptions, TIssueLayouts } from "@plane/types"; +// ui +import { CustomMenu } from "@plane/ui"; +// components +import { DisplayFiltersSelection, FilterSelection, FiltersDropdown } from "@/components/issues"; +// constants +import { EIssueFilterType, EIssuesStoreType, ISSUE_DISPLAY_FILTERS_BY_LAYOUT, ISSUE_LAYOUTS } from "@/constants/issue"; +// hooks +import { useIssues, useLabel } from "@/hooks/store"; + + +const ProfileIssuesMobileHeader = observer(() => { + // router + const router = useRouter(); + const { workspaceSlug, userId } = router.query; + // store hook + const { + issuesFilter: { issueFilters, updateFilters }, + } = useIssues(EIssuesStoreType.PROFILE); + + const { workspaceLabels } = useLabel(); + // derived values + const states = undefined; + // const members = undefined; + // const activeLayout = issueFilters?.displayFilters?.layout; + // const states = undefined; + const members = undefined; + const activeLayout = issueFilters?.displayFilters?.layout; + + const handleLayoutChange = useCallback( + (layout: TIssueLayouts) => { + if (!workspaceSlug || !userId) return; + updateFilters( + workspaceSlug.toString(), + undefined, + EIssueFilterType.DISPLAY_FILTERS, + { layout: layout }, + userId.toString() + ); + }, + [workspaceSlug, updateFilters, userId] + ); + + const handleFiltersUpdate = useCallback( + (key: keyof IIssueFilterOptions, value: string | string[]) => { + if (!workspaceSlug || !userId) return; + const newValues = issueFilters?.filters?.[key] ?? []; + + if (Array.isArray(value)) { + value.forEach((val) => { + if (!newValues.includes(val)) newValues.push(val); + }); + } else { + if (issueFilters?.filters?.[key]?.includes(value)) newValues.splice(newValues.indexOf(value), 1); + else newValues.push(value); + } + + updateFilters( + workspaceSlug.toString(), + undefined, + EIssueFilterType.FILTERS, + { [key]: newValues }, + userId.toString() + ); + }, + [workspaceSlug, issueFilters, updateFilters, userId] + ); + + const handleDisplayFilters = useCallback( + (updatedDisplayFilter: Partial) => { + if (!workspaceSlug || !userId) return; + updateFilters( + workspaceSlug.toString(), + undefined, + EIssueFilterType.DISPLAY_FILTERS, + updatedDisplayFilter, + userId.toString() + ); + }, + [workspaceSlug, updateFilters, userId] + ); + + const handleDisplayProperties = useCallback( + (property: Partial) => { + if (!workspaceSlug || !userId) return; + updateFilters( + workspaceSlug.toString(), + undefined, + EIssueFilterType.DISPLAY_PROPERTIES, + property, + userId.toString() + ); + }, + [workspaceSlug, updateFilters, userId] + ); + return ( +
+ Layout} + customButtonClassName="flex flex-grow justify-center text-custom-text-200 text-sm" + closeOnSelect + > + {ISSUE_LAYOUTS.map((layout, index) => { + if (layout.key === "spreadsheet" || layout.key === "gantt_chart" || layout.key === "calendar") return; + return ( + { + handleLayoutChange(ISSUE_LAYOUTS[index].key); + }} + className="flex items-center gap-2" + > + +
{layout.title}
+
+ ); + })} +
+
+ + Filters + + + } + > + + +
+
+ + Display + + + } + > + + +
+
+ ); +}); + +export default ProfileIssuesMobileHeader; diff --git a/web/layouts/settings-layout/profile/preferences/layout.tsx b/web/layouts/settings-layout/profile/preferences/layout.tsx index f7fff2ef1..4219696e2 100644 --- a/web/layouts/settings-layout/profile/preferences/layout.tsx +++ b/web/layouts/settings-layout/profile/preferences/layout.tsx @@ -1,10 +1,7 @@ import { FC, ReactNode } from "react"; // layout -import Link from "next/link"; -import { useRouter } from "next/router"; -import { ChevronDown } from "lucide-react"; -import { CustomMenu } from "@plane/ui"; import { SidebarHamburgerToggle } from "@/components/core/sidebar/sidebar-menu-hamburger-toggle"; +import { PreferencesMobileHeader } from "@/components/profile/preferences/preferences-mobile-header"; import { useApplication } from "@/hooks/store"; import { ProfileSettingsLayout } from "@/layouts/settings-layout"; import { ProfilePreferenceSettingsSidebar } from "./sidebar"; @@ -16,65 +13,26 @@ interface IProfilePreferenceSettingsLayout { export const ProfilePreferenceSettingsLayout: FC = (props) => { const { children, header } = props; - const router = useRouter(); const { theme: themeStore } = useApplication(); - const showMenuItem = () => { - const item = router.asPath.split("/"); - let splittedItem = item[item.length - 1]; - splittedItem = splittedItem.replace(splittedItem[0], splittedItem[0].toUpperCase()); - return splittedItem; - }; - - const profilePreferenceLinks: Array<{ - label: string; - href: string; - }> = [ - { - label: "Theme", - href: `/profile/preferences/theme`, - }, - { - label: "Email", - href: `/profile/preferences/email`, - }, - ]; return ( themeStore.toggleSidebar()} /> - - {showMenuItem()} - - - } - customButtonClassName="flex flex-grow justify-start text-custom-text-200 text-sm" - > - <> - {profilePreferenceLinks.map((link) => ( - - - {link.label} - - - ))} - } > -
- -
- {header} -
{children}
-
+
+ +
+ +
+ {header} +
{children}
+
+
); diff --git a/web/layouts/user-profile-layout/layout.tsx b/web/layouts/user-profile-layout/layout.tsx index ba7a3a88e..4f173353a 100644 --- a/web/layouts/user-profile-layout/layout.tsx +++ b/web/layouts/user-profile-layout/layout.tsx @@ -2,10 +2,10 @@ import { observer } from "mobx-react-lite"; import { useRouter } from "next/router"; // components import { ProfileNavbar, ProfileSidebar } from "@/components/profile"; -// hooks -import { useUser } from "@/hooks/store"; // constants import { EUserWorkspaceRoles } from "@/constants/workspace"; +// hooks +import { useUser } from "@/hooks/store"; type Props = { children: React.ReactNode; @@ -28,8 +28,7 @@ export const ProfileAuthWrapper: React.FC = observer((props) => { const isAuthorizedPath = router.pathname.includes("assigned" || "created" || "subscribed"); return ( -
- +
{isAuthorized || !isAuthorizedPath ? ( @@ -40,6 +39,7 @@ export const ProfileAuthWrapper: React.FC = observer((props) => {
)}
+
); }); diff --git a/web/pages/[workspaceSlug]/profile/[userId]/assigned.tsx b/web/pages/[workspaceSlug]/profile/[userId]/assigned.tsx index bc770cc95..2d73195fe 100644 --- a/web/pages/[workspaceSlug]/profile/[userId]/assigned.tsx +++ b/web/pages/[workspaceSlug]/profile/[userId]/assigned.tsx @@ -1,11 +1,12 @@ import React, { ReactElement } from "react"; -// layouts +// components import { PageHead } from "@/components/core"; import { UserProfileHeader } from "@/components/headers"; import { ProfileIssuesPage } from "@/components/profile/profile-issues"; +import ProfileIssuesMobileHeader from "@/components/profile/profile-issues-mobile-header"; +// layouts import { AppLayout } from "@/layouts/app-layout"; import { ProfileAuthWrapper } from "@/layouts/user-profile-layout"; -// components // types import { NextPageWithLayout } from "@/lib/types"; @@ -18,7 +19,7 @@ const ProfileAssignedIssuesPage: NextPageWithLayout = () => ( ProfileAssignedIssuesPage.getLayout = function getLayout(page: ReactElement) { return ( - }> + } mobileHeader={}> {page} ); diff --git a/web/pages/[workspaceSlug]/profile/[userId]/created.tsx b/web/pages/[workspaceSlug]/profile/[userId]/created.tsx index ef7179f0b..169ab4841 100644 --- a/web/pages/[workspaceSlug]/profile/[userId]/created.tsx +++ b/web/pages/[workspaceSlug]/profile/[userId]/created.tsx @@ -1,13 +1,14 @@ import { ReactElement } from "react"; // store import { observer } from "mobx-react-lite"; -// layouts +// components import { PageHead } from "@/components/core"; import { UserProfileHeader } from "@/components/headers"; import { ProfileIssuesPage } from "@/components/profile/profile-issues"; +import ProfileIssuesMobileHeader from "@/components/profile/profile-issues-mobile-header"; +// layouts import { AppLayout } from "@/layouts/app-layout"; import { ProfileAuthWrapper } from "@/layouts/user-profile-layout"; -// components // types import { NextPageWithLayout } from "@/lib/types"; @@ -20,7 +21,7 @@ const ProfileCreatedIssuesPage: NextPageWithLayout = () => ( ProfileCreatedIssuesPage.getLayout = function getLayout(page: ReactElement) { return ( - }> + } mobileHeader={}> {page} ); diff --git a/web/pages/[workspaceSlug]/profile/[userId]/subscribed.tsx b/web/pages/[workspaceSlug]/profile/[userId]/subscribed.tsx index e4a871ec8..feb7a0160 100644 --- a/web/pages/[workspaceSlug]/profile/[userId]/subscribed.tsx +++ b/web/pages/[workspaceSlug]/profile/[userId]/subscribed.tsx @@ -1,13 +1,14 @@ import { ReactElement } from "react"; // store import { observer } from "mobx-react-lite"; -// layouts +// components import { PageHead } from "@/components/core"; import { UserProfileHeader } from "@/components/headers"; import { ProfileIssuesPage } from "@/components/profile/profile-issues"; +import ProfileIssuesMobileHeader from "@/components/profile/profile-issues-mobile-header"; +// layouts import { AppLayout } from "@/layouts/app-layout"; import { ProfileAuthWrapper } from "@/layouts/user-profile-layout"; -// components // types import { NextPageWithLayout } from "@/lib/types"; @@ -20,7 +21,7 @@ const ProfileSubscribedIssuesPage: NextPageWithLayout = () => ( ProfileSubscribedIssuesPage.getLayout = function getLayout(page: ReactElement) { return ( - }> + } mobileHeader={}> {page} ); diff --git a/web/pages/profile/change-password.tsx b/web/pages/profile/change-password.tsx index 01bedb83d..6e496862d 100644 --- a/web/pages/profile/change-password.tsx +++ b/web/pages/profile/change-password.tsx @@ -91,7 +91,7 @@ const ChangePasswordPage: NextPageWithLayout = observer(() => {

Change password

diff --git a/web/pages/profile/index.tsx b/web/pages/profile/index.tsx index 6d2fe4d54..55c158e8f 100644 --- a/web/pages/profile/index.tsx +++ b/web/pages/profile/index.tsx @@ -172,7 +172,7 @@ const ProfileSettingsPage: NextPageWithLayout = observer(() => { )} /> setDeactivateAccountModal(false)} /> -
+
@@ -222,7 +222,7 @@ const ProfileSettingsPage: NextPageWithLayout = observer(() => {
-
+
{`${watch("first_name")} ${watch("last_name")}`} @@ -238,7 +238,7 @@ const ProfileSettingsPage: NextPageWithLayout = observer(() => { */}
-
+

First name* @@ -423,7 +423,7 @@ const ProfileSettingsPage: NextPageWithLayout = observer(() => {

- + {({ open }) => ( <> { return ( <> -
+
diff --git a/web/pages/profile/preferences/theme.tsx b/web/pages/profile/preferences/theme.tsx index 09dc9043e..0965716b4 100644 --- a/web/pages/profile/preferences/theme.tsx +++ b/web/pages/profile/preferences/theme.tsx @@ -54,7 +54,7 @@ const ProfilePreferencesThemePage: NextPageWithLayout = observer(() => { <> {currentUser ? ( -
+

Preferences