Add user profile layout

This commit is contained in:
srgooglo 2020-10-08 20:52:28 +02:00
parent b500171b01
commit 95a74eb3a2
7 changed files with 226 additions and 59 deletions

View File

@ -3,6 +3,10 @@ import { pathMatchRegexp } from 'core'
import { router } from 'core/libs/router'
import { Invalid } from 'components'
import styles from './index.less'
import { user } from 'core/models'
import FollowButton from './components/follow'
import Menu from './components/menu'
import * as antd from 'antd'
import { connect } from 'umi'
@ -10,16 +14,29 @@ const matchRegexp = pathMatchRegexp('/@/:id', location.pathname)
const __Avatar = "https://comty.pw/upload/photos/2020/09/MEmX2WskbYdqxxIfG1Ci_12_bf9ae629707074e3dde5b6ff4ccb1caf_avatar.jpeg?cache=1599917094"
const __Cover = "https://comty.pw/upload/photos/2020/09/ontbBGwvDruPxxHxzd7K_12_b36cb70f20df86ea77cd04005786bad7_cover.png?cache=1599917132"
const __About = "Cum cum cum me gusta damme"
const __Followed = false
const __Followers = 150
@connect(({ app }) => ({ app }))
class UserLayout extends React.Component{
state = {
styleComponent: "UserLayout",
userString: matchRegexp[1],
layoutData: {
avatar: null,
cover: null,
about: null,
followed: null,
followers: null
}
}
componentDidMount(){
const { layoutData } = this.props
if (layoutData) {
this.setState({ layoutData: {...this.state.layoutData, ...layoutData} })
console.log(this.state.layoutData)
}
}
render(){
@ -29,18 +46,36 @@ class UserLayout extends React.Component{
return(
<div className={toStyles("wrapper")} >
<div className={toStyles("cover")}>
<img src={__Cover} />
<img src={this.state.layoutData.cover} />
</div>
<div className={toStyles("header")}>
<div className={toStyles("avatar")}>
<antd.Avatar shape="square" src={__Avatar} />
<antd.Avatar shape="square" src={this.state.layoutData.avatar} />
</div>
<div className={toStyles("title")}>
<h1>{this.state.userString}</h1>
<antd.Tooltip title={`${this.state.layoutData.followers ?? "Non-existent"} Followers`}>
<h1>{this.state.userString}</h1>
</antd.Tooltip>
<span
style={{
fontSize: '14px',
fontWeight: '100',
lineHeight: '0',
marginBottom: '5px',
}}
dangerouslySetInnerHTML={{
__html: this.state.layoutData.about,
}}
/>
</div>
<div className={toStyles("options")}>
<div><FollowButton followed={this.state.layoutData.follow} /></div>
</div>
</div>
<div className={toStyles("content")}>
@ -51,12 +86,58 @@ class UserLayout extends React.Component{
}
}
@connect(({ app }) => ({ app }))
export default class UserIndexer extends React.Component {
render() {
const { location } = this.props
state = {
loading: true,
response: null,
layoutData: null
}
promiseState = async state => new Promise(resolve => this.setState(state, resolve));
componentDidMount(){
if (matchRegexp) {
return <UserLayout />
user.get.profileData({username: matchRegexp[1], server_key: this.props.app.server_key, access_token: this.props.app.session_token}, (err, res) => {
if (err) {
return false
}
try {
const data = JSON.parse(res)["user_data"]
const frame = {
avatar: data.avatar,
can_follow: data.can_follow,
country_id: data.contry_id,
about: data.about,
cover: data.cover,
is_pro: data.is_pro,
lastseen: data.lastseen,
points: data.points,
registered:data.registered,
user_id: data.user_id,
verified: data.verified,
birthday: data.birthday,
details: data.details
}
this.setState({ layoutData: frame, loading: false })
console.log(frame)
} catch (error) {
console.log(error)
return false
}
})
}else{
this.setState({ loading: false })
}
}
render() {
if (this.state.loading) {
return <div style={{ display: "flex", width: "100%", justifyContent: "center", alignContent: "center" }}><antd.Card style={{ width: "100%" }} ><antd.Skeleton active /></antd.Card></div>
}
if (matchRegexp) {
return <UserLayout layoutData={this.state.layoutData} />
}
return <Invalid type="index" messageProp1={location.pathname} />
}

View File

View File

@ -0,0 +1,13 @@
import React from 'react'
import styles from './index.less'
import classnames from 'classnames'
const FollowButton = (props) => {
return (
<a className={classnames(styles.button, {[styles.disabled]: !props.followed })}>
<span>{props.followed ? 'Following' : 'Follow'}</span>
</a>
)
}
export default FollowButton

View File

@ -0,0 +1,32 @@
.button {
user-select: none;
width: 100px;
height: 30px;
padding: 5px 15px 5px 15px;
text-decoration: none;
text-align: center;
vertical-align: middle;
letter-spacing: 1px;
&:hover {
color: #7e7e7e;
}
&.disabled{
&:hover {
border: none;
content: '';
color: white;
border-radius: 8px;
background: linear-gradient(120deg, #6559ae, #ff7159, #6559ae);
background-size: 400% 400%;
animation: gradient 15s ease-in-out infinite, border 1s forwards ease-in-out reverse;
}
}
}
@keyframes gradient {
0% { background-position: 14% 0%; }
50% { background-position: 87% 100%; }
100% { background-position: 14% 0%; }
}

View File

@ -0,0 +1,20 @@
import React from 'react'
import * as antd from 'antd'
import { Icons } from 'components'
const moreMenu = (
<antd.Menu>
<antd.Menu.Item>__</antd.Menu.Item>
<antd.Menu.Item>__set2</antd.Menu.Item>
</antd.Menu>
)
const Menu = (props) => {
return (
<antd.Dropdown overlay={moreMenu}>
<Icons.MoreOutlined />
</antd.Dropdown>
)
}
export default Menu

View File

@ -1,16 +1,13 @@
.UserLayout_wrapper{
display: flex;
height: 100%;
width: 100%;
flex-direction: column;
align-content: center;
padding: 0 68px 15px 68px;
align-items: center;
margin: auto;
border-radius: 0 0 20px 20px;
padding: 20px 0 3px 0;
padding-top: 0;
overflow: initial !important;
overflow: overlay !important;
}
.UserLayout_header{
@ -21,67 +18,91 @@
display: flex;
padding: 20px;
height: 24vh;
height: auto;
width: 100%;
max-width: 600px;
max-height: 200px;
background-color: #ffffff;
border-radius: 8px;
border-radius: 0 0 20px 20px;
transform: translate(0, -5px);
}
.UserLayout_cover{
display: flex;
position: relative;
width: 100%;
align-content: center;
max-height: 400px;
max-width: 600px;
overflow: hidden;
border-radius: 15px 15px 0 0;
border-radius: 8px;
img {
height: min-content;
width: min-content;
width: 100%;
margin: auto;
}
}
.follow_wrapper {
margin: 0 7px 0 7px;
position: relative;
float: right;
}
.UserLayout_title{
padding: 54px;
padding: 0 10px 10px 0;
color: #242424;
color: #2d2d2d;
font-weight: 500;
font-size: 20px;
line-height: 28px;
width: 100%;
height: 100%;
word-break: break-all;
h1 {
margin: 0;
}
span{
word-break: break-all;
}
}
.avatar {
transform: translate(-25px, -45px);
max-height: 200px;
max-width: 120px;
&>span {
position: relative;
z-index: 10;
width: 100%;
height: 100%;
}
.UserLayout_avatar {
transform: translate(-35px, -45px);
max-height: 200px;
max-width: 120px;
&.mobile{
transform: translate(0,-90px);
margin: auto;
}
:global {
.ant-avatar {
box-shadow: 13px 13px 17px 4px rgba(69, 69, 69, 0.151);
border-radius: 7px;
img {
width: 120px;
}
&>span {
position: relative;
z-index: 10;
width: 100%;
height: 100%;
}
&.mobile{
transform: translate(0,-90px);
margin: auto;
}
:global {
.ant-avatar {
box-shadow: 13px 13px 17px 4px rgba(69, 69, 69, 0.151);
border-radius: 7px;
img {
width: 120px;
}
}
}
}
.UserLayout_options{
display: flex;
flex-direction: column;
text-align: left;
> div {
text-align: left;
margin-bottom: 15px;
}
}

View File

@ -37,7 +37,7 @@ export class NormalLoginForm extends React.PureComponent {
switch (a) {
case 1:
const payload = { username: Object.values(values).toString() }
user.get.profileData(payload, (err, res) => {
user.get.basicData(payload, (err, res) => {
if (err || !res) return false
try {
const res_data = JSON.parse(res)