mirror of
https://github.com/elyby/accounts-frontend.git
synced 2024-12-16 02:08:59 +05:30
Наверстал форму смены пароля и чуток отрефакторил профиль
This commit is contained in:
parent
107a2bdd70
commit
e5552ee5f8
@ -7,9 +7,10 @@ import { userShape } from 'components/user/User';
|
||||
|
||||
import ProfileField from './ProfileField';
|
||||
import styles from './profile.scss';
|
||||
import profileForm from './profileForm.scss';
|
||||
import messages from './Profile.messages';
|
||||
|
||||
export class Profile extends Component {
|
||||
export default class Profile extends Component {
|
||||
static displayName = 'Profile';
|
||||
static propTypes = {
|
||||
user: userShape
|
||||
@ -19,62 +20,67 @@ export class Profile extends Component {
|
||||
const { user } = this.props;
|
||||
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
<div>
|
||||
<Message {...messages.accountPreferencesTitle}>
|
||||
{(pageTitle) => (
|
||||
<h2 className={styles.title}>
|
||||
<h2 className={styles.indexTitle}>
|
||||
<Helmet title={pageTitle} />
|
||||
{pageTitle}
|
||||
</h2>
|
||||
)}
|
||||
</Message>
|
||||
|
||||
<div className={styles.content}>
|
||||
<div className={styles.description}>
|
||||
<Message {...messages.accountDescription} />
|
||||
<div className={styles.indexContent}>
|
||||
<div className={styles.descriptionColumn}>
|
||||
<div className={styles.indexDescription}>
|
||||
<Message {...messages.accountDescription} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className={styles.options}>
|
||||
<div className={styles.item}>
|
||||
<h3 className={styles.optionsTitle}>
|
||||
<Message {...messages.personalData} />
|
||||
</h3>
|
||||
<p className={styles.optionsDescription}>
|
||||
<Message {...messages.preferencesDescription} />
|
||||
</p>
|
||||
<div className={styles.formColumn}>
|
||||
<div className={profileForm.form}>
|
||||
<div className={styles.item}>
|
||||
<h3 className={profileForm.title}>
|
||||
<Message {...messages.personalData} />
|
||||
</h3>
|
||||
<p className={profileForm.description}>
|
||||
<Message {...messages.preferencesDescription} />
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<ProfileField
|
||||
label={<Message {...messages.nickname} />}
|
||||
value={user.username}
|
||||
warningMessage={<Message {...messages.mojangPriorityWarning} />}
|
||||
/>
|
||||
|
||||
<ProfileField
|
||||
label={'E-mail'}
|
||||
value={user.email}
|
||||
/>
|
||||
|
||||
<ProfileField
|
||||
label={<Message {...messages.password} />}
|
||||
link="/profile/change-password"
|
||||
value={<Message {...messages.changedAt} values={{
|
||||
at: (<Relative value={user.passwordChangedAt * 1000} />)
|
||||
}} />}
|
||||
warningMessage={user.shouldChangePassword ? (
|
||||
<HTMLMessage {...messages.oldHashingAlgoWarning} />
|
||||
) : ''}
|
||||
/>
|
||||
|
||||
<ProfileField
|
||||
label={<Message {...messages.twoFactorAuth} />}
|
||||
value={<Message {...messages.disabled} />}
|
||||
/>
|
||||
|
||||
<ProfileField
|
||||
label={'UUID'}
|
||||
value={user.uuid}
|
||||
readonly
|
||||
/>
|
||||
</div>
|
||||
|
||||
<ProfileField
|
||||
label={<Message {...messages.nickname} />}
|
||||
value={user.username}
|
||||
warningMessage={<Message {...messages.mojangPriorityWarning} />}
|
||||
/>
|
||||
|
||||
<ProfileField
|
||||
label={'E-mail'}
|
||||
value={user.email}
|
||||
/>
|
||||
|
||||
<ProfileField
|
||||
label={<Message {...messages.password} />}
|
||||
value={<Message {...messages.changedAt} values={{
|
||||
at: (<Relative value={user.passwordChangedAt * 1000} />)
|
||||
}} />}
|
||||
warningMessage={user.shouldChangePassword ? (
|
||||
<HTMLMessage {...messages.oldHashingAlgoWarning} />
|
||||
) : ''}
|
||||
/>
|
||||
|
||||
<ProfileField
|
||||
label={<Message {...messages.twoFactorAuth} />}
|
||||
value={<Message {...messages.disabled} />}
|
||||
/>
|
||||
|
||||
<ProfileField
|
||||
label={'UUID'}
|
||||
value={user.uuid}
|
||||
readonly
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,18 +1,21 @@
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
|
||||
import { Link } from 'react-router';
|
||||
|
||||
import styles from './profile.scss';
|
||||
|
||||
export default class ProfileField extends Component {
|
||||
static displayName = 'ProfileField';
|
||||
static propTypes = {
|
||||
label: React.PropTypes.oneOfType([PropTypes.string, PropTypes.element]).isRequired,
|
||||
link: PropTypes.string,
|
||||
value: React.PropTypes.oneOfType([PropTypes.string, PropTypes.element]).isRequired,
|
||||
warningMessage: React.PropTypes.oneOfType([PropTypes.string, PropTypes.element]),
|
||||
readonly: PropTypes.bool
|
||||
};
|
||||
|
||||
render() {
|
||||
const {label, value, warningMessage, readonly} = this.props;
|
||||
const {label, value, warningMessage, readonly, link = '#'} = this.props;
|
||||
|
||||
return (
|
||||
<div className={styles.paramItem}>
|
||||
@ -22,9 +25,9 @@ export default class ProfileField extends Component {
|
||||
|
||||
{readonly ? '' : (
|
||||
<div className={styles.paramAction}>
|
||||
<a href="#">
|
||||
<Link to={link}>
|
||||
<span className={styles.paramEditIcon} />
|
||||
</a>
|
||||
</Link>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
65
src/components/profile/changePassword/ChangePassword.jsx
Normal file
65
src/components/profile/changePassword/ChangePassword.jsx
Normal file
@ -0,0 +1,65 @@
|
||||
import React, { Component } from 'react';
|
||||
|
||||
import { FormattedMessage as Message } from 'react-intl';
|
||||
import { Link } from 'react-router';
|
||||
import Helmet from 'react-helmet';
|
||||
import classNames from 'classnames';
|
||||
|
||||
import { LabeledInput } from 'components/ui/Form';
|
||||
import buttons from 'components/ui/buttons.scss';
|
||||
|
||||
import styles from 'components/profile/profileForm.scss';
|
||||
import messages from './ChangePassword.messages';
|
||||
|
||||
export default class ChangePassword extends Component {
|
||||
displayName = 'ChangePassword';
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className={styles.contentWithBackButton}>
|
||||
<Link className={styles.backButton} to="/" />
|
||||
|
||||
<div className={styles.form}>
|
||||
<div className={styles.formBody}>
|
||||
<Message {...messages.changePasswordTitle}>
|
||||
{(pageTitle) => (
|
||||
<h3 className={styles.title}>
|
||||
<Helmet title={pageTitle} />
|
||||
{pageTitle}
|
||||
</h3>
|
||||
)}
|
||||
</Message>
|
||||
|
||||
<div className={styles.formRow}>
|
||||
<p className={styles.description}>
|
||||
<Message {...messages.changePasswordDescription} />
|
||||
<br/>
|
||||
<b>
|
||||
<Message {...messages.achievementLossWarning} />
|
||||
</b>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className={styles.formRow}>
|
||||
<LabeledInput skin="light" label={messages.newPasswordLabel} />
|
||||
</div>
|
||||
|
||||
<div className={styles.formRow}>
|
||||
<p className={styles.description}>
|
||||
<Message {...messages.passwordRequirements} />
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className={styles.formRow}>
|
||||
<LabeledInput skin="light" label={messages.repeatNewPasswordLabel} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button className={classNames(buttons.green, buttons.block)}>
|
||||
<Message {...messages.changePasswordButton} />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
import { defineMessages } from 'react-intl';
|
||||
|
||||
export default defineMessages({
|
||||
changePasswordTitle: {
|
||||
id: 'changePasswordTitle',
|
||||
defaultMessage: 'Change password'
|
||||
// defaultMessage: 'Смена пароля'
|
||||
},
|
||||
changePasswordDescription: {
|
||||
id: 'changePasswordDescription',
|
||||
defaultMessage: 'Please take a password, that will be different from your passwords on the other sites and will not be the same you are using to enter Minecraft game servers you are playing.'
|
||||
// defaultMessage: 'Придумайте пароль, который будет отличаться от ваших паролей на других сайтах и не будет совпадаеть с тем паролем, который вы используете для входа на различные игровые сервера Minecraft.'
|
||||
},
|
||||
achievementLossWarning: {
|
||||
id: 'achievementLossWarning',
|
||||
defaultMessage: 'Are you cherish your game achievements, right?'
|
||||
// defaultMessage: 'Вы ведь дорожите своими игровыми достижениями?'
|
||||
},
|
||||
passwordRequirements: {
|
||||
id: 'passwordRequirements',
|
||||
defaultMessage: 'Password must contain at least 8 characters. It can be any symbols — do not limit yourself, create an unpredictable password!'
|
||||
// defaultMessage: 'Пароль должен содержать не менее 8 символов. Это могут быть любым символы — не ограничивайте себя, придумайте непредсказуемый пароль!'
|
||||
},
|
||||
changePasswordButton: {
|
||||
id: 'changePasswordButton',
|
||||
defaultMessage: 'Change password'
|
||||
// defaultMessage: 'Сменить пароль'
|
||||
},
|
||||
newPasswordLabel: {
|
||||
id: 'newPasswordLabel',
|
||||
defaultMessage: 'New password:'
|
||||
// defaultMessage: 'Новый пароль:'
|
||||
},
|
||||
repeatNewPasswordLabel: {
|
||||
id: 'repeatNewPasswordLabel',
|
||||
defaultMessage: 'Repeat the password:'
|
||||
// defaultMessage: 'Повторите указанный пароль:'
|
||||
}
|
||||
});
|
@ -1,62 +1,32 @@
|
||||
@import '~components/ui/fonts.scss';
|
||||
@import '~components/ui/colors.scss';
|
||||
|
||||
.container {
|
||||
margin-top: 55px;
|
||||
}
|
||||
|
||||
|
||||
.title {
|
||||
font-family: $font-family-title;
|
||||
font-size: 30px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.content {
|
||||
.indexContent {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.description {
|
||||
font-size: 14px;
|
||||
line-height: 1.4;
|
||||
color: #9a9a9a;
|
||||
width: 340px;
|
||||
padding: 12px 20px 0 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.options {
|
||||
background: #fff;
|
||||
.formColumn {
|
||||
flex-grow: 1;
|
||||
max-width: 416px;
|
||||
border-bottom: 10px solid #ddd8ce;
|
||||
}
|
||||
|
||||
.optionsTitle {
|
||||
position: relative;
|
||||
font-size: 24px;
|
||||
font-family: $font-family-title;
|
||||
padding-bottom: 9px;
|
||||
|
||||
&:after {
|
||||
content: '';
|
||||
display: block;
|
||||
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
height: 3px;
|
||||
width: 86px;
|
||||
|
||||
background: $green;
|
||||
}
|
||||
.descriptionColumn {
|
||||
width: 340px;
|
||||
padding: 12px 20px 0 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.optionsDescription {
|
||||
font-size: 13px;
|
||||
.indexTitle {
|
||||
font-family: $font-family-title;
|
||||
font-size: 30px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.indexDescription {
|
||||
font-size: 14px;
|
||||
line-height: 1.4;
|
||||
color: #9a9a9a;
|
||||
line-height: 1.25;
|
||||
margin-top: 25px;
|
||||
}
|
||||
|
||||
.item {
|
||||
|
65
src/components/profile/profileForm.scss
Normal file
65
src/components/profile/profileForm.scss
Normal file
@ -0,0 +1,65 @@
|
||||
@import '~components/ui/fonts.scss';
|
||||
@import '~components/ui/colors.scss';
|
||||
|
||||
.contentWithBackButton {
|
||||
position: relative;
|
||||
padding-left: 60px;
|
||||
width: 400px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.backButton {
|
||||
composes: arrow from 'components/ui/icons.scss';
|
||||
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 15px;
|
||||
width: 25px;
|
||||
height: 25px;
|
||||
padding: 15px;
|
||||
|
||||
transform: rotate(90deg);
|
||||
|
||||
color: #ccc;
|
||||
font-size: 25px;
|
||||
}
|
||||
|
||||
.form {
|
||||
background: #fff;
|
||||
overflow: hidden; // disable margin collapsing
|
||||
}
|
||||
|
||||
.formBody {
|
||||
margin: 30px;
|
||||
}
|
||||
|
||||
.formRow {
|
||||
margin: 25px 0;
|
||||
}
|
||||
|
||||
.title {
|
||||
position: relative;
|
||||
font-size: 24px;
|
||||
font-family: $font-family-title;
|
||||
padding-bottom: 9px;
|
||||
|
||||
&:after {
|
||||
content: '';
|
||||
display: block;
|
||||
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
height: 3px;
|
||||
width: 86px;
|
||||
|
||||
background: $green;
|
||||
}
|
||||
}
|
||||
|
||||
.description {
|
||||
font-size: 13px;
|
||||
color: #9a9a9a;
|
||||
line-height: 1.3;
|
||||
margin-top: 25px;
|
||||
}
|
@ -71,3 +71,8 @@
|
||||
@include button-theme('orange', $orange);
|
||||
@include button-theme('darkBlue', $dark_blue);
|
||||
@include button-theme('lightViolet', $light_violet);
|
||||
|
||||
.block {
|
||||
display: block;
|
||||
width: 100%;
|
||||
}
|
||||
|
@ -2,13 +2,18 @@ import React, { Component } from 'react';
|
||||
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import { Profile } from 'components/profile/Profile';
|
||||
import ProfilePage from 'pages/profile/ProfilePage';
|
||||
import Profile from 'components/profile/Profile';
|
||||
|
||||
class IndexPage extends Component {
|
||||
displayName = 'IndexPage';
|
||||
|
||||
render() {
|
||||
return (<Profile {...this.props} />);
|
||||
return (
|
||||
<ProfilePage>
|
||||
<Profile {...this.props} />
|
||||
</ProfilePage>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
15
src/pages/profile/ProfilePage.jsx
Normal file
15
src/pages/profile/ProfilePage.jsx
Normal file
@ -0,0 +1,15 @@
|
||||
import React, { Component } from 'react';
|
||||
|
||||
import styles from './profile.scss';
|
||||
|
||||
export default class ProfilePage extends Component {
|
||||
displayName = 'ProfilePage';
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
{this.props.children}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
3
src/pages/profile/profile.scss
Normal file
3
src/pages/profile/profile.scss
Normal file
@ -0,0 +1,3 @@
|
||||
.container {
|
||||
margin-top: 55px;
|
||||
}
|
@ -4,6 +4,7 @@ import { Route, IndexRoute } from 'react-router';
|
||||
import RootPage from 'pages/root/RootPage';
|
||||
import IndexPage from 'pages/index/IndexPage';
|
||||
import AuthPage from 'pages/auth/AuthPage';
|
||||
import ProfilePage from 'pages/profile/ProfilePage';
|
||||
|
||||
import { authenticate } from 'components/user/actions';
|
||||
|
||||
@ -18,6 +19,8 @@ import ChangePassword from 'components/auth/changePassword/ChangePassword';
|
||||
import ForgotPassword from 'components/auth/forgotPassword/ForgotPassword';
|
||||
import Finish from 'components/auth/finish/Finish';
|
||||
|
||||
import ProfileChangePassword from 'components/profile/changePassword/ChangePassword';
|
||||
|
||||
import authFlow from 'services/authFlow';
|
||||
|
||||
export default function routesFactory(store) {
|
||||
@ -50,6 +53,10 @@ export default function routesFactory(store) {
|
||||
<Route path="/change-password" components={new ChangePassword()} {...onEnter} />
|
||||
<Route path="/forgot-password" components={new ForgotPassword()} {...onEnter} />
|
||||
</Route>
|
||||
|
||||
<Route path="profile" component={ProfilePage}>
|
||||
<Route path="change-password" component={ProfileChangePassword} />
|
||||
</Route>
|
||||
</Route>
|
||||
);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user