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:
parent
0c3625cd18
commit
fe6f977cf1
12 changed files with 236 additions and 13 deletions
|
@ -44,7 +44,7 @@ const Component: FC<IProps> = ({ modal: { is_shown } }) => {
|
|||
<Route path={URLS.NODE_URL(':id')} component={NodeLayout} />
|
||||
<Route path={URLS.BORIS} component={BorisLayout} />
|
||||
<Route path={URLS.ERRORS.NOT_FOUND} component={ErrorNotFound} />
|
||||
<Route path={URLS.PROFILE_PAGE} component={ProfilePage} />
|
||||
<Route path={URLS.PROFILE_PAGE(':username')} component={ProfilePage} />
|
||||
|
||||
<Redirect to="/" />
|
||||
</Switch>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import React, { FC, useState, useCallback } from 'react';
|
||||
import React, { FC, useCallback } from 'react';
|
||||
import { BetterScrollDialog } from '../BetterScrollDialog';
|
||||
import { ProfileInfo } from '~/containers/profile/ProfileInfo';
|
||||
import { IDialogProps } from '~/redux/types';
|
||||
|
|
|
@ -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 };
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
58
src/containers/profile/ProfilePageLeft/index.tsx
Normal file
58
src/containers/profile/ProfilePageLeft/index.tsx
Normal 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 };
|
79
src/containers/profile/ProfilePageLeft/styles.scss
Normal file
79
src/containers/profile/ProfilePageLeft/styles.scss
Normal 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;
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue