mirror of
https://github.com/elyby/accounts-frontend.git
synced 2024-12-23 05:29:56 +05:30
Remove all *.intl.json files. Move strings to the corresponding views. Implement custom command to build i18n/en.json file
This commit is contained in:
parent
57cf6b3776
commit
bf6a76d006
24
@types/react-intl.d.ts
vendored
Normal file
24
@types/react-intl.d.ts
vendored
Normal file
@ -0,0 +1,24 @@
|
||||
import { PrimitiveType } from 'intl-messageformat';
|
||||
import { Formatters, IntlConfig, IntlFormatters, MessageDescriptor } from 'react-intl';
|
||||
|
||||
declare module 'react-intl' {
|
||||
// Babel's plugin react-intl-auto always converts passed strings messages into the MessageDescriptor
|
||||
export declare function defineMessages<U extends Record<string, string | MessageDescriptor>>(
|
||||
msgs: U,
|
||||
): Record<keyof U, MessageDescriptor>;
|
||||
|
||||
// Babel's plugin react-intl-auto allows to call the formatMessage function with "key" field to automatically
|
||||
// generate message's id
|
||||
export interface KeyBasedMessageDescriptor {
|
||||
key: string;
|
||||
defaultMessage: string;
|
||||
}
|
||||
|
||||
export declare interface IntlShape extends IntlConfig, IntlFormatters {
|
||||
formatters: Formatters;
|
||||
formatMessage(
|
||||
descriptor: MessageDescriptor | KeyBasedMessageDescriptor,
|
||||
values?: Record<string, PrimitiveType>,
|
||||
): string;
|
||||
}
|
||||
}
|
102
babel.config.js
102
babel.config.js
@ -1,50 +1,62 @@
|
||||
/* eslint-env node */
|
||||
module.exports = {
|
||||
presets: [
|
||||
[
|
||||
'@babel/preset-typescript',
|
||||
{
|
||||
allowDeclareFields: true,
|
||||
},
|
||||
],
|
||||
'@babel/preset-react',
|
||||
[
|
||||
'@babel/preset-env',
|
||||
{
|
||||
ignoreBrowserslistConfig: true,
|
||||
targets: {
|
||||
node: true,
|
||||
// @ts-nocheck
|
||||
module.exports = function (api) {
|
||||
api.cache(true);
|
||||
|
||||
return {
|
||||
presets: [
|
||||
[
|
||||
'@babel/preset-typescript',
|
||||
{
|
||||
allowDeclareFields: true,
|
||||
},
|
||||
modules: 'commonjs',
|
||||
},
|
||||
],
|
||||
],
|
||||
plugins: [
|
||||
'@babel/plugin-syntax-dynamic-import',
|
||||
'@babel/plugin-proposal-function-bind',
|
||||
'@babel/plugin-proposal-class-properties',
|
||||
[
|
||||
'@babel/plugin-transform-runtime',
|
||||
{
|
||||
corejs: 3,
|
||||
},
|
||||
],
|
||||
['react-intl', { messagesDir: './build/messages/' }],
|
||||
],
|
||||
env: {
|
||||
webpack: {
|
||||
plugins: ['react-hot-loader/babel'],
|
||||
presets: [
|
||||
[
|
||||
'@babel/preset-env',
|
||||
{
|
||||
ignoreBrowserslistConfig: false,
|
||||
modules: false,
|
||||
useBuiltIns: 'usage', // or "entry"
|
||||
corejs: 3,
|
||||
},
|
||||
],
|
||||
],
|
||||
'@babel/preset-react',
|
||||
[
|
||||
'@babel/preset-env',
|
||||
{
|
||||
ignoreBrowserslistConfig: true,
|
||||
targets: {
|
||||
node: true,
|
||||
},
|
||||
modules: 'commonjs',
|
||||
},
|
||||
],
|
||||
],
|
||||
plugins: [
|
||||
'@babel/plugin-syntax-dynamic-import',
|
||||
'@babel/plugin-proposal-function-bind',
|
||||
'@babel/plugin-proposal-class-properties',
|
||||
[
|
||||
'@babel/plugin-transform-runtime',
|
||||
{
|
||||
corejs: 3,
|
||||
},
|
||||
],
|
||||
[
|
||||
'react-intl-auto',
|
||||
{
|
||||
removePrefix: 'packages.app',
|
||||
messagesDir: './build/messages/',
|
||||
useKey: true,
|
||||
},
|
||||
],
|
||||
],
|
||||
env: {
|
||||
webpack: {
|
||||
plugins: ['react-hot-loader/babel'],
|
||||
presets: [
|
||||
[
|
||||
'@babel/preset-env',
|
||||
{
|
||||
ignoreBrowserslistConfig: false,
|
||||
modules: false,
|
||||
useBuiltIns: 'usage', // or "entry"
|
||||
corejs: 3,
|
||||
},
|
||||
],
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
};
|
||||
|
@ -35,7 +35,7 @@
|
||||
"ts:check": "tsc",
|
||||
"ci:check": "yarn lint:check && yarn ts:check && yarn test",
|
||||
"analyze": "yarn run clean && yarn run build:webpack --analyze",
|
||||
"i18n:collect": "babel-node --extensions \".ts\" ./packages/scripts/i18n-collect.ts",
|
||||
"i18n:extract": "extract-messages -l=en -o ./packages/app/i18n --flat true 'packages/app/!(node_modules)/**/*.[tj]s?(x)'",
|
||||
"i18n:push": "babel-node --extensions \".ts\" ./packages/scripts/i18n-crowdin.ts push",
|
||||
"i18n:pull": "babel-node --extensions \".ts\" ./packages/scripts/i18n-crowdin.ts pull",
|
||||
"build": "yarn run clean && yarn run build:webpack",
|
||||
@ -117,7 +117,7 @@
|
||||
"@typescript-eslint/eslint-plugin": "^3.0.0",
|
||||
"@typescript-eslint/parser": "^3.0.0",
|
||||
"babel-loader": "^8.0.0",
|
||||
"babel-plugin-react-intl": "^7.5.10",
|
||||
"babel-plugin-react-intl-auto": "^3.3.0",
|
||||
"core-js": "3.6.5",
|
||||
"csp-webpack-plugin": "^2.0.2",
|
||||
"css-loader": "^3.5.3",
|
||||
@ -130,6 +130,7 @@
|
||||
"eslint-plugin-prettier": "^3.1.3",
|
||||
"eslint-plugin-react": "^7.20.0",
|
||||
"exports-loader": "^0.7.0",
|
||||
"extract-react-intl-messages": "^4.1.1",
|
||||
"file-loader": "^6.0.0",
|
||||
"html-loader": "^1.1.0",
|
||||
"html-webpack-plugin": "^4.3.0",
|
||||
|
@ -1,5 +0,0 @@
|
||||
{
|
||||
"addAccount": "Add account",
|
||||
"goToEly": "Go to Ely.by profile",
|
||||
"logout": "Log out"
|
||||
}
|
@ -11,7 +11,6 @@ import { getActiveAccount, Account } from 'app/components/accounts/reducer';
|
||||
import { RootState } from 'app/reducers';
|
||||
|
||||
import styles from './accountSwitcher.scss';
|
||||
import messages from './AccountSwitcher.intl.json';
|
||||
|
||||
interface Props {
|
||||
switchAccount: (account: Account) => Promise<Account>;
|
||||
@ -70,7 +69,7 @@ export class AccountSwitcher extends React.Component<Props> {
|
||||
<div className={styles.links}>
|
||||
<div className={styles.link}>
|
||||
<a href={`http://ely.by/u${activeAccount.id}`} target="_blank">
|
||||
<Message {...messages.goToEly} />
|
||||
<Message key="goToEly" defaultMessage="Go to Ely.by profile" />
|
||||
</a>
|
||||
</div>
|
||||
<div className={styles.link}>
|
||||
@ -80,7 +79,7 @@ export class AccountSwitcher extends React.Component<Props> {
|
||||
onClick={this.onRemove(activeAccount)}
|
||||
href="#"
|
||||
>
|
||||
<Message {...messages.logout} />
|
||||
<Message key="logout" defaultMessage="Log out" />
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
@ -127,7 +126,7 @@ export class AccountSwitcher extends React.Component<Props> {
|
||||
small
|
||||
className={styles.addAccount}
|
||||
label={
|
||||
<Message {...messages.addAccount}>
|
||||
<Message key="addAccount" defaultMessage="Add account">
|
||||
{(message) => (
|
||||
<span>
|
||||
<div className={styles.addIcon} />
|
||||
|
@ -1,8 +0,0 @@
|
||||
{
|
||||
"title": "User Agreement",
|
||||
"accept": "Accept",
|
||||
"declineAndLogout": "Decline and logout",
|
||||
"description1": "We have updated our {link}.",
|
||||
"termsOfService": "terms of service",
|
||||
"description2": "In order to continue using {name} service, you need to accept them."
|
||||
}
|
@ -1,6 +1,12 @@
|
||||
import { defineMessages } from 'react-intl';
|
||||
import factory from '../factory';
|
||||
import Body from './AcceptRulesBody';
|
||||
import messages from './AcceptRules.intl.json';
|
||||
|
||||
const messages = defineMessages({
|
||||
title: 'User Agreement',
|
||||
accept: 'Accept',
|
||||
declineAndLogout: 'Decline and logout',
|
||||
});
|
||||
|
||||
export default factory({
|
||||
title: messages.title,
|
||||
|
@ -5,10 +5,9 @@ import { Link } from 'react-router-dom';
|
||||
|
||||
import icons from 'app/components/ui/icons.scss';
|
||||
import BaseAuthBody from 'app/components/auth/BaseAuthBody';
|
||||
import appInfo from 'app/components/auth/appInfo/AppInfo.intl.json';
|
||||
import appName from 'app/components/auth/appInfo/appName.intl';
|
||||
|
||||
import styles from './acceptRules.scss';
|
||||
import messages from './AcceptRules.intl.json';
|
||||
|
||||
export default class AcceptRulesBody extends BaseAuthBody {
|
||||
static displayName = 'AcceptRulesBody';
|
||||
@ -25,20 +24,22 @@ export default class AcceptRulesBody extends BaseAuthBody {
|
||||
|
||||
<p className={styles.descriptionText}>
|
||||
<Message
|
||||
{...messages.description1}
|
||||
key="description1"
|
||||
defaultMessage="We have updated our {link}."
|
||||
values={{
|
||||
link: (
|
||||
<Link to="/rules" target="_blank">
|
||||
<Message {...messages.termsOfService} />
|
||||
<Message key="termsOfService" defaultMessage="terms of service" />
|
||||
</Link>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
<br />
|
||||
<Message
|
||||
{...messages.description2}
|
||||
key="description2"
|
||||
defaultMessage="In order to continue using {name} service, you need to accept them."
|
||||
values={{
|
||||
name: <Message {...appInfo.appName} />,
|
||||
name: <Message {...appName} />,
|
||||
}}
|
||||
/>
|
||||
</p>
|
||||
|
@ -1,8 +0,0 @@
|
||||
{
|
||||
"accountActivationTitle": "Account activation",
|
||||
"activationMailWasSent": "Please check {email} for the message with further instructions",
|
||||
"activationMailWasSentNoEmail": "Please check your E‑mail for the message with further instructions",
|
||||
"confirmEmail": "Confirm E‑mail",
|
||||
"didNotReceivedEmail": "Did not received E‑mail?",
|
||||
"enterTheCode": "Enter the code from E‑mail here"
|
||||
}
|
@ -1,7 +1,13 @@
|
||||
import { defineMessages } from 'react-intl';
|
||||
import factory from '../factory';
|
||||
import messages from './Activation.intl.json';
|
||||
import Body from './ActivationBody';
|
||||
|
||||
const messages = defineMessages({
|
||||
accountActivationTitle: 'Account activation',
|
||||
confirmEmail: 'Confirm E‑mail',
|
||||
didNotReceivedEmail: 'Did not received E‑mail?',
|
||||
});
|
||||
|
||||
export default factory({
|
||||
title: messages.accountActivationTitle,
|
||||
body: Body,
|
||||
|
@ -1,12 +1,15 @@
|
||||
import React from 'react';
|
||||
|
||||
import { FormattedMessage as Message } from 'react-intl';
|
||||
import { defineMessages, FormattedMessage as Message } from 'react-intl';
|
||||
|
||||
import { Input } from 'app/components/ui/form';
|
||||
|
||||
import BaseAuthBody from 'app/components/auth/BaseAuthBody';
|
||||
import styles from './activation.scss';
|
||||
import messages from './Activation.intl.json';
|
||||
|
||||
const messages = defineMessages({
|
||||
enterTheCode: 'Enter the code from E‑mail here',
|
||||
});
|
||||
|
||||
export default class ActivationBody extends BaseAuthBody {
|
||||
static displayName = 'ActivationBody';
|
||||
@ -28,13 +31,17 @@ export default class ActivationBody extends BaseAuthBody {
|
||||
<div className={styles.descriptionText}>
|
||||
{email ? (
|
||||
<Message
|
||||
{...messages.activationMailWasSent}
|
||||
key="activationMailWasSent"
|
||||
defaultMessage="Please check {email} for the message with further instructions"
|
||||
values={{
|
||||
email: <b>{email}</b>,
|
||||
}}
|
||||
/>
|
||||
) : (
|
||||
<Message {...messages.activationMailWasSentNoEmail} />
|
||||
<Message
|
||||
key="activationMailWasSentNoEmail"
|
||||
defaultMessage="Please check your E‑mail for the message with further instructions"
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,7 +0,0 @@
|
||||
{
|
||||
"appName": "Ely Accounts",
|
||||
"goToAuth": "Go to auth",
|
||||
"appDescription": "You are on the Ely.by authorization service, that allows you to safely perform any operations on your account. This single entry point for websites and desktop software, including game launchers.",
|
||||
"useItYourself": "Visit our {link}, to learn how to use this service in you projects.",
|
||||
"documentation": "documentation"
|
||||
}
|
@ -1,10 +1,14 @@
|
||||
import React from 'react';
|
||||
import { FormattedMessage as Message } from 'react-intl';
|
||||
import { defineMessages, FormattedMessage as Message } from 'react-intl';
|
||||
import { Button } from 'app/components/ui/form';
|
||||
import { FooterMenu } from 'app/components/footerMenu';
|
||||
|
||||
import appName from './appName.intl';
|
||||
import styles from './appInfo.scss';
|
||||
import messages from './AppInfo.intl.json';
|
||||
|
||||
const messages = defineMessages({
|
||||
goToAuth: 'Go to auth',
|
||||
});
|
||||
|
||||
export default class AppInfo extends React.Component<{
|
||||
name?: string;
|
||||
@ -17,7 +21,7 @@ export default class AppInfo extends React.Component<{
|
||||
return (
|
||||
<div className={styles.appInfo}>
|
||||
<div className={styles.logoContainer}>
|
||||
<h2 className={styles.logo}>{name ? name : <Message {...messages.appName} />}</h2>
|
||||
<h2 className={styles.logo}>{name ? name : <Message {...appName} />}</h2>
|
||||
</div>
|
||||
<div className={styles.descriptionContainer}>
|
||||
{description ? (
|
||||
@ -25,15 +29,19 @@ export default class AppInfo extends React.Component<{
|
||||
) : (
|
||||
<div>
|
||||
<p className={styles.description}>
|
||||
<Message {...messages.appDescription} />
|
||||
<Message
|
||||
key="appDescription"
|
||||
defaultMessage="You are on the Ely.by authorization service, that allows you to safely perform any operations on your account. This single entry point for websites and desktop software, including game launchers."
|
||||
/>
|
||||
</p>
|
||||
<p className={styles.description}>
|
||||
<Message
|
||||
{...messages.useItYourself}
|
||||
key="useItYourself"
|
||||
defaultMessage="Visit our {link}, to learn how to use this service in you projects."
|
||||
values={{
|
||||
link: (
|
||||
<a href="http://docs.ely.by/oauth.html">
|
||||
<Message {...messages.documentation} />
|
||||
<Message key="documentation" defaultMessage="documentation" />
|
||||
</a>
|
||||
),
|
||||
}}
|
||||
|
7
packages/app/components/auth/appInfo/appName.intl.ts
Normal file
7
packages/app/components/auth/appInfo/appName.intl.ts
Normal file
@ -0,0 +1,7 @@
|
||||
import { defineMessages } from 'react-intl';
|
||||
|
||||
const { appName } = defineMessages({
|
||||
appName: 'Ely Accounts',
|
||||
});
|
||||
|
||||
export default appName;
|
@ -1,7 +0,0 @@
|
||||
{
|
||||
"chooseAccountTitle": "Choose an account",
|
||||
"addAccount": "Log into another account",
|
||||
"logoutAll": "Log out from all accounts",
|
||||
"pleaseChooseAccount": "Please select an account you're willing to use",
|
||||
"pleaseChooseAccountForApp": "Please select an account that you want to use to authorize {appName}"
|
||||
}
|
@ -1,7 +1,13 @@
|
||||
import { defineMessages } from 'react-intl';
|
||||
import factory from '../factory';
|
||||
import messages from './ChooseAccount.intl.json';
|
||||
import Body from './ChooseAccountBody';
|
||||
|
||||
const messages = defineMessages({
|
||||
chooseAccountTitle: 'Choose an account',
|
||||
addAccount: 'Log into another account',
|
||||
logoutAll: 'Log out from all accounts',
|
||||
});
|
||||
|
||||
export default factory({
|
||||
title: messages.chooseAccountTitle,
|
||||
body: Body,
|
||||
|
@ -7,7 +7,6 @@ import { AccountSwitcher } from 'app/components/accounts';
|
||||
import { Account } from 'app/components/accounts/reducer';
|
||||
|
||||
import styles from './chooseAccount.scss';
|
||||
import messages from './ChooseAccount.intl.json';
|
||||
|
||||
export default class ChooseAccountBody extends BaseAuthBody {
|
||||
static displayName = 'ChooseAccountBody';
|
||||
@ -23,14 +22,18 @@ export default class ChooseAccountBody extends BaseAuthBody {
|
||||
<div className={styles.description}>
|
||||
{client ? (
|
||||
<Message
|
||||
{...messages.pleaseChooseAccountForApp}
|
||||
key="pleaseChooseAccountForApp"
|
||||
defaultMessage="Please select an account that you want to use to authorize {appName}"
|
||||
values={{
|
||||
appName: <span className={styles.appName}>{client.name}</span>,
|
||||
}}
|
||||
/>
|
||||
) : (
|
||||
<div className={styles.description}>
|
||||
<Message {...messages.pleaseChooseAccount} />
|
||||
<Message
|
||||
key="pleaseChooseAccount"
|
||||
defaultMessage="Please select an account you're willing to use"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
@ -1,7 +0,0 @@
|
||||
{
|
||||
"authForAppSuccessful": "Authorization for {appName} was successfully completed",
|
||||
"authForAppFailed": "Authorization for {appName} was failed",
|
||||
"waitAppReaction": "Please, wait till your application response",
|
||||
"passCodeToApp": "To complete authorization process, please, provide the following code to {appName}",
|
||||
"copy": "Copy"
|
||||
}
|
@ -1,14 +1,17 @@
|
||||
import React, { MouseEventHandler } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { FormattedMessage as Message } from 'react-intl';
|
||||
import { defineMessages, FormattedMessage as Message } from 'react-intl';
|
||||
import { Helmet } from 'react-helmet-async';
|
||||
import { Button } from 'app/components/ui/form';
|
||||
import copy from 'app/services/copy';
|
||||
import { RootState } from 'app/reducers';
|
||||
|
||||
import messages from './Finish.intl.json';
|
||||
import styles from './finish.scss';
|
||||
|
||||
const messages = defineMessages({
|
||||
copy: 'Copy',
|
||||
});
|
||||
|
||||
interface Props {
|
||||
appName: string;
|
||||
code?: string;
|
||||
@ -36,7 +39,8 @@ class Finish extends React.Component<Props> {
|
||||
<div className={styles.successBackground} />
|
||||
<div className={styles.greenTitle}>
|
||||
<Message
|
||||
{...messages.authForAppSuccessful}
|
||||
key="authForAppSuccessful"
|
||||
defaultMessage="Authorization for {appName} was successfully completed"
|
||||
values={{
|
||||
appName: <span className={styles.appName}>{appName}</span>,
|
||||
}}
|
||||
@ -45,7 +49,11 @@ class Finish extends React.Component<Props> {
|
||||
{displayCode ? (
|
||||
<div data-testid="oauth-code-container">
|
||||
<div className={styles.description}>
|
||||
<Message {...messages.passCodeToApp} values={{ appName }} />
|
||||
<Message
|
||||
key="passCodeToApp"
|
||||
defaultMessage="To complete authorization process, please, provide the following code to {appName}"
|
||||
values={{ appName }}
|
||||
/>
|
||||
</div>
|
||||
<div className={styles.codeContainer}>
|
||||
<div className={styles.code}>{code}</div>
|
||||
@ -54,7 +62,10 @@ class Finish extends React.Component<Props> {
|
||||
</div>
|
||||
) : (
|
||||
<div className={styles.description}>
|
||||
<Message {...messages.waitAppReaction} />
|
||||
<Message
|
||||
key="waitAppReaction"
|
||||
defaultMessage="Please, wait till your application response"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
@ -63,14 +74,18 @@ class Finish extends React.Component<Props> {
|
||||
<div className={styles.failBackground} />
|
||||
<div className={styles.redTitle}>
|
||||
<Message
|
||||
{...messages.authForAppFailed}
|
||||
key="authForAppFailed"
|
||||
defaultMessage="Authorization for {appName} was failed"
|
||||
values={{
|
||||
appName: <span className={styles.appName}>{appName}</span>,
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div className={styles.description}>
|
||||
<Message {...messages.waitAppReaction} />
|
||||
<Message
|
||||
key="waitAppReaction"
|
||||
defaultMessage="Please, wait till your application response"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
@ -1,7 +0,0 @@
|
||||
{
|
||||
"title": "Forgot password",
|
||||
"sendMail": "Send mail",
|
||||
"specifyEmail": "Specify the registration E‑mail address or last used username for your account and we will send an E‑mail with instructions for further password recovery.",
|
||||
"pleasePressButton": "Please press the button bellow to get an E‑mail with password recovery code.",
|
||||
"alreadyHaveCode": "Already have a code"
|
||||
}
|
@ -1,7 +1,13 @@
|
||||
import { defineMessages } from 'react-intl';
|
||||
import factory from '../factory';
|
||||
import messages from './ForgotPassword.intl.json';
|
||||
import Body from './ForgotPasswordBody';
|
||||
|
||||
const messages = defineMessages({
|
||||
title: 'Forgot password',
|
||||
sendMail: 'Send mail',
|
||||
alreadyHaveCode: 'Already have a code',
|
||||
});
|
||||
|
||||
export default factory({
|
||||
title: messages.title,
|
||||
body: Body,
|
||||
|
@ -1,6 +1,6 @@
|
||||
import React from 'react';
|
||||
|
||||
import { FormattedMessage as Message } from 'react-intl';
|
||||
import { defineMessages, FormattedMessage as Message } from 'react-intl';
|
||||
|
||||
import { Input, Captcha } from 'app/components/ui/form';
|
||||
import { getLogin } from 'app/components/auth/reducer';
|
||||
@ -8,7 +8,10 @@ import { PanelIcon } from 'app/components/ui/Panel';
|
||||
import BaseAuthBody from 'app/components/auth/BaseAuthBody';
|
||||
|
||||
import styles from './forgotPassword.scss';
|
||||
import messages from './ForgotPassword.intl.json';
|
||||
|
||||
const messages = defineMessages({
|
||||
emailOrUsername: 'E‑mail or username',
|
||||
});
|
||||
|
||||
export default class ForgotPasswordBody extends BaseAuthBody {
|
||||
static displayName = 'ForgotPasswordBody';
|
||||
@ -36,14 +39,17 @@ export default class ForgotPasswordBody extends BaseAuthBody {
|
||||
{isLoginEditShown ? (
|
||||
<div>
|
||||
<p className={styles.descriptionText}>
|
||||
<Message {...messages.specifyEmail} />
|
||||
<Message
|
||||
key="specifyEmail"
|
||||
defaultMessage="Specify the registration E‑mail address or last used username for your account and we will send an E‑mail with instructions for further password recovery."
|
||||
/>
|
||||
</p>
|
||||
<Input
|
||||
{...this.bindField('login')}
|
||||
icon="envelope"
|
||||
color="lightViolet"
|
||||
required
|
||||
placeholder={messages.accountEmail}
|
||||
placeholder={messages.emailOrUsername}
|
||||
defaultValue={login}
|
||||
/>
|
||||
</div>
|
||||
@ -54,7 +60,10 @@ export default class ForgotPasswordBody extends BaseAuthBody {
|
||||
<span className={styles.editLogin} onClick={this.onClickEdit} data-testid="edit-login" />
|
||||
</div>
|
||||
<p className={styles.descriptionText}>
|
||||
<Message {...messages.pleasePressButton} />
|
||||
<Message
|
||||
key="pleasePressButton"
|
||||
defaultMessage="Please press the button bellow to get an E‑mail with password recovery code."
|
||||
/>
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
|
@ -1,6 +0,0 @@
|
||||
{
|
||||
"createNewAccount": "Create new account",
|
||||
"loginTitle": "Sign in",
|
||||
"emailOrUsername": "E‑mail or username",
|
||||
"next": "Next"
|
||||
}
|
@ -1,6 +1,12 @@
|
||||
import { defineMessages } from 'react-intl';
|
||||
import factory from '../factory';
|
||||
import Body from './LoginBody';
|
||||
import messages from './Login.intl.json';
|
||||
|
||||
const messages = defineMessages({
|
||||
createNewAccount: 'Create new account',
|
||||
loginTitle: 'Sign in',
|
||||
next: 'Next',
|
||||
});
|
||||
|
||||
export default factory({
|
||||
title: messages.loginTitle,
|
||||
|
@ -1,10 +1,13 @@
|
||||
import React from 'react';
|
||||
import { defineMessages } from 'react-intl';
|
||||
|
||||
import { Input } from 'app/components/ui/form';
|
||||
import BaseAuthBody from 'app/components/auth/BaseAuthBody';
|
||||
import { User } from 'app/components/user/reducer';
|
||||
|
||||
import messages from './Login.intl.json';
|
||||
const messages = defineMessages({
|
||||
emailOrUsername: 'E‑mail or username',
|
||||
});
|
||||
|
||||
export default class LoginBody extends BaseAuthBody {
|
||||
static displayName = 'LoginBody';
|
||||
|
@ -1,4 +0,0 @@
|
||||
{
|
||||
"enterTotp": "Enter code",
|
||||
"description": "In order to sign in this account, you need to enter a one-time password from mobile application"
|
||||
}
|
@ -1,13 +1,17 @@
|
||||
import { defineMessages } from 'react-intl';
|
||||
import factory from '../factory';
|
||||
import Body from './MfaBody';
|
||||
import messages from './Mfa.intl.json';
|
||||
import passwordMessages from '../password/Password.intl.json';
|
||||
|
||||
const messages = defineMessages({
|
||||
enterTotp: 'Enter code',
|
||||
signInButton: 'Sign in',
|
||||
});
|
||||
|
||||
export default factory({
|
||||
title: messages.enterTotp,
|
||||
body: Body,
|
||||
footer: {
|
||||
color: 'green',
|
||||
label: passwordMessages.signInButton,
|
||||
label: messages.signInButton,
|
||||
},
|
||||
});
|
||||
|
@ -1,11 +1,14 @@
|
||||
import React from 'react';
|
||||
import { FormattedMessage as Message } from 'react-intl';
|
||||
import { defineMessages, FormattedMessage as Message } from 'react-intl';
|
||||
import { PanelIcon } from 'app/components/ui/Panel';
|
||||
import { Input } from 'app/components/ui/form';
|
||||
import BaseAuthBody from 'app/components/auth/BaseAuthBody';
|
||||
|
||||
import styles from './mfa.scss';
|
||||
import messages from './Mfa.intl.json';
|
||||
|
||||
const messages = defineMessages({
|
||||
enterTotp: 'Enter code',
|
||||
});
|
||||
|
||||
export default class MfaBody extends BaseAuthBody {
|
||||
static panelId = 'mfa';
|
||||
@ -21,7 +24,10 @@ export default class MfaBody extends BaseAuthBody {
|
||||
<PanelIcon icon="lock" />
|
||||
|
||||
<p className={styles.descriptionText}>
|
||||
<Message {...messages.description} />
|
||||
<Message
|
||||
key="description"
|
||||
defaultMessage="In order to sign in this account, you need to enter a one-time password from mobile application"
|
||||
/>
|
||||
</p>
|
||||
|
||||
<Input
|
||||
|
@ -1,7 +0,0 @@
|
||||
{
|
||||
"passwordTitle": "Enter password",
|
||||
"signInButton": "Sign in",
|
||||
"forgotPassword": "Forgot password",
|
||||
"accountPassword": "Account password",
|
||||
"rememberMe": "Remember me on this device"
|
||||
}
|
@ -1,6 +1,12 @@
|
||||
import { defineMessages } from 'react-intl';
|
||||
import factory from '../factory';
|
||||
import Body from './PasswordBody';
|
||||
import messages from './Password.intl.json';
|
||||
|
||||
const messages = defineMessages({
|
||||
passwordTitle: 'Enter password',
|
||||
signInButton: 'Sign in',
|
||||
forgotPassword: 'Forgot password',
|
||||
});
|
||||
|
||||
export default factory({
|
||||
title: messages.passwordTitle,
|
||||
|
@ -3,9 +3,14 @@ import icons from 'app/components/ui/icons.scss';
|
||||
import { Input, Checkbox } from 'app/components/ui/form';
|
||||
import BaseAuthBody from 'app/components/auth/BaseAuthBody';
|
||||
import authStyles from 'app/components/auth/auth.scss';
|
||||
import { defineMessages } from 'react-intl';
|
||||
|
||||
import styles from './password.scss';
|
||||
import messages from './Password.intl.json';
|
||||
|
||||
const messages = defineMessages({
|
||||
accountPassword: 'Account password',
|
||||
rememberMe: 'Remember me on this device',
|
||||
});
|
||||
|
||||
export default class PasswordBody extends BaseAuthBody {
|
||||
static displayName = 'PasswordBody';
|
||||
|
@ -1,12 +0,0 @@
|
||||
{
|
||||
"permissionsTitle": "Application permissions",
|
||||
"youAuthorizedAs": "You authorized as:",
|
||||
"theAppNeedsAccess1": "This application needs access",
|
||||
"theAppNeedsAccess2": "to your data",
|
||||
"decline": "Decline",
|
||||
"approve": "Approve",
|
||||
"scope_minecraft_server_session": "Authorization data for minecraft server",
|
||||
"scope_offline_access": "Access to your profile data, when you offline",
|
||||
"scope_account_info": "Access to your profile data (except E‑mail)",
|
||||
"scope_account_email": "Access to your E‑mail address"
|
||||
}
|
@ -1,7 +1,13 @@
|
||||
import { defineMessages } from 'react-intl';
|
||||
import factory from '../factory';
|
||||
import messages from './Permissions.intl.json';
|
||||
import Body from './PermissionsBody';
|
||||
|
||||
const messages = defineMessages({
|
||||
permissionsTitle: 'Application permissions',
|
||||
decline: 'Decline',
|
||||
approve: 'Approve',
|
||||
});
|
||||
|
||||
export default factory({
|
||||
title: messages.permissionsTitle,
|
||||
body: Body,
|
||||
|
@ -1,11 +1,17 @@
|
||||
import React from 'react';
|
||||
import { FormattedMessage as Message } from 'react-intl';
|
||||
import { defineMessages, FormattedMessage as Message } from 'react-intl';
|
||||
import icons from 'app/components/ui/icons.scss';
|
||||
import { PanelBodyHeader } from 'app/components/ui/Panel';
|
||||
import BaseAuthBody from 'app/components/auth/BaseAuthBody';
|
||||
|
||||
import styles from './permissions.scss';
|
||||
import messages from './Permissions.intl.json';
|
||||
|
||||
const scopesMessages = defineMessages({
|
||||
scope_minecraft_server_session: 'Authorization data for minecraft server',
|
||||
scope_offline_access: 'Access to your profile data, when you offline',
|
||||
scope_account_info: 'Access to your profile data (except E‑mail)',
|
||||
scope_account_email: 'Access to your E‑mail address',
|
||||
});
|
||||
|
||||
export default class PermissionsBody extends BaseAuthBody {
|
||||
static displayName = 'PermissionsBody';
|
||||
@ -25,21 +31,22 @@ export default class PermissionsBody extends BaseAuthBody {
|
||||
{user.avatar ? <img src={user.avatar} /> : <span className={icons.user} />}
|
||||
</div>
|
||||
<div className={styles.authInfoTitle}>
|
||||
<Message {...messages.youAuthorizedAs} />
|
||||
<Message key="youAuthorizedAs" defaultMessage="You authorized as:" />
|
||||
</div>
|
||||
<div className={styles.authInfoEmail}>{user.username}</div>
|
||||
</div>
|
||||
</PanelBodyHeader>
|
||||
<div className={styles.permissionsContainer}>
|
||||
<div className={styles.permissionsTitle}>
|
||||
<Message {...messages.theAppNeedsAccess1} />
|
||||
<Message key="theAppNeedsAccess1" defaultMessage="This application needs access" />
|
||||
<br />
|
||||
<Message {...messages.theAppNeedsAccess2} />
|
||||
<Message key="theAppNeedsAccess2" defaultMessage="to your data" />
|
||||
</div>
|
||||
<ul className={styles.permissionsList}>
|
||||
{scopes.map((scope) => {
|
||||
const key = `scope_${scope}`;
|
||||
const message = messages[key];
|
||||
// @ts-ignore
|
||||
const message = scopesMessages[key];
|
||||
|
||||
return (
|
||||
<li key={key}>
|
||||
|
@ -1,12 +0,0 @@
|
||||
{
|
||||
"title": "Restore password",
|
||||
"contactSupport": "Contact support",
|
||||
"messageWasSent": "The recovery code was sent to your account E‑mail.",
|
||||
"messageWasSentTo": "The recovery code was sent to your E‑mail {email}.",
|
||||
"enterCodeBelow": "Please enter the code received into the field below:",
|
||||
"enterNewPasswordBelow": "Enter and repeat new password below:",
|
||||
"change": "Change password",
|
||||
"newPassword": "Enter new password",
|
||||
"newRePassword": "Repeat new password",
|
||||
"enterTheCode": "Enter confirmation code"
|
||||
}
|
@ -1,7 +1,13 @@
|
||||
import { defineMessages } from 'react-intl';
|
||||
import factory from '../factory';
|
||||
import messages from './RecoverPassword.intl.json';
|
||||
import Body from './RecoverPasswordBody';
|
||||
|
||||
const messages = defineMessages({
|
||||
title: 'Restore password',
|
||||
contactSupport: 'Contact support',
|
||||
change: 'Change password',
|
||||
});
|
||||
|
||||
export default factory({
|
||||
title: messages.title,
|
||||
body: Body,
|
||||
|
@ -1,15 +1,20 @@
|
||||
import React from 'react';
|
||||
|
||||
import { FormattedMessage as Message } from 'react-intl';
|
||||
import { defineMessages, FormattedMessage as Message } from 'react-intl';
|
||||
|
||||
import { Input } from 'app/components/ui/form';
|
||||
import BaseAuthBody from 'app/components/auth/BaseAuthBody';
|
||||
|
||||
import styles from './recoverPassword.scss';
|
||||
import messages from './RecoverPassword.intl.json';
|
||||
|
||||
// TODO: activation code field may be decoupled into common component and reused here and in activation panel
|
||||
|
||||
const placeholders = defineMessages({
|
||||
newPassword: 'Enter new password',
|
||||
newRePassword: 'Repeat new password',
|
||||
enterTheCode: 'Enter confirmation code',
|
||||
});
|
||||
|
||||
export default class RecoverPasswordBody extends BaseAuthBody {
|
||||
static displayName = 'RecoverPasswordBody';
|
||||
static panelId = 'recoverPassword';
|
||||
@ -28,15 +33,22 @@ export default class RecoverPasswordBody extends BaseAuthBody {
|
||||
<p className={styles.descriptionText}>
|
||||
{user.maskedEmail ? (
|
||||
<Message
|
||||
{...messages.messageWasSentTo}
|
||||
key="messageWasSentTo"
|
||||
defaultMessage="The recovery code was sent to your E‑mail {email}."
|
||||
values={{
|
||||
email: <b>{user.maskedEmail}</b>,
|
||||
}}
|
||||
/>
|
||||
) : (
|
||||
<Message {...messages.messageWasSent} />
|
||||
<Message
|
||||
key="messageWasSent"
|
||||
defaultMessage="The recovery code was sent to your account E‑mail."
|
||||
/>
|
||||
)}{' '}
|
||||
<Message {...messages.enterCodeBelow} />
|
||||
<Message
|
||||
key="enterCodeBelow"
|
||||
defaultMessage="Please enter the code received into the field below:"
|
||||
/>
|
||||
</p>
|
||||
|
||||
<Input
|
||||
@ -47,11 +59,11 @@ export default class RecoverPasswordBody extends BaseAuthBody {
|
||||
value={key}
|
||||
readOnly={!!key}
|
||||
autoComplete="off"
|
||||
placeholder={messages.enterTheCode}
|
||||
placeholder={placeholders.enterTheCode}
|
||||
/>
|
||||
|
||||
<p className={styles.descriptionText}>
|
||||
<Message {...messages.enterNewPasswordBelow} />
|
||||
<Message key="enterNewPasswordBelow" defaultMessage="Enter and repeat new password below:" />
|
||||
</p>
|
||||
|
||||
<Input
|
||||
@ -60,7 +72,7 @@ export default class RecoverPasswordBody extends BaseAuthBody {
|
||||
color="lightViolet"
|
||||
type="password"
|
||||
required
|
||||
placeholder={messages.newPassword}
|
||||
placeholder={placeholders.newPassword}
|
||||
/>
|
||||
|
||||
<Input
|
||||
@ -69,7 +81,7 @@ export default class RecoverPasswordBody extends BaseAuthBody {
|
||||
color="lightViolet"
|
||||
type="password"
|
||||
required
|
||||
placeholder={messages.newRePassword}
|
||||
placeholder={placeholders.newRePassword}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
@ -1,10 +0,0 @@
|
||||
{
|
||||
"registerTitle": "Sign Up",
|
||||
"yourNickname": "Your nickname",
|
||||
"yourEmail": "Your E‑mail",
|
||||
"accountPassword": "Account password",
|
||||
"repeatPassword": "Repeat password",
|
||||
"signUpButton": "Register",
|
||||
"acceptRules": "I agree with {link}",
|
||||
"termsOfService": "terms of service"
|
||||
}
|
@ -1,9 +1,14 @@
|
||||
import { defineMessages } from 'react-intl';
|
||||
import factory from '../factory';
|
||||
import activationMessages from '../activation/Activation.intl.json';
|
||||
import forgotPasswordMessages from '../forgotPassword/ForgotPassword.intl.json';
|
||||
import messages from './Register.intl.json';
|
||||
import Body from './RegisterBody';
|
||||
|
||||
const messages = defineMessages({
|
||||
registerTitle: 'Sign Up',
|
||||
signUpButton: 'Register',
|
||||
didNotReceivedEmail: 'Did not received E‑mail?',
|
||||
alreadyHaveCode: 'Already have a code',
|
||||
});
|
||||
|
||||
export default factory({
|
||||
title: messages.registerTitle,
|
||||
body: Body,
|
||||
@ -13,11 +18,11 @@ export default factory({
|
||||
},
|
||||
links: [
|
||||
{
|
||||
label: activationMessages.didNotReceivedEmail,
|
||||
label: messages.didNotReceivedEmail,
|
||||
payload: { requestEmail: true },
|
||||
},
|
||||
{
|
||||
label: forgotPasswordMessages.alreadyHaveCode,
|
||||
label: messages.alreadyHaveCode,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
@ -1,15 +1,20 @@
|
||||
import React from 'react';
|
||||
import { FormattedMessage as Message } from 'react-intl';
|
||||
import { defineMessages, FormattedMessage as Message } from 'react-intl';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { Input, Checkbox, Captcha } from 'app/components/ui/form';
|
||||
import BaseAuthBody from 'app/components/auth/BaseAuthBody';
|
||||
|
||||
import passwordMessages from '../password/Password.intl.json';
|
||||
import styles from '../auth.scss';
|
||||
import messages from './Register.intl.json';
|
||||
|
||||
// TODO: password and username can be validate for length and sameness
|
||||
|
||||
const placeholders = defineMessages({
|
||||
yourNickname: 'Your nickname',
|
||||
yourEmail: 'Your E‑mail',
|
||||
accountPassword: 'Account password',
|
||||
repeatPassword: 'Repeat password',
|
||||
});
|
||||
|
||||
export default class RegisterBody extends BaseAuthBody {
|
||||
static panelId = 'register';
|
||||
|
||||
@ -26,7 +31,7 @@ export default class RegisterBody extends BaseAuthBody {
|
||||
color="blue"
|
||||
type="text"
|
||||
required
|
||||
placeholder={messages.yourNickname}
|
||||
placeholder={placeholders.yourNickname}
|
||||
/>
|
||||
|
||||
<Input
|
||||
@ -35,7 +40,7 @@ export default class RegisterBody extends BaseAuthBody {
|
||||
color="blue"
|
||||
type="email"
|
||||
required
|
||||
placeholder={messages.yourEmail}
|
||||
placeholder={placeholders.yourEmail}
|
||||
/>
|
||||
|
||||
<Input
|
||||
@ -44,7 +49,7 @@ export default class RegisterBody extends BaseAuthBody {
|
||||
color="blue"
|
||||
type="password"
|
||||
required
|
||||
placeholder={passwordMessages.accountPassword}
|
||||
placeholder={placeholders.accountPassword}
|
||||
/>
|
||||
|
||||
<Input
|
||||
@ -53,7 +58,7 @@ export default class RegisterBody extends BaseAuthBody {
|
||||
color="blue"
|
||||
type="password"
|
||||
required
|
||||
placeholder={messages.repeatPassword}
|
||||
placeholder={placeholders.repeatPassword}
|
||||
/>
|
||||
|
||||
<Captcha {...this.bindField('captcha')} delay={600} />
|
||||
@ -65,11 +70,12 @@ export default class RegisterBody extends BaseAuthBody {
|
||||
required
|
||||
label={
|
||||
<Message
|
||||
{...messages.acceptRules}
|
||||
key="acceptRules"
|
||||
defaultMessage="I agree with {link}"
|
||||
values={{
|
||||
link: (
|
||||
<Link to="/rules" target="_blank">
|
||||
<Message {...messages.termsOfService} />
|
||||
<Message key="termsOfService" defaultMessage="terms of service" />
|
||||
</Link>
|
||||
),
|
||||
}}
|
||||
|
@ -1,5 +0,0 @@
|
||||
{
|
||||
"title": "Did not received an E‑mail",
|
||||
"specifyYourEmail": "Please, enter an E‑mail you've registered with and we will send you new activation code",
|
||||
"sendNewEmail": "Send new E‑mail"
|
||||
}
|
@ -1,8 +1,13 @@
|
||||
import { defineMessages } from 'react-intl';
|
||||
import factory from '../factory';
|
||||
import forgotPasswordMessages from '../forgotPassword/ForgotPassword.intl.json';
|
||||
import messages from './ResendActivation.intl.json';
|
||||
import Body from './ResendActivationBody';
|
||||
|
||||
const messages = defineMessages({
|
||||
title: 'Did not received an E‑mail',
|
||||
sendNewEmail: 'Send new E‑mail',
|
||||
alreadyHaveCode: 'Already have a code',
|
||||
});
|
||||
|
||||
export default factory({
|
||||
title: messages.title,
|
||||
body: Body,
|
||||
@ -11,6 +16,6 @@ export default factory({
|
||||
label: messages.sendNewEmail,
|
||||
},
|
||||
links: {
|
||||
label: forgotPasswordMessages.alreadyHaveCode,
|
||||
label: messages.alreadyHaveCode,
|
||||
},
|
||||
});
|
||||
|
@ -1,11 +1,13 @@
|
||||
import React from 'react';
|
||||
import { FormattedMessage as Message } from 'react-intl';
|
||||
import { defineMessages, FormattedMessage as Message } from 'react-intl';
|
||||
import { Input, Captcha } from 'app/components/ui/form';
|
||||
|
||||
import BaseAuthBody from '../BaseAuthBody';
|
||||
import registerMessages from '../register/Register.intl.json';
|
||||
import styles from './resendActivation.scss';
|
||||
import messages from './ResendActivation.intl.json';
|
||||
|
||||
const placeholders = defineMessages({
|
||||
yourEmail: 'Your E‑mail',
|
||||
});
|
||||
|
||||
export default class ResendActivation extends BaseAuthBody {
|
||||
static displayName = 'ResendActivation';
|
||||
@ -20,7 +22,10 @@ export default class ResendActivation extends BaseAuthBody {
|
||||
{this.renderErrors()}
|
||||
|
||||
<div className={styles.description}>
|
||||
<Message {...messages.specifyYourEmail} />
|
||||
<Message
|
||||
key="specifyYourEmail"
|
||||
defaultMessage="Please, enter an E‑mail you've registered with and we will send you new activation code"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<Input
|
||||
@ -29,7 +34,7 @@ export default class ResendActivation extends BaseAuthBody {
|
||||
color="blue"
|
||||
type="email"
|
||||
required
|
||||
placeholder={registerMessages.yourEmail}
|
||||
placeholder={placeholders.yourEmail}
|
||||
defaultValue={this.context.user.email}
|
||||
/>
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
import React from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import clsx from 'clsx';
|
||||
import { FormattedMessage as Message } from 'react-intl';
|
||||
import { FormattedMessage as Message, defineMessages } from 'react-intl';
|
||||
import { Input, TextArea, Button, Form, FormModel, Dropdown } from 'app/components/ui/form';
|
||||
import feedback from 'app/services/api/feedback';
|
||||
import icons from 'app/components/ui/icons.scss';
|
||||
@ -11,17 +11,27 @@ import logger from 'app/services/logger';
|
||||
import { User } from 'app/components/user';
|
||||
|
||||
import styles from './contactForm.scss';
|
||||
import messages from './contactForm.intl.json';
|
||||
|
||||
const CONTACT_CATEGORIES = {
|
||||
// TODO: сюда позже проставить реальные id категорий с backend
|
||||
0: <Message {...messages.cannotAccessMyAccount} />,
|
||||
1: <Message {...messages.foundBugOnSite} />,
|
||||
2: <Message {...messages.improvementsSuggestion} />,
|
||||
3: <Message {...messages.integrationQuestion} />,
|
||||
4: <Message {...messages.other} />,
|
||||
0: <Message key="cannotAccessMyAccount" defaultMessage="Can not access my account" />,
|
||||
1: <Message key="foundBugOnSite" defaultMessage="I found a bug on the site" />,
|
||||
2: <Message key="improvementsSuggestion" defaultMessage="I have a suggestion for improving the functional" />,
|
||||
3: <Message key="integrationQuestion" defaultMessage="Service integration question" />,
|
||||
4: <Message key="other" defaultMessage="Other" />,
|
||||
};
|
||||
|
||||
const labels = defineMessages({
|
||||
subject: 'Subject',
|
||||
email: 'E‑mail',
|
||||
message: 'Message',
|
||||
whichQuestion: 'What are you interested in?',
|
||||
|
||||
send: 'Send',
|
||||
|
||||
close: 'Close',
|
||||
});
|
||||
|
||||
export class ContactForm extends React.Component<
|
||||
{
|
||||
onClose: () => void;
|
||||
@ -54,7 +64,7 @@ export class ContactForm extends React.Component<
|
||||
<div className={popupStyles.popup}>
|
||||
<div className={popupStyles.header}>
|
||||
<h2 className={popupStyles.headerTitle}>
|
||||
<Message {...messages.title} />
|
||||
<Message key="title" defaultMessage="Feedback form" />
|
||||
</h2>
|
||||
<span
|
||||
className={clsx(icons.close, popupStyles.close)}
|
||||
@ -78,24 +88,30 @@ export class ContactForm extends React.Component<
|
||||
<Form form={form} onSubmit={this.onSubmit} isLoading={isLoading}>
|
||||
<div className={popupStyles.body}>
|
||||
<div className={styles.philosophicalThought}>
|
||||
<Message {...messages.philosophicalThought} />
|
||||
<Message
|
||||
key="philosophicalThought"
|
||||
defaultMessage="Properly formulated question — half of the answer"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className={styles.formDisclaimer}>
|
||||
<Message {...messages.disclaimer} />
|
||||
<Message
|
||||
key="disclaimer"
|
||||
defaultMessage="Please formulate your feedback providing as much useful information, as possible to help us understand your problem and solve it"
|
||||
/>
|
||||
<br />
|
||||
</div>
|
||||
|
||||
<div className={styles.pairInputRow}>
|
||||
<div className={styles.pairInput}>
|
||||
<Input {...form.bindField('subject')} required label={messages.subject} skin="light" />
|
||||
<Input {...form.bindField('subject')} required label={labels.subject} skin="light" />
|
||||
</div>
|
||||
|
||||
<div className={styles.pairInput}>
|
||||
<Input
|
||||
{...form.bindField('email')}
|
||||
required
|
||||
label={messages.email}
|
||||
label={labels.email}
|
||||
type="email"
|
||||
skin="light"
|
||||
defaultValue={user.email}
|
||||
@ -106,7 +122,7 @@ export class ContactForm extends React.Component<
|
||||
<div className={styles.formMargin}>
|
||||
<Dropdown
|
||||
{...form.bindField('category')}
|
||||
label={messages.whichQuestion}
|
||||
label={labels.whichQuestion}
|
||||
items={CONTACT_CATEGORIES}
|
||||
block
|
||||
/>
|
||||
@ -115,7 +131,7 @@ export class ContactForm extends React.Component<
|
||||
<TextArea
|
||||
{...form.bindField('message')}
|
||||
required
|
||||
label={messages.message}
|
||||
label={labels.message}
|
||||
skin="light"
|
||||
minRows={6}
|
||||
maxRows={6}
|
||||
@ -123,7 +139,7 @@ export class ContactForm extends React.Component<
|
||||
</div>
|
||||
|
||||
<div className={styles.footer}>
|
||||
<Button label={messages.send} block type="submit" disabled={isLoading} />
|
||||
<Button label={labels.send} block type="submit" disabled={isLoading} />
|
||||
</div>
|
||||
</Form>
|
||||
);
|
||||
@ -138,13 +154,16 @@ export class ContactForm extends React.Component<
|
||||
<div className={styles.successBody}>
|
||||
<span className={styles.successIcon} />
|
||||
<div className={styles.successDescription}>
|
||||
<Message {...messages.youMessageReceived} />
|
||||
<Message
|
||||
key="youMessageReceived"
|
||||
defaultMessage="Your message was received. We will respond to you shortly. The answer will come to your E‑mail:"
|
||||
/>
|
||||
</div>
|
||||
<div className={styles.sentToEmail}>{email}</div>
|
||||
</div>
|
||||
|
||||
<div className={styles.footer}>
|
||||
<Button label={messages.close} block onClick={onClose} data-testid="feedback-popup-close-button" />
|
||||
<Button label={labels.close} block onClick={onClose} data-testid="feedback-popup-close-button" />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
@ -1,19 +0,0 @@
|
||||
{
|
||||
"title": "Feedback form",
|
||||
"subject": "Subject",
|
||||
"email": "E‑mail",
|
||||
"message": "Message",
|
||||
"send": "Send",
|
||||
"philosophicalThought": "Properly formulated question — half of the answer",
|
||||
"disclaimer": "Please formulate your feedback providing as much useful information, as possible to help us understand your problem and solve it",
|
||||
"whichQuestion": "What are you interested in?",
|
||||
|
||||
"cannotAccessMyAccount": "Can not access my account",
|
||||
"foundBugOnSite": "I found a bug on the site",
|
||||
"improvementsSuggestion": "I have a suggestion for improving the functional",
|
||||
"integrationQuestion": "Service integration question",
|
||||
"other": "Other",
|
||||
|
||||
"youMessageReceived": "Your message was received. We will respond to you shortly. The answer will come to your E‑mail:",
|
||||
"close": "Close"
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
{
|
||||
"accountsForDevelopers": "Ely.by Accounts for developers",
|
||||
"accountsAllowsYouYoUseOauth2": "Ely.by Accounts service provides users with a quick and easy-to-use way to login to your site, launcher or Minecraft server via OAuth2 authorization protocol. You can find more information about integration with Ely.by Accounts in {ourDocumentation}.",
|
||||
"ourDocumentation": "our documentation",
|
||||
"ifYouHaveAnyTroubles": "If you are experiencing difficulties, you can always use {feedback}. We'll surely help you.",
|
||||
"feedback": "feedback",
|
||||
"weDontKnowAnythingAboutYou": "We don't know anything about you yet.",
|
||||
"youMustAuthToBegin": "You have to authorize to start.",
|
||||
"authorization": "Authorization",
|
||||
"youDontHaveAnyApplication": "You don't have any app registered yet.",
|
||||
"shallWeStart": "Shall we start?",
|
||||
"addNew": "Add new",
|
||||
"yourApplications": "Your applications:",
|
||||
"countUsers": "{count, plural, =0 {No users} one {# user} other {# users}}",
|
||||
"ifYouSuspectingThatSecretHasBeenCompromised": "If you are suspecting that your Client Secret has been compromised, then you may want to reset it value. It'll cause recall of the all \"access\" and \"refresh\" tokens that have been issued. You can also recall all issued tokens without changing Client Secret.",
|
||||
"revokeAllTokens": "Revoke all tokens",
|
||||
"resetClientSecret": "Reset Client Secret",
|
||||
"delete": "Delete",
|
||||
"editDescription": "{icon} Edit description",
|
||||
"allRefreshTokensWillBecomeInvalid": "All \"refresh\" tokens will become invalid and after next authorization the user will get permissions prompt.",
|
||||
"appAndAllTokenWillBeDeleted": "Application and all associated tokens will be deleted.",
|
||||
"takeCareAccessTokensInvalidation": "Take care because \"access\" tokens won't be invalidated immediately.",
|
||||
"cancel": "Cancel",
|
||||
"continue": "Continue",
|
||||
"performing": "Performing…"
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
import React from 'react';
|
||||
import clsx from 'clsx';
|
||||
import { FormattedMessage as Message } from 'react-intl';
|
||||
import { defineMessages, FormattedMessage as Message } from 'react-intl';
|
||||
import { Helmet } from 'react-helmet-async';
|
||||
import { LinkButton } from 'app/components/ui/form';
|
||||
import { COLOR_GREEN, COLOR_BLUE } from 'app/components/ui';
|
||||
@ -8,12 +8,16 @@ import { ContactLink } from 'app/components/contact';
|
||||
import { OauthAppResponse } from 'app/services/api/oauth';
|
||||
|
||||
import styles from './applicationsIndex.scss';
|
||||
import messages from './ApplicationsIndex.intl.json';
|
||||
import cubeIcon from './icons/cube.svg';
|
||||
import loadingCubeIcon from './icons/loading-cube.svg';
|
||||
import toolsIcon from './icons/tools.svg';
|
||||
import ApplicationsList from './list';
|
||||
|
||||
const labels = defineMessages({
|
||||
addNew: 'Add new',
|
||||
authorization: 'Authorization',
|
||||
});
|
||||
|
||||
type Props = {
|
||||
clientId: string | null;
|
||||
resetClientId: () => void; // notify parent to remove clientId from current location.href
|
||||
@ -29,7 +33,7 @@ export default class ApplicationsIndex extends React.Component<Props> {
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
<div className={styles.welcomeContainer}>
|
||||
<Message {...messages.accountsForDevelopers}>
|
||||
<Message key="accountsForDevelopers" defaultMessage="Ely.by Accounts for developers">
|
||||
{(pageTitle: string) => (
|
||||
<h2 className={styles.welcomeTitle}>
|
||||
<Helmet title={pageTitle} />
|
||||
@ -40,11 +44,12 @@ export default class ApplicationsIndex extends React.Component<Props> {
|
||||
<div className={styles.welcomeTitleDelimiter} />
|
||||
<div className={styles.welcomeParagraph}>
|
||||
<Message
|
||||
{...messages.accountsAllowsYouYoUseOauth2}
|
||||
key="accountsAllowsYouYoUseOauth2"
|
||||
defaultMessage="Ely.by Accounts service provides users with a quick and easy-to-use way to login to your site, launcher or Minecraft server via OAuth2 authorization protocol. You can find more information about integration with Ely.by Accounts in {ourDocumentation}."
|
||||
values={{
|
||||
ourDocumentation: (
|
||||
<a href="https://docs.ely.by/en/oauth.html" target="_blank">
|
||||
<Message {...messages.ourDocumentation} />
|
||||
<Message key="ourDocumentation" defaultMessage="our documentation" />
|
||||
</a>
|
||||
),
|
||||
}}
|
||||
@ -52,11 +57,12 @@ export default class ApplicationsIndex extends React.Component<Props> {
|
||||
</div>
|
||||
<div className={styles.welcomeParagraph}>
|
||||
<Message
|
||||
{...messages.ifYouHaveAnyTroubles}
|
||||
key="ifYouHaveAnyTroubles"
|
||||
defaultMessage="If you are experiencing difficulties, you can always use {feedback}. We'll surely help you."
|
||||
values={{
|
||||
feedback: (
|
||||
<ContactLink>
|
||||
<Message {...messages.feedback} />
|
||||
<Message key="feedback" defaultMessage="feedback" />
|
||||
</ContactLink>
|
||||
),
|
||||
}}
|
||||
@ -104,17 +110,20 @@ function Loader({ noApps }: { noApps: boolean }) {
|
||||
>
|
||||
<div className={styles.emptyStateText}>
|
||||
<div>
|
||||
<Message {...messages.youDontHaveAnyApplication} />
|
||||
<Message
|
||||
key="youDontHaveAnyApplication"
|
||||
defaultMessage="You don't have any app registered yet."
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<Message {...messages.shallWeStart} />
|
||||
<Message key="shallWeStart" defaultMessage="Shall we start?" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<LinkButton
|
||||
to="/dev/applications/new"
|
||||
data-e2e="newApp"
|
||||
label={messages.addNew}
|
||||
label={labels.addNew}
|
||||
color={COLOR_GREEN}
|
||||
className={styles.emptyStateActionButton}
|
||||
/>
|
||||
@ -129,16 +138,16 @@ function Guest() {
|
||||
<img src={toolsIcon} className={styles.emptyStateIcon} />
|
||||
<div className={styles.emptyStateText}>
|
||||
<div>
|
||||
<Message {...messages.weDontKnowAnythingAboutYou} />
|
||||
<Message key="weDontKnowAnythingAboutYou" defaultMessage="We don't know anything about you yet." />
|
||||
</div>
|
||||
<div>
|
||||
<Message {...messages.youMustAuthToBegin} />
|
||||
<Message key="youMustAuthToBegin" defaultMessage="You have to authorize to start." />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<LinkButton
|
||||
to="/login"
|
||||
label={messages.authorization}
|
||||
label={labels.authorization}
|
||||
color={COLOR_BLUE}
|
||||
className={styles.emptyStateActionButton}
|
||||
/>
|
||||
|
@ -1,20 +0,0 @@
|
||||
{
|
||||
"creatingApplication": "Creating an application",
|
||||
"website": "Web site",
|
||||
"minecraftServer": "Minecraft server",
|
||||
"toDisplayRegistrationFormChooseType": "To display registration form for a new application choose necessary type.",
|
||||
"applicationName": "Application name:",
|
||||
"appDescriptionWillBeAlsoVisibleOnOauthPage": "Application's description will be displayed at the authorization page too. It isn't a required field. In authorization process the value may be overridden.",
|
||||
"description": "Description:",
|
||||
"websiteLinkWillBeUsedAsAdditionalId": "Site's link is optional, but it can be used as an additional identifier of the application.",
|
||||
"websiteLink": "Website link:",
|
||||
"redirectUriLimitsAllowableBaseAddress": "Redirection URI (redirectUri) determines a base address, that user will be allowed to be redirected to after authorization. In order to improve security it's better to use the whole path instead of just a domain name. For example: https://example.com/oauth/ely.",
|
||||
"redirectUri": "Redirect URI:",
|
||||
"createApplication": "Create application",
|
||||
"serverName": "Server name:",
|
||||
"ipAddressIsOptionButPreferable": "IP address is optional, but is very preferable. It might become handy in case of we suddenly decide to play on your server with the entire band (=",
|
||||
"serverIp": "Server IP:",
|
||||
"youCanAlsoSpecifyServerSite": "You also can specify either server's site URL or its community in a social network.",
|
||||
"updatingApplication": "Updating an application",
|
||||
"updateApplication": "Update application"
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
import React from 'react';
|
||||
import { FormattedMessage as Message } from 'react-intl';
|
||||
import { FormattedMessage as Message, defineMessages } from 'react-intl';
|
||||
import { Helmet } from 'react-helmet-async';
|
||||
import { MessageDescriptor } from 'react-intl';
|
||||
import { OauthAppResponse } from 'app/services/api/oauth';
|
||||
@ -10,12 +10,22 @@ import { COLOR_GREEN } from 'app/components/ui';
|
||||
import { TYPE_APPLICATION, TYPE_MINECRAFT_SERVER } from 'app/components/dev/apps';
|
||||
import styles from 'app/components/profile/profileForm.scss';
|
||||
import logger from 'app/services/logger';
|
||||
import messages from './ApplicationForm.intl.json';
|
||||
|
||||
import ApplicationTypeSwitcher from './ApplicationTypeSwitcher';
|
||||
import WebsiteType from './WebsiteType';
|
||||
import MinecraftServerType from './MinecraftServerType';
|
||||
|
||||
const messages = defineMessages({
|
||||
website: 'Web site',
|
||||
minecraftServer: 'Minecraft server',
|
||||
|
||||
creatingApplication: 'Creating an application',
|
||||
createApplication: 'Create application',
|
||||
|
||||
updatingApplication: 'Updating an application',
|
||||
updateApplication: 'Update application',
|
||||
});
|
||||
|
||||
type TypeToForm = Record<
|
||||
ApplicationType,
|
||||
{
|
||||
@ -94,7 +104,10 @@ export default class ApplicationForm extends React.Component<{
|
||||
) : (
|
||||
<div className={styles.formRow}>
|
||||
<p className={styles.description}>
|
||||
<Message {...messages.toDisplayRegistrationFormChooseType} />
|
||||
<Message
|
||||
key="toDisplayRegistrationFormChooseType"
|
||||
defaultMessage="To display registration form for a new application choose necessary type."
|
||||
/>
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
|
@ -1,11 +1,18 @@
|
||||
import React, { ComponentType } from 'react';
|
||||
import { FormattedMessage as Message } from 'react-intl';
|
||||
import { FormattedMessage as Message, defineMessages } from 'react-intl';
|
||||
import { OauthAppResponse } from 'app/services/api/oauth';
|
||||
import { Input, FormModel } from 'app/components/ui/form';
|
||||
import { SKIN_LIGHT } from 'app/components/ui';
|
||||
import styles from 'app/components/profile/profileForm.scss';
|
||||
|
||||
import messages from './ApplicationForm.intl.json';
|
||||
const messages = defineMessages({
|
||||
serverName: 'Server name:',
|
||||
ipAddressIsOptionButPreferable:
|
||||
'IP address is optional, but is very preferable. It might become handy in case of we suddenly decide to play on your server with the entire band (=',
|
||||
serverIp: 'Server IP:',
|
||||
youCanAlsoSpecifyServerSite: "You also can specify either server's site URL or its community in a social network.",
|
||||
websiteLink: 'Website link:',
|
||||
});
|
||||
|
||||
interface Props {
|
||||
form: FormModel;
|
||||
|
@ -1,11 +1,22 @@
|
||||
import React, { ComponentType } from 'react';
|
||||
import { FormattedMessage as Message } from 'react-intl';
|
||||
import { defineMessages, FormattedMessage as Message } from 'react-intl';
|
||||
import { Input, TextArea, FormModel } from 'app/components/ui/form';
|
||||
import { OauthAppResponse } from 'app/services/api/oauth';
|
||||
import { SKIN_LIGHT } from 'app/components/ui';
|
||||
import styles from 'app/components/profile/profileForm.scss';
|
||||
|
||||
import messages from './ApplicationForm.intl.json';
|
||||
const messages = defineMessages({
|
||||
applicationName: 'Application name:',
|
||||
appDescriptionWillBeAlsoVisibleOnOauthPage:
|
||||
"Application's description will be displayed at the authorization page too. It isn't a required field. In authorization process the value may be overridden.",
|
||||
description: 'Description:',
|
||||
websiteLinkWillBeUsedAsAdditionalId:
|
||||
"Site's link is optional, but it can be used as an additional identifier of the application.",
|
||||
websiteLink: 'Website link:',
|
||||
redirectUriLimitsAllowableBaseAddress:
|
||||
"Redirection URI (redirectUri) determines a base address, that user will be allowed to be redirected to after authorization. In order to improve security it's better to use the whole path instead of just a domain name. For example: https://example.com/oauth/ely.",
|
||||
redirectUri: 'Redirect URI:',
|
||||
});
|
||||
|
||||
interface Props {
|
||||
form: FormModel;
|
||||
|
24
packages/app/components/dev/apps/list.intl.ts
Normal file
24
packages/app/components/dev/apps/list.intl.ts
Normal file
@ -0,0 +1,24 @@
|
||||
/**
|
||||
* Extract this file to the level upper to keep the messages prefix. Will be resolved later.
|
||||
*/
|
||||
|
||||
import { defineMessages } from 'react-intl';
|
||||
|
||||
export default defineMessages({
|
||||
revokeAllTokens: 'Revoke all tokens',
|
||||
resetClientSecret: 'Reset Client Secret',
|
||||
delete: 'Delete',
|
||||
countUsers: '{count, plural, =0 {No users} one {# user} other {# users}}',
|
||||
editDescription: '{icon} Edit description',
|
||||
ifYouSuspectingThatSecretHasBeenCompromised:
|
||||
'If you are suspecting that your Client Secret has been compromised, then you may want to reset it value. It\'ll cause recall of the all "access" and "refresh" tokens that have been issued. You can also recall all issued tokens without changing Client Secret.',
|
||||
allRefreshTokensWillBecomeInvalid:
|
||||
'All "refresh" tokens will become invalid and after next authorization the user will get permissions prompt.',
|
||||
takeCareAccessTokensInvalidation: 'Take care because "access" tokens won\'t be invalidated immediately.',
|
||||
cancel: 'Cancel',
|
||||
performing: 'Performing…',
|
||||
continue: 'Continue',
|
||||
appAndAllTokenWillBeDeleted: 'Application and all associated tokens will be deleted.',
|
||||
yourApplications: 'Your applications:',
|
||||
addNew: 'Add new',
|
||||
});
|
@ -8,7 +8,7 @@ import { OauthAppResponse } from 'app/services/api/oauth';
|
||||
import Collapse from 'app/components/ui/collapse';
|
||||
|
||||
import styles from '../applicationsIndex.scss';
|
||||
import messages from '../ApplicationsIndex.intl.json';
|
||||
import messages from '../list.intl';
|
||||
|
||||
const ACTION_REVOKE_TOKENS = 'revoke-tokens';
|
||||
const ACTION_RESET_SECRET = 'reset-secret';
|
||||
|
@ -5,7 +5,7 @@ import { LinkButton } from 'app/components/ui/form';
|
||||
import { COLOR_GREEN } from 'app/components/ui';
|
||||
import { OauthAppResponse } from 'app/services/api/oauth';
|
||||
|
||||
import messages from '../ApplicationsIndex.intl.json';
|
||||
import messages from '../list.intl';
|
||||
import styles from '../applicationsIndex.scss';
|
||||
import ApplicationItem from './ApplicationItem';
|
||||
|
||||
|
@ -7,7 +7,6 @@ import { create as createPopup } from 'app/components/ui/popup/actions';
|
||||
import { ContactLink } from 'app/components/contact';
|
||||
|
||||
import styles from './footerMenu.scss';
|
||||
import messages from './footerMenu.intl.json';
|
||||
|
||||
const FooterMenu: ComponentType = () => {
|
||||
const dispatch = useDispatch();
|
||||
@ -22,19 +21,19 @@ const FooterMenu: ComponentType = () => {
|
||||
return (
|
||||
<div className={styles.footerMenu} data-testid="footer">
|
||||
<Link to="/rules" className={styles.footerItem}>
|
||||
<Message {...messages.rules} />
|
||||
<Message key="rules" defaultMessage="Rules" />
|
||||
</Link>
|
||||
<ContactLink className={styles.footerItem}>
|
||||
<Message {...messages.contactUs} />
|
||||
<Message key="contactUs" defaultMessage="Contact Us" />
|
||||
</ContactLink>
|
||||
<Link to="/dev" className={styles.footerItem}>
|
||||
<Message {...messages.forDevelopers} />
|
||||
<Message key="forDevelopers" defaultMessage="For developers" />
|
||||
</Link>
|
||||
|
||||
<div className={styles.langTriggerContainer}>
|
||||
<a href="#" className={styles.langTrigger} onClick={onLanguageSwitcherClick}>
|
||||
<span className={styles.langTriggerIcon} />
|
||||
<Message {...messages.siteLanguage} />
|
||||
<Message key="siteLanguage" defaultMessage="Site language" />
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,6 +0,0 @@
|
||||
{
|
||||
"rules": "Rules",
|
||||
"contactUs": "Contact Us",
|
||||
"siteLanguage": "Site language",
|
||||
"forDevelopers": "For developers"
|
||||
}
|
@ -12,7 +12,6 @@ import { FormattedMessage as Message } from 'react-intl';
|
||||
import clsx from 'clsx';
|
||||
|
||||
import LocaleItem from './LocaleItem';
|
||||
import messages from './languageSwitcher.intl.json';
|
||||
import { LocalesMap } from './LanguageSwitcher';
|
||||
import styles from './languageSwitcher.scss';
|
||||
|
||||
@ -92,7 +91,10 @@ export default class LanguageList extends React.Component<{
|
||||
className={styles.emptyLanguagesListCaption}
|
||||
/>
|
||||
<div className={styles.emptyLanguagesListSubtitle}>
|
||||
<Message {...messages.weDoNotSupportThisLang} />
|
||||
<Message
|
||||
key="weDoNotSupportThisLang"
|
||||
defaultMessage="Sorry, we do not support this language"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -9,7 +9,6 @@ import popupStyles from 'app/components/ui/popup/popup.scss';
|
||||
import icons from 'app/components/ui/icons.scss';
|
||||
|
||||
import styles from './languageSwitcher.scss';
|
||||
import messages from './languageSwitcher.intl.json';
|
||||
import LanguageList from './LanguageList';
|
||||
import { RootState } from 'app/reducers';
|
||||
|
||||
@ -70,7 +69,7 @@ class LanguageSwitcher extends React.Component<
|
||||
<div className={popupStyles.popup}>
|
||||
<div className={popupStyles.header}>
|
||||
<h2 className={popupStyles.headerTitle}>
|
||||
<Message {...messages.siteLanguage} />
|
||||
<Message key="siteLanguage" defaultMessage="Site language" />
|
||||
</h2>
|
||||
<span className={clsx(icons.close, popupStyles.close)} onClick={onClose} />
|
||||
</div>
|
||||
@ -79,7 +78,10 @@ class LanguageSwitcher extends React.Component<
|
||||
<div className={styles.searchBox}>
|
||||
<input
|
||||
className={clsx(formStyles.lightTextField, formStyles.greenTextField)}
|
||||
placeholder={intl.formatMessage(messages.startTyping)}
|
||||
placeholder={intl.formatMessage({
|
||||
key: 'startTyping',
|
||||
defaultMessage: 'Start typing…',
|
||||
})}
|
||||
onChange={this.onFilterUpdate}
|
||||
onKeyPress={this.onFilterKeyPress()}
|
||||
autoFocus
|
||||
@ -97,12 +99,18 @@ class LanguageSwitcher extends React.Component<
|
||||
<div className={styles.improveTranslatesIcon} />
|
||||
<div className={styles.improveTranslatesContent}>
|
||||
<div className={styles.improveTranslatesTitle}>
|
||||
<Message {...messages.improveTranslates} />
|
||||
<Message key="improveTranslates" defaultMessage="Improve Ely.by translation" />
|
||||
</div>
|
||||
<div className={styles.improveTranslatesText}>
|
||||
<Message {...messages.improveTranslatesDescription} />{' '}
|
||||
<Message
|
||||
key="improveTranslatesDescription"
|
||||
defaultMessage="Ely.by’s localization is a community effort. If you want to improve the translation of Ely.by, we'd love your help."
|
||||
/>{' '}
|
||||
<a href={translateUrl} target="_blank">
|
||||
<Message {...messages.improveTranslatesParticipate} />
|
||||
<Message
|
||||
key="improveTranslatesParticipate"
|
||||
defaultMessage="Click here to participate."
|
||||
/>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -2,7 +2,6 @@ import React, { ComponentType, ReactNode } from 'react';
|
||||
import { localeFlags } from 'app/components/i18n';
|
||||
import { FormattedMessage as Message } from 'react-intl';
|
||||
|
||||
import messages from './languageSwitcher.intl.json';
|
||||
import styles from './languageSwitcher.scss';
|
||||
import { LocaleData } from './LanguageSwitcher';
|
||||
|
||||
@ -16,14 +15,15 @@ const LocaleItem: ComponentType<Props> = ({ locale: { code, name, englishName, p
|
||||
if (progress !== 100) {
|
||||
progressLabel = (
|
||||
<Message
|
||||
{...messages.translationProgress}
|
||||
key="translationProgress"
|
||||
defaultMessage="{progress}% translated"
|
||||
values={{
|
||||
progress,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
} else if (!isReleased) {
|
||||
progressLabel = <Message {...messages.mayBeInaccurate} />;
|
||||
progressLabel = <Message key="mayBeInaccurate" defaultMessage="May be inaccurate" />;
|
||||
}
|
||||
|
||||
return (
|
||||
|
@ -1,10 +0,0 @@
|
||||
{
|
||||
"siteLanguage": "Site language",
|
||||
"startTyping": "Start typing…",
|
||||
"translationProgress": "{progress}% translated",
|
||||
"mayBeInaccurate": "May be inaccurate",
|
||||
"weDoNotSupportThisLang": "Sorry, we do not support this language",
|
||||
"improveTranslates": "Improve Ely.by translation",
|
||||
"improveTranslatesDescription": "Ely.by’s localization is a community effort. If you want to improve the translation of Ely.by, we'd love your help.",
|
||||
"improveTranslatesParticipate": "Click here to participate."
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
{
|
||||
"accountPreferencesTitle": "Ely.by account preferences",
|
||||
"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.",
|
||||
"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 {rules}, account owner has the right to demand the restoration of control over nickname.",
|
||||
"projectRules": "project rules",
|
||||
"changedAt": "Changed {at}",
|
||||
"disabled": "Disabled",
|
||||
"enabled": "Enabled",
|
||||
"nickname": "Nickname:",
|
||||
"email": "E‑mail:",
|
||||
"password": "Password:",
|
||||
"siteLanguage": "Site language:",
|
||||
"languageIsUnavailableWarning": "The locale \"{locale}\" you've used earlier isn't currently translated enough. If you want to continue using the selected language, please {participateInTheTranslation} of the project.",
|
||||
"participateInTheTranslation": "participate in the translation",
|
||||
"twoFactorAuth": "Two‑factor auth:",
|
||||
"uuid": "UUID:"
|
||||
}
|
@ -12,7 +12,6 @@ import { RootState } from 'app/reducers';
|
||||
import ProfileField from './ProfileField';
|
||||
import styles from './profile.scss';
|
||||
import profileForm from './profileForm.scss';
|
||||
import messages from './Profile.intl.json';
|
||||
|
||||
type Props = {
|
||||
user: User;
|
||||
@ -27,7 +26,7 @@ class Profile extends React.PureComponent<Props> {
|
||||
|
||||
return (
|
||||
<div data-testid="profile-index">
|
||||
<Message {...messages.accountPreferencesTitle}>
|
||||
<Message key="accountPreferencesTitle" defaultMessage="Ely.by account preferences">
|
||||
{(pageTitle: string) => (
|
||||
<h2 className={styles.indexTitle}>
|
||||
<Helmet title={pageTitle} />
|
||||
@ -39,7 +38,10 @@ class Profile extends React.PureComponent<Props> {
|
||||
<div className={styles.indexContent}>
|
||||
<div className={styles.descriptionColumn}>
|
||||
<div className={styles.indexDescription}>
|
||||
<Message {...messages.accountDescription} />
|
||||
<Message
|
||||
key="accountDescription"
|
||||
defaultMessage="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."
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -47,21 +49,25 @@ class Profile extends React.PureComponent<Props> {
|
||||
<div className={profileForm.form}>
|
||||
<div className={styles.item}>
|
||||
<h3 className={profileForm.title}>
|
||||
<Message {...messages.personalData} />
|
||||
<Message key="personalData" defaultMessage="Personal data" />
|
||||
</h3>
|
||||
<p className={profileForm.description}>
|
||||
<Message {...messages.preferencesDescription} />
|
||||
<Message
|
||||
key="preferencesDescription"
|
||||
defaultMessage="Here you can change the key preferences of your account. Please note that all actions must be confirmed by entering a password."
|
||||
/>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<ProfileField
|
||||
link="/profile/change-username"
|
||||
label={<Message {...messages.nickname} />}
|
||||
label={<Message key="nickname" defaultMessage="Nickname:" />}
|
||||
value={user.username}
|
||||
warningMessage={
|
||||
user.hasMojangUsernameCollision ? (
|
||||
<Message
|
||||
{...messages.mojangPriorityWarning}
|
||||
key="mojangPriorityWarning"
|
||||
defaultMessage="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."
|
||||
values={{
|
||||
rules: (
|
||||
<Link
|
||||
@ -70,7 +76,7 @@ class Profile extends React.PureComponent<Props> {
|
||||
hash: `#${RulesPage.getRuleHash(1, 4)}`,
|
||||
}}
|
||||
>
|
||||
<Message {...messages.projectRules} />
|
||||
<Message key="projectRules" defaultMessage="project rules" />
|
||||
</Link>
|
||||
),
|
||||
}}
|
||||
@ -83,16 +89,17 @@ class Profile extends React.PureComponent<Props> {
|
||||
|
||||
<ProfileField
|
||||
link="/profile/change-email"
|
||||
label={<Message {...messages.email} />}
|
||||
label={<Message key="email" defaultMessage="E‑mail:" />}
|
||||
value={user.email}
|
||||
/>
|
||||
|
||||
<ProfileField
|
||||
link="/profile/change-password"
|
||||
label={<Message {...messages.password} />}
|
||||
label={<Message key="password" defaultMessage="Password:" />}
|
||||
value={
|
||||
<Message
|
||||
{...messages.changedAt}
|
||||
key="changedAt"
|
||||
defaultMessage="Changed {at}"
|
||||
values={{
|
||||
at: <RelativeTime timestamp={user.passwordChangedAt * 1000} />,
|
||||
}}
|
||||
@ -101,19 +108,25 @@ class Profile extends React.PureComponent<Props> {
|
||||
/>
|
||||
|
||||
<ProfileField
|
||||
label={<Message {...messages.siteLanguage} />}
|
||||
label={<Message key="siteLanguage" defaultMessage="Site language:" />}
|
||||
value={<ChangeLanguageLink />}
|
||||
warningMessage={
|
||||
user.lang === interfaceLocale ? (
|
||||
''
|
||||
) : (
|
||||
<Message
|
||||
{...messages.languageIsUnavailableWarning}
|
||||
key="languageIsUnavailableWarning"
|
||||
defaultMessage={
|
||||
'The locale "{locale}" you\'ve used earlier isn\'t currently translated enough. If you want to continue using the selected language, please {participateInTheTranslation} of the project.'
|
||||
}
|
||||
values={{
|
||||
locale: user.lang,
|
||||
participateInTheTranslation: (
|
||||
<a href="http://ely.by/translate" target="_blank">
|
||||
<Message {...messages.participateInTheTranslation} />
|
||||
<Message
|
||||
key="participateInTheTranslation"
|
||||
defaultMessage="participate in the translation"
|
||||
/>
|
||||
</a>
|
||||
),
|
||||
}}
|
||||
@ -124,18 +137,18 @@ class Profile extends React.PureComponent<Props> {
|
||||
|
||||
<ProfileField
|
||||
link="/profile/mfa"
|
||||
label={<Message {...messages.twoFactorAuth} />}
|
||||
label={<Message key="twoFactorAuth" defaultMessage="Two‑factor auth:" />}
|
||||
value={
|
||||
user.isOtpEnabled ? (
|
||||
<Message {...messages.enabled} />
|
||||
<Message key="enabled" defaultMessage="Enabled" />
|
||||
) : (
|
||||
<Message {...messages.disabled} />
|
||||
<Message key="disabled" defaultMessage="Disabled" />
|
||||
)
|
||||
}
|
||||
/>
|
||||
|
||||
<ProfileField
|
||||
label={<Message {...messages.uuid} />}
|
||||
label={<Message key="uuid" defaultMessage="UUID:" />}
|
||||
value={
|
||||
<span
|
||||
className={styles.uuid}
|
||||
|
@ -1,3 +0,0 @@
|
||||
{
|
||||
"back": "Back"
|
||||
}
|
@ -1,10 +1,13 @@
|
||||
import React from 'react';
|
||||
import { FormattedMessage as Message } from 'react-intl';
|
||||
import { defineMessages, FormattedMessage as Message } from 'react-intl';
|
||||
import { Link } from 'react-router-dom';
|
||||
import FormComponent from 'app/components/ui/form/FormComponent';
|
||||
|
||||
import styles from './profileForm.scss';
|
||||
import messages from './ProfileForm.intl.json';
|
||||
|
||||
const { back: backMsg } = defineMessages({
|
||||
back: 'Back',
|
||||
});
|
||||
|
||||
export class BackButton extends FormComponent<{
|
||||
to: string;
|
||||
@ -20,12 +23,12 @@ export class BackButton extends FormComponent<{
|
||||
<Link
|
||||
className={styles.backButton}
|
||||
to={to}
|
||||
title={this.formatMessage(messages.back)}
|
||||
title={this.formatMessage(backMsg)}
|
||||
data-testid="back-to-profile"
|
||||
>
|
||||
<span className={styles.backIcon} />
|
||||
<span className={styles.backText}>
|
||||
<Message {...messages.back} />
|
||||
<Message {...backMsg} />
|
||||
</span>
|
||||
</Link>
|
||||
);
|
||||
|
@ -1,17 +0,0 @@
|
||||
{
|
||||
"changeEmailTitle": "Change E‑mail",
|
||||
"changeEmailDescription": "To change current account E‑mail you must first verify that you own the current address and then confirm the new one.",
|
||||
"currentAccountEmail": "Current account E‑mail address:",
|
||||
"pressButtonToStart": "Press the button below to send a message with the code for E‑mail change initialization.",
|
||||
"enterInitializationCode": "The E‑mail with an initialization code for E‑mail change procedure was sent to {email}. Please enter the code into the field below:",
|
||||
|
||||
"enterNewEmail": "Then provide your new E‑mail address, that you want to use with this account. You will be mailed with confirmation code.",
|
||||
"finalizationCodeWasSentToEmail": "The E‑mail change confirmation code was sent to {email}.",
|
||||
"enterFinalizationCode": "In order to confirm your new E‑mail, please enter the code received into the field below:",
|
||||
|
||||
"newEmailPlaceholder": "Enter new E‑mail",
|
||||
"codePlaceholder": "Paste the code here",
|
||||
"sendEmailButton": "Send E‑mail",
|
||||
"changeEmailButton": "Change E‑mail",
|
||||
"alreadyReceivedCode": "Already received code"
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
import React, { ReactNode } from 'react';
|
||||
import { FormattedMessage as Message } from 'react-intl';
|
||||
import { defineMessages, FormattedMessage as Message } from 'react-intl';
|
||||
import { Helmet } from 'react-helmet-async';
|
||||
import { SlideMotion } from 'app/components/ui/motion';
|
||||
import { ScrollIntoView } from 'app/components/ui/scroll';
|
||||
@ -10,7 +10,6 @@ import helpLinks from 'app/components/auth/helpLinks.scss';
|
||||
import Stepper from 'app/components/ui/stepper';
|
||||
|
||||
import changeEmail from './changeEmail.scss';
|
||||
import messages from './ChangeEmail.intl.json';
|
||||
|
||||
const STEPS_TOTAL = 3;
|
||||
|
||||
@ -40,6 +39,13 @@ interface FormStepParams {
|
||||
code?: string;
|
||||
}
|
||||
|
||||
const labels = defineMessages({
|
||||
changeEmailButton: 'Change E‑mail',
|
||||
sendEmailButton: 'Send E‑mail',
|
||||
codePlaceholder: 'Paste the code here',
|
||||
newEmailPlaceholder: 'Enter new E‑mail',
|
||||
});
|
||||
|
||||
export default class ChangeEmail extends React.Component<Props, State> {
|
||||
static get defaultProps(): Partial<Props> {
|
||||
return {
|
||||
@ -73,7 +79,7 @@ export default class ChangeEmail extends React.Component<Props, State> {
|
||||
|
||||
<div className={styles.form}>
|
||||
<div className={styles.formBody}>
|
||||
<Message {...messages.changeEmailTitle}>
|
||||
<Message key="changeEmailTitle" defaultMessage="Change E‑mail">
|
||||
{(pageTitle) => (
|
||||
<h3 className={styles.violetTitle}>
|
||||
<Helmet title={pageTitle as string} />
|
||||
@ -84,7 +90,10 @@ export default class ChangeEmail extends React.Component<Props, State> {
|
||||
|
||||
<div className={styles.formRow}>
|
||||
<p className={styles.description}>
|
||||
<Message {...messages.changeEmailDescription} />
|
||||
<Message
|
||||
key="changeEmailDescription"
|
||||
defaultMessage="To change current account E‑mail you must first verify that you own the current address and then confirm the new one."
|
||||
/>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@ -103,14 +112,14 @@ export default class ChangeEmail extends React.Component<Props, State> {
|
||||
color="violet"
|
||||
type="submit"
|
||||
block
|
||||
label={this.isLastStep() ? messages.changeEmailButton : messages.sendEmailButton}
|
||||
label={this.isLastStep() ? labels.changeEmailButton : labels.sendEmailButton}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className={helpLinks.helpLinks}>
|
||||
{this.isLastStep() ? null : (
|
||||
<a href="#" onClick={this.onSwitchStep}>
|
||||
<Message {...messages.alreadyReceivedCode} />
|
||||
<Message key="alreadyReceivedCode" defaultMessage="Already received code" />
|
||||
</a>
|
||||
)}
|
||||
</div>
|
||||
@ -153,7 +162,7 @@ export default class ChangeEmail extends React.Component<Props, State> {
|
||||
<div key="step0" data-testid="step1" className={styles.formBody}>
|
||||
<div className={styles.formRow}>
|
||||
<p className={styles.description}>
|
||||
<Message {...messages.currentAccountEmail} />
|
||||
<Message key="currentAccountEmail" defaultMessage="Current account E‑mail address:" />
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@ -165,7 +174,10 @@ export default class ChangeEmail extends React.Component<Props, State> {
|
||||
|
||||
<div className={styles.formRow}>
|
||||
<p className={styles.description}>
|
||||
<Message {...messages.pressButtonToStart} />
|
||||
<Message
|
||||
key="pressButtonToStart"
|
||||
defaultMessage="Press the button below to send a message with the code for E‑mail change initialization."
|
||||
/>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@ -178,7 +190,8 @@ export default class ChangeEmail extends React.Component<Props, State> {
|
||||
<div className={styles.formRow}>
|
||||
<p className={styles.description}>
|
||||
<Message
|
||||
{...messages.enterInitializationCode}
|
||||
key="enterInitializationCode"
|
||||
defaultMessage="The E‑mail with an initialization code for E‑mail change procedure was sent to {email}. Please enter the code into the field below:"
|
||||
values={{
|
||||
email: <b>{email}</b>,
|
||||
}}
|
||||
@ -196,13 +209,16 @@ export default class ChangeEmail extends React.Component<Props, State> {
|
||||
autoComplete="off"
|
||||
skin="light"
|
||||
color="violet"
|
||||
placeholder={messages.codePlaceholder}
|
||||
placeholder={labels.codePlaceholder}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className={styles.formRow}>
|
||||
<p className={styles.description}>
|
||||
<Message {...messages.enterNewEmail} />
|
||||
<Message
|
||||
key="enterNewEmail"
|
||||
defaultMessage="Then provide your new E‑mail address, that you want to use with this account. You will be mailed with confirmation code."
|
||||
/>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@ -212,7 +228,7 @@ export default class ChangeEmail extends React.Component<Props, State> {
|
||||
required={isActiveStep}
|
||||
skin="light"
|
||||
color="violet"
|
||||
placeholder={messages.newEmailPlaceholder}
|
||||
placeholder={labels.newEmailPlaceholder}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@ -229,14 +245,18 @@ export default class ChangeEmail extends React.Component<Props, State> {
|
||||
{newEmail ? (
|
||||
<span>
|
||||
<Message
|
||||
{...messages.finalizationCodeWasSentToEmail}
|
||||
key="finalizationCodeWasSentToEmail"
|
||||
defaultMessage="The E‑mail change confirmation code was sent to {email}."
|
||||
values={{
|
||||
email: <b>{newEmail}</b>,
|
||||
}}
|
||||
/>{' '}
|
||||
</span>
|
||||
) : null}
|
||||
<Message {...messages.enterFinalizationCode} />
|
||||
<Message
|
||||
key="enterFinalizationCode"
|
||||
defaultMessage="In order to confirm your new E‑mail, please enter the code received into the field below:"
|
||||
/>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@ -250,7 +270,7 @@ export default class ChangeEmail extends React.Component<Props, State> {
|
||||
autoComplete="off"
|
||||
skin="light"
|
||||
color="violet"
|
||||
placeholder={messages.codePlaceholder}
|
||||
placeholder={labels.codePlaceholder}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,10 +0,0 @@
|
||||
{
|
||||
"changePasswordTitle": "Change password",
|
||||
"changePasswordDescription": "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.",
|
||||
"achievementLossWarning": "Are you cherish your game achievements, right?",
|
||||
"passwordRequirements": "Password must contain at least 8 characters. It can be any symbols — do not limit yourself, create an unpredictable password!",
|
||||
"changePasswordButton": "Change password",
|
||||
"newPasswordLabel": "New password:",
|
||||
"repeatNewPasswordLabel": "Repeat the password:",
|
||||
"logoutOnAllDevices": "Logout on all devices"
|
||||
}
|
@ -1,11 +1,17 @@
|
||||
import React from 'react';
|
||||
import { FormattedMessage as Message } from 'react-intl';
|
||||
import { defineMessages, FormattedMessage as Message } from 'react-intl';
|
||||
import { Helmet } from 'react-helmet-async';
|
||||
import { Input, Button, Checkbox, Form, FormModel } from 'app/components/ui/form';
|
||||
|
||||
import { BackButton } from '../ProfileForm';
|
||||
import styles from '../profileForm.scss';
|
||||
import messages from './ChangePassword.intl.json';
|
||||
|
||||
const labels = defineMessages({
|
||||
changePasswordButton: 'Change password',
|
||||
newPasswordLabel: 'New password:',
|
||||
repeatNewPasswordLabel: 'Repeat the password:',
|
||||
logoutOnAllDevices: 'Logout on all devices',
|
||||
});
|
||||
|
||||
interface Props {
|
||||
form: FormModel;
|
||||
@ -29,7 +35,7 @@ export default class ChangePassword extends React.Component<Props> {
|
||||
|
||||
<div className={styles.form}>
|
||||
<div className={styles.formBody}>
|
||||
<Message {...messages.changePasswordTitle}>
|
||||
<Message key="changePasswordTitle" defaultMessage="Change password">
|
||||
{(pageTitle) => (
|
||||
<h3 className={styles.title}>
|
||||
<Helmet title={pageTitle as string} />
|
||||
@ -40,10 +46,16 @@ export default class ChangePassword extends React.Component<Props> {
|
||||
|
||||
<div className={styles.formRow}>
|
||||
<p className={styles.description}>
|
||||
<Message {...messages.changePasswordDescription} />
|
||||
<Message
|
||||
key="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."
|
||||
/>
|
||||
<br />
|
||||
<b>
|
||||
<Message {...messages.achievementLossWarning} />
|
||||
<Message
|
||||
key="achievementLossWarning"
|
||||
defaultMessage="Are you cherish your game achievements, right?"
|
||||
/>
|
||||
</b>
|
||||
</p>
|
||||
</div>
|
||||
@ -54,13 +66,16 @@ export default class ChangePassword extends React.Component<Props> {
|
||||
type="password"
|
||||
required
|
||||
skin="light"
|
||||
label={messages.newPasswordLabel}
|
||||
label={labels.newPasswordLabel}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className={styles.formRow}>
|
||||
<p className={styles.description}>
|
||||
<Message {...messages.passwordRequirements} />
|
||||
<Message
|
||||
key="passwordRequirements"
|
||||
defaultMessage="Password must contain at least 8 characters. It can be any symbols — do not limit yourself, create an unpredictable password!"
|
||||
/>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@ -70,7 +85,7 @@ export default class ChangePassword extends React.Component<Props> {
|
||||
type="password"
|
||||
required
|
||||
skin="light"
|
||||
label={messages.repeatNewPasswordLabel}
|
||||
label={labels.repeatNewPasswordLabel}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@ -79,12 +94,12 @@ export default class ChangePassword extends React.Component<Props> {
|
||||
{...form.bindField('logoutAll')}
|
||||
defaultChecked
|
||||
skin="light"
|
||||
label={messages.logoutOnAllDevices}
|
||||
label={labels.logoutOnAllDevices}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Button color="green" block label={messages.changePasswordButton} type="submit" />
|
||||
<Button color="green" block label={labels.changePasswordButton} type="submit" />
|
||||
</div>
|
||||
</div>
|
||||
</Form>
|
||||
|
@ -1,6 +0,0 @@
|
||||
{
|
||||
"changeUsernameTitle": "Change nickname",
|
||||
"changeUsernameDescription": "You can change your nickname to any arbitrary value. Remember that it is not recommended to take a nickname of already existing Mojang account.",
|
||||
"changeUsernameWarning": "Be careful: if you playing on the server with nickname binding, then after changing nickname you may lose all your progress.",
|
||||
"changeUsernameButton": "Change nickname"
|
||||
}
|
@ -1,11 +1,14 @@
|
||||
import React from 'react';
|
||||
import { FormattedMessage as Message } from 'react-intl';
|
||||
import { defineMessages, FormattedMessage as Message } from 'react-intl';
|
||||
import { Helmet } from 'react-helmet-async';
|
||||
import { Input, Button, Form, FormModel } from 'app/components/ui/form';
|
||||
import { BackButton } from 'app/components/profile/ProfileForm';
|
||||
|
||||
import styles from '../profileForm.scss';
|
||||
import messages from './ChangeUsername.intl.json';
|
||||
|
||||
const labels = defineMessages({
|
||||
changeUsernameButton: 'Change nickname',
|
||||
});
|
||||
|
||||
interface Props {
|
||||
username: string;
|
||||
@ -31,7 +34,7 @@ export default class ChangeUsername extends React.Component<Props> {
|
||||
|
||||
<div className={styles.form}>
|
||||
<div className={styles.formBody}>
|
||||
<Message {...messages.changeUsernameTitle}>
|
||||
<Message key="changeUsernameTitle" defaultMessage="Change nickname">
|
||||
{(pageTitle) => (
|
||||
<h3 className={styles.title}>
|
||||
<Helmet title={pageTitle as string} />
|
||||
@ -42,7 +45,10 @@ export default class ChangeUsername extends React.Component<Props> {
|
||||
|
||||
<div className={styles.formRow}>
|
||||
<p className={styles.description}>
|
||||
<Message {...messages.changeUsernameDescription} />
|
||||
<Message
|
||||
key="changeUsernameDescription"
|
||||
defaultMessage="You can change your nickname to any arbitrary value. Remember that it is not recommended to take a nickname of already existing Mojang account."
|
||||
/>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@ -58,12 +64,15 @@ export default class ChangeUsername extends React.Component<Props> {
|
||||
|
||||
<div className={styles.formRow}>
|
||||
<p className={styles.description}>
|
||||
<Message {...messages.changeUsernameWarning} />
|
||||
<Message
|
||||
key="changeUsernameWarning"
|
||||
defaultMessage="Be careful: if you playing on the server with nickname binding, then after changing nickname you may lose all your progress."
|
||||
/>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Button color="green" block label={messages.changeUsernameButton} type="submit" />
|
||||
<Button color="green" block label={labels.changeUsernameButton} type="submit" />
|
||||
</div>
|
||||
</div>
|
||||
</Form>
|
||||
|
@ -1,10 +1,12 @@
|
||||
import React from 'react';
|
||||
import { FormattedMessage as Message } from 'react-intl';
|
||||
import { defineMessages, FormattedMessage as Message } from 'react-intl';
|
||||
|
||||
import { Input, Form, FormModel } from 'app/components/ui/form';
|
||||
import profileForm from 'app/components/profile/profileForm.scss';
|
||||
|
||||
import messages from '../MultiFactorAuth.intl.json';
|
||||
const messages = defineMessages({
|
||||
codePlaceholder: 'Enter the code here',
|
||||
});
|
||||
|
||||
export default function Confirmation({
|
||||
form,
|
||||
@ -22,7 +24,10 @@ export default function Confirmation({
|
||||
<div className={profileForm.formBody}>
|
||||
<div className={profileForm.formRow}>
|
||||
<p className={profileForm.description}>
|
||||
<Message {...messages.enterCodeFromApp} />
|
||||
<Message
|
||||
key="enterCodeFromApp"
|
||||
defaultMessage="In order to finish two‑factor auth setup, please enter the code received in the mobile app:"
|
||||
/>
|
||||
</p>
|
||||
</div>
|
||||
|
@ -4,8 +4,8 @@ import { disable as disableMFA } from 'app/services/api/mfa';
|
||||
import { FormModel } from 'app/components/ui/form';
|
||||
|
||||
import Context from '../Context';
|
||||
import MfaDisableForm from './disableForm/MfaDisableForm';
|
||||
import MfaStatus from './status/MfaStatus';
|
||||
import MfaDisableForm from './MfaDisableForm';
|
||||
import MfaStatus from './MfaStatus';
|
||||
|
||||
export default class MfaDisable extends React.Component<
|
||||
{
|
||||
|
@ -1,10 +1,14 @@
|
||||
import React from 'react';
|
||||
import { FormattedMessage as Message } from 'react-intl';
|
||||
import { defineMessages, FormattedMessage as Message } from 'react-intl';
|
||||
import { Button, Input, Form, FormModel } from 'app/components/ui/form';
|
||||
import styles from 'app/components/profile/profileForm.scss';
|
||||
|
||||
import messages from '../MultiFactorAuth.intl.json';
|
||||
import mfaStyles from '../mfa.scss';
|
||||
import mfaStyles from './mfa.scss';
|
||||
|
||||
const messages = defineMessages({
|
||||
codePlaceholder: 'Enter the code here',
|
||||
disable: 'Disable',
|
||||
});
|
||||
|
||||
export default class MfaDisableForm extends React.Component<{
|
||||
onSubmit: (form: FormModel) => Promise<void>;
|
||||
@ -20,13 +24,16 @@ export default class MfaDisableForm extends React.Component<{
|
||||
<div className={styles.formBody}>
|
||||
<div className={styles.formRow}>
|
||||
<p className={`${styles.description} ${mfaStyles.mfaTitle}`}>
|
||||
<Message {...messages.disableMfa} />
|
||||
<Message key="disableMfa" defaultMessage="Disable two‑factor authentication" />
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className={styles.formRow}>
|
||||
<p className={styles.description}>
|
||||
<Message {...messages.disableMfaInstruction} />
|
||||
<Message
|
||||
key="disableMfaInstruction"
|
||||
defaultMessage="In order to disable two‑factor authentication, you need to provide a code from your mobile app and confirm your action with your current account password."
|
||||
/>
|
||||
</p>
|
||||
</div>
|
||||
|
@ -7,12 +7,12 @@ import { ScrollIntoView } from 'app/components/ui/scroll';
|
||||
import logger from 'app/services/logger';
|
||||
import { getSecret, enable as enableMFA } from 'app/services/api/mfa';
|
||||
import { Form } from 'app/components/ui/form';
|
||||
import { defineMessages } from 'react-intl';
|
||||
|
||||
import Context from '../Context';
|
||||
import Instructions from './instructions';
|
||||
import KeyForm from './keyForm';
|
||||
import Confirmation from './confirmation';
|
||||
import messages from './MultiFactorAuth.intl.json';
|
||||
|
||||
const STEPS_TOTAL = 3;
|
||||
|
||||
@ -25,6 +25,12 @@ type Props = {
|
||||
step: MfaStep;
|
||||
};
|
||||
|
||||
const labels = defineMessages({
|
||||
theAppIsInstalled: 'App has been installed',
|
||||
ready: 'Ready',
|
||||
enable: 'Enable',
|
||||
});
|
||||
|
||||
interface State {
|
||||
isLoading: boolean;
|
||||
activeStep: MfaStep;
|
||||
@ -73,15 +79,15 @@ export default class MfaEnable extends React.PureComponent<Props, State> {
|
||||
|
||||
const stepsData = [
|
||||
{
|
||||
buttonLabel: messages.theAppIsInstalled,
|
||||
buttonLabel: labels.theAppIsInstalled,
|
||||
buttonAction: () => this.nextStep(),
|
||||
},
|
||||
{
|
||||
buttonLabel: messages.ready,
|
||||
buttonLabel: labels.ready,
|
||||
buttonAction: () => this.nextStep(),
|
||||
},
|
||||
{
|
||||
buttonLabel: messages.enable,
|
||||
buttonLabel: labels.enable,
|
||||
buttonAction: () => this.confirmationFormEl && this.confirmationFormEl.submit(),
|
||||
},
|
||||
];
|
||||
|
@ -4,8 +4,7 @@ import { ScrollIntoView } from 'app/components/ui/scroll';
|
||||
import styles from 'app/components/profile/profileForm.scss';
|
||||
import icons from 'app/components/ui/icons.scss';
|
||||
|
||||
import messages from '../MultiFactorAuth.intl.json';
|
||||
import mfaStyles from '../mfa.scss';
|
||||
import mfaStyles from './mfa.scss';
|
||||
|
||||
export default function MfaStatus({ onProceed }: { onProceed: () => void }) {
|
||||
return (
|
||||
@ -17,13 +16,19 @@ export default function MfaStatus({ onProceed }: { onProceed: () => void }) {
|
||||
<span className={icons.lock} />
|
||||
</div>
|
||||
<p className={`${styles.description} ${mfaStyles.mfaTitle}`}>
|
||||
<Message {...messages.mfaEnabledForYourAcc} />
|
||||
<Message
|
||||
key="mfaEnabledForYourAcc"
|
||||
defaultMessage="Two‑factor authentication for your account is active now"
|
||||
/>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className={styles.formRow}>
|
||||
<p className={styles.description}>
|
||||
<Message {...messages.mfaLoginFlowDesc} />
|
||||
<Message
|
||||
key="mfaLoginFlowDesc"
|
||||
defaultMessage="Additional code will be requested next time you log in. Please note, that Minecraft authorization won't work when two‑factor auth is enabled."
|
||||
/>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@ -36,7 +41,7 @@ export default function MfaStatus({ onProceed }: { onProceed: () => void }) {
|
||||
onProceed();
|
||||
}}
|
||||
>
|
||||
<Message {...messages.disable} />
|
||||
<Message key="disable" defaultMessage="Disable" />
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
@ -1,25 +0,0 @@
|
||||
{
|
||||
"mfaTitle": "Two‑factor authentication",
|
||||
"mfaDescription": "Two‑factor authentication is an extra layer of security designed to ensure you that you're the only person who can access your account, even if the password gets stolen.",
|
||||
|
||||
"mfaIntroduction": "First of all, you need to install one of our suggested apps on your phone. This app will generate login codes for you. Please choose your OS to get corresponding installation links.",
|
||||
"installOnOfTheApps": "Install one of the following apps:",
|
||||
"findAlternativeApps": "Find alternative apps",
|
||||
"theAppIsInstalled": "App has been installed",
|
||||
|
||||
"scanQrCode": "Open your favorite QR scanner app and scan the following QR code:",
|
||||
"or": "OR",
|
||||
"enterKeyManually": "If you can't scan QR code, try entering your secret key manually:",
|
||||
"whenKeyEntered": "If a temporary code appears in your two‑factor auth app, then you may proceed to the next step.",
|
||||
"ready": "Ready",
|
||||
|
||||
"codePlaceholder": "Enter the code here",
|
||||
"enterCodeFromApp": "In order to finish two‑factor auth setup, please enter the code received in the mobile app:",
|
||||
"enable": "Enable",
|
||||
|
||||
"disable": "Disable",
|
||||
"mfaEnabledForYourAcc": "Two‑factor authentication for your account is active now",
|
||||
"mfaLoginFlowDesc": "Additional code will be requested next time you log in. Please note, that Minecraft authorization won't work when two‑factor auth is enabled.",
|
||||
"disableMfa": "Disable two‑factor authentication",
|
||||
"disableMfaInstruction": "In order to disable two‑factor authentication, you need to provide a code from your mobile app and confirm your action with your current account password."
|
||||
}
|
@ -7,7 +7,6 @@ import { FormModel } from 'app/components/ui/form';
|
||||
|
||||
import MfaEnable, { MfaStep } from './MfaEnable';
|
||||
import MfaDisable from './MfaDisable';
|
||||
import messages from './MultiFactorAuth.intl.json';
|
||||
|
||||
class MultiFactorAuth extends React.Component<{
|
||||
step: MfaStep;
|
||||
@ -25,7 +24,7 @@ class MultiFactorAuth extends React.Component<{
|
||||
|
||||
<div className={styles.form}>
|
||||
<div className={styles.formBody}>
|
||||
<Message {...messages.mfaTitle}>
|
||||
<Message key="mfaTitle" defaultMessage="Two‑factor authentication">
|
||||
{(pageTitle) => (
|
||||
<h3 className={styles.title}>
|
||||
<Helmet title={pageTitle as string} />
|
||||
@ -36,7 +35,10 @@ class MultiFactorAuth extends React.Component<{
|
||||
|
||||
<div className={styles.formRow}>
|
||||
<p className={styles.description}>
|
||||
<Message {...messages.mfaDescription} />
|
||||
<Message
|
||||
key="mfaDescription"
|
||||
defaultMessage="Two‑factor authentication is an extra layer of security designed to ensure you that you're the only person who can access your account, even if the password gets stolen."
|
||||
/>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1 +0,0 @@
|
||||
export { default } from './Confirmation';
|
@ -0,0 +1,12 @@
|
||||
/**
|
||||
* Extract this file to the level upper to keep the messages prefix. Will be resolved later.
|
||||
*/
|
||||
|
||||
import { defineMessages } from 'react-intl';
|
||||
|
||||
export default defineMessages({
|
||||
mfaIntroduction:
|
||||
'First of all, you need to install one of our suggested apps on your phone. This app will generate login codes for you. Please choose your OS to get corresponding installation links.',
|
||||
installOnOfTheApps: 'Install one of the following apps:',
|
||||
findAlternativeApps: 'Find alternative apps',
|
||||
});
|
@ -3,7 +3,7 @@ import { FormattedMessage as Message } from 'react-intl';
|
||||
import clsx from 'clsx';
|
||||
|
||||
import profileForm from '../../profileForm.scss';
|
||||
import messages from '../MultiFactorAuth.intl.json';
|
||||
import messages from '../instructions.intl';
|
||||
import OsInstruction from './OsInstruction';
|
||||
import OsTile from './OsTile';
|
||||
import styles from './instructions.scss';
|
||||
|
@ -1,7 +1,7 @@
|
||||
import React from 'react';
|
||||
import { FormattedMessage as Message } from 'react-intl';
|
||||
|
||||
import messages from '../MultiFactorAuth.intl.json';
|
||||
import messages from '../instructions.intl';
|
||||
import styles from './instructions.scss';
|
||||
|
||||
type OS = 'android' | 'ios' | 'windows';
|
||||
|
@ -0,0 +1,12 @@
|
||||
/**
|
||||
* Extract this file to the level upper to keep the messages prefix. Will be resolved later.
|
||||
*/
|
||||
|
||||
import { defineMessages } from 'react-intl';
|
||||
|
||||
export default defineMessages({
|
||||
scanQrCode: 'Open your favorite QR scanner app and scan the following QR code:',
|
||||
or: 'OR',
|
||||
enterKeyManually: "If you can't scan QR code, try entering your secret key manually:",
|
||||
whenKeyEntered: 'If a temporary code appears in your two‑factor auth app, then you may proceed to the next step.',
|
||||
});
|
@ -4,7 +4,7 @@ import { FormattedMessage as Message } from 'react-intl';
|
||||
import { ImageLoader } from 'app/components/ui/loader';
|
||||
import profileForm from 'app/components/profile/profileForm.scss';
|
||||
|
||||
import messages from '../MultiFactorAuth.intl.json';
|
||||
import messages from '../keyForm.intl';
|
||||
import styles from './key-form.scss';
|
||||
|
||||
export default function KeyForm({ secret, qrCodeSrc }: { secret: string; qrCodeSrc: string }) {
|
||||
|
@ -1,5 +0,0 @@
|
||||
{
|
||||
"title": "Confirm your action",
|
||||
"description": "To complete action enter the account password",
|
||||
"continue": "Continue"
|
||||
}
|
@ -1,12 +1,15 @@
|
||||
import React, { ComponentType } from 'react';
|
||||
import { FormattedMessage as Message } from 'react-intl';
|
||||
import { defineMessages, FormattedMessage as Message } from 'react-intl';
|
||||
import clsx from 'clsx';
|
||||
|
||||
import { Form, Button, Input, FormModel } from 'app/components/ui/form';
|
||||
import popupStyles from 'app/components/ui/popup/popup.scss';
|
||||
|
||||
import styles from './passwordRequestForm.scss';
|
||||
import messages from './PasswordRequestForm.intl.json';
|
||||
|
||||
const labels = defineMessages({
|
||||
continue: 'Continue',
|
||||
});
|
||||
|
||||
interface Props {
|
||||
form: FormModel;
|
||||
@ -19,7 +22,7 @@ const PasswordRequestForm: ComponentType<Props> = ({ form, onSubmit }) => (
|
||||
<Form onSubmit={onSubmit} form={form}>
|
||||
<div className={popupStyles.header}>
|
||||
<h2 className={popupStyles.headerTitle}>
|
||||
<Message {...messages.title} />
|
||||
<Message key="title" defaultMessage="Confirm your action" />
|
||||
</h2>
|
||||
</div>
|
||||
|
||||
@ -27,7 +30,7 @@ const PasswordRequestForm: ComponentType<Props> = ({ form, onSubmit }) => (
|
||||
<span className={styles.lockIcon} />
|
||||
|
||||
<div className={styles.description}>
|
||||
<Message {...messages.description} />
|
||||
<Message key="description" defaultMessage="To complete action enter the account password" />
|
||||
</div>
|
||||
|
||||
<Input
|
||||
@ -40,7 +43,7 @@ const PasswordRequestForm: ComponentType<Props> = ({ form, onSubmit }) => (
|
||||
center
|
||||
/>
|
||||
</div>
|
||||
<Button color="green" label={messages.continue} block type="submit" />
|
||||
<Button color="green" label={labels.continue} block type="submit" />
|
||||
</Form>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,5 +0,0 @@
|
||||
{
|
||||
"criticalErrorHappened": "There was a critical error due to which the application can not continue its normal operation.",
|
||||
"reloadPageOrContactUs": "Please reload this page and try again. If problem occurs again, please report it to the developers by sending email to",
|
||||
"alsoYouCanInteractWithBackground": "You can also play around with the background – it's interactable ;)"
|
||||
}
|
@ -1,12 +1,11 @@
|
||||
import React, { ComponentType } from 'react';
|
||||
import { FormattedMessage as Message } from 'react-intl';
|
||||
|
||||
import appInfo from 'app/components/auth/appInfo/AppInfo.intl.json';
|
||||
import appName from 'app/components/auth/appInfo/appName.intl';
|
||||
|
||||
import BoxesField from './BoxesField';
|
||||
|
||||
import styles from './styles.scss';
|
||||
import messages from './BSoD.intl.json';
|
||||
|
||||
interface State {
|
||||
lastEventId?: string | void;
|
||||
@ -31,19 +30,28 @@ const BSoD: ComponentType<Props> = ({ lastEventId }) => {
|
||||
|
||||
<div className={styles.wrapper}>
|
||||
<div className={styles.title}>
|
||||
<Message {...appInfo.appName} />
|
||||
<Message {...appName} />
|
||||
</div>
|
||||
<div className={styles.lineWithMargin}>
|
||||
<Message {...messages.criticalErrorHappened} />
|
||||
<Message
|
||||
key="criticalErrorHappened"
|
||||
defaultMessage="There was a critical error due to which the application can not continue its normal operation."
|
||||
/>
|
||||
</div>
|
||||
<div className={styles.line}>
|
||||
<Message {...messages.reloadPageOrContactUs} />
|
||||
<Message
|
||||
key="reloadPageOrContactUs"
|
||||
defaultMessage="Please reload this page and try again. If problem occurs again, please report it to the developers by sending email to"
|
||||
/>
|
||||
</div>
|
||||
<a href={emailUrl} className={styles.support}>
|
||||
support@ely.by
|
||||
</a>
|
||||
<div className={styles.easterEgg}>
|
||||
<Message {...messages.alsoYouCanInteractWithBackground} />
|
||||
<Message
|
||||
key="alsoYouCanInteractWithBackground"
|
||||
defaultMessage="You can also play around with the background – it's interactable ;)"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,3 +0,0 @@
|
||||
{
|
||||
"logout": "Logout"
|
||||
}
|
@ -1,4 +0,0 @@
|
||||
{
|
||||
"register": "Join",
|
||||
"login": "Sign in"
|
||||
}
|
@ -4,7 +4,6 @@ import { FormattedMessage as Message } from 'react-intl';
|
||||
import { Account } from 'app/components/accounts/reducer';
|
||||
import buttons from 'app/components/ui/buttons.scss';
|
||||
|
||||
import messages from './Userbar.intl.json';
|
||||
import styles from './userbar.scss';
|
||||
import LoggedInPanel from './LoggedInPanel';
|
||||
|
||||
@ -27,7 +26,7 @@ export default class Userbar extends Component<{
|
||||
case 'login':
|
||||
guestAction = (
|
||||
<Link to="/login" className={buttons.blue}>
|
||||
<Message {...messages.login} />
|
||||
<Message key="login" defaultMessage="Sign in" />
|
||||
</Link>
|
||||
);
|
||||
break;
|
||||
@ -35,7 +34,7 @@ export default class Userbar extends Component<{
|
||||
default:
|
||||
guestAction = (
|
||||
<Link to="/register" className={buttons.blue}>
|
||||
<Message {...messages.register} />
|
||||
<Message key="register" defaultMessage="Join" />
|
||||
</Link>
|
||||
);
|
||||
break;
|
||||
|
@ -30,6 +30,7 @@
|
||||
"components.auth.finish.passCodeToApp": "To complete authorization process, please, provide the following code to {appName}",
|
||||
"components.auth.finish.waitAppReaction": "Please, wait till your application response",
|
||||
"components.auth.forgotPassword.alreadyHaveCode": "Already have a code",
|
||||
"components.auth.forgotPassword.emailOrUsername": "E‑mail or username",
|
||||
"components.auth.forgotPassword.pleasePressButton": "Please press the button bellow to get an E‑mail with password recovery code.",
|
||||
"components.auth.forgotPassword.sendMail": "Send mail",
|
||||
"components.auth.forgotPassword.specifyEmail": "Specify the registration E‑mail address or last used username for your account and we will send an E‑mail with instructions for further password recovery.",
|
||||
@ -40,6 +41,7 @@
|
||||
"components.auth.login.next": "Next",
|
||||
"components.auth.mfa.description": "In order to sign in this account, you need to enter a one-time password from mobile application",
|
||||
"components.auth.mfa.enterTotp": "Enter code",
|
||||
"components.auth.mfa.signInButton": "Sign in",
|
||||
"components.auth.password.accountPassword": "Account password",
|
||||
"components.auth.password.forgotPassword": "Forgot password",
|
||||
"components.auth.password.passwordTitle": "Enter password",
|
||||
@ -67,15 +69,19 @@
|
||||
"components.auth.recoverPassword.title": "Restore password",
|
||||
"components.auth.register.acceptRules": "I agree with {link}",
|
||||
"components.auth.register.accountPassword": "Account password",
|
||||
"components.auth.register.alreadyHaveCode": "Already have a code",
|
||||
"components.auth.register.didNotReceivedEmail": "Did not received E‑mail?",
|
||||
"components.auth.register.registerTitle": "Sign Up",
|
||||
"components.auth.register.repeatPassword": "Repeat password",
|
||||
"components.auth.register.signUpButton": "Register",
|
||||
"components.auth.register.termsOfService": "terms of service",
|
||||
"components.auth.register.yourEmail": "Your E‑mail",
|
||||
"components.auth.register.yourNickname": "Your nickname",
|
||||
"components.auth.resendActivation.alreadyHaveCode": "Already have a code",
|
||||
"components.auth.resendActivation.sendNewEmail": "Send new E‑mail",
|
||||
"components.auth.resendActivation.specifyYourEmail": "Please, enter an E‑mail you've registered with and we will send you new activation code",
|
||||
"components.auth.resendActivation.title": "Did not received an E‑mail",
|
||||
"components.auth.resendActivation.yourEmail": "Your E‑mail",
|
||||
"components.contact.cannotAccessMyAccount": "Can not access my account",
|
||||
"components.contact.close": "Close",
|
||||
"components.contact.disclaimer": "Please formulate your feedback providing as much useful information, as possible to help us understand your problem and solve it",
|
||||
|
@ -1,6 +0,0 @@
|
||||
{
|
||||
"title": "Page not found",
|
||||
"nothingHere": "This is not a place that you are looking for",
|
||||
"returnToTheHomePage": "Try to go back to the {link}",
|
||||
"homePage": "main page"
|
||||
}
|
@ -5,12 +5,13 @@ import { Helmet } from 'react-helmet-async';
|
||||
import { FooterMenu } from 'app/components/footerMenu';
|
||||
|
||||
import styles from './404.scss';
|
||||
import messages from './PageNotFound.intl.json';
|
||||
import profileStyles from '../profile/profile.scss';
|
||||
|
||||
const PageNotFound: ComponentType = () => (
|
||||
<div className={styles.page}>
|
||||
<Message {...messages.title}>{(pageTitle) => <Helmet title={pageTitle as string} />}</Message>
|
||||
<Message key="title" defaultMessage="Page not found">
|
||||
{(pageTitle) => <Helmet title={pageTitle as string} />}
|
||||
</Message>
|
||||
|
||||
<div className={styles.loading}>
|
||||
<div className={styles.cube} />
|
||||
@ -29,15 +30,16 @@ const PageNotFound: ComponentType = () => (
|
||||
</div>
|
||||
</div>
|
||||
<p className={styles.text}>
|
||||
<Message {...messages.nothingHere} />
|
||||
<Message key="nothingHere" defaultMessage="This is not a place that you are looking for" />
|
||||
</p>
|
||||
<p className={styles.subText}>
|
||||
<Message
|
||||
{...messages.returnToTheHomePage}
|
||||
key="returnToTheHomePage"
|
||||
defaultMessage="Try to go back to the {link}"
|
||||
values={{
|
||||
link: (
|
||||
<Link to="/">
|
||||
<Message {...messages.homePage} />
|
||||
<Message key="homePage" defaultMessage="main page" />
|
||||
</Link>
|
||||
),
|
||||
}}
|
||||
|
@ -1,7 +0,0 @@
|
||||
{
|
||||
"title": "Authorization successful",
|
||||
"applicationAuth": "Application authorization",
|
||||
"authorizationSuccessful": "Authorization has been successfully completed.",
|
||||
"authorizationForAppSuccessful": "Authorization for {appName} has been successfully completed.",
|
||||
"youCanCloseThisPage": "You can close this window and return to your application."
|
||||
}
|
@ -5,9 +5,8 @@ import { Helmet } from 'react-helmet-async';
|
||||
import * as loader from 'app/services/loader';
|
||||
import { Query } from 'app/services/request';
|
||||
|
||||
import rootMessages from '../root/RootPage.intl.json';
|
||||
import siteName from 'app/pages/root/siteName.intl';
|
||||
import styles from './success-oauth.scss';
|
||||
import messages from './SuccessOauthPage.intl.json';
|
||||
|
||||
export default class SuccessOauthPage extends React.Component<{
|
||||
location: {
|
||||
@ -41,15 +40,17 @@ export default class SuccessOauthPage extends React.Component<{
|
||||
|
||||
return (
|
||||
<div className={styles.page}>
|
||||
<Message {...messages.title}>{(pageTitle) => <Helmet title={pageTitle as string} />}</Message>
|
||||
<Message key="title" defaultMessage="Authorization successful">
|
||||
{(pageTitle) => <Helmet title={pageTitle as string} />}
|
||||
</Message>
|
||||
|
||||
<div className={styles.wrapper}>
|
||||
<Link to="/" className={styles.logo}>
|
||||
<Message {...rootMessages.siteName} />
|
||||
<Message {...siteName} />
|
||||
</Link>
|
||||
|
||||
<div className={styles.title}>
|
||||
<Message {...messages.applicationAuth} />
|
||||
<Message key="applicationAuth" defaultMessage="Application authorization" />
|
||||
</div>
|
||||
|
||||
<div className={styles.checkmark} />
|
||||
@ -57,16 +58,23 @@ export default class SuccessOauthPage extends React.Component<{
|
||||
<div className={styles.description}>
|
||||
{appName ? (
|
||||
<Message
|
||||
{...messages.authorizationForAppSuccessful}
|
||||
key="authorizationForAppSuccessful"
|
||||
defaultMessage="Authorization for {appName} has been successfully completed."
|
||||
values={{
|
||||
appName: <b>{appName}</b>,
|
||||
}}
|
||||
/>
|
||||
) : (
|
||||
<Message {...messages.authorizationSuccessful} />
|
||||
<Message
|
||||
key="authorizationSuccessful"
|
||||
defaultMessage="Authorization has been successfully completed."
|
||||
/>
|
||||
)}
|
||||
|
||||
<Message {...messages.youCanCloseThisPage} />
|
||||
<Message
|
||||
key="youCanCloseThisPage"
|
||||
defaultMessage="You can close this window and return to your application."
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,3 +0,0 @@
|
||||
{
|
||||
"siteName": "Ely.by"
|
||||
}
|
@ -19,7 +19,7 @@ import { RootState } from 'app/reducers';
|
||||
import { ComponentLoader } from 'app/components/ui/loader';
|
||||
|
||||
import styles from './root.scss';
|
||||
import messages from './RootPage.intl.json';
|
||||
import siteName from './siteName.intl';
|
||||
|
||||
const ProfilePage = React.lazy(() =>
|
||||
import(/* webpackChunkName: "page-profile-all" */ 'app/pages/profile/ProfilePage'),
|
||||
@ -76,7 +76,7 @@ class RootPage extends React.PureComponent<{
|
||||
<div className={styles.header} data-testid="toolbar">
|
||||
<div className={styles.headerContent}>
|
||||
<Link to="/" className={styles.logo} onClick={onLogoClick} data-testid="home-page">
|
||||
<Message {...messages.siteName} />
|
||||
<Message {...siteName} />
|
||||
</Link>
|
||||
<div className={styles.userbar}>
|
||||
<Userbar account={account} guestAction={isRegisterPage ? 'login' : 'register'} />
|
||||
|
7
packages/app/pages/root/siteName.intl.ts
Normal file
7
packages/app/pages/root/siteName.intl.ts
Normal file
@ -0,0 +1,7 @@
|
||||
import { defineMessages } from 'react-intl';
|
||||
|
||||
const { siteName } = defineMessages({
|
||||
siteName: 'Ely.by',
|
||||
});
|
||||
|
||||
export default siteName;
|
@ -1,24 +0,0 @@
|
||||
{
|
||||
"title": "Site rules",
|
||||
|
||||
"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.",
|
||||
"mainProvision2": "We (here and in the next points) — Ely.by project developers team that make creating qualitative services for Minecraft community.",
|
||||
"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.",
|
||||
"mainProvision4": "The registration of the users account at server is free. Account creation Ely.by is only possible at that page {link}.",
|
||||
|
||||
"emailAndNickname": "E‑mail and nickname",
|
||||
"emailAndNickname1": "Account registration with usage of temporary mail services is prohibited. We speak about services that gives random E‑mail in any quantity.",
|
||||
"emailAndNickname2": "We try to counteract it, but if you succesed in registration of account with usage of temporary mail services, there wont be any technical support for it and later, during of update of ours filters, account will be blocked with your nickname.",
|
||||
"emailAndNickname3": "There are no any moral restrictions for users nickname that will be used in game.",
|
||||
"emailAndNickname4": "Nicknames, belonging to famous persons, can be released at their favor for requirement and proves of that persons.",
|
||||
"emailAndNickname5": "Minecraft premium account owner has right to require a control restore of his nickname an if it happened you have to change your nickname in 3 days or it will be done automatically.",
|
||||
"emailAndNickname6": "If there is no any activity at your account during last 3 month, your nickname can be occupied by any user.",
|
||||
"emailAndNickname7": "We aren't responsible for losing your game progress at servers if it was result of nickname changing, including changes on our demand.",
|
||||
|
||||
"elyAccountsAsService": "{name} as service",
|
||||
"elyAccountsAsServiceDesc1": "{name} has free providing to any project, that interested in it usage for Minecraft.",
|
||||
"elyAccountsAsServiceDesc2": "Despite we do our utmost to provide fast and stable work of service, we are not saved from DDOS-attack, hosters links work interruptions, electricity disorders or any cases, that impossible to be predicted. For avoiding possible incomprehension, we obliged to discuss next agreements, that will work in case of situations mentioned before:",
|
||||
"elyAccountsAsService1": "We don't have any guarantee about fault free work time of this service.",
|
||||
"elyAccountsAsService2": "We are not responsible for delays and lost income as the result of ours service inoperability."
|
||||
}
|
@ -3,31 +3,36 @@ import { Link } from 'react-router-dom';
|
||||
import { FormattedMessage as Message } from 'react-intl';
|
||||
import { Helmet } from 'react-helmet-async';
|
||||
import { FooterMenu } from 'app/components/footerMenu';
|
||||
import appInfo from 'app/components/auth/appInfo/AppInfo.intl.json';
|
||||
import appName from 'app/components/auth/appInfo/appName.intl';
|
||||
|
||||
import styles from './rules.scss';
|
||||
import messages from './RulesPage.intl.json';
|
||||
|
||||
const projectName = <Message {...appInfo.appName} />;
|
||||
const projectName = <Message {...appName} />;
|
||||
|
||||
import clsx from 'clsx';
|
||||
|
||||
const rules = [
|
||||
{
|
||||
title: <Message {...messages.mainProvisions} />,
|
||||
title: <Message key="mainProvisions" defaultMessage="Main provisions" />,
|
||||
items: [
|
||||
<Message
|
||||
key="0"
|
||||
{...messages.mainProvision1}
|
||||
key="mainProvision1"
|
||||
defaultMessage="{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."
|
||||
values={{
|
||||
name: <b>{projectName}</b>,
|
||||
}}
|
||||
/>,
|
||||
<Message key="1" {...messages.mainProvision2} />,
|
||||
<Message key="2" {...messages.mainProvision3} />,
|
||||
<Message
|
||||
key="3"
|
||||
{...messages.mainProvision4}
|
||||
key="mainProvision2"
|
||||
defaultMessage="We (here and in the next points) — Ely.by project developers team that make creating qualitative services for Minecraft community."
|
||||
/>,
|
||||
<Message
|
||||
key="mainProvision3"
|
||||
defaultMessage="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."
|
||||
/>,
|
||||
<Message
|
||||
key="mainProvision4"
|
||||
defaultMessage="The registration of the users account at server is free. Account creation Ely.by is only possible at that page {link}."
|
||||
values={{
|
||||
link: <Link to="/register">https://account.ely.by/register</Link>,
|
||||
}}
|
||||
@ -35,21 +40,43 @@ const rules = [
|
||||
],
|
||||
},
|
||||
{
|
||||
title: <Message {...messages.emailAndNickname} />,
|
||||
title: <Message key="emailAndNickname" defaultMessage="E‑mail and nickname" />,
|
||||
items: [
|
||||
<Message key="0" {...messages.emailAndNickname1} />,
|
||||
<Message key="1" {...messages.emailAndNickname2} />,
|
||||
<Message key="2" {...messages.emailAndNickname3} />,
|
||||
<Message key="3" {...messages.emailAndNickname4} />,
|
||||
<Message key="4" {...messages.emailAndNickname5} />,
|
||||
<Message key="5" {...messages.emailAndNickname6} />,
|
||||
<Message key="6" {...messages.emailAndNickname7} />,
|
||||
<Message
|
||||
key="emailAndNickname1"
|
||||
defaultMessage="Account registration with usage of temporary mail services is prohibited. We speak about services that gives random E‑mail in any quantity."
|
||||
/>,
|
||||
<Message
|
||||
key="emailAndNickname2"
|
||||
defaultMessage="We try to counteract it, but if you succesed in registration of account with usage of temporary mail services, there wont be any technical support for it and later, during of update of ours filters, account will be blocked with your nickname."
|
||||
/>,
|
||||
<Message
|
||||
key="emailAndNickname3"
|
||||
defaultMessage="There are no any moral restrictions for users nickname that will be used in game."
|
||||
/>,
|
||||
<Message
|
||||
key="emailAndNickname4"
|
||||
defaultMessage="Nicknames, belonging to famous persons, can be released at their favor for requirement and proves of that persons."
|
||||
/>,
|
||||
<Message
|
||||
key="emailAndNickname5"
|
||||
defaultMessage="Minecraft premium account owner has right to require a control restore of his nickname an if it happened you have to change your nickname in 3 days or it will be done automatically."
|
||||
/>,
|
||||
<Message
|
||||
key="emailAndNickname6"
|
||||
defaultMessage="If there is no any activity at your account during last 3 month, your nickname can be occupied by any user."
|
||||
/>,
|
||||
<Message
|
||||
key="emailAndNickname7"
|
||||
defaultMessage="We aren't responsible for losing your game progress at servers if it was result of nickname changing, including changes on our demand."
|
||||
/>,
|
||||
],
|
||||
},
|
||||
{
|
||||
title: (
|
||||
<Message
|
||||
{...messages.elyAccountsAsService}
|
||||
key="elyAccountsAsService"
|
||||
defaultMessage="{name} as service"
|
||||
values={{
|
||||
name: projectName,
|
||||
}}
|
||||
@ -59,20 +86,30 @@ const rules = [
|
||||
<div>
|
||||
<p>
|
||||
<Message
|
||||
{...messages.elyAccountsAsServiceDesc1}
|
||||
key="elyAccountsAsServiceDesc1"
|
||||
defaultMessage="{name} has free providing to any project, that interested in it usage for Minecraft."
|
||||
values={{
|
||||
name: <b>{projectName}</b>,
|
||||
}}
|
||||
/>
|
||||
</p>
|
||||
<p>
|
||||
<Message {...messages.elyAccountsAsServiceDesc2} />
|
||||
<Message
|
||||
key="elyAccountsAsServiceDesc2"
|
||||
defaultMessage="Despite we do our utmost to provide fast and stable work of service, we are not saved from DDOS-attack, hosters links work interruptions, electricity disorders or any cases, that impossible to be predicted. For avoiding possible incomprehension, we obliged to discuss next agreements, that will work in case of situations mentioned before:"
|
||||
/>
|
||||
</p>
|
||||
</div>
|
||||
),
|
||||
items: [
|
||||
<Message key="0" {...messages.elyAccountsAsService1} />,
|
||||
<Message key="1" {...messages.elyAccountsAsService2} />,
|
||||
<Message
|
||||
key="elyAccountsAsService1"
|
||||
defaultMessage="We don't have any guarantee about fault free work time of this service."
|
||||
/>,
|
||||
<Message
|
||||
key="elyAccountsAsService2"
|
||||
defaultMessage="We are not responsible for delays and lost income as the result of ours service inoperability."
|
||||
/>,
|
||||
],
|
||||
},
|
||||
];
|
||||
@ -97,7 +134,9 @@ export default class RulesPage extends Component<{
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Message {...messages.title}>{(pageTitle) => <Helmet title={pageTitle as string} />}</Message>
|
||||
<Message key="title" defaultMessage="Site rules">
|
||||
{(pageTitle) => <Helmet title={pageTitle as string} />}
|
||||
</Message>
|
||||
|
||||
<div className={styles.rules}>
|
||||
{rules.map((block, sectionIndex) => (
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user