web/front/UserPage.tsx
import { useRouter } from 'next/router'
import React from 'react'
import { AppContext, ArticleIcon, useEEdit, HomeIcon, IssueIcon, LikeIcon, UserIcon } from 'front'
import ArticleList from 'front/ArticleList'
import { cant } from 'front/cant'
import config from 'front/config'
import CustomLink from 'front/CustomLink'
import CustomImage from 'front/CustomImage'
import LoadingSpinner from 'front/LoadingSpinner'
import LogoutButton from 'front/LogoutButton'
import Maybe from 'front/Maybe'
import FollowUserButton from 'front/FollowUserButton'
import { DisplayAndUsername, displayAndUsernameText } from 'front/user'
import routes from 'front/routes'
import Article from 'front/Article'
import { ArticleType, ArticleLinkType } from 'front/types/ArticleType'
import { CommentType } from 'front/types/CommentType'
import { IssueType } from 'front/types/IssueType'
import { TopicType } from 'front/types/TopicType'
import { UserType } from 'front/types/UserType'
import UserList from 'front/UserList'
export interface UserPageProps {
ancestors?: ArticleLinkType[];
article?: ArticleType & IssueType;
articles?: (ArticleType & IssueType & TopicType)[];
articlesCount?: number;
articlesInSamePage?: ArticleType[];
articlesInSamePageForToc?: ArticleType[];
commentCountByLoggedInUser?: number;
comments?: CommentType[];
incomingLinks?: ArticleLinkType[];
issuesCount?: number;
itemType?: 'article' | 'discussion' | 'like'| 'topic' | 'user';
latestIssues?: IssueType[];
loggedInUser?: UserType;
order: string;
page: number;
synonymLinks?: ArticleLinkType[];
tagged?: ArticleLinkType[];
topIssues?: IssueType[];
user: UserType;
users?: UserType[];
usersCount?: number;
what: 'follows' | 'followed' | 'followed-articles' | 'home' | 'liked' | 'likes' | 'user-issues' | 'user-articles';
}
export default function UserPage({
article,
articles,
articlesCount,
articlesInSamePage,
articlesInSamePageForToc,
ancestors,
comments,
commentCountByLoggedInUser,
incomingLinks,
issuesCount,
itemType,
latestIssues,
loggedInUser,
order,
page,
synonymLinks,
tagged,
topIssues,
user,
users,
usersCount,
what,
}: UserPageProps) {
const router = useRouter();
const username = user?.username
const isCurrentUser = loggedInUser && username === loggedInUser?.username
let paginationUrlFunc
switch (what) {
case 'follows':
paginationUrlFunc = page => routes.userFollows(user.username, { page })
break
case 'followed':
paginationUrlFunc = page => routes.userFollowed(user.username, { page })
break
case 'followed-articles':
paginationUrlFunc = page => routes.userFollowsArticles(user.username, { page })
break
case 'liked':
paginationUrlFunc = page => routes.userLiked(user.username, { page })
break
case 'likes':
paginationUrlFunc = page => routes.userLikes(user.username, { page })
break
case 'user-issues':
paginationUrlFunc = page => routes.userIssues(user.username, { page, sort: order })
break
case 'user-articles':
paginationUrlFunc = page => routes.userArticles(user.username, { page, sort: order })
break
}
const canEdit = loggedInUser && loggedInUser?.username === username
useEEdit(canEdit, article?.slug)
// Following state.
const [following, setFollowing] = React.useState(false)
const [followerCount, setFollowerCount] = React.useState(user?.followerCount)
React.useEffect(() => {
setFollowing(user?.following)
setFollowerCount(user?.followerCount)
}, [
user?.following,
user?.followerCount,
])
// title
const { setTitle } = React.useContext(AppContext)
React.useEffect(() => {
setTitle(displayAndUsernameText(user))
}, [user?.displayName, user?.username])
if (router.isFallback) { return <LoadingSpinner />; }
return (<>
<div className="profile-page">
<div className="user-info content-not-ourbigbook">
<h1>
<DisplayAndUsername user={user}></DisplayAndUsername>
</h1>
<div className="user-actions">
<FollowUserButton {...{ loggedInUser, user, showUsername: false }}/>
<CustomLink className="btn" href={routes.issueNew(`${user.username}`)}>
<IssueIcon /> Message
</CustomLink>
<Maybe test={!cant.viewUserSettings(loggedInUser, user)}>
<CustomLink
href={routes.userEdit(user.username)}
className="btn btn-sm btn-outline-secondary action-btn"
>
<i className="ion-gear-a" /> Settings
</CustomLink>
</Maybe>
{isCurrentUser &&
<>
<LogoutButton />
</>
}
</div>
{user.admin && <h2><i className="ion-star" /> <a href={`${config.docsAdminUrl}`}>Admin</a> <i className="ion-star" /> </h2>}
<CustomImage
src={user.effectiveImage}
alt="User's profile image"
className="user-img"
/>
<div className="tab-list">
<CustomLink
href={routes.user(username)}
className={`tab-item${what === 'home' ? ' active' : ''}`}
>
<HomeIcon /> Home
</CustomLink>
<CustomLink
href={routes.userArticles(username, { sort: 'score' })}
className={`tab-item${what === 'user-articles' && order === 'score' ? ' active' : ''}`}
>
<ArticleIcon /> Top
</CustomLink>
<CustomLink
href={routes.userArticles(username, { sort: 'created' })}
className={`tab-item${what === 'user-articles' && order === 'createdAt' ? ' active' : ''}`}
>
<ArticleIcon /> Latest
</CustomLink>
<CustomLink
href={routes.userLikes(username)}
className={`tab-item${what === 'likes' ? ' active' : ''}`}
>
<ArticleIcon /> Likes
</CustomLink>
<CustomLink
href={routes.userLiked(username)}
className={`tab-item${what === 'liked' ? ' active' : ''}`}
>
<LikeIcon /> Received likes
</CustomLink>
<CustomLink
href={routes.userFollows(username)}
className={`tab-item${what === 'follows' ? ' active' : ''}`}
>
<UserIcon /> Follows
</CustomLink>
<CustomLink
href={routes.userFollowed(username)}
className={`tab-item${what === 'followed' ? ' active' : ''}`}
>
<UserIcon /> Followed by
</CustomLink>
<CustomLink
href={routes.userFollowsArticles(username)}
className={`tab-item${what === 'followed-articles' ? ' active' : ''}`}
>
<ArticleIcon /> Follows
</CustomLink>
<CustomLink
href={routes.userIssues(user.username, { sort: 'created' })}
className={`tab-item${itemType === 'discussion' && order === 'createdAt' ? ' active' : ''}`}
>
<IssueIcon /> Latest<span className="mobile-hide"> Discussions</span>
</CustomLink>
<CustomLink
href={routes.userIssues(user.username, { sort: 'score' })}
className={`tab-item${itemType === 'discussion' && order === 'score' ? ' active' : ''}`}
>
<IssueIcon /> Top<span className="mobile-hide"> Discussions</span>
</CustomLink>
</div>
</div>
{what === 'home' &&
<Article {...{
ancestors,
article,
articlesInSamePage,
articlesInSamePageForToc,
comments,
commentCountByLoggedInUser,
latestIssues,
incomingLinks,
issuesCount,
loggedInUser,
synonymLinks,
tagged,
topIssues,
}}/>
}
</div>
{(itemType === 'article' || itemType === 'discussion' || itemType === 'like') &&
<div className="content-not-ourbigbook">
<ArticleList {...{
articles,
articlesCount,
itemType,
loggedInUser,
page,
paginationUrlFunc,
showAuthor: what === 'likes' || what === 'followed-articles',
what,
}}/>
</div>
}
{itemType === 'user' &&
<div className="content-not-ourbigbook">
<UserList {...{
loggedInUser,
page,
paginationUrlFunc,
users,
usersCount,
}}/>
</div>
}
</>);
}