Merge remote-tracking branch 'origin/rules_improvements'

This commit is contained in:
SleepWalker 2016-06-03 22:45:45 +03:00
commit 02a18aee13
8 changed files with 162 additions and 53 deletions

View File

@ -3,7 +3,8 @@
"personalData": "Personal data", "personalData": "Personal data",
"accountDescription": "Ely.by account allows you to get access to many Minecraft resources. Please, take care of your account safety. Use secure password and change it regularly.", "accountDescription": "Ely.by account allows you to get access to many Minecraft resources. Please, take care of your account safety. Use secure password and change it regularly.",
"preferencesDescription": "Here you can change the key preferences of your account. Please note that all actions must be confirmed by entering a password.", "preferencesDescription": "Here you can change the key preferences of your account. Please note that all actions must be confirmed by entering a password.",
"mojangPriorityWarning": "A Mojang account with the same nickname was found. According to project rules, account owner has the right to demand the restoration of control over nickname.", "mojangPriorityWarning": "A Mojang account with the same nickname was found. According to {rules}, account owner has the right to demand the restoration of control over nickname.",
"projectRules": "project rules",
"oldHashingAlgoWarning": "Your was hashed with an old hashing algorithm.<br />Please, change password.", "oldHashingAlgoWarning": "Your was hashed with an old hashing algorithm.<br />Please, change password.",
"changedAt": "Changed {at}", "changedAt": "Changed {at}",
"disabled": "Disabled", "disabled": "Disabled",

View File

@ -1,6 +1,7 @@
import React, { Component } from 'react'; import React, { Component } from 'react';
import { FormattedMessage as Message, FormattedRelative as Relative, FormattedHTMLMessage as HTMLMessage } from 'react-intl'; import { FormattedMessage as Message, FormattedRelative as Relative, FormattedHTMLMessage as HTMLMessage } from 'react-intl';
import { Link } from 'react-router';
import Helmet from 'react-helmet'; import Helmet from 'react-helmet';
import { userShape } from 'components/user/User'; import { userShape } from 'components/user/User';
@ -12,6 +13,8 @@ import styles from './profile.scss';
import profileForm from './profileForm.scss'; import profileForm from './profileForm.scss';
import messages from './Profile.intl.json'; import messages from './Profile.intl.json';
import RulesPage from 'pages/rules/RulesPage';
export default class Profile extends Component { export default class Profile extends Component {
static displayName = 'Profile'; static displayName = 'Profile';
static propTypes = { static propTypes = {
@ -55,7 +58,16 @@ export default class Profile extends Component {
label={<Message {...messages.nickname} />} label={<Message {...messages.nickname} />}
value={user.username} value={user.username}
warningMessage={user.hasMojangUsernameCollision ? ( warningMessage={user.hasMojangUsernameCollision ? (
<Message {...messages.mojangPriorityWarning} /> <Message {...messages.mojangPriorityWarning} values={{
rules: (
<Link to={{
pathname: '/rules',
hash: `#${RulesPage.getRuleHash(1, 4)}`
}}>
<Message {...messages.projectRules} />
</Link>
)
}} />
) : ''} ) : ''}
/> />

View File

@ -95,6 +95,16 @@ $formColumnWidth: 416px;
color: $red; color: $red;
font-size: 11px; font-size: 11px;
line-height: 1.2; line-height: 1.2;
a {
color: $red;
border-bottom: 1px dashed transparent;
transition: .25s;
&:hover {
border-bottom-color: lighter($red);
}
}
} }
.uuid { .uuid {

View File

@ -104,7 +104,7 @@
"components.profile.changeUsername.changeUsernameWarning": "Be careful: if you playing on the server with nickname binding, then after changing nickname you may lose all your progress.", "components.profile.changeUsername.changeUsernameWarning": "Be careful: if you playing on the server with nickname binding, then after changing nickname you may lose all your progress.",
"components.profile.changedAt": "Changed {at}", "components.profile.changedAt": "Changed {at}",
"components.profile.disabled": "Disabled", "components.profile.disabled": "Disabled",
"components.profile.mojangPriorityWarning": "A Mojang account with the same nickname was found. According to project rules, account owner has the right to demand the restoration of control over nickname.", "components.profile.mojangPriorityWarning": "A Mojang account with the same nickname was found. According to {rules}, account owner has the right to demand the restoration of control over nickname.",
"components.profile.nickname": "Nickname", "components.profile.nickname": "Nickname",
"components.profile.oldHashingAlgoWarning": "Your was hashed with an old hashing algorithm.<br />Please, change password.", "components.profile.oldHashingAlgoWarning": "Your was hashed with an old hashing algorithm.<br />Please, change password.",
"components.profile.password": "Password", "components.profile.password": "Password",
@ -112,6 +112,7 @@
"components.profile.passwordRequestForm.title": "Confirm your action", "components.profile.passwordRequestForm.title": "Confirm your action",
"components.profile.personalData": "Personal data", "components.profile.personalData": "Personal data",
"components.profile.preferencesDescription": "Here you can change the key preferences of your account. Please note that all actions must be confirmed by entering a password.", "components.profile.preferencesDescription": "Here you can change the key preferences of your account. Please note that all actions must be confirmed by entering a password.",
"components.profile.projectRules": "project rules",
"components.profile.twoFactorAuth": "Two factor auth", "components.profile.twoFactorAuth": "Two factor auth",
"components.userbar.logout": "Logout", "components.userbar.logout": "Logout",
"components.userbar.register": "Join", "components.userbar.register": "Join",
@ -134,6 +135,7 @@
"pages.rules.mainProvision3": "Ely.by is side project, that has nothing to do with Mojang and Microsoft companies. We don't provide support to Minecraft premium accounts, and we have nothing to do with servers that use or don't use our services.", "pages.rules.mainProvision3": "Ely.by is side project, that has nothing to do with Mojang and Microsoft companies. We don't provide support to Minecraft premium accounts, and we have nothing to do with servers that use or don't use our services.",
"pages.rules.mainProvision4": "The registration of the users account at server is free. Account creation Ely.by is only possible at that page {link}.", "pages.rules.mainProvision4": "The registration of the users account at server is free. Account creation Ely.by is only possible at that page {link}.",
"pages.rules.mainProvisions": "Main provisions", "pages.rules.mainProvisions": "Main provisions",
"pages.rules.title": "Site rules",
"services.accountAlreadyActivated": "This account is already activated", "services.accountAlreadyActivated": "This account is already activated",
"services.accountNotActivated": "The account is not activated", "services.accountNotActivated": "The account is not activated",
"services.doYouWantRequestKey": "Do you want to request a new key?", "services.doYouWantRequestKey": "Do you want to request a new key?",

View File

@ -104,7 +104,7 @@
"components.profile.changeUsername.changeUsernameWarning": "Будьте внимательны: если вы играли на сервере с привязкой по нику, то после смены ника вы можете утратить весь свой прогресс.", "components.profile.changeUsername.changeUsernameWarning": "Будьте внимательны: если вы играли на сервере с привязкой по нику, то после смены ника вы можете утратить весь свой прогресс.",
"components.profile.changedAt": "Изменен {at}", "components.profile.changedAt": "Изменен {at}",
"components.profile.disabled": "Не включена", "components.profile.disabled": "Не включена",
"components.profile.mojangPriorityWarning": "Найден аккаунт Mojang с таким же ником и, по правилам проекта, его владелец вправе потребовать восстановления контроля над ником.", "components.profile.mojangPriorityWarning": "Найден аккаунт Mojang с таким же ником и, по {rules}, его владелец вправе потребовать восстановления контроля над ником.",
"components.profile.nickname": "Ник", "components.profile.nickname": "Ник",
"components.profile.oldHashingAlgoWarning": "Для пароля применяется старый алгоритм хэширования<br />Пожалуйста, смените пароль.", "components.profile.oldHashingAlgoWarning": "Для пароля применяется старый алгоритм хэширования<br />Пожалуйста, смените пароль.",
"components.profile.password": "Пароль", "components.profile.password": "Пароль",
@ -112,6 +112,7 @@
"components.profile.passwordRequestForm.title": "Confirm your action", "components.profile.passwordRequestForm.title": "Confirm your action",
"components.profile.personalData": "Персональные данные", "components.profile.personalData": "Персональные данные",
"components.profile.preferencesDescription": "Здесь вы можете сменить ключевые параметры вашего аккаунта. Обратите внимание, что для всех действий необходимо подтверждение при помощи ввода пароля.", "components.profile.preferencesDescription": "Здесь вы можете сменить ключевые параметры вашего аккаунта. Обратите внимание, что для всех действий необходимо подтверждение при помощи ввода пароля.",
"components.profile.projectRules": "правилам проекта",
"components.profile.twoFactorAuth": "Двухфакторная аутентификация", "components.profile.twoFactorAuth": "Двухфакторная аутентификация",
"components.userbar.logout": "Выход", "components.userbar.logout": "Выход",
"components.userbar.register": "Регистрация", "components.userbar.register": "Регистрация",
@ -134,6 +135,7 @@
"pages.rules.mainProvision3": "Ely.by является сторонней разработкой, не имеющей никакого отношения к компаниям Mojang и Microsoft. Мы не оказываем поддержки по премиум аккаунтам Minecraft, а также никак не связаны с игровыми серверами, использующими или не использующими наши сервисы.", "pages.rules.mainProvision3": "Ely.by является сторонней разработкой, не имеющей никакого отношения к компаниям Mojang и Microsoft. Мы не оказываем поддержки по премиум аккаунтам Minecraft, а также никак не связаны с игровыми серверами, использующими или не использующими наши сервисы.",
"pages.rules.mainProvision4": "Регистрация пользовательского аккаунта на сервисе бесплатна. Создание аккаунта Ely.by возможно только на странице {link}.", "pages.rules.mainProvision4": "Регистрация пользовательского аккаунта на сервисе бесплатна. Создание аккаунта Ely.by возможно только на странице {link}.",
"pages.rules.mainProvisions": "Основные положения", "pages.rules.mainProvisions": "Основные положения",
"pages.rules.title": "Правила сайта",
"services.accountAlreadyActivated": "Этот аккаунт уже активирован", "services.accountAlreadyActivated": "Этот аккаунт уже активирован",
"services.accountNotActivated": "Аккаунт не активирован", "services.accountNotActivated": "Аккаунт не активирован",
"services.doYouWantRequestKey": "Не хотите отправить новый код?", "services.doYouWantRequestKey": "Не хотите отправить новый код?",

View File

@ -1,4 +1,6 @@
{ {
"title" : "Site rules",
"mainProvisions": "Main provisions", "mainProvisions": "Main provisions",
"mainProvision1": "{name} service was created for the organization of safety access to Ely.by's users accounts, his partners and any side project that wish to use one of the our's services", "mainProvision1": "{name} service was created for the organization of safety access to Ely.by's users accounts, his partners and any side project that wish to use one of the our's services",
"mainProvision2": "We (here and in the next points) - Ely.by project developers team that make creating qualitative services for Minecraft community.", "mainProvision2": "We (here and in the next points) - Ely.by project developers team that make creating qualitative services for Minecraft community.",

View File

@ -1,7 +1,8 @@
import React from 'react'; import React, { Component, PropTypes } from 'react';
import { Link } from 'react-router'; import { Link } from 'react-router';
import { FormattedMessage as Message } from 'react-intl'; import { FormattedMessage as Message } from 'react-intl';
import Helmet from 'react-helmet';
import { FooterMenu } from 'components/footerMenu'; import { FooterMenu } from 'components/footerMenu';
@ -12,30 +13,32 @@ import appInfo from 'components/auth/appInfo/AppInfo.intl.json';
const projectName = <Message {...appInfo.appName} />; const projectName = <Message {...appInfo.appName} />;
import classNames from 'classnames';
const rules = [ const rules = [
{ {
title: <Message {...messages.mainProvisions} />, title: <Message {...messages.mainProvisions} />,
items: [ items: [
(<Message {...messages.mainProvision1} values={{ <Message {...messages.mainProvision1} values={{
name: (<b>{projectName}</b>) name: (<b>{projectName}</b>)
}} />), }} />,
(<Message {...messages.mainProvision2} />), <Message {...messages.mainProvision2} />,
(<Message {...messages.mainProvision3} />), <Message {...messages.mainProvision3} />,
(<Message {...messages.mainProvision4} values={{ <Message {...messages.mainProvision4} values={{
link: (<Link to={'/register'}>https://account.ely.by/register</Link>) link: (<Link to={'/register'}>https://account.ely.by/register</Link>)
}} />) }} />
] ]
}, },
{ {
title: <Message {...messages.emailAndNickname} />, title: <Message {...messages.emailAndNickname} />,
items: [ items: [
(<Message {...messages.emailAndNickname1} />), <Message {...messages.emailAndNickname1} />,
(<Message {...messages.emailAndNickname2} />), <Message {...messages.emailAndNickname2} />,
(<Message {...messages.emailAndNickname3} />), <Message {...messages.emailAndNickname3} />,
(<Message {...messages.emailAndNickname4} />), <Message {...messages.emailAndNickname4} />,
(<Message {...messages.emailAndNickname5} />), <Message {...messages.emailAndNickname5} />,
(<Message {...messages.emailAndNickname6} />), <Message {...messages.emailAndNickname6} />,
(<Message {...messages.emailAndNickname7} />) <Message {...messages.emailAndNickname7} />
] ]
}, },
{ {
@ -49,20 +52,51 @@ const rules = [
<p><Message {...messages.elyAccountsAsServiceDesc2} /></p> <p><Message {...messages.elyAccountsAsServiceDesc2} /></p>
</div>), </div>),
items: [ items: [
(<Message {...messages.elyAccountsAsService1} />), <Message {...messages.elyAccountsAsService1} />,
(<Message {...messages.elyAccountsAsService2} />) <Message {...messages.elyAccountsAsService2} />
] ]
} }
]; ];
export default function RulesPage() { export default class RulesPage extends Component {
static propTypes = {
location: PropTypes.shape({
hash: PropTypes.string
})
};
static contextTypes = {
router: PropTypes.shape({
createLocation: PropTypes.func.required,
replace: PropTypes.func.required
}).isRequired
};
render() {
let {hash} = this.props.location;
if (hash) {
hash = hash.substring(1);
}
return ( return (
<div> <div>
<Message {...messages.title}>
{(pageTitle) => (
<Helmet title={pageTitle} />
)}
</Message>
<div className={styles.rules}> <div className={styles.rules}>
{rules.map((block, sectionIndex) => ( {rules.map((block, sectionIndex) => (
<div className={styles.rulesSection} key={sectionIndex}> <div className={styles.rulesSection} key={sectionIndex}>
<span id={`rule-${sectionIndex + 1}`} /> <h2
<h2 className={styles.rulesSectionTitle}>{block.title}</h2> className={classNames(styles.rulesSectionTitle, {
[styles.target]: RulesPage.getTitleHash(sectionIndex) === hash
})}
id={RulesPage.getTitleHash(sectionIndex)}
>
{block.title}
</h2>
<div className={styles.rulesBody}> <div className={styles.rulesBody}>
{block.description ? ( {block.description ? (
@ -72,8 +106,14 @@ export default function RulesPage() {
) : ''} ) : ''}
<ol className={styles.rulesList}> <ol className={styles.rulesList}>
{block.items.map((item, ruleIndex) => ( {block.items.map((item, ruleIndex) => (
<li className={styles.rulesItem} key={ruleIndex}> <li
<span id={`rule-${sectionIndex + 1}-${ruleIndex + 1}`} /> className={classNames(styles.rulesItem, {
[styles.target]: RulesPage.getRuleHash(sectionIndex, ruleIndex) === hash
})}
key={ruleIndex}
id={RulesPage.getRuleHash(sectionIndex, ruleIndex)}
onClick={this.onRuleClick.bind(this)}
>
{item} {item}
</li> </li>
))} ))}
@ -89,4 +129,20 @@ export default function RulesPage() {
); );
} }
onRuleClick(event) {
const {id} = event.currentTarget;
const {router} = this.context;
const newLocation = router.createLocation({...location, hash: `#${id}`});
router.replace(newLocation);
}
static getTitleHash(sectionIndex) {
return `rule-${sectionIndex + 1}`;
}
static getRuleHash(sectionIndex, ruleIndex) {
return `${RulesPage.getTitleHash(sectionIndex)}-${ruleIndex + 1}`;
}
}
RulesPage.displayName = 'RulesPage'; RulesPage.displayName = 'RulesPage';

View File

@ -25,6 +25,10 @@
} }
.rulesBody { .rulesBody {
position: relative;
// z-index, чтобы положить :before ниже текста, но выше фона блока
z-index: 0;
padding: 20px; padding: 20px;
background: #fff; background: #fff;
font-size: 14px; font-size: 14px;
@ -53,22 +57,42 @@
@extend %rulesTextFormat; @extend %rulesTextFormat;
list-style: decimal; list-style: decimal;
position: relative;
cursor: pointer;
&:last-of-type { &:last-of-type {
margin-bottom: 0; margin-bottom: 0;
} }
&.target {
&:before {
cursor: default;
$border: 8px solid #ddd8ce;
content: '';
position: absolute;
top: -10px;
left: -40px;
width: calc(100% + 60px);
height: calc(100% + 20px);
background: $light;
border-left: $border;
border-right: $border;
box-sizing: border-box;
z-index: -1;
}
}
a { a {
color: #444; color: #444;
border-bottom: 1px dotted #aaa; border-bottom: 1px dotted #aaa;
text-decoration: none; text-decoration: none;
transition: .25s transition: .25s;
}
a:hover { &:hover {
border-bottom-color: #444 border-bottom-color: #444
} }
} }
}
.footer { .footer {
text-align: center; text-align: center;