1
0
Fork 0
mirror of https://github.com/muerwre/vault-frontend.git synced 2025-04-25 12:56:41 +07:00

profile layout

This commit is contained in:
Fedor Katurov 2020-04-08 20:47:12 +07:00
parent 0c3625cd18
commit fe6f977cf1
12 changed files with 236 additions and 13 deletions

View file

@ -1,10 +1,53 @@
import React, { FC } from 'react';
import React, { FC, useEffect } from 'react';
import styles from './styles.scss';
import { ProfilePageLeft } from '../ProfilePageLeft';
import { Switch, Route, RouteComponentProps } from 'react-router';
import { IState } from '~/redux/store';
import { selectAuthProfile } from '~/redux/auth/selectors';
import { connect } from 'react-redux';
import * as AUTH_ACTIONS from '~/redux/auth/actions';
interface IProps {}
const mapStateToProps = (state: IState) => ({
profile: selectAuthProfile(state),
});
const ProfilePage: FC<IProps> = ({}) => {
return <div className={styles.wrap}>PROFILE</div>;
const mapDispatchToProps = {
authLoadProfile: AUTH_ACTIONS.authLoadProfile,
};
type Props = ReturnType<typeof mapStateToProps> &
typeof mapDispatchToProps &
RouteComponentProps<{ username: string }> & {};
const ProfilePageUnconnected: FC<Props> = ({
profile,
authLoadProfile,
match: {
params: { username },
},
}) => {
useEffect(() => {
authLoadProfile(username);
}, [username]);
return (
<div className={styles.wrap}>
<div className={styles.left}>
<ProfilePageLeft profile={profile} username={username} />
</div>
<div className={styles.right}>
<Switch>
<Route path="/profile/:username" render={() => <div>DEFAULT</div>} />
<Route path="/profile/:username/tab" render={() => <div>TAB</div>} />
</Switch>
</div>
</div>
);
};
const ProfilePage = connect(
mapStateToProps,
mapDispatchToProps
)(ProfilePageUnconnected);
export { ProfilePage };

View file

@ -2,6 +2,19 @@
flex: 1;
background: $content_bg;
display: flex;
align-items: center;
justify-content: center;
align-items: stretch;
justify-content: stretch;
box-shadow: $node_shadow;
border-radius: $radius;
}
.left {
flex: 1;
background: darken($content_bg, 2%);
border-radius: $radius 0 0 $radius;
box-sizing: border-box;
}
.right {
flex: 3;
}

View file

@ -0,0 +1,58 @@
import React, { FC, useMemo } from 'react';
import styles from './styles.scss';
import { IAuthState } from '~/redux/auth/types';
import { getURL } from '~/utils/dom';
import { PRESETS, URLS } from '~/constants/urls';
import { Placeholder } from '~/components/placeholders/Placeholder';
import { Link } from 'react-router-dom';
import { Icon } from '~/components/input/Icon';
interface IProps {
profile: IAuthState['profile'];
username: string;
}
const ProfilePageLeft: FC<IProps> = ({ username, profile }) => {
const thumb = useMemo(() => {
if (!profile || !profile.user || !profile.user.photo) return '';
return getURL(profile.user.photo, PRESETS.small_hero);
}, [profile]);
return (
<div className={styles.wrap}>
<div className={styles.avatar} style={{ backgroundImage: `url('${thumb}')` }} />
<div className={styles.region_wrap}>
<div className={styles.region}>
<div className={styles.name}>
{profile.is_loading ? <Placeholder /> : profile.user.fullname}
</div>
<div className={styles.username}>
{profile.is_loading ? <Placeholder /> : `~${profile.user.username}`}
</div>
<div className={styles.menu}>
<Link to={`${URLS.PROFILE_PAGE(username)}/`}>
<Icon icon="profile" size={20} />
Профиль
</Link>
<Link to={`${URLS.PROFILE_PAGE(username)}/settings`}>
<Icon icon="settings" size={20} />
Настройки
</Link>
<Link to={`${URLS.PROFILE_PAGE(username)}/messages`}>
<Icon icon="messages" size={20} />
Сообщения
</Link>
</div>
</div>
</div>
</div>
);
};
export { ProfilePageLeft };

View file

@ -0,0 +1,79 @@
.wrap {
display: flex;
align-items: flex-start;
justify-content: stretch;
flex-direction: column;
}
.avatar {
width: 100%;
padding-bottom: 50%;
border-radius: $radius 0 0 0;
background: 50% 50% no-repeat;
background-size: cover;
}
.region_wrap {
width: 100%;
padding: 0 10px;
position: relative;
top: -$radius;
box-sizing: border-box;
}
.region {
background: $content_bg;
width: 100%;
border-radius: $radius;
box-shadow: rgba(0, 0, 0, 0.3) 0 2px;
}
.name {
font: $font_24_semibold;
color: white;
padding: $gap $gap 0 $gap;
text-transform: uppercase;
width: 100%;
box-sizing: border-box;
}
.username {
font: $font_14_semibold;
padding: 0 $gap $gap $gap;
box-sizing: border-box;
width: 100%;
color: transparentize(white, 0.5);
}
.menu {
padding: $gap 0 $gap 0;
display: flex;
align-items: stretch;
width: 100%;
flex-direction: column;
box-sizing: border-box;
a {
width: 100%;
color: inherit;
text-decoration: none;
text-transform: uppercase;
font: $font_18_semibold;
padding: $gap $gap;
display: flex;
align-items: center;
justify-content: flex-start;
opacity: 0.5;
box-sizing: border-box;
transition: opacity 0.25s;
&:hover {
opacity: 1;
}
}
svg {
margin-right: $gap;
fill: currentColor;
}
}