From 82c50450c79e8ab3ef3e21540afd2bbae88bcf4f Mon Sep 17 00:00:00 2001 From: Roie Natan Date: Wed, 27 Sep 2023 15:01:55 +0300 Subject: [PATCH 01/39] fixing - discussion messages appear only after touching the screen in mobile --- .../components/ChatContent/ChatContent.tsx | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/pages/common/components/ChatComponent/components/ChatContent/ChatContent.tsx b/src/pages/common/components/ChatComponent/components/ChatContent/ChatContent.tsx index 141992de99..9112cbee87 100644 --- a/src/pages/common/components/ChatComponent/components/ChatContent/ChatContent.tsx +++ b/src/pages/common/components/ChatComponent/components/ChatContent/ChatContent.tsx @@ -185,13 +185,13 @@ const ChatContent: ForwardRefRenderFunction< } }, [messageIdParam]); - useImperativeHandle( - chatContentRef, - () => ({ - scrollToContainerBottom, - }), - [scrollToContainerBottom], - ); + // useImperativeHandle( + // chatContentRef, + // () => ({ + // scrollToContainerBottom, + // }), + // [scrollToContainerBottom], + // ); if (!hasAccess || isHidden) { return ( From a3efc6d9e682e74230bca85ab70f7049c46e4dff Mon Sep 17 00:00:00 2001 From: Roie Natan Date: Wed, 27 Sep 2023 15:47:23 +0300 Subject: [PATCH 02/39] try #2 --- .../components/ChatContent/ChatContent.tsx | 14 +++++++------- .../ChatMobileModal/ChatMobileModal.module.scss | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/pages/common/components/ChatComponent/components/ChatContent/ChatContent.tsx b/src/pages/common/components/ChatComponent/components/ChatContent/ChatContent.tsx index 9112cbee87..141992de99 100644 --- a/src/pages/common/components/ChatComponent/components/ChatContent/ChatContent.tsx +++ b/src/pages/common/components/ChatComponent/components/ChatContent/ChatContent.tsx @@ -185,13 +185,13 @@ const ChatContent: ForwardRefRenderFunction< } }, [messageIdParam]); - // useImperativeHandle( - // chatContentRef, - // () => ({ - // scrollToContainerBottom, - // }), - // [scrollToContainerBottom], - // ); + useImperativeHandle( + chatContentRef, + () => ({ + scrollToContainerBottom, + }), + [scrollToContainerBottom], + ); if (!hasAccess || isHidden) { return ( diff --git a/src/pages/common/components/ChatMobileModal/ChatMobileModal.module.scss b/src/pages/common/components/ChatMobileModal/ChatMobileModal.module.scss index 3f1e08039e..a56780552d 100644 --- a/src/pages/common/components/ChatMobileModal/ChatMobileModal.module.scss +++ b/src/pages/common/components/ChatMobileModal/ChatMobileModal.module.scss @@ -43,7 +43,7 @@ flex-direction: column; align-items: center; text-align: center; - height: calc(100vh - #{$container-mobile-header-height}); + //height: calc(100vh - #{$container-mobile-header-height}); } .commonName { From 56aff1d6c573ecd22d93a1893d7d37007ff5cae1 Mon Sep 17 00:00:00 2001 From: Roie Natan Date: Thu, 28 Sep 2023 15:35:29 +0300 Subject: [PATCH 03/39] . --- .../components/ChatContent/ChatContent.tsx | 25 ++++++++++--------- 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/src/pages/common/components/ChatComponent/components/ChatContent/ChatContent.tsx b/src/pages/common/components/ChatComponent/components/ChatContent/ChatContent.tsx index 141992de99..fe64c56a85 100644 --- a/src/pages/common/components/ChatComponent/components/ChatContent/ChatContent.tsx +++ b/src/pages/common/components/ChatComponent/components/ChatContent/ChatContent.tsx @@ -143,11 +143,12 @@ const ChatContent: ForwardRefRenderFunction< const dateListReverse = useMemo(() => [...dateList].reverse(), [dateList]); - useEffect(() => { - if (!highlightedMessageId) { - scrollToContainerBottom(); - } - }, [highlightedMessageId, scrollToContainerBottom, discussionId]); + // useEffect(() => { + // if (!highlightedMessageId) { + // console.log("scroll down 148") + // scrollToContainerBottom(); + // } + // }, [highlightedMessageId, scrollToContainerBottom, discussionId]); useEffect(() => { if (!highlightedMessageId || dateList.length === 0 || scrolledToMessage) @@ -185,13 +186,13 @@ const ChatContent: ForwardRefRenderFunction< } }, [messageIdParam]); - useImperativeHandle( - chatContentRef, - () => ({ - scrollToContainerBottom, - }), - [scrollToContainerBottom], - ); + // useImperativeHandle( + // chatContentRef, + // () => {console.log("scroll down useImperativeHandle"); return {scrollToContainerBottom}} + + // , + // [scrollToContainerBottom], + // ); if (!hasAccess || isHidden) { return ( From 91156e0c5956e8b3aa1a6410ca8cf259bcb0de7c Mon Sep 17 00:00:00 2001 From: Roie Natan Date: Thu, 28 Sep 2023 15:51:41 +0300 Subject: [PATCH 04/39] . --- .../components/ChatContent/ChatContent.tsx | 25 +++++++++---------- .../ChatMobileModal.module.scss | 2 +- 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/src/pages/common/components/ChatComponent/components/ChatContent/ChatContent.tsx b/src/pages/common/components/ChatComponent/components/ChatContent/ChatContent.tsx index fe64c56a85..141992de99 100644 --- a/src/pages/common/components/ChatComponent/components/ChatContent/ChatContent.tsx +++ b/src/pages/common/components/ChatComponent/components/ChatContent/ChatContent.tsx @@ -143,12 +143,11 @@ const ChatContent: ForwardRefRenderFunction< const dateListReverse = useMemo(() => [...dateList].reverse(), [dateList]); - // useEffect(() => { - // if (!highlightedMessageId) { - // console.log("scroll down 148") - // scrollToContainerBottom(); - // } - // }, [highlightedMessageId, scrollToContainerBottom, discussionId]); + useEffect(() => { + if (!highlightedMessageId) { + scrollToContainerBottom(); + } + }, [highlightedMessageId, scrollToContainerBottom, discussionId]); useEffect(() => { if (!highlightedMessageId || dateList.length === 0 || scrolledToMessage) @@ -186,13 +185,13 @@ const ChatContent: ForwardRefRenderFunction< } }, [messageIdParam]); - // useImperativeHandle( - // chatContentRef, - // () => {console.log("scroll down useImperativeHandle"); return {scrollToContainerBottom}} - - // , - // [scrollToContainerBottom], - // ); + useImperativeHandle( + chatContentRef, + () => ({ + scrollToContainerBottom, + }), + [scrollToContainerBottom], + ); if (!hasAccess || isHidden) { return ( diff --git a/src/pages/common/components/ChatMobileModal/ChatMobileModal.module.scss b/src/pages/common/components/ChatMobileModal/ChatMobileModal.module.scss index a56780552d..825c239d06 100644 --- a/src/pages/common/components/ChatMobileModal/ChatMobileModal.module.scss +++ b/src/pages/common/components/ChatMobileModal/ChatMobileModal.module.scss @@ -43,7 +43,7 @@ flex-direction: column; align-items: center; text-align: center; - //height: calc(100vh - #{$container-mobile-header-height}); + height: 100%; //calc(100vh - #{$container-mobile-header-height}); } .commonName { From aaed82eda37236370d27beb16520cc74eb5f3925 Mon Sep 17 00:00:00 2001 From: Roie Natan Date: Thu, 28 Sep 2023 18:49:00 +0300 Subject: [PATCH 05/39] try 2 --- .../ChatMobileModal.module.scss | 15 ---- .../ChatMobileModal/ChatMobileModal.tsx | 70 +++++++++---------- 2 files changed, 34 insertions(+), 51 deletions(-) diff --git a/src/pages/common/components/ChatMobileModal/ChatMobileModal.module.scss b/src/pages/common/components/ChatMobileModal/ChatMobileModal.module.scss index 825c239d06..11a4a1489e 100644 --- a/src/pages/common/components/ChatMobileModal/ChatMobileModal.module.scss +++ b/src/pages/common/components/ChatMobileModal/ChatMobileModal.module.scss @@ -10,13 +10,6 @@ padding: 0 !important; } -.modalChildren { - height: 100%; - width: 100%; - padding-top: 0.5rem; - box-sizing: border-box; -} - .header { display: flex; flex-direction: row; @@ -38,14 +31,6 @@ margin-right: 0.25rem; } -.content { - display: flex; - flex-direction: column; - align-items: center; - text-align: center; - height: 100%; //calc(100vh - #{$container-mobile-header-height}); -} - .commonName { margin: 0; } diff --git a/src/pages/common/components/ChatMobileModal/ChatMobileModal.tsx b/src/pages/common/components/ChatMobileModal/ChatMobileModal.tsx index 5d285b4034..ae06c3ee11 100644 --- a/src/pages/common/components/ChatMobileModal/ChatMobileModal.tsx +++ b/src/pages/common/components/ChatMobileModal/ChatMobileModal.tsx @@ -56,44 +56,42 @@ const ChatMobileModal: FC = (props) => { isHeaderSticky={Boolean(header)} mobileFullScreen > -
- {!header && ( -
-
- {hasBackButton && ( - - - - )} - {`${commonName}'s -

{commonName}

-
- {hasCloseIcon && ( - + {!header && ( +
+
+ {hasBackButton && ( + + + )} + {`${commonName}'s +

{commonName}

- )} - {title && ( -

- {title} -

- )} -
{children}
-
+ {hasCloseIcon && ( + + )} +
+ )} + {title && ( +

+ {title} +

+ )} + {children} ); }; From 11c098bfe65d071bd032689a4049e453d35730d8 Mon Sep 17 00:00:00 2001 From: Roie Natan Date: Tue, 3 Oct 2023 18:03:25 +0300 Subject: [PATCH 06/39] . --- .../common/components/ChatComponent/ChatComponent.module.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/common/components/ChatComponent/ChatComponent.module.scss b/src/pages/common/components/ChatComponent/ChatComponent.module.scss index 116687b69a..aa9fded6f9 100644 --- a/src/pages/common/components/ChatComponent/ChatComponent.module.scss +++ b/src/pages/common/components/ChatComponent/ChatComponent.module.scss @@ -20,7 +20,7 @@ .messages { height: 100%; overflow: auto; - overscroll-behavior: contain; + //overscroll-behavior: contain; display: flex; flex-direction: column-reverse; padding: 0.5rem 2rem 0; From 7acf4fd1c5843fe1e9f576035a05ad90e97ad1c8 Mon Sep 17 00:00:00 2001 From: Roie Natan Date: Tue, 3 Oct 2023 18:07:50 +0300 Subject: [PATCH 07/39] .. --- .../common/components/ChatComponent/ChatComponent.module.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/common/components/ChatComponent/ChatComponent.module.scss b/src/pages/common/components/ChatComponent/ChatComponent.module.scss index aa9fded6f9..6fb4c20399 100644 --- a/src/pages/common/components/ChatComponent/ChatComponent.module.scss +++ b/src/pages/common/components/ChatComponent/ChatComponent.module.scss @@ -24,7 +24,7 @@ display: flex; flex-direction: column-reverse; padding: 0.5rem 2rem 0; - padding-bottom: calc(var(--chat-input-wrapper-height) + 7rem); + //padding-bottom: calc(var(--chat-input-wrapper-height) + 7rem); } .emptyChat { From f5146936196866dfb74cdf45e6bf9fd0571d5b87 Mon Sep 17 00:00:00 2001 From: Roie Natan Date: Wed, 4 Oct 2023 16:31:23 +0300 Subject: [PATCH 08/39] . --- .../components/ChatMobileModal/ChatMobileModal.module.scss | 7 +++++++ src/pages/commonFeed/components/FeedLayout/FeedLayout.tsx | 4 ++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/pages/common/components/ChatMobileModal/ChatMobileModal.module.scss b/src/pages/common/components/ChatMobileModal/ChatMobileModal.module.scss index 11a4a1489e..401eba5dab 100644 --- a/src/pages/common/components/ChatMobileModal/ChatMobileModal.module.scss +++ b/src/pages/common/components/ChatMobileModal/ChatMobileModal.module.scss @@ -10,6 +10,13 @@ padding: 0 !important; } +.modalChildren { + height: 100%; + width: 100%; + padding-top: 0.5rem; + box-sizing: border-box; +} + .header { display: flex; flex-direction: row; diff --git a/src/pages/commonFeed/components/FeedLayout/FeedLayout.tsx b/src/pages/commonFeed/components/FeedLayout/FeedLayout.tsx index b320084497..7659be87c5 100644 --- a/src/pages/commonFeed/components/FeedLayout/FeedLayout.tsx +++ b/src/pages/commonFeed/components/FeedLayout/FeedLayout.tsx @@ -644,7 +644,7 @@ const FeedLayout: ForwardRefRenderFunction = ( isLoading={loading} loaderDelay={LOADER_APPEARANCE_DELAY} > - {allFeedItems?.map((item) => { + {allFeedItems?.map((item, index) => { const isActive = item.itemId === activeFeedItemId; if (checkIsFeedItemFollowLayoutItem(item)) { @@ -662,7 +662,7 @@ const FeedLayout: ForwardRefRenderFunction = ( ref={(ref) => { refsByItemId.current[item.itemId] = ref; }} - key={item.feedItem.id} + key={item.feedItem.id + index} commonMember={commonMember} commonId={commonData?.id} commonName={commonData?.name || ""} From 12b23a9e09b88d498cc1a1689bdf721ac032f588 Mon Sep 17 00:00:00 2001 From: Andrey Mikhadyuk Date: Mon, 16 Oct 2023 14:12:11 +0300 Subject: [PATCH 09/39] change default settings to `all` value --- .../Settings/components/SettingsForm/SettingsForm.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pages/settings/components/Settings/components/SettingsForm/SettingsForm.tsx b/src/pages/settings/components/Settings/components/SettingsForm/SettingsForm.tsx index 9161f3da8a..9ce009e0aa 100644 --- a/src/pages/settings/components/Settings/components/SettingsForm/SettingsForm.tsx +++ b/src/pages/settings/components/Settings/components/SettingsForm/SettingsForm.tsx @@ -41,9 +41,9 @@ const getInitialValues = ( > | null, ): FormValues => ({ pushNotificationPreference: - data?.pushNotificationPreference ?? UserPushNotificationPreference.None, + data?.pushNotificationPreference ?? UserPushNotificationPreference.All, emailNotificationPreference: - data?.emailNotificationPreference ?? UserEmailNotificationPreference.None, + data?.emailNotificationPreference ?? UserEmailNotificationPreference.All, }); const SettingsForm: FC = (props) => { From d2d3d84ae0667da153af9327eb0a32637181aabe Mon Sep 17 00:00:00 2001 From: Pavel Meyer Date: Mon, 16 Oct 2023 14:20:25 +0300 Subject: [PATCH 10/39] CW-2025 Added react-zoom-pan-pinch library and ImageWithZoom --- package.json | 1 + src/shared/components/Image/Image.tsx | 28 ++++++++++++++----- .../ImageWithZoom/ImageWithZoom.module.scss | 4 +++ .../ImageWithZoom/ImageWithZoom.tsx | 23 +++++++++++++++ src/shared/components/ImageWithZoom/index.ts | 1 + src/shared/components/index.tsx | 1 + .../ImageGalleryMobileModal.tsx | 1 + .../ImageGalleryModal/ImageGalleryModal.scss | 5 ++++ .../ImageGalleryModal/ImageGalleryModal.tsx | 2 ++ yarn.lock | 5 ++++ 10 files changed, 64 insertions(+), 7 deletions(-) create mode 100644 src/shared/components/ImageWithZoom/ImageWithZoom.module.scss create mode 100644 src/shared/components/ImageWithZoom/ImageWithZoom.tsx create mode 100644 src/shared/components/ImageWithZoom/index.ts diff --git a/package.json b/package.json index c9f9c2bf94..84a2b15b3a 100644 --- a/package.json +++ b/package.json @@ -62,6 +62,7 @@ "react-split-pane": "^0.1.92", "react-use": "^17.4.0", "react-virtualized": "^9.22.3", + "react-zoom-pan-pinch": "^3.2.0", "redux": "^4.0.4", "redux-saga": "^1.1.3", "reselect": "^4.0.0", diff --git a/src/shared/components/Image/Image.tsx b/src/shared/components/Image/Image.tsx index a8609da1f9..3e32f9c523 100644 --- a/src/shared/components/Image/Image.tsx +++ b/src/shared/components/Image/Image.tsx @@ -8,6 +8,7 @@ import React, { ReactEventHandler, } from "react"; import classNames from "classnames"; +import { ImageWithZoom } from "../ImageWithZoom"; import styles from "./Image.module.scss"; interface CustomImageProps extends ImgHTMLAttributes { @@ -16,6 +17,7 @@ interface CustomImageProps extends ImgHTMLAttributes { placeholderElement?: ReactNode; imageOverlayClassName?: string; imageContainerClassName?: string; + hasZoom?: boolean; } const CustomImage: FC = (props) => { @@ -28,6 +30,7 @@ const CustomImage: FC = (props) => { imageOverlayClassName, imageContainerClassName, onClick, + hasZoom = false, ...restProps } = props; const [isLoaded, setIsLoaded] = useState(false); @@ -70,13 +73,24 @@ const CustomImage: FC = (props) => { return hasError && (placeholderElement || placeholderElement === null) ? ( <>{placeholderElement} ) : ( -
- {alt} -
-
+ <> + {hasZoom ? ( + + ) : ( +
+ {alt} +
+
+ )} + ); }; diff --git a/src/shared/components/ImageWithZoom/ImageWithZoom.module.scss b/src/shared/components/ImageWithZoom/ImageWithZoom.module.scss new file mode 100644 index 0000000000..c87c46f308 --- /dev/null +++ b/src/shared/components/ImageWithZoom/ImageWithZoom.module.scss @@ -0,0 +1,4 @@ +.imageWithZoomContainer { + width: 100%; + height: 100%; +} diff --git a/src/shared/components/ImageWithZoom/ImageWithZoom.tsx b/src/shared/components/ImageWithZoom/ImageWithZoom.tsx new file mode 100644 index 0000000000..2c8b2b7dbc --- /dev/null +++ b/src/shared/components/ImageWithZoom/ImageWithZoom.tsx @@ -0,0 +1,23 @@ +import React, { ImgHTMLAttributes } from "react"; +import { TransformWrapper, TransformComponent } from "react-zoom-pan-pinch"; +import styles from "./ImageWithZoom.module.scss"; + +const ImageWthZoom = ({ + src, + alt, + className, + ...restProps +}: ImgHTMLAttributes) => { + return ( + + + {alt} + + + ); +}; + +export default ImageWthZoom; diff --git a/src/shared/components/ImageWithZoom/index.ts b/src/shared/components/ImageWithZoom/index.ts new file mode 100644 index 0000000000..a40fbbecb6 --- /dev/null +++ b/src/shared/components/ImageWithZoom/index.ts @@ -0,0 +1 @@ +export { default as ImageWithZoom } from "./ImageWithZoom"; \ No newline at end of file diff --git a/src/shared/components/index.tsx b/src/shared/components/index.tsx index 522ef5eae2..0e8ec5fdbf 100644 --- a/src/shared/components/index.tsx +++ b/src/shared/components/index.tsx @@ -41,3 +41,4 @@ export * from "./BackgroundNotificationModal"; export * from "./Chat"; export * from "./ReportModal"; export * from "./UserInfoPopup"; +export * from "./ImageWithZoom"; diff --git a/src/shared/ui-kit/ImageGallery/components/ImageGalleryMobileModal/ImageGalleryMobileModal.tsx b/src/shared/ui-kit/ImageGallery/components/ImageGalleryMobileModal/ImageGalleryMobileModal.tsx index 741688fd47..28d97d352e 100644 --- a/src/shared/ui-kit/ImageGallery/components/ImageGalleryMobileModal/ImageGalleryMobileModal.tsx +++ b/src/shared/ui-kit/ImageGallery/components/ImageGalleryMobileModal/ImageGalleryMobileModal.tsx @@ -73,6 +73,7 @@ const ImageGalleryMobileModal: FC = (props) => { )} {images.map((imageURL, index) => ( = (props) => { loop={true} pagination initialSlide={initialSlide} + allowTouchMove={false} > {videoSrc && ( @@ -61,6 +62,7 @@ const ImageGalleryModal: FC = (props) => { {images.map((imageURL, index) => ( {`Common Date: Mon, 16 Oct 2023 15:31:28 +0300 Subject: [PATCH 11/39] update billing page's UI --- .../components/Billing/Billing.module.scss | 14 +++++ .../MyAccount/components/Billing/Billing.tsx | 22 ++++---- .../Billing/MobileBilling/index.scss | 4 +- .../components/Header/Header.module.scss | 37 +++++++++++++ .../Billing/components/Header/Header.tsx | 54 +++++++++++++++++++ .../Billing/components/Header/index.ts | 1 + .../components/Billing/components/index.ts | 1 + .../MyAccount/components/Billing/index.scss | 12 +++-- .../MyAccount/components/Profile/index.scss | 12 ----- src/pages/billing/Billing.module.scss | 14 ++--- src/pages/billing/Billing.tsx | 12 +++-- src/pages/billing/Billing_v04.tsx | 12 +++-- 12 files changed, 152 insertions(+), 43 deletions(-) create mode 100644 src/pages/MyAccount/components/Billing/Billing.module.scss create mode 100644 src/pages/MyAccount/components/Billing/components/Header/Header.module.scss create mode 100644 src/pages/MyAccount/components/Billing/components/Header/Header.tsx create mode 100644 src/pages/MyAccount/components/Billing/components/Header/index.ts create mode 100644 src/pages/MyAccount/components/Billing/components/index.ts diff --git a/src/pages/MyAccount/components/Billing/Billing.module.scss b/src/pages/MyAccount/components/Billing/Billing.module.scss new file mode 100644 index 0000000000..12459bba7c --- /dev/null +++ b/src/pages/MyAccount/components/Billing/Billing.module.scss @@ -0,0 +1,14 @@ +@import "../../../../constants"; +@import "../../../../styles/sizes"; + +.container { + width: 100%; +} + +.header { + margin-bottom: 2.25rem; + + @include tablet { + margin-bottom: 0; + } +} diff --git a/src/pages/MyAccount/components/Billing/Billing.tsx b/src/pages/MyAccount/components/Billing/Billing.tsx index 1d3864f8fe..f459747378 100644 --- a/src/pages/MyAccount/components/Billing/Billing.tsx +++ b/src/pages/MyAccount/components/Billing/Billing.tsx @@ -1,20 +1,22 @@ import React, { useEffect, useState, FC } from "react"; -import { useDispatch, useSelector } from "react-redux"; +import { useDispatch } from "react-redux"; import { getBankDetails, loadUserCards } from "@/pages/OldCommon/store/actions"; -import { ScreenSize } from "@/shared/constants"; import { usePaymentMethodChange, useUserContributions, } from "@/shared/hooks/useCases"; +import { useIsTabletView } from "@/shared/hooks/viewport"; import { BankAccountDetails, Payment, Subscription } from "@/shared/models"; -import { getScreenSize } from "@/shared/store/selectors"; import { DesktopBilling } from "./DesktopBilling"; import { MobileBilling } from "./MobileBilling"; +import { Header } from "./components"; import { BankAccountState, BillingProps, CardsState } from "./types"; +import styles from "./Billing.module.scss"; import "./index.scss"; const Billing: FC = () => { const dispatch = useDispatch(); + const isMobileView = useIsTabletView(); const [cardsState, setCardsState] = useState({ loading: false, fetched: false, @@ -28,8 +30,6 @@ const Billing: FC = () => { const [activeContribution, setActiveContribution] = useState< Payment | Subscription | null >(null); - const screenSize = useSelector(getScreenSize()); - const isMobileView = screenSize === ScreenSize.Mobile; const { changePaymentMethodState, onPaymentMethodChange, @@ -138,13 +138,11 @@ const Billing: FC = () => { }; return ( -
- {(!isMobileView || !activeContribution) && ( -
-

Billing

-
- )} - +
+
+
+ +
); }; diff --git a/src/pages/MyAccount/components/Billing/MobileBilling/index.scss b/src/pages/MyAccount/components/Billing/MobileBilling/index.scss index b5a2f47de0..39f43b8bb8 100644 --- a/src/pages/MyAccount/components/Billing/MobileBilling/index.scss +++ b/src/pages/MyAccount/components/Billing/MobileBilling/index.scss @@ -1,7 +1,7 @@ @import "../../../../../constants"; .my-account-mobile-billing { - --content-ph: var(--container-pl, #{$content-padding-mobile}); + --content-ph: 1rem; flex: 1; display: flex; @@ -19,13 +19,13 @@ .my-account-mobile-billing__tabs-wrapper { padding: 0 var(--content-ph); - margin: 0 calc(var(--content-ph) * -1); white-space: nowrap; border-bottom: 1px solid $light-gray-1; } .my-account-mobile-billing__tab-panels { height: 100%; + padding: 0 var(--content-ph); } .my-account-mobile-billing__tab-panel { diff --git a/src/pages/MyAccount/components/Billing/components/Header/Header.module.scss b/src/pages/MyAccount/components/Billing/components/Header/Header.module.scss new file mode 100644 index 0000000000..21247df7e5 --- /dev/null +++ b/src/pages/MyAccount/components/Billing/components/Header/Header.module.scss @@ -0,0 +1,37 @@ +@import "../../../../../../constants"; + +.desktopContainer { + display: flex; + align-items: center; + justify-content: space-between; +} + +.desktopTitle { + margin: 0; + font-family: Lexend, sans-serif; + font-weight: normal; + font-size: 2.25rem; + line-height: 3rem; +} + +.topNavigationWithBlocks { + z-index: 10; +} + +.backIcon { + flex-shrink: 0; + width: 0.875rem; + height: 0.875rem; +} + +.mobileTitle { + margin: 0; + font-family: PoppinsSans, sans-serif; + font-weight: 500; + font-size: 1rem; + text-align: center; + color: $c-gray-100; + white-space: nowrap; + text-overflow: ellipsis; + overflow: hidden; +} diff --git a/src/pages/MyAccount/components/Billing/components/Header/Header.tsx b/src/pages/MyAccount/components/Billing/components/Header/Header.tsx new file mode 100644 index 0000000000..e68aff2d6f --- /dev/null +++ b/src/pages/MyAccount/components/Billing/components/Header/Header.tsx @@ -0,0 +1,54 @@ +import React, { FC } from "react"; +import { useHistory } from "react-router-dom"; +import classNames from "classnames"; +import { useRoutesContext } from "@/shared/contexts"; +import { useGoBack } from "@/shared/hooks"; +import { LongLeftArrowIcon } from "@/shared/icons"; +import { + TopNavigationBackButton, + TopNavigationWithBlocks, +} from "@/shared/ui-kit"; +import styles from "./Header.module.scss"; + +interface HeaderProps { + className?: string; + isMobileVersion?: boolean; +} + +const Header: FC = (props) => { + const { className, isMobileVersion = false } = props; + const history = useHistory(); + const { canGoBack, goBack } = useGoBack(); + const { getProfilePagePath } = useRoutesContext(); + + if (!isMobileVersion) { + return ( +
+

Billing

+
+ ); + } + + const handleBackButtonClick = () => { + if (canGoBack) { + goBack(); + } else { + history.push(getProfilePagePath()); + } + }; + + return ( + } + onClick={handleBackButtonClick} + /> + } + centralElement={

Billing

} + /> + ); +}; + +export default Header; diff --git a/src/pages/MyAccount/components/Billing/components/Header/index.ts b/src/pages/MyAccount/components/Billing/components/Header/index.ts new file mode 100644 index 0000000000..d88c989bbd --- /dev/null +++ b/src/pages/MyAccount/components/Billing/components/Header/index.ts @@ -0,0 +1 @@ +export { default as Header } from "./Header"; diff --git a/src/pages/MyAccount/components/Billing/components/index.ts b/src/pages/MyAccount/components/Billing/components/index.ts new file mode 100644 index 0000000000..9e08a64dbf --- /dev/null +++ b/src/pages/MyAccount/components/Billing/components/index.ts @@ -0,0 +1 @@ +export * from "./Header"; diff --git a/src/pages/MyAccount/components/Billing/index.scss b/src/pages/MyAccount/components/Billing/index.scss index c919e50329..d2db0f7536 100644 --- a/src/pages/MyAccount/components/Billing/index.scss +++ b/src/pages/MyAccount/components/Billing/index.scss @@ -2,15 +2,17 @@ @import "../../../../styles/sizes"; .my-account-billing { + max-width: 36.25rem; width: 100%; + margin: 0 auto; + padding-top: 3.375rem; + display: flex; + flex-direction: column; font-family: PoppinsSans, sans-serif; color: $secondary-blue; - overflow: hidden; - @include big-phone { - display: flex; - flex-direction: column; - overflow: initial; + @include tablet { + padding-top: 0; } .my-account-billing__header { diff --git a/src/pages/MyAccount/components/Profile/index.scss b/src/pages/MyAccount/components/Profile/index.scss index 8b12f92037..c482b034eb 100644 --- a/src/pages/MyAccount/components/Profile/index.scss +++ b/src/pages/MyAccount/components/Profile/index.scss @@ -12,18 +12,6 @@ padding-top: 0; } - .profile-wrapper__header { - height: 4.5rem; - margin-bottom: 2.5rem; - display: flex; - align-items: center; - justify-content: space-between; - - @include tablet { - margin-bottom: 0; - } - } - .profile-wrapper__buttons-wrapper { @include flex-list-with-gap(1rem); } diff --git a/src/pages/billing/Billing.module.scss b/src/pages/billing/Billing.module.scss index 0069aa000a..779c11b95f 100644 --- a/src/pages/billing/Billing.module.scss +++ b/src/pages/billing/Billing.module.scss @@ -1,15 +1,17 @@ +@import "../../constants"; @import "../../styles/sizes"; -.topNavigation { - z-index: 2; -} - .container { - padding-top: 3rem; + flex: 1; + max-width: 49.5rem; + padding-top: var(--header-h); padding-bottom: 3rem; + border-left: 0.0625rem solid $c-gray-10; + border-right: 0.0625rem solid $c-gray-10; @include tablet { - padding-top: 1rem; + padding-top: 0; padding-bottom: 1rem; + border: 0; } } diff --git a/src/pages/billing/Billing.tsx b/src/pages/billing/Billing.tsx index 32fca7e0f0..38f63931d3 100644 --- a/src/pages/billing/Billing.tsx +++ b/src/pages/billing/Billing.tsx @@ -1,14 +1,20 @@ import React, { FC } from "react"; import { Billing } from "@/pages/MyAccount/components/Billing"; +import { ViewportBreakpointVariant } from "@/shared/constants"; import { MainRoutesProvider } from "@/shared/contexts"; -import { Container, PureCommonTopNavigation } from "@/shared/ui-kit"; +import { Container } from "@/shared/ui-kit"; import styles from "./Billing.module.scss"; const BillingPage: FC = () => { return ( - - + diff --git a/src/pages/billing/Billing_v04.tsx b/src/pages/billing/Billing_v04.tsx index b1d36f6fad..399f7237df 100644 --- a/src/pages/billing/Billing_v04.tsx +++ b/src/pages/billing/Billing_v04.tsx @@ -1,14 +1,20 @@ import React, { FC } from "react"; import { Billing } from "@/pages/MyAccount/components/Billing"; +import { ViewportBreakpointVariant } from "@/shared/constants"; import { RoutesV04Provider } from "@/shared/contexts"; -import { Container, PureCommonTopNavigation } from "@/shared/ui-kit"; +import { Container } from "@/shared/ui-kit"; import styles from "./Billing.module.scss"; const BillingPage_v04: FC = () => { return ( - - + From 794ef1d32af87674bb239db86629eb68ccac562d Mon Sep 17 00:00:00 2001 From: Andrey Mikhadyuk Date: Mon, 16 Oct 2023 16:30:51 +0300 Subject: [PATCH 12/39] add icon element to menu item --- .../components/MenuItem/MenuItem.module.scss | 12 +++++++++++- .../components/MenuItem/MenuItem.tsx | 19 ++++++++++++++++++- .../UserInfo/components/MenuItems/types.ts | 1 + 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/src/shared/layouts/SidenavLayout/components/SidenavContent/components/UserInfo/components/MenuItems/components/MenuItem/MenuItem.module.scss b/src/shared/layouts/SidenavLayout/components/SidenavContent/components/UserInfo/components/MenuItems/components/MenuItem/MenuItem.module.scss index 664877803e..17721a6e55 100644 --- a/src/shared/layouts/SidenavLayout/components/SidenavContent/components/UserInfo/components/MenuItems/components/MenuItem/MenuItem.module.scss +++ b/src/shared/layouts/SidenavLayout/components/SidenavContent/components/UserInfo/components/MenuItems/components/MenuItem/MenuItem.module.scss @@ -5,13 +5,16 @@ --item-border: 0.0625rem solid #{$c-neutrals-100}; padding: 1.125rem 1.5rem; + display: flex; + align-items: center; text-decoration: none; color: inherit; background-color: var(--item-bg-color); border: var(--item-border); border-bottom: 0; font-family: PoppinsSans, sans-serif; - font-size: $small; + font-size: 1rem; + font-weight: 500; text-align: left; cursor: pointer; box-sizing: border-box; @@ -30,3 +33,10 @@ .itemActive { --item-bg-color: var(--hover-fill); } + +.icon { + width: 1.5rem; + height: 1.5rem; + margin-right: 1rem; + color: inherit; +} diff --git a/src/shared/layouts/SidenavLayout/components/SidenavContent/components/UserInfo/components/MenuItems/components/MenuItem/MenuItem.tsx b/src/shared/layouts/SidenavLayout/components/SidenavContent/components/UserInfo/components/MenuItems/components/MenuItem/MenuItem.tsx index d569f8e4bf..16cadcc424 100644 --- a/src/shared/layouts/SidenavLayout/components/SidenavContent/components/UserInfo/components/MenuItems/components/MenuItem/MenuItem.tsx +++ b/src/shared/layouts/SidenavLayout/components/SidenavContent/components/UserInfo/components/MenuItems/components/MenuItem/MenuItem.tsx @@ -1,7 +1,10 @@ import React, { + cloneElement, forwardRef, ForwardRefRenderFunction, + isValidElement, MouseEventHandler, + ReactNode, RefObject, } from "react"; import { NavLink } from "react-router-dom"; @@ -20,10 +23,24 @@ const MenuItem: ForwardRefRenderFunction = ( ref, ) => { const { item, active, ...restProps } = props; - const content = item.text; + let iconEl: ReactNode | null = null; + + if (isValidElement(item.icon)) { + iconEl = cloneElement(item.icon, { + ...item.icon.props, + className: classNames(styles.icon, item.icon.props.className), + }); + } + const className = classNames(styles.item, item.className, { [styles.itemActive]: active, }); + const content = ( + <> + {iconEl} + {item.text} + + ); switch (item.type) { case ItemType.Button: diff --git a/src/shared/layouts/SidenavLayout/components/SidenavContent/components/UserInfo/components/MenuItems/types.ts b/src/shared/layouts/SidenavLayout/components/SidenavContent/components/UserInfo/components/MenuItems/types.ts index 69a3858abc..ed180e01bb 100644 --- a/src/shared/layouts/SidenavLayout/components/SidenavContent/components/UserInfo/components/MenuItems/types.ts +++ b/src/shared/layouts/SidenavLayout/components/SidenavContent/components/UserInfo/components/MenuItems/types.ts @@ -10,6 +10,7 @@ interface GeneralItem { key: string; className?: string; text: ReactNode; + icon?: ReactNode; } interface LinkItem extends GeneralItem { From af9922d41ecaaa3e5a5635089a23f3d482d4c224 Mon Sep 17 00:00:00 2001 From: Andrey Mikhadyuk Date: Mon, 16 Oct 2023 16:33:34 +0300 Subject: [PATCH 13/39] add icons to the profile menu --- src/shared/icons/avatar3.icon.tsx | 44 +++++++++++++++++++ src/shared/icons/billing.icon.tsx | 44 +++++++++++++++++++ src/shared/icons/index.ts | 3 ++ src/shared/icons/settings.icon.tsx | 37 ++++++++++++++++ .../MenuItems/MenuItems.module.scss | 4 -- .../components/MenuItems/MenuItems.tsx | 11 ++++- 6 files changed, 138 insertions(+), 5 deletions(-) create mode 100644 src/shared/icons/avatar3.icon.tsx create mode 100644 src/shared/icons/billing.icon.tsx create mode 100644 src/shared/icons/settings.icon.tsx diff --git a/src/shared/icons/avatar3.icon.tsx b/src/shared/icons/avatar3.icon.tsx new file mode 100644 index 0000000000..6cd1eb5693 --- /dev/null +++ b/src/shared/icons/avatar3.icon.tsx @@ -0,0 +1,44 @@ +import React, { FC } from "react"; + +interface Avatar3IconProps { + className?: string; +} + +const Avatar3Icon: FC = ({ className }) => { + const color = "currentColor"; + + return ( + + + + + + ); +}; + +export default Avatar3Icon; diff --git a/src/shared/icons/billing.icon.tsx b/src/shared/icons/billing.icon.tsx new file mode 100644 index 0000000000..f2a36eae6b --- /dev/null +++ b/src/shared/icons/billing.icon.tsx @@ -0,0 +1,44 @@ +import React, { FC } from "react"; + +interface BillingIconProps { + className?: string; +} + +const BillingIcon: FC = ({ className }) => { + const color = "currentColor"; + + return ( + + + + + + ); +}; + +export default BillingIcon; diff --git a/src/shared/icons/index.ts b/src/shared/icons/index.ts index 230f33abbb..9f9a8fb7b3 100644 --- a/src/shared/icons/index.ts +++ b/src/shared/icons/index.ts @@ -1,6 +1,8 @@ export * from "./socials"; export { default as AttachIcon } from "./attach.icon"; export { default as Avatar2Icon } from "./avatar2.icon"; +export { default as Avatar3Icon } from "./avatar3.icon"; +export { default as BillingIcon } from "./billing.icon"; export { default as BlocksIcon } from "./blocks.icon"; export { default as BoldMarkIcon } from "./boldMark.icon"; export { default as BoldPlusIcon } from "./boldPlus.icon"; @@ -58,6 +60,7 @@ export { default as ShareIcon } from "./share.icon"; export { default as Share2Icon } from "./share2.icon"; export { default as Share3Icon } from "./share3.icon"; export { default as SendIcon } from "./send.icon"; +export { default as SettingsIcon } from "./settings.icon"; export { default as MinusIcon } from "./minus.icon"; export { default as FileIcon } from "./file.icon"; export { default as EmojiIcon } from "./emoji.icon"; diff --git a/src/shared/icons/settings.icon.tsx b/src/shared/icons/settings.icon.tsx new file mode 100644 index 0000000000..136299a67b --- /dev/null +++ b/src/shared/icons/settings.icon.tsx @@ -0,0 +1,37 @@ +import React, { FC } from "react"; + +interface SettingsIconProps { + className?: string; +} + +const SettingsIcon: FC = ({ className }) => { + const color = "currentColor"; + + return ( + + + + + ); +}; + +export default SettingsIcon; diff --git a/src/shared/layouts/SidenavLayout/components/SidenavContent/components/UserInfo/components/MenuItems/MenuItems.module.scss b/src/shared/layouts/SidenavLayout/components/SidenavContent/components/UserInfo/components/MenuItems/MenuItems.module.scss index c37fa11e7d..dbeec0bb42 100644 --- a/src/shared/layouts/SidenavLayout/components/SidenavContent/components/UserInfo/components/MenuItems/MenuItems.module.scss +++ b/src/shared/layouts/SidenavLayout/components/SidenavContent/components/UserInfo/components/MenuItems/MenuItems.module.scss @@ -22,7 +22,3 @@ .itemsWrapperPlacementBottom { top: 100%; } - -.logoutItem { - color: $c-error-300; -} diff --git a/src/shared/layouts/SidenavLayout/components/SidenavContent/components/UserInfo/components/MenuItems/MenuItems.tsx b/src/shared/layouts/SidenavLayout/components/SidenavContent/components/UserInfo/components/MenuItems/MenuItems.tsx index 383dfece6f..78b6884971 100644 --- a/src/shared/layouts/SidenavLayout/components/SidenavContent/components/UserInfo/components/MenuItems/MenuItems.tsx +++ b/src/shared/layouts/SidenavLayout/components/SidenavContent/components/UserInfo/components/MenuItems/MenuItems.tsx @@ -4,6 +4,12 @@ import classNames from "classnames"; import { Menu } from "@headlessui/react"; import { logOut } from "@/pages/Auth/store/actions"; import { useRoutesContext } from "@/shared/contexts"; +import { + Avatar3Icon, + BillingIcon, + LogoutIcon, + SettingsIcon, +} from "@/shared/icons"; import { MenuItem } from "./components"; import { Item, ItemType } from "./types"; import styles from "./MenuItems.module.scss"; @@ -31,23 +37,26 @@ const MenuItems: FC = (props) => { { key: "my-profile", text: "My profile", + icon: , to: getProfilePagePath(), }, { key: "settings", text: "Settings", + icon: , to: getSettingsPagePath(), }, { key: "billing", text: "Billing", + icon: , to: getBillingPagePath(), }, { key: "log-out", - className: styles.logoutItem, type: ItemType.Button, text: "Log out", + icon: , onClick: () => { dispatch(logOut()); }, From 2c50fcde32e9c03098e2bf8e8d5600386a30bd1a Mon Sep 17 00:00:00 2001 From: Andrey Mikhadyuk Date: Mon, 16 Oct 2023 16:48:29 +0300 Subject: [PATCH 14/39] change edit button icon of profile page --- src/pages/MyAccount/components/Profile/Profile.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/pages/MyAccount/components/Profile/Profile.tsx b/src/pages/MyAccount/components/Profile/Profile.tsx index 3d548994fa..2a490aa160 100644 --- a/src/pages/MyAccount/components/Profile/Profile.tsx +++ b/src/pages/MyAccount/components/Profile/Profile.tsx @@ -9,8 +9,7 @@ import { import { ButtonIcon, Loader } from "@/shared/components"; import { useRoutesContext } from "@/shared/contexts"; import { useIsTabletView } from "@/shared/hooks/viewport"; -import { LogoutIcon } from "@/shared/icons"; -import EditIcon from "@/shared/icons/edit.icon"; +import { Edit3Icon as EditIcon, LogoutIcon } from "@/shared/icons"; import { Button, ButtonVariant } from "@/shared/ui-kit"; import { Header, MenuButton } from "./components"; import styles from "./Profile.module.scss"; From 99e8ca1ab9468a4b7fb71b697f9632e2b255ce8b Mon Sep 17 00:00:00 2001 From: Andrey Mikhadyuk Date: Mon, 16 Oct 2023 17:17:01 +0300 Subject: [PATCH 15/39] copy UserDetails to profile page component --- .../MyAccount/components/Profile/Profile.tsx | 7 +- .../UserDetails/UserDetails.module.scss | 127 +++++++ .../components/UserDetails/UserDetails.tsx | 340 ++++++++++++++++++ .../UserDetailsPreview.module.scss | 47 +++ .../UserDetailsPreview/UserDetailsPreview.tsx | 32 ++ .../components/UserDetailsPreview/index.ts | 1 + .../UserDetails/components/index.ts | 1 + .../Profile/components/UserDetails/index.ts | 2 + .../UserDetails/validationSchema.ts | 10 + .../components/Profile/components/index.ts | 1 + 10 files changed, 562 insertions(+), 6 deletions(-) create mode 100644 src/pages/MyAccount/components/Profile/components/UserDetails/UserDetails.module.scss create mode 100644 src/pages/MyAccount/components/Profile/components/UserDetails/UserDetails.tsx create mode 100644 src/pages/MyAccount/components/Profile/components/UserDetails/components/UserDetailsPreview/UserDetailsPreview.module.scss create mode 100644 src/pages/MyAccount/components/Profile/components/UserDetails/components/UserDetailsPreview/UserDetailsPreview.tsx create mode 100644 src/pages/MyAccount/components/Profile/components/UserDetails/components/UserDetailsPreview/index.ts create mode 100644 src/pages/MyAccount/components/Profile/components/UserDetails/components/index.ts create mode 100644 src/pages/MyAccount/components/Profile/components/UserDetails/index.ts create mode 100644 src/pages/MyAccount/components/Profile/components/UserDetails/validationSchema.ts diff --git a/src/pages/MyAccount/components/Profile/Profile.tsx b/src/pages/MyAccount/components/Profile/Profile.tsx index 2a490aa160..1ba181b2ae 100644 --- a/src/pages/MyAccount/components/Profile/Profile.tsx +++ b/src/pages/MyAccount/components/Profile/Profile.tsx @@ -2,16 +2,12 @@ import React, { FC, useRef, useState } from "react"; import { useDispatch, useSelector } from "react-redux"; import { logOut } from "@/pages/Auth/store/actions"; import { selectUser } from "@/pages/Auth/store/selectors"; -import { - UserDetails, - UserDetailsRef, -} from "@/pages/Login/components/LoginContainer/UserDetails"; import { ButtonIcon, Loader } from "@/shared/components"; import { useRoutesContext } from "@/shared/contexts"; import { useIsTabletView } from "@/shared/hooks/viewport"; import { Edit3Icon as EditIcon, LogoutIcon } from "@/shared/icons"; import { Button, ButtonVariant } from "@/shared/ui-kit"; -import { Header, MenuButton } from "./components"; +import { Header, MenuButton, UserDetails, UserDetailsRef } from "./components"; import styles from "./Profile.module.scss"; import "./index.scss"; @@ -100,7 +96,6 @@ const Profile: FC = (props) => { ref={userDetailsRef} className="profile-wrapper__user-details" user={user} - showAuthProvider={false} customSaveButton isCountryDropdownFixed={false} isEditing={isEditing} diff --git a/src/pages/MyAccount/components/Profile/components/UserDetails/UserDetails.module.scss b/src/pages/MyAccount/components/Profile/components/UserDetails/UserDetails.module.scss new file mode 100644 index 0000000000..c2dc2cd29a --- /dev/null +++ b/src/pages/MyAccount/components/Profile/components/UserDetails/UserDetails.module.scss @@ -0,0 +1,127 @@ +@import "../../../../../../constants"; +@import "../../../../../../styles/sizes"; + +.container { + width: 100%; + max-width: 36.5rem; + margin: 0 auto; + display: flex; + flex-direction: column; + align-items: center; + text-align: center; + color: $secondary-blue; +} + +.form { + width: 100%; + display: flex; + flex-direction: column; +} + +.avatarWrapper { + position: relative; +} + +.avatar { + position: relative; + text-align: center; + margin-top: 1.5rem; +} + +.avatarInputFile { + display: none; +} + +.userPhoto { + width: 4.125rem; + height: 4.125rem; + border-radius: 50%; + object-fit: cover; +} + +.editAvatarButton { + width: 1.75rem; + height: 1.75rem; + background-color: $purple; + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + position: absolute; + top: 38px; + left: 52%; + cursor: pointer; +} + +.editAvatarImage { + width: 0.875rem; + height: 0.875rem; +} + +.textFieldContainer { + max-width: 100%; + display: grid; + gap: 0.5rem 1.75rem; + grid-auto-columns: minmax(0, 1fr); + grid-template-areas: + "firstName lastName" + "email country" + "intro intro"; + + @include tablet { + gap: 1.5rem 0; + grid-template-areas: + "firstName" + "lastName" + "email" + "country" + "intro"; + } +} + +.textField { + width: 100%; + text-align: left; + z-index: 1; +} + +.textFieldLabelWrapper { + font-size: $xsmall; +} + +.textFieldInput { + padding-left: 0.75rem; + padding-right: 0.875rem; +} + +.firstNameTextField { + grid-area: firstName; +} + +.lastNameTextField { + grid-area: lastName; +} + +.emailTextField { + grid-area: email; +} + +.countryTextField { + grid-area: country; +} + +.textareaTextField { + grid-area: intro; + width: 100%; +} + +.saveButton { + max-width: 20.5rem; + width: 100%; + margin: 2.5rem auto 0; + + @include tablet { + max-width: unset; + margin-top: 3.5rem; + } +} diff --git a/src/pages/MyAccount/components/Profile/components/UserDetails/UserDetails.tsx b/src/pages/MyAccount/components/Profile/components/UserDetails/UserDetails.tsx new file mode 100644 index 0000000000..3cf15c6b43 --- /dev/null +++ b/src/pages/MyAccount/components/Profile/components/UserDetails/UserDetails.tsx @@ -0,0 +1,340 @@ +import React, { + useCallback, + useEffect, + useMemo, + useRef, + useState, + useImperativeHandle, + forwardRef, + ForwardRefRenderFunction, +} from "react"; +import { useDispatch } from "react-redux"; +import classNames from "classnames"; +import { Formik, FormikConfig } from "formik"; +import { FormikProps } from "formik/dist/types"; +import { updateUserDetails } from "@/pages/Auth/store/actions"; +import { uploadImage } from "@/pages/Auth/store/saga"; +import { countryList } from "@/shared/assets/countries"; +import { Button, DropdownOption, UserAvatar } from "@/shared/components"; +import { Form, Dropdown, TextField } from "@/shared/components/Form/Formik"; +import { + ANONYMOUS_USER_FIRST_NAME, + ANONYMOUS_USER_LAST_NAME, +} from "@/shared/constants"; +import { useImageSizeCheck } from "@/shared/hooks"; +import { User } from "@/shared/models"; +import { Loader } from "@/shared/ui-kit"; +import { getUserName } from "@/shared/utils"; +import { UserDetailsPreview } from "./components"; +import { validationSchema } from "./validationSchema"; +import styles from "./UserDetails.module.scss"; + +interface Styles { + avatarWrapper?: string; + avatar?: string; + userAvatar?: string; + editAvatar?: string; + fieldContainer?: string; + introInputWrapper?: string; +} + +export interface UserDetailsRef { + submit: () => void; +} + +interface UserDetailsProps { + className?: string; + user: User; + isNewUser?: boolean; + closeModal?: () => void; + customSaveButton?: boolean; + isCountryDropdownFixed?: boolean; + isEditing?: boolean; + onLoading?: (isLoading: boolean) => void; + onSubmitting?: (isSubmitting: boolean) => void; + styles?: Styles; +} + +interface FormValues { + firstName: string; + lastName: string; + email: string; + country: string; + photo: string; + intro: string; +} + +const getInitialValues = (user: User, isNewUser: boolean): FormValues => { + const names = (user.displayName || "").split(" "); + const isAnonymousUser = + isNewUser && + user.firstName === ANONYMOUS_USER_FIRST_NAME && + user.lastName === ANONYMOUS_USER_LAST_NAME; + + return { + firstName: (!isAnonymousUser && (user.firstName || names[0])) || "", + lastName: (!isAnonymousUser && (user.lastName || names[1])) || "", + email: user.email || "", + country: user.country || "", + photo: user.photoURL || "", + intro: user.intro || "", + }; +}; + +const UserDetails: ForwardRefRenderFunction< + UserDetailsRef, + UserDetailsProps +> = (props, userDetailsRef) => { + const { + className, + user, + isNewUser = false, + closeModal, + customSaveButton = false, + isCountryDropdownFixed = true, + isEditing = true, + styles: outerStyles, + onLoading, + onSubmitting, + } = props; + const dispatch = useDispatch(); + const formRef = useRef>(null); + const { checkImageSize } = useImageSizeCheck(); + const [loading, setLoading] = useState(false); + const [uploadedPhoto, setUploadedPhoto] = useState(""); + const inputFile = useRef(null); + const options = useMemo( + () => + countryList.map((item) => ({ + text: item.name, + value: item.value, + })), + [], + ); + + const uploadAvatar = ( + files: FileList | null, + setFieldValue: ( + field: string, + value: any, + shouldValidate?: boolean, + ) => void, + ) => { + const file = files && files[0]; + + if (!file) { + return; + } + + if (!checkImageSize(file.name, file.size)) { + return; + } + + setLoading(true); + + if (onLoading) { + onLoading(true); + } + + const fileReader = new FileReader(); + fileReader.readAsDataURL(file); + fileReader.addEventListener("load", async function () { + const imageUrl = await uploadImage(this.result); + setUploadedPhoto(URL.createObjectURL(file)); + setLoading(false); + setFieldValue("photo", imageUrl); + + if (onLoading) { + onLoading(false); + } + }); + }; + + const handleSubmit = useCallback["onSubmit"]>( + (values, { setSubmitting }) => { + setSubmitting(true); + + if (onSubmitting) { + onSubmitting(true); + } + + dispatch( + updateUserDetails.request({ + user: { ...user, ...values }, + callback: () => { + if (closeModal) { + closeModal(); + } + if (onSubmitting) { + onSubmitting(false); + } + + setSubmitting(false); + }, + }), + ); + }, + [closeModal, dispatch, user, onSubmitting], + ); + + useImperativeHandle( + userDetailsRef, + () => ({ + submit: () => { + formRef.current?.submitForm(); + }, + }), + [formRef], + ); + + const fieldStyles = { + labelWrapper: styles.textFieldLabelWrapper, + input: { + default: styles.textFieldInput, + }, + }; + + useEffect(() => { + if (!isEditing) { + formRef.current?.setFieldValue("photo", user.photoURL || ""); + setUploadedPhoto(""); + } + }, [isEditing, user]); + + return ( +
+ + {({ values, setFieldValue, isValid, isSubmitting }) => ( + <> +
+
+
+ + {isEditing && !isSubmitting ? ( +
+ inputFile?.current && inputFile?.current?.click() + : undefined + } + > + {loading ? ( + + ) : ( + edit-avatar + )} +
+ ) : null} + + uploadAvatar(value.target.files, setFieldValue) + } + /> +
+
+ {!isEditing && } + {isEditing && ( +
+ + + + + +
+ )} + {!customSaveButton && ( + + )} + + + )} +
+
+ ); +}; + +export default forwardRef(UserDetails); diff --git a/src/pages/MyAccount/components/Profile/components/UserDetails/components/UserDetailsPreview/UserDetailsPreview.module.scss b/src/pages/MyAccount/components/Profile/components/UserDetails/components/UserDetailsPreview/UserDetailsPreview.module.scss new file mode 100644 index 0000000000..fab5b09852 --- /dev/null +++ b/src/pages/MyAccount/components/Profile/components/UserDetails/components/UserDetailsPreview/UserDetailsPreview.module.scss @@ -0,0 +1,47 @@ +@import "../../../../../../../../constants"; +@import "../../../../../../../../styles/sizes"; + +.container { + display: flex; + flex-direction: column; + text-align: left; +} + +.name { + margin: 0 0 0.5rem; + height: 1.5rem; + font-size: $moderate-small; + font-weight: bold; +} + +.info { + margin: 0 0 0.5rem; + font-size: $xsmall; + color: $light-gray-2; + word-break: break-word; + + &:last-child { + margin: 0; + } +} + +.introWrapper { + max-width: 20.5rem; + margin-top: 2.5rem; + + @include tablet { + max-width: unset; + margin-top: 1.5rem; + } +} + +.introTitle { + margin: 0 0 0.5rem; + font-size: $moderate; +} + +.introContent { + margin: 0; + font-size: $xsmall; + white-space: pre-line; +} diff --git a/src/pages/MyAccount/components/Profile/components/UserDetails/components/UserDetailsPreview/UserDetailsPreview.tsx b/src/pages/MyAccount/components/Profile/components/UserDetails/components/UserDetailsPreview/UserDetailsPreview.tsx new file mode 100644 index 0000000000..1755836e93 --- /dev/null +++ b/src/pages/MyAccount/components/Profile/components/UserDetails/components/UserDetailsPreview/UserDetailsPreview.tsx @@ -0,0 +1,32 @@ +import React, { FC } from "react"; +import { countryList } from "@/shared/assets/countries"; +import { User } from "@/shared/models"; +import { getUserName } from "@/shared/utils"; +import styles from "./UserDetailsPreview.module.scss"; + +interface UserDetailsPreviewProps { + user: User; +} + +const UserDetailsPreview: FC = (props) => { + const { user } = props; + const country = countryList.find((item) => item.value === user.country); + + return ( +
+
+

{getUserName(user)}

+ {user.email &&

{user.email}

} + {country &&

{country.name}

} +
+ {user.intro && ( +
+

Intro

+

{user.intro}

+
+ )} +
+ ); +}; + +export default UserDetailsPreview; diff --git a/src/pages/MyAccount/components/Profile/components/UserDetails/components/UserDetailsPreview/index.ts b/src/pages/MyAccount/components/Profile/components/UserDetails/components/UserDetailsPreview/index.ts new file mode 100644 index 0000000000..1cc006214b --- /dev/null +++ b/src/pages/MyAccount/components/Profile/components/UserDetails/components/UserDetailsPreview/index.ts @@ -0,0 +1 @@ +export { default as UserDetailsPreview } from "./UserDetailsPreview"; diff --git a/src/pages/MyAccount/components/Profile/components/UserDetails/components/index.ts b/src/pages/MyAccount/components/Profile/components/UserDetails/components/index.ts new file mode 100644 index 0000000000..06c4870654 --- /dev/null +++ b/src/pages/MyAccount/components/Profile/components/UserDetails/components/index.ts @@ -0,0 +1 @@ +export * from "./UserDetailsPreview"; diff --git a/src/pages/MyAccount/components/Profile/components/UserDetails/index.ts b/src/pages/MyAccount/components/Profile/components/UserDetails/index.ts new file mode 100644 index 0000000000..c507ba11ad --- /dev/null +++ b/src/pages/MyAccount/components/Profile/components/UserDetails/index.ts @@ -0,0 +1,2 @@ +export { default as UserDetails } from "./UserDetails"; +export type { UserDetailsRef } from "./UserDetails"; diff --git a/src/pages/MyAccount/components/Profile/components/UserDetails/validationSchema.ts b/src/pages/MyAccount/components/Profile/components/UserDetails/validationSchema.ts new file mode 100644 index 0000000000..7bffd24fd5 --- /dev/null +++ b/src/pages/MyAccount/components/Profile/components/UserDetails/validationSchema.ts @@ -0,0 +1,10 @@ +import * as Yup from "yup"; +import { FORM_ERROR_MESSAGES } from "@/shared/constants"; + +export const validationSchema = Yup.object({ + firstName: Yup.string().required(FORM_ERROR_MESSAGES.REQUIRED), + lastName: Yup.string().required(FORM_ERROR_MESSAGES.REQUIRED), + email: Yup.string() + .required(FORM_ERROR_MESSAGES.EMAIL) + .email(FORM_ERROR_MESSAGES.EMAIL), +}); diff --git a/src/pages/MyAccount/components/Profile/components/index.ts b/src/pages/MyAccount/components/Profile/components/index.ts index 6733922ac9..5a9a72ed74 100644 --- a/src/pages/MyAccount/components/Profile/components/index.ts +++ b/src/pages/MyAccount/components/Profile/components/index.ts @@ -1,2 +1,3 @@ export * from "./Header"; export * from "./MenuButton"; +export * from "./UserDetails"; From 75bc80f5965ad5e612f462a34d1b1767dc6f660a Mon Sep 17 00:00:00 2001 From: Andrey Mikhadyuk Date: Mon, 16 Oct 2023 17:46:51 +0300 Subject: [PATCH 16/39] update user details preview displaying --- .../MyAccount/components/Profile/Profile.tsx | 1 - .../UserDetails/UserDetails.module.scss | 30 +++++++++++++- .../components/UserDetails/UserDetails.tsx | 19 +++++++-- .../UserDetailsPreview.module.scss | 41 ++++++------------- .../UserDetailsPreview/UserDetailsPreview.tsx | 33 ++++++++------- .../MyAccount/components/Profile/index.scss | 13 ------ src/shared/models/User.tsx | 7 ++-- src/styles/typography.scss | 6 +-- 8 files changed, 79 insertions(+), 71 deletions(-) diff --git a/src/pages/MyAccount/components/Profile/Profile.tsx b/src/pages/MyAccount/components/Profile/Profile.tsx index 1ba181b2ae..d5f9547705 100644 --- a/src/pages/MyAccount/components/Profile/Profile.tsx +++ b/src/pages/MyAccount/components/Profile/Profile.tsx @@ -102,7 +102,6 @@ const Profile: FC = (props) => { onLoading={setIsSubmitting} onSubmitting={handleSubmittingChange} styles={{ - avatarWrapper: "profile-wrapper__avatar-wrapper", avatar: "profile-wrapper__avatar", userAvatar: "profile-wrapper__user-avatar", editAvatar: "profile-wrapper__edit-avatar", diff --git a/src/pages/MyAccount/components/Profile/components/UserDetails/UserDetails.module.scss b/src/pages/MyAccount/components/Profile/components/UserDetails/UserDetails.module.scss index c2dc2cd29a..532ee9a173 100644 --- a/src/pages/MyAccount/components/Profile/components/UserDetails/UserDetails.module.scss +++ b/src/pages/MyAccount/components/Profile/components/UserDetails/UserDetails.module.scss @@ -1,5 +1,6 @@ @import "../../../../../../constants"; @import "../../../../../../styles/sizes"; +@import "../../../../../../styles/typography"; .container { width: 100%; @@ -18,8 +19,29 @@ flex-direction: column; } -.avatarWrapper { - position: relative; +.previewWrapper { + display: flex; + align-items: flex-start; +} + +.introWrapper { + margin-top: 2.25rem; +} + +.introTitle { + @include h5; + + margin: 0 0 0.5rem; + text-align: left; +} + +.introDescription { + @include body-sm-regular; + + max-width: 24.875rem; + margin: 0; + text-align: left; + word-break: break-word; } .avatar { @@ -32,6 +54,10 @@ display: none; } +.userDetailsPreview { + margin-left: 1rem; +} + .userPhoto { width: 4.125rem; height: 4.125rem; diff --git a/src/pages/MyAccount/components/Profile/components/UserDetails/UserDetails.tsx b/src/pages/MyAccount/components/Profile/components/UserDetails/UserDetails.tsx index 3cf15c6b43..92cf096b29 100644 --- a/src/pages/MyAccount/components/Profile/components/UserDetails/UserDetails.tsx +++ b/src/pages/MyAccount/components/Profile/components/UserDetails/UserDetails.tsx @@ -30,7 +30,7 @@ import { validationSchema } from "./validationSchema"; import styles from "./UserDetails.module.scss"; interface Styles { - avatarWrapper?: string; + previewWrapper?: string; avatar?: string; userAvatar?: string; editAvatar?: string; @@ -215,8 +215,8 @@ const UserDetails: ForwardRefRenderFunction<
@@ -264,8 +264,19 @@ const UserDetails: ForwardRefRenderFunction< } />
+ {!isEditing && ( + + )}
- {!isEditing && } + {!isEditing && user.intro && ( +
+

About

+

{user.intro}

+
+ )} {isEditing && (
= (props) => { - const { user } = props; + const { className, user } = props; const country = countryList.find((item) => item.value === user.country); + const countryName = + country && country.name.slice(0, country.name.lastIndexOf(" ")); return ( -
-
-

{getUserName(user)}

- {user.email &&

{user.email}

} - {country &&

{country.name}

} -
- {user.intro && ( -
-

Intro

-

{user.intro}

-
- )} +
+

{getUserName(user)}

+ {user.email &&

{user.email}

} +

+ Join at{" "} + {formatDate( + new Date(user.createdAt.seconds * 1000), + DateFormat.SuperShortSecondary, + )} +

+ {countryName &&

{countryName}

}
); }; diff --git a/src/pages/MyAccount/components/Profile/index.scss b/src/pages/MyAccount/components/Profile/index.scss index c482b034eb..7c75986c73 100644 --- a/src/pages/MyAccount/components/Profile/index.scss +++ b/src/pages/MyAccount/components/Profile/index.scss @@ -24,19 +24,6 @@ } } - .profile-wrapper__avatar-wrapper { - margin-bottom: 2.5rem; - display: flex; - flex-direction: column; - align-items: flex-start; - - @include tablet { - margin-bottom: 1.5rem; - justify-content: center; - align-items: center; - } - } - .profile-wrapper__avatar { margin: 0; } diff --git a/src/shared/models/User.tsx b/src/shared/models/User.tsx index 060933f486..fa6afdad06 100644 --- a/src/shared/models/User.tsx +++ b/src/shared/models/User.tsx @@ -1,4 +1,5 @@ -import { Proposal } from "."; +import { BaseEntity } from "./BaseEntity"; +import { Proposal } from "./Proposals"; export enum UserRole { Trustee = "trustee", @@ -17,7 +18,7 @@ export enum UserEmailNotificationPreference { AllInbox = "allInbox", } -export interface User { +export interface User extends Omit { displayName?: string; country: string; firstName: string; @@ -27,8 +28,6 @@ export interface User { photo?: string; photoURL?: string; intro?: string; - createdAt?: Date; - updatedAt?: Date; proposals?: Proposal[]; uid: string; roles?: UserRole[]; diff --git a/src/styles/typography.scss b/src/styles/typography.scss index f9ea03f775..74a1321b9a 100644 --- a/src/styles/typography.scss +++ b/src/styles/typography.scss @@ -3,7 +3,7 @@ @mixin h5 { font-family: PoppinsSans, sans-serif; font-weight: normal; - font-size: $moderate-small-2; + font-size: 1.125rem; line-height: 1.25rem; color: $c-gray-90; text-align: center; @@ -12,7 +12,7 @@ @mixin h6 { font-family: PoppinsSans, sans-serif; font-weight: 500; - font-size: $moderate-xsmall; + font-size: 1rem; line-height: 1.5rem; color: $c-gray-100; text-align: center; @@ -21,7 +21,7 @@ @mixin body-sm-regular { font-family: PoppinsSans, sans-serif; font-weight: normal; - font-size: $mobile-title; + font-size: 0.875rem; line-height: 1.25rem; color: $c-gray-50; text-align: center; From f651de34ff07e08a21016e36c5bab9eecb892d0d Mon Sep 17 00:00:00 2001 From: Andrey Mikhadyuk Date: Tue, 17 Oct 2023 11:43:42 +0300 Subject: [PATCH 17/39] update edit avatar button icon --- .../UserDetails/UserDetails.module.scss | 8 ++++- .../components/UserDetails/UserDetails.tsx | 30 ++++++++++--------- 2 files changed, 23 insertions(+), 15 deletions(-) diff --git a/src/pages/MyAccount/components/Profile/components/UserDetails/UserDetails.module.scss b/src/pages/MyAccount/components/Profile/components/UserDetails/UserDetails.module.scss index 532ee9a173..4cfd37f0c0 100644 --- a/src/pages/MyAccount/components/Profile/components/UserDetails/UserDetails.module.scss +++ b/src/pages/MyAccount/components/Profile/components/UserDetails/UserDetails.module.scss @@ -68,7 +68,7 @@ .editAvatarButton { width: 1.75rem; height: 1.75rem; - background-color: $purple; + background-color: $c-pink-mention; border-radius: 50%; display: flex; align-items: center; @@ -82,6 +82,12 @@ .editAvatarImage { width: 0.875rem; height: 0.875rem; + color: $c-pink-light; +} + +.editAvatarLoader { + width: 1.25rem; + height: 1.25rem; } .textFieldContainer { diff --git a/src/pages/MyAccount/components/Profile/components/UserDetails/UserDetails.tsx b/src/pages/MyAccount/components/Profile/components/UserDetails/UserDetails.tsx index 92cf096b29..10141d1ff5 100644 --- a/src/pages/MyAccount/components/Profile/components/UserDetails/UserDetails.tsx +++ b/src/pages/MyAccount/components/Profile/components/UserDetails/UserDetails.tsx @@ -15,15 +15,21 @@ import { FormikProps } from "formik/dist/types"; import { updateUserDetails } from "@/pages/Auth/store/actions"; import { uploadImage } from "@/pages/Auth/store/saga"; import { countryList } from "@/shared/assets/countries"; -import { Button, DropdownOption, UserAvatar } from "@/shared/components"; +import { + Button, + ButtonIcon, + DropdownOption, + UserAvatar, +} from "@/shared/components"; import { Form, Dropdown, TextField } from "@/shared/components/Form/Formik"; import { ANONYMOUS_USER_FIRST_NAME, ANONYMOUS_USER_LAST_NAME, } from "@/shared/constants"; import { useImageSizeCheck } from "@/shared/hooks"; +import { Edit3Icon as EditIcon } from "@/shared/icons"; import { User } from "@/shared/models"; -import { Loader } from "@/shared/ui-kit"; +import { Loader, LoaderColor } from "@/shared/ui-kit"; import { getUserName } from "@/shared/utils"; import { UserDetailsPreview } from "./components"; import { validationSchema } from "./validationSchema"; @@ -231,28 +237,24 @@ const UserDetails: ForwardRefRenderFunction< userName={getUserName(values)} /> {isEditing && !isSubmitting ? ( -
- inputFile?.current && inputFile?.current?.click() - : undefined + !loading ? () => inputFile?.current?.click() : undefined } > {loading ? ( - - ) : ( - edit-avatar + ) : ( + )} -
+ ) : null} Date: Tue, 17 Oct 2023 11:58:24 +0300 Subject: [PATCH 18/39] update profile page edit form --- src/constants.scss | 1 + .../MyAccount/components/Profile/Profile.tsx | 9 +-- .../UserDetails/UserDetails.module.scss | 65 +++++++++++++------ .../components/UserDetails/UserDetails.tsx | 11 ++-- .../UserDetailsPreview.module.scss | 8 +++ .../UserDetailsPreview/UserDetailsPreview.tsx | 23 ++++--- .../MyAccount/components/Profile/index.scss | 45 ------------- src/shared/components/Dropdown/Dropdown.tsx | 8 ++- 8 files changed, 83 insertions(+), 87 deletions(-) diff --git a/src/constants.scss b/src/constants.scss index dd8fbd33f1..2afb37a95a 100644 --- a/src/constants.scss +++ b/src/constants.scss @@ -149,6 +149,7 @@ $c-gray-30: #b7bcd2; $c-gray-40: #8d91a9; $c-gray-50: #7a819c; $c-gray-60: #6b718e; +$c-gray-80: #2e3452; $c-gray-90: #1f2535; $c-gray-100: #131b23; $c-gray-800: #27292c; diff --git a/src/pages/MyAccount/components/Profile/Profile.tsx b/src/pages/MyAccount/components/Profile/Profile.tsx index d5f9547705..6d8004987a 100644 --- a/src/pages/MyAccount/components/Profile/Profile.tsx +++ b/src/pages/MyAccount/components/Profile/Profile.tsx @@ -99,16 +99,9 @@ const Profile: FC = (props) => { customSaveButton isCountryDropdownFixed={false} isEditing={isEditing} + isMobileView={isMobileView} onLoading={setIsSubmitting} onSubmitting={handleSubmittingChange} - styles={{ - avatar: "profile-wrapper__avatar", - userAvatar: "profile-wrapper__user-avatar", - editAvatar: "profile-wrapper__edit-avatar", - fieldContainer: "profile-wrapper__field-container", - introInputWrapper: - "profile-wrapper__form-intro-input-wrapper", - }} /> {isEditing && buttonsWrapperEl}
diff --git a/src/pages/MyAccount/components/Profile/components/UserDetails/UserDetails.module.scss b/src/pages/MyAccount/components/Profile/components/UserDetails/UserDetails.module.scss index 4cfd37f0c0..fad6607bd9 100644 --- a/src/pages/MyAccount/components/Profile/components/UserDetails/UserDetails.module.scss +++ b/src/pages/MyAccount/components/Profile/components/UserDetails/UserDetails.module.scss @@ -22,6 +22,11 @@ .previewWrapper { display: flex; align-items: flex-start; + + @include tablet { + flex-direction: column; + align-items: center; + } } .introWrapper { @@ -47,7 +52,10 @@ .avatar { position: relative; text-align: center; - margin-top: 1.5rem; + + @include tablet { + margin-bottom: 0.625rem; + } } .avatarInputFile { @@ -56,26 +64,31 @@ .userDetailsPreview { margin-left: 1rem; + + @include tablet { + margin-left: 0; + } } .userPhoto { - width: 4.125rem; - height: 4.125rem; + width: 6.25rem; + height: 6.25rem; border-radius: 50%; object-fit: cover; } .editAvatarButton { - width: 1.75rem; - height: 1.75rem; - background-color: $c-pink-mention; - border-radius: 50%; + position: absolute; + right: 0; + bottom: 0; + width: 2rem; + height: 2rem; display: flex; align-items: center; justify-content: center; - position: absolute; - top: 38px; - left: 52%; + background-color: $c-pink-mention; + border: 0.125rem solid $white; + border-radius: 50%; cursor: pointer; } @@ -92,8 +105,9 @@ .textFieldContainer { max-width: 100%; + margin-top: 2.25rem; display: grid; - gap: 0.5rem 1.75rem; + gap: 2rem 2.5rem; grid-auto-columns: minmax(0, 1fr); grid-template-areas: "firstName lastName" @@ -101,7 +115,6 @@ "intro intro"; @include tablet { - gap: 1.5rem 0; grid-template-areas: "firstName" "lastName" @@ -111,19 +124,30 @@ } } -.textField { +.textField, +.textareaTextField { width: 100%; text-align: left; z-index: 1; -} -.textFieldLabelWrapper { - font-size: $xsmall; -} + .textFieldLabelWrapper { + @include body-sm-regular; -.textFieldInput { - padding-left: 0.75rem; - padding-right: 0.875rem; + color: $c-gray-80; + } + + .textFieldInput { + padding-left: 0.75rem; + padding-right: 0.875rem; + } + + .introInputWrapper { + height: 100%; + + @include tablet { + height: 9rem; + } + } } .firstNameTextField { @@ -139,6 +163,7 @@ } .countryTextField { + z-index: 2; grid-area: country; } diff --git a/src/pages/MyAccount/components/Profile/components/UserDetails/UserDetails.tsx b/src/pages/MyAccount/components/Profile/components/UserDetails/UserDetails.tsx index 10141d1ff5..5ebf7158b5 100644 --- a/src/pages/MyAccount/components/Profile/components/UserDetails/UserDetails.tsx +++ b/src/pages/MyAccount/components/Profile/components/UserDetails/UserDetails.tsx @@ -56,6 +56,7 @@ interface UserDetailsProps { customSaveButton?: boolean; isCountryDropdownFixed?: boolean; isEditing?: boolean; + isMobileView?: boolean; onLoading?: (isLoading: boolean) => void; onSubmitting?: (isSubmitting: boolean) => void; styles?: Styles; @@ -99,6 +100,7 @@ const UserDetails: ForwardRefRenderFunction< customSaveButton = false, isCountryDropdownFixed = true, isEditing = true, + isMobileView = false, styles: outerStyles, onLoading, onSubmitting, @@ -270,6 +272,7 @@ const UserDetails: ForwardRefRenderFunction< )}
@@ -291,7 +294,6 @@ const UserDetails: ForwardRefRenderFunction< id="firstName" name="firstName" label="First name" - isRequired styles={fieldStyles} /> = (props) => { - const { className, user } = props; + const { className, user, isMobileView = false } = props; const country = countryList.find((item) => item.value === user.country); const countryName = country && country.name.slice(0, country.name.lastIndexOf(" ")); @@ -20,14 +21,18 @@ const UserDetailsPreview: FC = (props) => {

{getUserName(user)}

{user.email &&

{user.email}

} -

- Join at{" "} - {formatDate( - new Date(user.createdAt.seconds * 1000), - DateFormat.SuperShortSecondary, - )} -

- {countryName &&

{countryName}

} + {!isMobileView && ( + <> +

+ Join at{" "} + {formatDate( + new Date(user.createdAt.seconds * 1000), + DateFormat.SuperShortSecondary, + )} +

+ {countryName &&

{countryName}

} + + )}
); }; diff --git a/src/pages/MyAccount/components/Profile/index.scss b/src/pages/MyAccount/components/Profile/index.scss index 7c75986c73..a5f0f137ac 100644 --- a/src/pages/MyAccount/components/Profile/index.scss +++ b/src/pages/MyAccount/components/Profile/index.scss @@ -23,51 +23,6 @@ margin-bottom: 1.375rem; } } - - .profile-wrapper__avatar { - margin: 0; - } - - .profile-wrapper__user-avatar { - width: 6.5rem; - height: 6.5rem; - margin-right: auto; - } - - .profile-wrapper__edit-avatar { - top: unset; - right: 0; - bottom: 0; - left: unset; - width: 2rem; - height: 2rem; - border: 0.125rem solid $white; - } - - .profile-wrapper__field-container { - gap: 2rem 2.5rem; - grid-template-areas: - "firstName country" - "lastName intro" - "email intro"; - - @include tablet { - grid-template-areas: - "firstName" - "lastName" - "email" - "country" - "intro"; - } - } - - .profile-wrapper__form-intro-input-wrapper { - height: 100%; - - @include tablet { - height: 9rem; - } - } } .profile-wrapper__delete-account-button { diff --git a/src/shared/components/Dropdown/Dropdown.tsx b/src/shared/components/Dropdown/Dropdown.tsx index 019f1f1303..68e0b0d4a0 100644 --- a/src/shared/components/Dropdown/Dropdown.tsx +++ b/src/shared/components/Dropdown/Dropdown.tsx @@ -27,6 +27,7 @@ import { GlobalOverlay } from "../GlobalOverlay"; import "./index.scss"; export interface Styles { + labelWrapper?: string; menuButton?: string; value?: string; placeholder?: string; @@ -205,7 +206,12 @@ const Dropdown: ForwardRefRenderFunction = ( onMenuToggle={handleMenuToggle} > {label && ( -
+
{label}
)} From 14b76b00f22d92d46dd4b8b32dd407a75a9112cd Mon Sep 17 00:00:00 2001 From: Andrey Mikhadyuk Date: Tue, 17 Oct 2023 12:30:56 +0300 Subject: [PATCH 19/39] create light pink button variant --- src/shared/ui-kit/Button/Button.module.scss | 19 +++++++++++++++++++ src/shared/ui-kit/Button/Button.tsx | 2 ++ 2 files changed, 21 insertions(+) diff --git a/src/shared/ui-kit/Button/Button.module.scss b/src/shared/ui-kit/Button/Button.module.scss index e77542eb27..cfc8e566a7 100644 --- a/src/shared/ui-kit/Button/Button.module.scss +++ b/src/shared/ui-kit/Button/Button.module.scss @@ -161,6 +161,25 @@ } } +.buttonLightPinkVariant { + --btn-color: #{$c-pink-mention}; + --btn-bg-color: #{$c-pink-active-feed-cards-light}; + --btn-border-color: none; + --btn-border: 0; + + &:hover { + --btn-bg-color: #{$c-pink-hover-feed-cards}; + } + + &:active { + --btn-bg-color: #{$c-pink-active-btn}; + } + + &.buttonDisabled { + --btn-bg-color: #{$c-gray-10}; + } +} + .buttonOutlineBlueVariant { --btn-color: #{$c-primary-400}; --btn-bg-color: #{$c-primary-100}; diff --git a/src/shared/ui-kit/Button/Button.tsx b/src/shared/ui-kit/Button/Button.tsx index 554a4a0d61..846e7132c7 100644 --- a/src/shared/ui-kit/Button/Button.tsx +++ b/src/shared/ui-kit/Button/Button.tsx @@ -17,6 +17,7 @@ export enum ButtonVariant { PrimaryPurple = "primary-purple", PrimaryPink = "primary-pink", LightPurple = "light-purple", + LightPink = "light-pink", OutlineBlue = "outline-blue", OutlinePink = "outline-pink", OutlineDarkPink = "outline-dark-pink", @@ -60,6 +61,7 @@ const Button: ForwardRefRenderFunction = ( variant === ButtonVariant.PrimaryPurple, [styles.buttonPrimaryPinkVariant]: variant === ButtonVariant.PrimaryPink, [styles.buttonLightPurpleVariant]: variant === ButtonVariant.LightPurple, + [styles.buttonLightPinkVariant]: variant === ButtonVariant.LightPink, [styles.buttonOutlineBlueVariant]: variant === ButtonVariant.OutlineBlue, [styles.buttonOutlinePinkVariant]: variant === ButtonVariant.OutlinePink, [styles.buttonOutlineDarkPinkVariant]: From 5e18e6faf04724cba326a3e3e3392469a781f601 Mon Sep 17 00:00:00 2001 From: Andrey Mikhadyuk Date: Tue, 17 Oct 2023 12:33:10 +0300 Subject: [PATCH 20/39] add edit profile button to profile preview --- .../MyAccount/components/Profile/Profile.tsx | 1 + .../UserDetails/UserDetails.module.scss | 9 +++++ .../components/UserDetails/UserDetails.tsx | 39 +++++++++++++------ 3 files changed, 37 insertions(+), 12 deletions(-) diff --git a/src/pages/MyAccount/components/Profile/Profile.tsx b/src/pages/MyAccount/components/Profile/Profile.tsx index 6d8004987a..cac53999a6 100644 --- a/src/pages/MyAccount/components/Profile/Profile.tsx +++ b/src/pages/MyAccount/components/Profile/Profile.tsx @@ -100,6 +100,7 @@ const Profile: FC = (props) => { isCountryDropdownFixed={false} isEditing={isEditing} isMobileView={isMobileView} + onEdit={handleEditClick} onLoading={setIsSubmitting} onSubmitting={handleSubmittingChange} /> diff --git a/src/pages/MyAccount/components/Profile/components/UserDetails/UserDetails.module.scss b/src/pages/MyAccount/components/Profile/components/UserDetails/UserDetails.module.scss index fad6607bd9..19cba74edc 100644 --- a/src/pages/MyAccount/components/Profile/components/UserDetails/UserDetails.module.scss +++ b/src/pages/MyAccount/components/Profile/components/UserDetails/UserDetails.module.scss @@ -70,6 +70,15 @@ } } +.editProfileButton { + --btn-h: 1.5rem; + --btn-pl: 0.25rem; + --btn-pr: 0.25rem; + + margin-top: 0.25rem; + font-weight: 500; +} + .userPhoto { width: 6.25rem; height: 6.25rem; diff --git a/src/pages/MyAccount/components/Profile/components/UserDetails/UserDetails.tsx b/src/pages/MyAccount/components/Profile/components/UserDetails/UserDetails.tsx index 5ebf7158b5..863c7657c2 100644 --- a/src/pages/MyAccount/components/Profile/components/UserDetails/UserDetails.tsx +++ b/src/pages/MyAccount/components/Profile/components/UserDetails/UserDetails.tsx @@ -15,12 +15,7 @@ import { FormikProps } from "formik/dist/types"; import { updateUserDetails } from "@/pages/Auth/store/actions"; import { uploadImage } from "@/pages/Auth/store/saga"; import { countryList } from "@/shared/assets/countries"; -import { - Button, - ButtonIcon, - DropdownOption, - UserAvatar, -} from "@/shared/components"; +import { ButtonIcon, DropdownOption, UserAvatar } from "@/shared/components"; import { Form, Dropdown, TextField } from "@/shared/components/Form/Formik"; import { ANONYMOUS_USER_FIRST_NAME, @@ -29,7 +24,13 @@ import { import { useImageSizeCheck } from "@/shared/hooks"; import { Edit3Icon as EditIcon } from "@/shared/icons"; import { User } from "@/shared/models"; -import { Loader, LoaderColor } from "@/shared/ui-kit"; +import { + Button, + ButtonSize, + ButtonVariant, + Loader, + LoaderColor, +} from "@/shared/ui-kit"; import { getUserName } from "@/shared/utils"; import { UserDetailsPreview } from "./components"; import { validationSchema } from "./validationSchema"; @@ -57,6 +58,7 @@ interface UserDetailsProps { isCountryDropdownFixed?: boolean; isEditing?: boolean; isMobileView?: boolean; + onEdit: () => void; onLoading?: (isLoading: boolean) => void; onSubmitting?: (isSubmitting: boolean) => void; styles?: Styles; @@ -102,6 +104,7 @@ const UserDetails: ForwardRefRenderFunction< isEditing = true, isMobileView = false, styles: outerStyles, + onEdit, onLoading, onSubmitting, } = props; @@ -269,11 +272,23 @@ const UserDetails: ForwardRefRenderFunction< />
{!isEditing && ( - + <> + + {isMobileView && ( + + )} + )}
{!isEditing && user.intro && ( From 5276f53dc8c51894b923a0c077e60bbfa5c46aee Mon Sep 17 00:00:00 2001 From: Pavel Meyer Date: Tue, 17 Oct 2023 13:37:46 +0300 Subject: [PATCH 21/39] CW-Webview Changed path to inbox --- .../App/handlers/WebViewLoginHandler/WebViewLoginHandler.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pages/App/handlers/WebViewLoginHandler/WebViewLoginHandler.tsx b/src/pages/App/handlers/WebViewLoginHandler/WebViewLoginHandler.tsx index d3f1aac2e3..3a293f7004 100644 --- a/src/pages/App/handlers/WebViewLoginHandler/WebViewLoginHandler.tsx +++ b/src/pages/App/handlers/WebViewLoginHandler/WebViewLoginHandler.tsx @@ -4,7 +4,7 @@ import { webviewLogin } from "@/pages/Auth/store/actions"; import { history } from "@/shared/appConfig"; import { WebviewActions } from "@/shared/constants"; import { FirebaseCredentials } from "@/shared/interfaces/FirebaseCredentials"; -import { getInboxPagePath_v04 } from "@/shared/utils"; +import { getInboxPagePath } from "@/shared/utils"; import { parseJson } from "@/shared/utils/json"; const WebViewLoginHandler: FC = () => { @@ -25,7 +25,7 @@ const WebViewLoginHandler: FC = () => { window.ReactNativeWebView.postMessage( WebviewActions.loginSuccess, ); - history.push(getInboxPagePath_v04()); + history.push(getInboxPagePath()); } else { window.ReactNativeWebView.postMessage(WebviewActions.loginError); } From 706c3cdbc9a3e04566eea92d379d41cc419ba0de Mon Sep 17 00:00:00 2001 From: Andrey Mikhadyuk Date: Tue, 17 Oct 2023 12:44:38 +0300 Subject: [PATCH 22/39] update profile form on mobile --- .../components/Profile/Profile.module.scss | 35 ++++++++++++++++ .../MyAccount/components/Profile/Profile.tsx | 10 ++--- .../UserDetails/UserDetails.module.scss | 36 +++++++++++------ .../components/UserDetails/UserDetails.tsx | 40 +++++++++++-------- .../MyAccount/components/Profile/index.scss | 30 -------------- 5 files changed, 86 insertions(+), 65 deletions(-) delete mode 100644 src/pages/MyAccount/components/Profile/index.scss diff --git a/src/pages/MyAccount/components/Profile/Profile.module.scss b/src/pages/MyAccount/components/Profile/Profile.module.scss index 20ec36bfc2..dd4e764f0d 100644 --- a/src/pages/MyAccount/components/Profile/Profile.module.scss +++ b/src/pages/MyAccount/components/Profile/Profile.module.scss @@ -1,4 +1,5 @@ @import "../../../../constants"; +@import "../../../../styles/mixins"; @import "../../../../styles/sizes"; .container { @@ -6,6 +7,17 @@ width: 100%; } +.content { + max-width: 36.25rem; + width: 100%; + margin: 0 auto; + padding-top: 3.375rem; + + @include tablet { + padding-top: 0; + } +} + .header { margin-bottom: 2.25rem; @@ -37,6 +49,14 @@ } } +.userDetails { + margin-bottom: 2.25rem; + + @include tablet { + margin-bottom: 0; + } +} + .menuButtonsWrapper { border-top: 0.0625rem solid $c-gray-20; } @@ -48,3 +68,18 @@ .logoutMenuButton { color: $c-pink-mention; } + +.buttonsWrapper { + @include flex-list-with-gap(1rem); + + @include tablet { + width: 100%; + margin: 1.5rem 0 0; + flex-direction: column-reverse; + box-sizing: border-box; + + & > * { + margin: 0 0 1rem; + } + } +} diff --git a/src/pages/MyAccount/components/Profile/Profile.tsx b/src/pages/MyAccount/components/Profile/Profile.tsx index cac53999a6..d0ffbcafb6 100644 --- a/src/pages/MyAccount/components/Profile/Profile.tsx +++ b/src/pages/MyAccount/components/Profile/Profile.tsx @@ -9,7 +9,6 @@ import { Edit3Icon as EditIcon, LogoutIcon } from "@/shared/icons"; import { Button, ButtonVariant } from "@/shared/ui-kit"; import { Header, MenuButton, UserDetails, UserDetailsRef } from "./components"; import styles from "./Profile.module.scss"; -import "./index.scss"; interface ProfileProps { onEditingChange?: (isEditing: boolean) => void; @@ -55,7 +54,7 @@ const Profile: FC = (props) => { }; const buttonsWrapperEl = ( -
+
); @@ -81,7 +80,7 @@ const Profile: FC = (props) => { return (
{!isMobileView && !isEditing && editButtonEl} -
+
= (props) => {
void; - customSaveButton?: boolean; isCountryDropdownFixed?: boolean; isEditing?: boolean; isMobileView?: boolean; @@ -99,7 +98,6 @@ const UserDetails: ForwardRefRenderFunction< user, isNewUser = false, closeModal, - customSaveButton = false, isCountryDropdownFixed = true, isEditing = true, isMobileView = false, @@ -188,6 +186,12 @@ const UserDetails: ForwardRefRenderFunction< [closeModal, dispatch, user, onSubmitting], ); + const handleAvatarEdit = () => { + if (!loading) { + inputFile?.current?.click(); + } + }; + useImperativeHandle( userDetailsRef, () => ({ @@ -241,15 +245,13 @@ const UserDetails: ForwardRefRenderFunction< nameForRandomAvatar={values.email} userName={getUserName(values)} /> - {isEditing && !isSubmitting ? ( + {isEditing && !isSubmitting && !isMobileView && ( inputFile?.current?.click() : undefined - } + onClick={handleAvatarEdit} > {loading ? ( )} - ) : null} + )} + {isEditing && + !isSubmitting && + isMobileView && + (!loading ? ( + + ) : ( + + ))}
)} - {!customSaveButton && ( - - )} )} diff --git a/src/pages/MyAccount/components/Profile/index.scss b/src/pages/MyAccount/components/Profile/index.scss deleted file mode 100644 index a5f0f137ac..0000000000 --- a/src/pages/MyAccount/components/Profile/index.scss +++ /dev/null @@ -1,30 +0,0 @@ -@import "../../../../constants"; -@import "../../../../styles/mixins"; -@import "../../../../styles/sizes"; - -.profile-wrapper { - max-width: 36.25rem; - width: 100%; - margin: 0 auto; - padding-top: 3.375rem; - - @include tablet { - padding-top: 0; - } - - .profile-wrapper__buttons-wrapper { - @include flex-list-with-gap(1rem); - } - - .profile-wrapper__user-details { - margin-bottom: 2.125rem; - - @include tablet { - margin-bottom: 1.375rem; - } - } -} - -.profile-wrapper__delete-account-button { - margin-top: 1.5rem; -} From d8310cc9f34b243b82539bc56bd3a2638954db5e Mon Sep 17 00:00:00 2001 From: Andrey Mikhadyuk Date: Tue, 17 Oct 2023 14:39:06 +0300 Subject: [PATCH 23/39] add "required" info to common image label --- .../ProjectCreationForm.tsx | 8 +++++-- .../ProjectCreationForm/configuration.ts | 21 +++++++++++++------ .../commonCreation/hooks/useCommonForm.ts | 6 +++++- 3 files changed, 26 insertions(+), 9 deletions(-) diff --git a/src/pages/commonCreation/components/ProjectCreation/components/ProjectCreationForm/ProjectCreationForm.tsx b/src/pages/commonCreation/components/ProjectCreation/components/ProjectCreationForm/ProjectCreationForm.tsx index 79c91d8e78..ebca1317b8 100644 --- a/src/pages/commonCreation/components/ProjectCreation/components/ProjectCreationForm/ProjectCreationForm.tsx +++ b/src/pages/commonCreation/components/ProjectCreation/components/ProjectCreationForm/ProjectCreationForm.tsx @@ -178,8 +178,12 @@ const ProjectCreationForm: FC = (props) => { ref={formRef} initialValues={initialValues} onSubmit={isEditing ? handleProjectUpdate : handleProjectCreate} - items={getConfiguration(true, roles, { - existingNames: existingProjectsNames, + items={getConfiguration({ + isProject: true, + roles, + shouldBeUnique: { + existingNames: existingProjectsNames, + }, })} submitButtonText={isEditing ? "Save changes" : "Create Space"} disabled={isLoading} diff --git a/src/pages/commonCreation/components/ProjectCreation/components/ProjectCreationForm/configuration.ts b/src/pages/commonCreation/components/ProjectCreation/components/ProjectCreationForm/configuration.ts index 118bedcf33..d18f9938db 100644 --- a/src/pages/commonCreation/components/ProjectCreation/components/ProjectCreationForm/configuration.ts +++ b/src/pages/commonCreation/components/ProjectCreation/components/ProjectCreationForm/configuration.ts @@ -9,11 +9,20 @@ import { } from "../../constants"; import styles from "./ProjectCreationForm.module.scss"; -export const getConfiguration = ( - isProject = true, - roles?: Roles, - shouldBeUnique?: { existingNames: string[] }, -): CreationFormItem[] => { +interface Options { + isProject: boolean; + roles?: Roles; + shouldBeUnique?: { existingNames: string[] }; + isImageRequired?: boolean; +} + +export const getConfiguration = (options: Options): CreationFormItem[] => { + const { + isProject = true, + roles, + shouldBeUnique, + isImageRequired = false, + } = options; const type = isProject ? "Space" : "Common"; const items: CreationFormItem[] = [ @@ -22,7 +31,7 @@ export const getConfiguration = ( className: styles.projectImages, props: { name: "projectImages", - label: `${type} picture`, + label: `${type} picture${isImageRequired ? " (required)" : ""}`, maxImagesAmount: 1, }, }, diff --git a/src/pages/commonCreation/hooks/useCommonForm.ts b/src/pages/commonCreation/hooks/useCommonForm.ts index 18ed453a27..c614e73d1f 100644 --- a/src/pages/commonCreation/hooks/useCommonForm.ts +++ b/src/pages/commonCreation/hooks/useCommonForm.ts @@ -76,6 +76,10 @@ export const useCommonForm = ( return { initialValues, onSubmit, - formItems: getConfiguration(false, roles), + formItems: getConfiguration({ + isProject: false, + roles, + isImageRequired: true, + }), }; }; From 98d1a1432a04cd8cfcc3837a7b4b6df6c192a77d Mon Sep 17 00:00:00 2001 From: Andrey Mikhadyuk Date: Tue, 17 Oct 2023 14:47:06 +0300 Subject: [PATCH 24/39] add validation message to the common picture form item --- .../components/ProjectCreationForm/configuration.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/pages/commonCreation/components/ProjectCreation/components/ProjectCreationForm/configuration.ts b/src/pages/commonCreation/components/ProjectCreation/components/ProjectCreationForm/configuration.ts index d18f9938db..85064ac204 100644 --- a/src/pages/commonCreation/components/ProjectCreation/components/ProjectCreationForm/configuration.ts +++ b/src/pages/commonCreation/components/ProjectCreation/components/ProjectCreationForm/configuration.ts @@ -34,6 +34,14 @@ export const getConfiguration = (options: Options): CreationFormItem[] => { label: `${type} picture${isImageRequired ? " (required)" : ""}`, maxImagesAmount: 1, }, + validation: isImageRequired + ? { + min: { + value: 1, + message: `${type} picture is required`, + }, + } + : undefined, }, { type: CreationFormItemType.TextField, From 5f7b7dced32f96ed4cf856ab2fcee7fcb30aca68 Mon Sep 17 00:00:00 2001 From: Andrey Mikhadyuk Date: Tue, 17 Oct 2023 15:40:49 +0300 Subject: [PATCH 25/39] add `lastActivity` field to `Common` model --- src/shared/models/Common.tsx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/shared/models/Common.tsx b/src/shared/models/Common.tsx index c03ad4ca19..31989caa75 100644 --- a/src/shared/models/Common.tsx +++ b/src/shared/models/Common.tsx @@ -4,6 +4,7 @@ import { Discussion } from "./Discussion"; import { DiscussionMessage } from "./DiscussionMessage"; import { PaymentAmount } from "./Payment"; import { Proposal } from "./Proposals"; +import { Timestamp } from "./Timestamp"; import { User } from "./User"; import { AllowedActions, @@ -119,6 +120,8 @@ export interface Common extends BaseEntity { hasPublicItems: boolean; rootCommonId?: string; + + lastActivity?: Timestamp; } export interface Project extends Common { From 1e5006057027608c87398c52cd00eb17b2f83674 Mon Sep 17 00:00:00 2001 From: Andrey Mikhadyuk Date: Tue, 17 Oct 2023 15:58:05 +0300 Subject: [PATCH 26/39] sort breadcrumbs items by name --- src/shared/utils/index.tsx | 1 + src/shared/utils/sortProjectsStateItemsByName.ts | 9 +++++++++ src/store/states/multipleSpacesLayout/reducer.ts | 16 ++++++++++++++++ 3 files changed, 26 insertions(+) create mode 100644 src/shared/utils/sortProjectsStateItemsByName.ts diff --git a/src/shared/utils/index.tsx b/src/shared/utils/index.tsx index dbf698daac..2b5eb09b4c 100755 --- a/src/shared/utils/index.tsx +++ b/src/shared/utils/index.tsx @@ -29,6 +29,7 @@ export * from "./circles"; export * from "./notifications"; export * from "./getFirebaseToken"; export * from "./sidenav"; +export * from "./sortProjectsStateItemsByName"; export * from "./text"; export * from "./hasPermission"; export * from "./getProjectCircleDefinition"; diff --git a/src/shared/utils/sortProjectsStateItemsByName.ts b/src/shared/utils/sortProjectsStateItemsByName.ts new file mode 100644 index 0000000000..00bb29d76b --- /dev/null +++ b/src/shared/utils/sortProjectsStateItemsByName.ts @@ -0,0 +1,9 @@ +import { ProjectsStateItem } from "@/store/states"; + +export const sortProjectsStateItemsByName = ( + items: ProjectsStateItem[], +): ProjectsStateItem[] => { + return [...items].sort((prevItem, nextItem) => + prevItem.name < nextItem.name ? -1 : 1, + ); +}; diff --git a/src/store/states/multipleSpacesLayout/reducer.ts b/src/store/states/multipleSpacesLayout/reducer.ts index 347ae0914f..76e58b8a13 100644 --- a/src/store/states/multipleSpacesLayout/reducer.ts +++ b/src/store/states/multipleSpacesLayout/reducer.ts @@ -3,6 +3,7 @@ import { WritableDraft } from "immer/dist/types/types-external"; import { cloneDeep } from "lodash"; import { ActionType, createReducer } from "typesafe-actions"; import { InboxItemType } from "@/shared/constants"; +import { sortProjectsStateItemsByName } from "@/shared/utils"; import * as actions from "./actions"; import { MultipleSpacesLayoutState, ProjectsStateItem } from "./types"; @@ -35,6 +36,16 @@ const updateProjectInBreadcrumbs = ( } }; +const sortBreadcrumbsItems = ( + state: WritableDraft, +) => { + if (state.breadcrumbs?.type === InboxItemType.FeedItemFollow) { + state.breadcrumbs.items = sortProjectsStateItemsByName( + state.breadcrumbs.items, + ); + } +}; + export const reducer = createReducer( initialState, ) @@ -44,6 +55,7 @@ export const reducer = createReducer( .handleAction(actions.setBreadcrumbsData, (state, { payload }) => produce(state, (nextState) => { nextState.breadcrumbs = payload && { ...payload }; + sortBreadcrumbsItems(nextState); }), ) .handleAction(actions.moveBreadcrumbsToPrevious, (state) => @@ -70,11 +82,15 @@ export const reducer = createReducer( nextState.breadcrumbs.items = nextState.breadcrumbs.items.concat(payload); } + + sortBreadcrumbsItems(nextState); }), ) .handleAction(actions.updateProjectInBreadcrumbs, (state, { payload }) => produce(state, (nextState) => { updateProjectInBreadcrumbs(nextState, payload); + + sortBreadcrumbsItems(nextState); }), ) .handleAction(actions.setBackUrl, (state, { payload }) => From 8e8385bea5a45de28e5c0fc08e55a0acc355c1ab Mon Sep 17 00:00:00 2001 From: Roie Natan Date: Tue, 17 Oct 2023 14:29:59 +0100 Subject: [PATCH 27/39] . --- .../components/ChatContent/ChatContent.tsx | 15 ++++++++++++++- .../components/FeedLayout/FeedLayout.tsx | 4 ++-- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/src/pages/common/components/ChatComponent/components/ChatContent/ChatContent.tsx b/src/pages/common/components/ChatComponent/components/ChatContent/ChatContent.tsx index f8775030d4..3cce86ea79 100644 --- a/src/pages/common/components/ChatComponent/components/ChatContent/ChatContent.tsx +++ b/src/pages/common/components/ChatComponent/components/ChatContent/ChatContent.tsx @@ -17,7 +17,7 @@ import { LOADER_APPEARANCE_DELAY, QueryParamKey, } from "@/shared/constants"; -import { useQueryParams } from "@/shared/hooks"; +import { useForceUpdate, useQueryParams } from "@/shared/hooks"; import { checkIsUserDiscussionMessage, CommonFeedObjectUserUnique, @@ -97,6 +97,19 @@ const ChatContent: ForwardRefRenderFunction< const userId = user?.uid; const queryParams = useQueryParams(); const messageIdParam = queryParams[QueryParamKey.Message]; + const forceUpdate = useForceUpdate(); + + useEffect(() => { + if (messages) { + console.log(messages); + forceUpdate(); + } + + if (dateList) { + console.log(dateList); + forceUpdate(); + } + }, [messages, dateList]); const [highlightedMessageId, setHighlightedMessageId] = useState( () => (typeof messageIdParam === "string" && messageIdParam) || null, diff --git a/src/pages/commonFeed/components/FeedLayout/FeedLayout.tsx b/src/pages/commonFeed/components/FeedLayout/FeedLayout.tsx index 7659be87c5..b320084497 100644 --- a/src/pages/commonFeed/components/FeedLayout/FeedLayout.tsx +++ b/src/pages/commonFeed/components/FeedLayout/FeedLayout.tsx @@ -644,7 +644,7 @@ const FeedLayout: ForwardRefRenderFunction = ( isLoading={loading} loaderDelay={LOADER_APPEARANCE_DELAY} > - {allFeedItems?.map((item, index) => { + {allFeedItems?.map((item) => { const isActive = item.itemId === activeFeedItemId; if (checkIsFeedItemFollowLayoutItem(item)) { @@ -662,7 +662,7 @@ const FeedLayout: ForwardRefRenderFunction = ( ref={(ref) => { refsByItemId.current[item.itemId] = ref; }} - key={item.feedItem.id + index} + key={item.feedItem.id} commonMember={commonMember} commonId={commonData?.id} commonName={commonData?.name || ""} From f99962960733d4a70cd843ec0b98a35950e26a84 Mon Sep 17 00:00:00 2001 From: Roie Natan Date: Tue, 17 Oct 2023 14:35:40 +0100 Subject: [PATCH 28/39] . --- .../ChatComponent/components/ChatContent/ChatContent.tsx | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/pages/common/components/ChatComponent/components/ChatContent/ChatContent.tsx b/src/pages/common/components/ChatComponent/components/ChatContent/ChatContent.tsx index 3cce86ea79..17c3d6c60a 100644 --- a/src/pages/common/components/ChatComponent/components/ChatContent/ChatContent.tsx +++ b/src/pages/common/components/ChatComponent/components/ChatContent/ChatContent.tsx @@ -101,15 +101,9 @@ const ChatContent: ForwardRefRenderFunction< useEffect(() => { if (messages) { - console.log(messages); forceUpdate(); } - - if (dateList) { - console.log(dateList); - forceUpdate(); - } - }, [messages, dateList]); + }, [messages]); const [highlightedMessageId, setHighlightedMessageId] = useState( () => (typeof messageIdParam === "string" && messageIdParam) || null, From 458a25a5181db7beb2f2af81f8b59469d773f458 Mon Sep 17 00:00:00 2001 From: Andrey Mikhadyuk Date: Tue, 17 Oct 2023 16:37:32 +0300 Subject: [PATCH 29/39] revert "sort breadcrumbs items by name" This reverts commit 1e500605 --- src/shared/utils/index.tsx | 1 - src/shared/utils/sortProjectsStateItemsByName.ts | 9 --------- src/store/states/multipleSpacesLayout/reducer.ts | 16 ---------------- 3 files changed, 26 deletions(-) delete mode 100644 src/shared/utils/sortProjectsStateItemsByName.ts diff --git a/src/shared/utils/index.tsx b/src/shared/utils/index.tsx index 2b5eb09b4c..dbf698daac 100755 --- a/src/shared/utils/index.tsx +++ b/src/shared/utils/index.tsx @@ -29,7 +29,6 @@ export * from "./circles"; export * from "./notifications"; export * from "./getFirebaseToken"; export * from "./sidenav"; -export * from "./sortProjectsStateItemsByName"; export * from "./text"; export * from "./hasPermission"; export * from "./getProjectCircleDefinition"; diff --git a/src/shared/utils/sortProjectsStateItemsByName.ts b/src/shared/utils/sortProjectsStateItemsByName.ts deleted file mode 100644 index 00bb29d76b..0000000000 --- a/src/shared/utils/sortProjectsStateItemsByName.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { ProjectsStateItem } from "@/store/states"; - -export const sortProjectsStateItemsByName = ( - items: ProjectsStateItem[], -): ProjectsStateItem[] => { - return [...items].sort((prevItem, nextItem) => - prevItem.name < nextItem.name ? -1 : 1, - ); -}; diff --git a/src/store/states/multipleSpacesLayout/reducer.ts b/src/store/states/multipleSpacesLayout/reducer.ts index 76e58b8a13..347ae0914f 100644 --- a/src/store/states/multipleSpacesLayout/reducer.ts +++ b/src/store/states/multipleSpacesLayout/reducer.ts @@ -3,7 +3,6 @@ import { WritableDraft } from "immer/dist/types/types-external"; import { cloneDeep } from "lodash"; import { ActionType, createReducer } from "typesafe-actions"; import { InboxItemType } from "@/shared/constants"; -import { sortProjectsStateItemsByName } from "@/shared/utils"; import * as actions from "./actions"; import { MultipleSpacesLayoutState, ProjectsStateItem } from "./types"; @@ -36,16 +35,6 @@ const updateProjectInBreadcrumbs = ( } }; -const sortBreadcrumbsItems = ( - state: WritableDraft, -) => { - if (state.breadcrumbs?.type === InboxItemType.FeedItemFollow) { - state.breadcrumbs.items = sortProjectsStateItemsByName( - state.breadcrumbs.items, - ); - } -}; - export const reducer = createReducer( initialState, ) @@ -55,7 +44,6 @@ export const reducer = createReducer( .handleAction(actions.setBreadcrumbsData, (state, { payload }) => produce(state, (nextState) => { nextState.breadcrumbs = payload && { ...payload }; - sortBreadcrumbsItems(nextState); }), ) .handleAction(actions.moveBreadcrumbsToPrevious, (state) => @@ -82,15 +70,11 @@ export const reducer = createReducer( nextState.breadcrumbs.items = nextState.breadcrumbs.items.concat(payload); } - - sortBreadcrumbsItems(nextState); }), ) .handleAction(actions.updateProjectInBreadcrumbs, (state, { payload }) => produce(state, (nextState) => { updateProjectInBreadcrumbs(nextState, payload); - - sortBreadcrumbsItems(nextState); }), ) .handleAction(actions.setBackUrl, (state, { payload }) => From 5a025240c6e072aee4a4f4b4a0b7f357efdd9f2c Mon Sep 17 00:00:00 2001 From: Andrey Mikhadyuk Date: Tue, 17 Oct 2023 16:43:39 +0300 Subject: [PATCH 30/39] add breadcrumbs sorting by lastActivity --- .../saga/fetchBreadcrumbsItemsByCommonId.ts | 20 +++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/store/states/multipleSpacesLayout/saga/fetchBreadcrumbsItemsByCommonId.ts b/src/store/states/multipleSpacesLayout/saga/fetchBreadcrumbsItemsByCommonId.ts index b505658868..187b0b5488 100644 --- a/src/store/states/multipleSpacesLayout/saga/fetchBreadcrumbsItemsByCommonId.ts +++ b/src/store/states/multipleSpacesLayout/saga/fetchBreadcrumbsItemsByCommonId.ts @@ -102,16 +102,28 @@ export function* fetchBreadcrumbsItemsByCommonId( commonId, user?.uid, )) as Awaited>; - const projectsData: ProjectsStateItem[] = projectsInfo.map( - ({ common, hasMembership, hasPermissionToAddProject }) => ({ + const projectsData: ProjectsStateItem[] = [...projectsInfo] + .sort((prevItem, nextItem) => { + if (!nextItem.common.lastActivity) { + return -1; + } + if (!prevItem.common.lastActivity) { + return 1; + } + + return ( + nextItem.common.lastActivity.seconds - + prevItem.common.lastActivity.seconds + ); + }) + .map(({ common, hasMembership, hasPermissionToAddProject }) => ({ commonId: common.id, image: common.image, name: common.name, directParent: common.directParent, hasMembership, hasPermissionToAddProject, - }), - ); + })); const currentBreadcrumbs = (yield select( selectMultipleSpacesLayoutBreadcrumbs, From 14b3118243e1f28f7615ce325e7aa21c191e7447 Mon Sep 17 00:00:00 2001 From: Roie Natan Date: Tue, 17 Oct 2023 15:00:46 +0100 Subject: [PATCH 31/39] change 'What do you think?' chat placeholder to 'Message' --- src/pages/common/components/ChatComponent/ChatComponent.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/common/components/ChatComponent/ChatComponent.tsx b/src/pages/common/components/ChatComponent/ChatComponent.tsx index 8bcb77ad89..918b8a7651 100644 --- a/src/pages/common/components/ChatComponent/ChatComponent.tsx +++ b/src/pages/common/components/ChatComponent/ChatComponent.tsx @@ -645,7 +645,7 @@ export default function ChatComponent({ }} value={message} onChange={setMessage} - placeholder="What do you think?" + placeholder="Message" onKeyDown={onEnterKeyDown} users={users} shouldReinitializeEditor={shouldReinitializeEditor} From 8fc2e831c255941cc9de9a58ad6b90f9c5596a65 Mon Sep 17 00:00:00 2001 From: Andrey Mikhadyuk Date: Tue, 17 Oct 2023 17:18:27 +0300 Subject: [PATCH 32/39] add commons sorting in the navigation dropdown --- .../utils/compareCommonsByLastActivity.ts | 15 +++++++++++++++ src/shared/utils/index.tsx | 1 + .../states/commonLayout/saga/getCommons.ts | 12 +++++++----- .../saga/fetchBreadcrumbsItemsByCommonId.ts | 17 ++++------------- 4 files changed, 27 insertions(+), 18 deletions(-) create mode 100644 src/shared/utils/compareCommonsByLastActivity.ts diff --git a/src/shared/utils/compareCommonsByLastActivity.ts b/src/shared/utils/compareCommonsByLastActivity.ts new file mode 100644 index 0000000000..2f21f85c19 --- /dev/null +++ b/src/shared/utils/compareCommonsByLastActivity.ts @@ -0,0 +1,15 @@ +import { Common } from "@/shared/models"; + +export const compareCommonsByLastActivity = ( + prevCommon: Common, + nextCommon: Common, +): number => { + if (!nextCommon.lastActivity) { + return -1; + } + if (!prevCommon.lastActivity) { + return 1; + } + + return nextCommon.lastActivity.seconds - prevCommon.lastActivity.seconds; +}; diff --git a/src/shared/utils/index.tsx b/src/shared/utils/index.tsx index dbf698daac..74e159b1d9 100755 --- a/src/shared/utils/index.tsx +++ b/src/shared/utils/index.tsx @@ -15,6 +15,7 @@ export * from "./parseLinksForSubmission"; export * from "./proposals"; export * from "./queryParams"; export { default as request } from "./request"; +export * from "./compareCommonsByLastActivity"; export * from "./convertDatesToFirestoreTimestamps"; export * from "./convertLinkToUploadFile"; export * from "./timeAgo"; diff --git a/src/store/states/commonLayout/saga/getCommons.ts b/src/store/states/commonLayout/saga/getCommons.ts index 08d44bd956..46e4efd778 100644 --- a/src/store/states/commonLayout/saga/getCommons.ts +++ b/src/store/states/commonLayout/saga/getCommons.ts @@ -3,7 +3,7 @@ import { selectUser } from "@/pages/Auth/store/selectors"; import { CommonService, GovernanceService, ProjectService } from "@/services"; import { Awaited } from "@/shared/interfaces"; import { User } from "@/shared/models"; -import { isError } from "@/shared/utils"; +import { compareCommonsByLastActivity, isError } from "@/shared/utils"; import { ProjectsStateItem } from "../../projects"; import * as actions from "../actions"; import { getPermissionsDataByAllUserCommonMemberInfo } from "./utils"; @@ -80,8 +80,11 @@ export function* getCommons( commonId, userId, )) as Awaited>; - const projectsData: ProjectsStateItem[] = data.map( - ({ common, hasMembership, hasPermissionToAddProject }) => ({ + const projectsData: ProjectsStateItem[] = [...data] + .sort((prevItem, nextItem) => + compareCommonsByLastActivity(prevItem.common, nextItem.common), + ) + .map(({ common, hasMembership, hasPermissionToAddProject }) => ({ commonId: common.id, image: common.image, name: common.name, @@ -89,8 +92,7 @@ export function* getCommons( hasMembership, hasPermissionToAddProject, notificationsAmount: 0, - }), - ); + })); yield put( actions.getCommons.success({ diff --git a/src/store/states/multipleSpacesLayout/saga/fetchBreadcrumbsItemsByCommonId.ts b/src/store/states/multipleSpacesLayout/saga/fetchBreadcrumbsItemsByCommonId.ts index 187b0b5488..ea01e5e933 100644 --- a/src/store/states/multipleSpacesLayout/saga/fetchBreadcrumbsItemsByCommonId.ts +++ b/src/store/states/multipleSpacesLayout/saga/fetchBreadcrumbsItemsByCommonId.ts @@ -4,6 +4,7 @@ import { CommonService, GovernanceService, ProjectService } from "@/services"; import { InboxItemType } from "@/shared/constants"; import { Awaited } from "@/shared/interfaces"; import { Common, User } from "@/shared/models"; +import { compareCommonsByLastActivity } from "@/shared/utils"; import { getPermissionsDataByAllUserCommonMemberInfo } from "../../commonLayout/saga/utils"; import * as actions from "../actions"; import { selectMultipleSpacesLayoutBreadcrumbs } from "../selectors"; @@ -103,19 +104,9 @@ export function* fetchBreadcrumbsItemsByCommonId( user?.uid, )) as Awaited>; const projectsData: ProjectsStateItem[] = [...projectsInfo] - .sort((prevItem, nextItem) => { - if (!nextItem.common.lastActivity) { - return -1; - } - if (!prevItem.common.lastActivity) { - return 1; - } - - return ( - nextItem.common.lastActivity.seconds - - prevItem.common.lastActivity.seconds - ); - }) + .sort((prevItem, nextItem) => + compareCommonsByLastActivity(prevItem.common, nextItem.common), + ) .map(({ common, hasMembership, hasPermissionToAddProject }) => ({ commonId: common.id, image: common.image, From 2a48891238ecb857c072eacae1a596a6a52ce243 Mon Sep 17 00:00:00 2001 From: Andrey Mikhadyuk Date: Tue, 17 Oct 2023 17:21:44 +0300 Subject: [PATCH 33/39] add projects sorting in the sidenav --- src/store/states/commonLayout/saga/getProjects.ts | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/store/states/commonLayout/saga/getProjects.ts b/src/store/states/commonLayout/saga/getProjects.ts index 978dfe64bb..1ea036ff11 100644 --- a/src/store/states/commonLayout/saga/getProjects.ts +++ b/src/store/states/commonLayout/saga/getProjects.ts @@ -3,7 +3,7 @@ import { selectUser } from "@/pages/Auth/store/selectors"; import { CommonService, GovernanceService, ProjectService } from "@/services"; import { Awaited } from "@/shared/interfaces"; import { User } from "@/shared/models"; -import { isError } from "@/shared/utils"; +import { compareCommonsByLastActivity, isError } from "@/shared/utils"; import { ProjectsStateItem } from "../../projects"; import * as actions from "../actions"; import { getPermissionsDataByAllUserCommonMemberInfo } from "./utils"; @@ -48,8 +48,11 @@ export function* getProjects( userCommonIds, permissionsData, ); - const projectsData: ProjectsStateItem[] = data.map( - ({ common, hasMembership, hasPermissionToAddProject }) => ({ + const projectsData: ProjectsStateItem[] = data + .sort((prevItem, nextItem) => + compareCommonsByLastActivity(prevItem.common, nextItem.common), + ) + .map(({ common, hasMembership, hasPermissionToAddProject }) => ({ commonId: common.id, image: common.image, name: common.name, @@ -57,8 +60,7 @@ export function* getProjects( hasMembership, hasPermissionToAddProject, notificationsAmount: 0, - }), - ); + })); yield put(actions.getProjects.success(projectsData)); } catch (error) { From 9651014d3cbda8fcd21263e6b36a30588cdf38a0 Mon Sep 17 00:00:00 2001 From: Andrey Mikhadyuk Date: Tue, 17 Oct 2023 17:27:00 +0300 Subject: [PATCH 34/39] added loader delay on mobile for feed --- src/pages/commonFeed/CommonFeed.tsx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/pages/commonFeed/CommonFeed.tsx b/src/pages/commonFeed/CommonFeed.tsx index 0da50b96fa..5f3c58f20d 100644 --- a/src/pages/commonFeed/CommonFeed.tsx +++ b/src/pages/commonFeed/CommonFeed.tsx @@ -29,7 +29,6 @@ import { useRoutesContext } from "@/shared/contexts"; import { useAuthorizedModal, useQueryParams } from "@/shared/hooks"; import { useCommonFeedItems, useUserCommonIds } from "@/shared/hooks/useCases"; import { useCommonPinnedFeedItems } from "@/shared/hooks/useCases/useCommonPinnedFeedItems"; -import { useIsTabletView } from "@/shared/hooks/viewport"; import { RightArrowThinIcon } from "@/shared/icons"; import { checkIsFeedItemFollowLayoutItem, @@ -92,7 +91,6 @@ const CommonFeedComponent: FC = (props) => { onActiveItemDataChange, } = props; const { getCommonPagePath, getProfilePagePath } = useRoutesContext(); - const isTabletView = useIsTabletView(); const queryParams = useQueryParams(); const dispatch = useDispatch(); const history = useHistory(); @@ -437,7 +435,7 @@ const CommonFeedComponent: FC = (props) => { <> {headerEl}
- +
From 8b8985309622a03c0e311d663d011854e5334e44 Mon Sep 17 00:00:00 2001 From: Andrey Mikhadyuk Date: Tue, 17 Oct 2023 17:59:42 +0300 Subject: [PATCH 35/39] revert "add projects sorting in the sidenav" This reverts commit 2a488912 --- src/store/states/commonLayout/saga/getProjects.ts | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/store/states/commonLayout/saga/getProjects.ts b/src/store/states/commonLayout/saga/getProjects.ts index 1ea036ff11..978dfe64bb 100644 --- a/src/store/states/commonLayout/saga/getProjects.ts +++ b/src/store/states/commonLayout/saga/getProjects.ts @@ -3,7 +3,7 @@ import { selectUser } from "@/pages/Auth/store/selectors"; import { CommonService, GovernanceService, ProjectService } from "@/services"; import { Awaited } from "@/shared/interfaces"; import { User } from "@/shared/models"; -import { compareCommonsByLastActivity, isError } from "@/shared/utils"; +import { isError } from "@/shared/utils"; import { ProjectsStateItem } from "../../projects"; import * as actions from "../actions"; import { getPermissionsDataByAllUserCommonMemberInfo } from "./utils"; @@ -48,11 +48,8 @@ export function* getProjects( userCommonIds, permissionsData, ); - const projectsData: ProjectsStateItem[] = data - .sort((prevItem, nextItem) => - compareCommonsByLastActivity(prevItem.common, nextItem.common), - ) - .map(({ common, hasMembership, hasPermissionToAddProject }) => ({ + const projectsData: ProjectsStateItem[] = data.map( + ({ common, hasMembership, hasPermissionToAddProject }) => ({ commonId: common.id, image: common.image, name: common.name, @@ -60,7 +57,8 @@ export function* getProjects( hasMembership, hasPermissionToAddProject, notificationsAmount: 0, - })); + }), + ); yield put(actions.getProjects.success(projectsData)); } catch (error) { From b19b381f245ba89b58ce76d24f5dfc711de97adb Mon Sep 17 00:00:00 2001 From: Kiryl Budnik Date: Wed, 18 Oct 2023 11:39:34 +0200 Subject: [PATCH 36/39] show project feed item counter even if nothing has been updated --- .../common/components/FeedItem/FeedItem.tsx | 12 +----------- .../ProjectFeedItem/ProjectFeedItem.tsx | 17 +++++++++-------- 2 files changed, 10 insertions(+), 19 deletions(-) diff --git a/src/pages/common/components/FeedItem/FeedItem.tsx b/src/pages/common/components/FeedItem/FeedItem.tsx index bafa9ab5eb..96b79f19fb 100644 --- a/src/pages/common/components/FeedItem/FeedItem.tsx +++ b/src/pages/common/components/FeedItem/FeedItem.tsx @@ -15,7 +15,6 @@ import { DiscussionFeedCard } from "../DiscussionFeedCard"; import { ProposalFeedCard } from "../ProposalFeedCard"; import { ProjectFeedItem } from "./components"; import { useFeedItemContext } from "./context"; -import { useFeedItemCounters } from "./hooks"; import { FeedItemRef } from "./types"; interface FeedItemProps { @@ -68,8 +67,6 @@ const FeedItem = forwardRef((props, ref) => { const { onFeedItemUpdate, getLastMessage, getNonAllowedItems, onUserSelect } = useFeedItemContext(); useFeedItemSubscription(item.id, commonId, onFeedItemUpdate); - const { projectUnreadStreamsCount, projectUnreadMessages } = - useFeedItemCounters(item.id, commonId); if ( shouldCheckItemVisibility && @@ -118,14 +115,7 @@ const FeedItem = forwardRef((props, ref) => { } if (item.data.type === CommonFeedType.Project) { - return ( - - ); + return ; } return null; diff --git a/src/pages/common/components/FeedItem/components/ProjectFeedItem/ProjectFeedItem.tsx b/src/pages/common/components/FeedItem/components/ProjectFeedItem/ProjectFeedItem.tsx index fdb107b579..ae282dc417 100644 --- a/src/pages/common/components/FeedItem/components/ProjectFeedItem/ProjectFeedItem.tsx +++ b/src/pages/common/components/FeedItem/components/ProjectFeedItem/ProjectFeedItem.tsx @@ -8,28 +8,29 @@ import { OpenIcon } from "@/shared/icons"; import { CommonFeed } from "@/shared/models"; import { CommonAvatar, parseStringToTextEditorValue } from "@/shared/ui-kit"; import { checkIsProject } from "@/shared/utils"; +import { useFeedItemCounters } from "../../hooks"; import styles from "./ProjectFeedItem.module.scss"; interface ProjectFeedItemProps { item: CommonFeed; isMobileVersion: boolean; - unreadStreamsCount?: number; - unreadMessages?: number; } export const ProjectFeedItem: FC = (props) => { - const { item, isMobileVersion, unreadStreamsCount, unreadMessages } = props; + const { item, isMobileVersion } = props; const history = useHistory(); const { getCommonPagePath } = useRoutesContext(); const { renderFeedItemBaseContent } = useFeedItemContext(); const { data: common, fetched: isCommonFetched, fetchCommon } = useCommon(); + const { + projectUnreadStreamsCount: unreadStreamsCount, + projectUnreadMessages: unreadMessages, + } = useFeedItemCounters(item.id, common?.directParent?.commonId); const commonId = item.data.id; const lastMessage = parseStringToTextEditorValue( - Number.isInteger(unreadStreamsCount) - ? `${unreadStreamsCount} updated stream${ - unreadStreamsCount === 1 ? "" : "s" - }` - : undefined, + `${unreadStreamsCount ?? 0} updated stream${ + unreadStreamsCount === 1 ? "" : "s" + }`, ); const isProject = checkIsProject(common); const titleEl = ( From 5df1ee6595b9992c2134910fb2843ed310ed5969 Mon Sep 17 00:00:00 2001 From: Kiryl Budnik Date: Wed, 18 Oct 2023 13:36:09 +0200 Subject: [PATCH 37/39] add follow space feature for v04 layout --- src/pages/commonFeed/CommonFeedPage_v04.tsx | 7 +- .../HeaderContent_v04.module.scss | 13 ++++ .../HeaderContent_v04/HeaderContent_v04.tsx | 67 +++++++++++-------- src/shared/utils/generateStaticShareLink.ts | 29 ++++++-- 4 files changed, 77 insertions(+), 39 deletions(-) diff --git a/src/pages/commonFeed/CommonFeedPage_v04.tsx b/src/pages/commonFeed/CommonFeedPage_v04.tsx index 4f4e0373ca..b0fc1ac089 100644 --- a/src/pages/commonFeed/CommonFeedPage_v04.tsx +++ b/src/pages/commonFeed/CommonFeedPage_v04.tsx @@ -1,7 +1,6 @@ import React, { FC } from "react"; import { RoutesV04Provider } from "@/shared/contexts"; import { CommonSidenavLayoutPageContent } from "@/shared/layouts"; -import { checkIsProject } from "@/shared/utils"; import BaseCommonFeedPage from "./BaseCommonFeedPage"; import { RenderCommonFeedContentWrapper } from "./CommonFeed"; import HeaderContent_v04 from "./components/HeaderContent_v04/HeaderContent_v04"; @@ -19,13 +18,9 @@ const renderContentWrapper: RenderCommonFeedContentWrapper = ({ headerClassName={styles.layoutHeader} headerContent={ } isGlobalLoading={!isGlobalDataFetched} diff --git a/src/pages/commonFeed/components/HeaderContent_v04/HeaderContent_v04.module.scss b/src/pages/commonFeed/components/HeaderContent_v04/HeaderContent_v04.module.scss index 90e0145540..7adfd958c3 100644 --- a/src/pages/commonFeed/components/HeaderContent_v04/HeaderContent_v04.module.scss +++ b/src/pages/commonFeed/components/HeaderContent_v04/HeaderContent_v04.module.scss @@ -12,6 +12,13 @@ } } +.actionsContainer { + display: flex; + flex-direction: row; + align-items: center; + gap: 16px; +} + .openSidenavButton { display: none; @@ -78,6 +85,12 @@ overflow: hidden; } +.commonMainInfoWrapper { + display: flex; + align-items: center; + column-gap: 8px; +} + .commonName { margin: 0; font-family: PoppinsSans, sans-serif; diff --git a/src/pages/commonFeed/components/HeaderContent_v04/HeaderContent_v04.tsx b/src/pages/commonFeed/components/HeaderContent_v04/HeaderContent_v04.tsx index adc058837a..bf4d0ea019 100644 --- a/src/pages/commonFeed/components/HeaderContent_v04/HeaderContent_v04.tsx +++ b/src/pages/commonFeed/components/HeaderContent_v04/HeaderContent_v04.tsx @@ -3,37 +3,36 @@ import { NavLink } from "react-router-dom"; import classNames from "classnames"; import { NewStreamButton } from "@/pages/common/components/CommonTabPanels/components/FeedTab/components"; import { useRoutesContext } from "@/shared/contexts"; +import { useCommonFollow } from "@/shared/hooks/useCases"; import { useIsTabletView } from "@/shared/hooks/viewport"; -import { RightArrowThinIcon } from "@/shared/icons"; -import { CirclesPermissions, CommonMember, Governance } from "@/shared/models"; +import { RightArrowThinIcon, StarIcon } from "@/shared/icons"; +import { + CirclesPermissions, + Common, + CommonMember, + Governance, +} from "@/shared/models"; import { CommonAvatar, TopNavigationOpenSidenavButton } from "@/shared/ui-kit"; -import { getPluralEnding } from "@/shared/utils"; +import { checkIsProject, getPluralEnding } from "@/shared/utils"; +import { ActionsButton } from "../HeaderContent/components"; import styles from "./HeaderContent_v04.module.scss"; interface HeaderContentProps { className?: string; - commonId: string; - commonName: string; - commonImage: string; - commonMembersAmount: number; - isProject?: boolean; + common: Common; commonMember: (CommonMember & CirclesPermissions) | null; governance: Governance; } const HeaderContent_v04: FC = (props) => { - const { - className, - commonId, - commonName, - commonImage, - commonMembersAmount, - isProject = false, - commonMember, - governance, - } = props; + const { className, common, commonMember, governance } = props; const { getCommonPageAboutTabPath } = useRoutesContext(); const isMobileVersion = useIsTabletView(); + const isProject = checkIsProject(common); + const commonFollow = useCommonFollow(common.id, commonMember); + const showFollowIcon = commonFollow.isFollowInProgress + ? !commonMember?.isFollowing + : commonMember?.isFollowing; return (
@@ -44,11 +43,11 @@ const HeaderContent_v04: FC = (props) => { /> = (props) => { />
-

{commonName}

+
+

{common.name}

+ {showFollowIcon && } +

- {commonMembersAmount} member{getPluralEnding(commonMembersAmount)} + {common.memberCount} member{getPluralEnding(common.memberCount)}

- +
+ + +
); }; diff --git a/src/shared/utils/generateStaticShareLink.ts b/src/shared/utils/generateStaticShareLink.ts index 51a2df05fc..c68737288f 100644 --- a/src/shared/utils/generateStaticShareLink.ts +++ b/src/shared/utils/generateStaticShareLink.ts @@ -1,5 +1,6 @@ -import { Environment, REACT_APP_ENV } from "../constants"; +import { Environment, REACT_APP_ENV, ROUTE_PATHS } from "../constants"; import { Common, Discussion, DiscussionMessage, Proposal } from "../models"; +import { matchRoute } from "./matchRoute"; const staticLinkPrefix = () => { if (window.location.hostname === "localhost") { @@ -15,6 +16,24 @@ const staticLinkPrefix = () => { } }; +const getStaticLinkBasePath = (): string => { + const pathname: string = window.location.pathname; + + if (matchRoute(pathname, ROUTE_PATHS.COMMON)) { + return "commons"; + } + + if (matchRoute(pathname, ROUTE_PATHS.V04_COMMON)) { + return "commons-v04"; + } + + if (matchRoute(pathname, ROUTE_PATHS.V03_COMMON)) { + return "commons-v03"; + } + + return "commons"; +}; + export const enum StaticLinkType { DiscussionMessage, ProposalComment, @@ -28,22 +47,24 @@ export const generateStaticShareLink = ( elem: Common | Proposal | Discussion | DiscussionMessage, feedItemId?: string, ): string => { + const basePath: string = getStaticLinkBasePath(); + if (!feedItemId && linkType === StaticLinkType.Common) { elem = elem as Common; - return `${staticLinkPrefix()}/commons/${elem.id}`; + return `${staticLinkPrefix()}/${basePath}/${elem.id}`; } switch (linkType) { case StaticLinkType.Proposal: case StaticLinkType.Discussion: elem = elem as Discussion; - return `${staticLinkPrefix()}/commons/${ + return `${staticLinkPrefix()}/${basePath}/${ elem.commonId }?item=${feedItemId}`; case StaticLinkType.DiscussionMessage: case StaticLinkType.ProposalComment: elem = elem as DiscussionMessage; - return `${staticLinkPrefix()}/commons/${ + return `${staticLinkPrefix()}/${basePath}/${ elem.commonId }?item=${feedItemId}&message=${elem.id}`; default: From 87bf7c66d472233e9c3fb70f58783819071ca3a5 Mon Sep 17 00:00:00 2001 From: Roie Natan Date: Wed, 18 Oct 2023 20:23:41 +0100 Subject: [PATCH 38/39] message menu on mobile: long press --- .../components/Chat/ChatMessage/ChatMessage.tsx | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/shared/components/Chat/ChatMessage/ChatMessage.tsx b/src/shared/components/Chat/ChatMessage/ChatMessage.tsx index 343a2e74c9..c7a7274694 100644 --- a/src/shared/components/Chat/ChatMessage/ChatMessage.tsx +++ b/src/shared/components/Chat/ChatMessage/ChatMessage.tsx @@ -7,6 +7,7 @@ import React, { useMemo, } from "react"; import classNames from "classnames"; +import { useLongPress } from "use-long-press"; import { ElementDropdown, UserAvatar, @@ -224,12 +225,18 @@ export default function ChatMessage({ } }; - const handleMessageClick: MouseEventHandler = () => { - if (isTabletView) { - setIsMenuOpen(true); - } + const handleLongPress = () => { + setIsMenuOpen(true); }; + const getLongPressProps = useLongPress( + isTabletView ? handleLongPress : null, + { + threshold: 400, + cancelOnMovement: true, + }, + ); + const handleContextMenu: MouseEventHandler = (event) => { if (!isTabletView) { event.preventDefault(); @@ -387,7 +394,7 @@ export default function ChatMessage({ [styles.highlightedOwn]: highlighted && !isNotCurrentUserMessage, })} - onClick={handleMessageClick} + {...getLongPressProps()} > {isNotCurrentUserMessage && !isSystemMessage && (
From bbb89c1428a41eb20262376b6c72bcf9256d7f6b Mon Sep 17 00:00:00 2001 From: Roie Natan Date: Wed, 18 Oct 2023 21:12:16 +0100 Subject: [PATCH 39/39] editor: same indentation for new lines --- .../components/ChatComponent/ChatComponent.module.scss | 5 +++-- .../ui-kit/TextEditor/components/Editor/Editor.module.scss | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/pages/common/components/ChatComponent/ChatComponent.module.scss b/src/pages/common/components/ChatComponent/ChatComponent.module.scss index 73a2fb1550..32838bd7c3 100644 --- a/src/pages/common/components/ChatComponent/ChatComponent.module.scss +++ b/src/pages/common/components/ChatComponent/ChatComponent.module.scss @@ -76,7 +76,7 @@ flex-direction: column; justify-content: center; word-break: break-word; - padding: 0.125rem 1.75rem 0.125rem 0.25rem; + padding: 0.125rem 1.75rem 0.125rem 0.75rem; margin: 0.3rem 0; } @@ -86,7 +86,8 @@ .messageInputEmpty { line-height: 2.25rem; - padding-left: 0; + padding-left: 0.75rem; + overflow-x: hidden; } .addFilesIcon { diff --git a/src/shared/ui-kit/TextEditor/components/Editor/Editor.module.scss b/src/shared/ui-kit/TextEditor/components/Editor/Editor.module.scss index 2dea5f321f..271cc4c195 100644 --- a/src/shared/ui-kit/TextEditor/components/Editor/Editor.module.scss +++ b/src/shared/ui-kit/TextEditor/components/Editor/Editor.module.scss @@ -3,7 +3,7 @@ .editor { --text-editor-h: auto; height: var(--text-editor-h); - text-indent: 0.75rem; + padding: 0.75rem; font-family: PoppinsSans, sans-serif; font-style: normal; font-weight: normal;