reimplement account style

This commit is contained in:
srgooglo 2022-03-15 04:24:48 +01:00
parent fbb1f9a62b
commit 79231d2c6a
2 changed files with 191 additions and 87 deletions

View File

@ -1,10 +1,10 @@
import React from "react"
import * as antd from "antd"
import { Translation } from "react-i18next"
import classnames from "classnames"
import moment from "moment"
import { Icons } from "components/Icons"
import { Skeleton, PostsFeed, FollowButton } from "components"
import { Skeleton, PostsFeed, FollowButton, FollowersList } from "components"
import { Session, User } from "models"
import "./index.less"
@ -13,6 +13,9 @@ export default class Account extends React.Component {
static bindApp = ["userController", "sessionController"]
state = {
transitionActive: false,
activeKey: "posts",
isSelf: false,
isFollowed: false,
user: null,
@ -44,15 +47,16 @@ export default class Account extends React.Component {
if (!isSelf) {
const followedResult = await this.api.get.isFollowed(undefined, { user_id: user._id }).catch(() => false)
const followersResult = await this.api.get.followers(undefined, { user_id: user._id }).catch(() => false)
if (followedResult) {
isFollowed = followedResult.isFollowed
}
}
if (followersResult) {
followers = followersResult
}
const followersResult = await this.api.get.followers(undefined, { user_id: user._id }).catch(() => false)
if (followersResult) {
followers = followersResult
}
}
@ -92,6 +96,28 @@ export default class Account extends React.Component {
})
}
handlePageTransition = (key) => {
if (this.state.activeKey === key) {
return false
}
this.setState({
transitionActive: true,
})
setTimeout(() => {
this.setState({
activeKey: key
})
setTimeout(() => {
this.setState({
transitionActive: false,
})
}, 100)
}, 100)
}
render() {
const user = this.state.user
@ -99,58 +125,82 @@ export default class Account extends React.Component {
return <Skeleton />
}
const createdAtYear = moment(new Date(Number(user.createdAt))).format("YYYY")
return (
<div className="accountProfile">
<div className="card">
<div className="header">
<div className="user">
<div>
<img src={user.avatar} />
{user.cover && <div className="cover" style={{ backgroundImage: `url("${user.cover}")` }} />}
<div className="profileCard">
<div className="basicData">
<div className="title">
<div className="field">
<div className="avatar">
<img src={user.avatar} />
</div>
</div>
<div>
<div className="field">
<div>
<h1>{user.fullName ?? user.username}</h1>
<span>@{user.username}</span>
{user.verified && <Icons.verifiedBadge />}
</div>
<div id="statistics" className="statistics">
<div>
<span><Icons.Users /> {this.state.followers.length} Followers</span>
</div>
<div>
<span><Icons.FileText /> 0 Posts</span>
</div>
<div>
<span>Joined at {createdAtYear}</span>
</div>
</div>
<span>@{user.username}</span>
</div>
</div>
{!this.state.isSelf && <div>
<FollowButton
count={this.state.followers.length}
onClick={this.onClickFollow}
followed={this.state.isFollowed}
/>
</div>}
</div>
<div className="extension">
<div className="badgesList">
{user.badges.map((role, index) => {
return <antd.Tag>{role}</antd.Tag>
})}
</div>
<div className="description">
<p>
{user.description}
</p>
</div>
</div>
<div className="posts">
<PostsFeed
fromUserId={user._id}
/>
</div>
<antd.Tabs
className="tabs"
type="card"
activeKey={this.state.activeKey}
onTabClick={this.handlePageTransition}
destroyInactiveTabPane
>
<antd.Tabs.TabPane tab={<Icons.Inbox />} key="posts">
<div className={classnames("fade-opacity-active", { "fade-opacity-leave": this.state.transitionActive })}>
<div className="posts">
<PostsFeed
fromUserId={user._id}
/>
</div>
</div>
</antd.Tabs.TabPane>
<antd.Tabs.TabPane tab={<Icons.Users />} key="followers">
<div className={classnames("fade-opacity-active", { "fade-opacity-leave": this.state.transitionActive })}>
<FollowersList
followers={this.state.followers}
/>
</div>
</antd.Tabs.TabPane>
<antd.Tabs.TabPane tab={<Icons.Info />} key="details">
<div className={classnames("fade-opacity-active", { "fade-opacity-leave": this.state.transitionActive })}>
<div id="statistics" className="statistics">
<div>
<span><Icons.Users /> {this.state.followers.length} Followers</span>
</div>
<div>
<span><Icons.FileText /> 0 Posts</span>
</div>
<div>
<span>Joined at {moment(new Date(Number(user.createdAt))).format("YYYY")}</span>
</div>
</div>
</div>
</antd.Tabs.TabPane>
</antd.Tabs>
</div>
)
}

View File

@ -1,67 +1,89 @@
@borderColor : #dddddd;
@borderRadius: 12px;
.accountProfile {
.card {
padding: 0 20px;
.cover {
z-index : 50;
position : relative;
border-radius: @borderRadius @borderRadius 0 0;
outline: 1px solid var(--border-color);
content: "";
width: 100%;
background-position: center;
background-size : cover;
height: 18vh;
transform: translate(0, 10px);
}
.profileCard {
z-index : 51;
position: relative;
display : flex;
flex-direction: column;
color : var(--background-color-contrast);
h1,
h2,
h3,
h4,
h5,
h6,
span {
color: var(--background-color-contrast);
}
color : var(--background-color-contrast);
background-color: var(--background-color-primary);
.header {
position: relative;
display : inline-flex;
border : 1px solid var(--border-color);
border-radius: @borderRadius;
align-items : center;
padding: 20px 15px;
.basicData {
display : inline-flex;
flex-direction : row;
justify-content: space-between;
z-index: 15;
width : 100%;
padding: 12px 24px;
font-family: "Roboto Mono", monospace;
color : var(--background-color-contrast);
border : 1px solid var(--border-color);
border-radius: @borderRadius;
word-break: break-all;
.user {
display: inline-flex;
flex-direction: row;
> div {
align-self: flex-start;
margin-right: 15px;
> div {
margin-bottom: 5px;
}
}
margin-bottom: 15px;
.avatar {
img {
width : 70px;
height: 70px;
width : 70px;
height : 70px;
border-radius: 4px;
}
}
svg {
fill: var(--appColor);
}
.title {
display : inline-flex;
flex-direction: row;
align-items : center;
}
.field {
display : inline-flex;
flex-direction: column;
margin-right: 15px;
h1 {
margin : 0;
margin: 0;
font-size: 35px;
font-size : 35px;
line-height: 37px;
}
>div {
display: inline-flex;
}
}
}
.description {
p {
word-break: break-all;
margin : 0;
}
}
@ -84,9 +106,41 @@
border-radius: 0 0 @borderRadius @borderRadius;
}
h1,
h2,
h3,
h4,
h5,
h6,
span,
p {
user-select: text;
}
}
>div {
margin-bottom: 10px;
.tabs {
.ant-tabs-nav {
margin: 0 30px 20px 30px;
}
.ant-tabs-nav::before {
border: none !important;
}
.ant-tabs-tab {
padding : 8px 20px !important;
border-color : var(--border-color) !important;
margin-right : 20px !important;
background-color: var(--background-color-primary) !important;
border-top : 0 !important;
border-radius : 0 0 4px 4px !important;
svg {
font-size: 1rem;
margin : 0 !important;
}
}
}
}