From bde75ca7b952c5c607139b4314478670b593fac0 Mon Sep 17 00:00:00 2001 From: Dusty Reagan Date: Fri, 10 Jan 2025 10:12:56 -0600 Subject: [PATCH] Reader: Pass header content to Stream components (#98045) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * ➖ REMOVE: remove extra localize function from ReaderAvatar * UPDATE: jsconfig for improving TS speed * UPDATE: migrate ReaderAuthorLink to TypeScript * REFACTOR: Update ReaderFollowButton to use TypeScript * REFACTOR: Update AuthorCompactProfile to functional component and use TypeScript * ➕ ADDS: author info and improve styling * ➖ REMOVE: extra user tabs * 👌 IMPROVE: selector namings and section alignments * ➕ ADDS: empty content placeholders in user profile * 🔨 REFACTOR: update EmptyContent to functional component and use TypeScript * 💫 UPDATE: only keep code related to refactor * FIX: actionURL in EmptyContent * ➖ REMOVE: code related to refactoring * Reader: Pass header content to Stream components * Remove reducer update from this PR * Remove optional modifier and rename children to headerContent * Create UserProfileHeader component * Move nav into header and use header directly in views * IMPROVE: spacing and remove extra properties * 🔨 REFACTOR: move header styles to its dedicated file * Move UserProfileHeader to own folder and scope CSS --------- Co-authored-by: Mehmood Ahmad <31419912+mehmoodak@users.noreply.github.com> --- .../components/user-profile-header/index.tsx | 66 +++++++++++++++++++ .../components/user-profile-header/style.scss | 48 ++++++++++++++ client/reader/user-stream/index.tsx | 64 ++---------------- client/reader/user-stream/style.scss | 56 ---------------- client/reader/user-stream/views/lists.tsx | 11 +++- client/reader/user-stream/views/posts.tsx | 9 ++- 6 files changed, 136 insertions(+), 118 deletions(-) create mode 100644 client/reader/user-stream/components/user-profile-header/index.tsx create mode 100644 client/reader/user-stream/components/user-profile-header/style.scss diff --git a/client/reader/user-stream/components/user-profile-header/index.tsx b/client/reader/user-stream/components/user-profile-header/index.tsx new file mode 100644 index 00000000000000..7ef389b0fa0ff2 --- /dev/null +++ b/client/reader/user-stream/components/user-profile-header/index.tsx @@ -0,0 +1,66 @@ +import page from '@automattic/calypso-router'; +import { useTranslate } from 'i18n-calypso'; +import ReaderAuthorLink from 'calypso/blocks/reader-author-link'; +import ReaderAvatar from 'calypso/blocks/reader-avatar'; +import SectionNav from 'calypso/components/section-nav'; +import NavItem from 'calypso/components/section-nav/item'; +import NavTabs from 'calypso/components/section-nav/tabs'; +import { UserData } from 'calypso/lib/user/user'; + +import './style.scss'; + +interface UserProfileHeaderProps { + user: UserData; +} + +const UserProfileHeader = ( { user }: UserProfileHeaderProps ): JSX.Element => { + const translate = useTranslate(); + const currentPath = page.current; + const userId = user.ID; + + const navigationItems = [ + { + label: translate( 'Posts' ), + path: `/read/users/${ userId }`, + selected: currentPath === `/read/users/${ userId }`, + }, + { + label: translate( 'Lists' ), + path: `/read/users/${ userId }/lists`, + selected: currentPath === `/read/users/${ userId }/lists`, + }, + ]; + + const selectedTab = navigationItems.find( ( item ) => item.selected )?.label || ''; + + return ( +
+
+ +
+
+ + { user.display_name } + +
+ { user.bio && ( +
+

{ user.bio }

+
+ ) } +
+
+ + + { navigationItems.map( ( item ) => ( + + { item.label } + + ) ) } + + +
+ ); +}; + +export default UserProfileHeader; diff --git a/client/reader/user-stream/components/user-profile-header/style.scss b/client/reader/user-stream/components/user-profile-header/style.scss new file mode 100644 index 00000000000000..bf15d6b7ad4c09 --- /dev/null +++ b/client/reader/user-stream/components/user-profile-header/style.scss @@ -0,0 +1,48 @@ +.is-section-reader { + .user-profile-header { + max-width: 768px; + margin: 0 auto; + + &__main { + align-items: center; + display: flex; + padding: 36px 0 24px; + + .reader-avatar { + margin: 0 24px 0 0; + } + } + + &__display-name { + font-family: Recoleta, sans-serif; + font-size: 2rem; + line-height: 1.5; + } + + &__bio { + /* stylelint-disable-next-line scales/font-sizes */ + font-size: 1.125rem; + } + + &__bio-desc { + margin-bottom: 0; + } + + .section-nav { + box-shadow: none; + border-bottom: 1px solid var( --color-border-subtle ); + height: auto !important; + } + + .section-nav-tab__link { + &:hover { + background: none; + } + } + + .section-nav-tab__text { + font-weight: 500; + color: var( --studio-black ); + } + } +} diff --git a/client/reader/user-stream/index.tsx b/client/reader/user-stream/index.tsx index 8a2a07a1d4ded4..56625ecf65a85d 100644 --- a/client/reader/user-stream/index.tsx +++ b/client/reader/user-stream/index.tsx @@ -1,24 +1,12 @@ import page from '@automattic/calypso-router'; -import { useTranslate } from 'i18n-calypso'; import { useEffect } from 'react'; import { connect } from 'react-redux'; -import ReaderAuthorLink from 'calypso/blocks/reader-author-link'; -import ReaderAvatar from 'calypso/blocks/reader-avatar'; -import SectionNav from 'calypso/components/section-nav'; -import NavItem from 'calypso/components/section-nav/item'; -import NavTabs from 'calypso/components/section-nav/tabs'; import { UserData } from 'calypso/lib/user/user'; +import UserLists from 'calypso/reader/user-stream/views/lists'; +import UserPosts from 'calypso/reader/user-stream/views/posts'; import { requestUser } from 'calypso/state/reader/users/actions'; -import UserLists from './views/lists'; -import UserPosts from './views/posts'; import './style.scss'; -interface NavigationItem { - label: string; - path: string; - selected: boolean; -} - interface UserStreamProps { streamKey?: string; userId: string; @@ -41,66 +29,26 @@ export function UserStream( { userId, requestUser, user, streamKey, isLoading }: requestUser( userId ); }, [ userId, requestUser ] ); - const translate = useTranslate(); - if ( isLoading || ! user ) { return <>; } const currentPath = page.current; - const navigationItems: NavigationItem[] = [ - { - label: translate( 'Posts' ), - path: `/read/users/${ userId }`, - selected: currentPath === `/read/users/${ userId }`, - }, - { - label: translate( 'Lists' ), - path: `/read/users/${ userId }/lists`, - selected: currentPath === `/read/users/${ userId }/lists`, - }, - ]; - - const selectedTab = navigationItems.find( ( item ) => item.selected )?.label || ''; - const renderContent = (): React.ReactNode => { const basePath = currentPath.split( '?' )[ 0 ]; - switch ( basePath ) { case `/read/users/${ userId }`: - return ; + return ; case `/read/users/${ userId }/lists`: - return ; + return ; + default: + return null; } }; return (
-
- -
-
- - { user.display_name } - -
- { user.bio && ( -
-

{ user.bio }

-
- ) } -
-
- - - { navigationItems.map( ( item ) => ( - - { item.label } - - ) ) } - -
{ renderContent() }
diff --git a/client/reader/user-stream/style.scss b/client/reader/user-stream/style.scss index e6cbba7e19c179..8508f381e0efa4 100644 --- a/client/reader/user-stream/style.scss +++ b/client/reader/user-stream/style.scss @@ -1,67 +1,11 @@ .is-section-reader { - $padding: 24px; - $tab-content-width: 768px; - .user-profile { - >* { - scrollbar-gutter: stable; - } - .empty-content { margin-top: 150px; } } - .user-profile__header { - align-items: center; - display: flex; - max-width: $tab-content-width; - margin: 16px auto 0; - padding: $padding 0; - - .reader-avatar { - margin: 0 $padding 0 0; - } - } - - .user-profile-header__display-name { - font-family: Recoleta, sans-serif; - font-size: 2rem; - line-height: 1.5; - } - - .user-profile-header__bio { - /* stylelint-disable-next-line scales/font-sizes */ - font-size: 1.125rem; - } - - .section-nav { - box-shadow: none; - border-bottom: 1px solid var(--color-border-subtle); - height: auto !important; - margin: 0; - } - - .section-nav-tabs { - max-width: $tab-content-width; - margin: 0 auto; - } - - .section-nav-tab__link { - &:hover { - background: none; - } - } - - .section-nav-tab__text { - font-weight: 500; - color: var(--studio-black); - } - div.user-profile__content { - margin: $padding auto; - max-width: $tab-content-width; - main.main.is-user-stream { padding: 0; border-block-end: none; diff --git a/client/reader/user-stream/views/lists.tsx b/client/reader/user-stream/views/lists.tsx index b8cad4b899692c..84c3c99c212448 100644 --- a/client/reader/user-stream/views/lists.tsx +++ b/client/reader/user-stream/views/lists.tsx @@ -1,12 +1,19 @@ import { formatListBullets, Icon } from '@wordpress/icons'; import { useTranslate } from 'i18n-calypso'; import EmptyContent from 'calypso/components/empty-content'; +import { UserData } from 'calypso/lib/user/user'; +import UserProfileHeader from 'calypso/reader/user-stream/components/user-profile-header'; -const UserLists = (): JSX.Element => { +interface UserListsProps { + user: UserData; +} + +const UserLists = ( { user }: UserListsProps ): JSX.Element => { const translate = useTranslate(); return ( -
+
+ } diff --git a/client/reader/user-stream/views/posts.tsx b/client/reader/user-stream/views/posts.tsx index 36ea914be6f86e..2855def3ea3226 100644 --- a/client/reader/user-stream/views/posts.tsx +++ b/client/reader/user-stream/views/posts.tsx @@ -1,13 +1,16 @@ import { Icon, postList } from '@wordpress/icons'; import { useTranslate } from 'i18n-calypso'; import EmptyContent from 'calypso/components/empty-content'; +import { UserData } from 'calypso/lib/user/user'; import Stream from 'calypso/reader/stream'; +import UserProfileHeader from 'calypso/reader/user-stream/components/user-profile-header'; interface UserPostsProps { streamKey: string; + user: UserData; } -const UserPosts = ( { streamKey }: UserPostsProps ): JSX.Element => { +const UserPosts = ( { streamKey, user }: UserPostsProps ): JSX.Element => { const translate = useTranslate(); return ( @@ -28,7 +31,9 @@ const UserPosts = ( { streamKey }: UserPostsProps ): JSX.Element => { line={ translate( 'No posts yet.' ) } /> ) } - /> + > + + ); };