diff --git a/.eslintrc.json b/.eslintrc.json index 91bad378..4636c068 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -5,12 +5,14 @@ "jest/globals": true }, "parser": "babel-eslint", - "extends": ["airbnb"], + "extends": [ + "airbnb", + "plugin:jsdoc/recommended" + ], "globals": { "Atomics": "readonly", "SharedArrayBuffer": "readonly" }, - "parserOptions": { "ecmaFeatures": { "jsx": true @@ -18,7 +20,11 @@ "ecmaVersion": 2018, "sourceType": "module" }, - "plugins": ["react", "jest"], + "plugins": [ + "react", + "jsdoc", + "jest" + ], "rules": { "react/jsx-filename-extension": [1, { "extensions": [".js", ".jsx"] }], "no-underscore-dangle":"off", diff --git a/package-lock.json b/package-lock.json index 5b262551..38aa348c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5120,6 +5120,12 @@ "graceful-readlink": ">= 1.0.0" } }, + "comment-parser": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-0.7.0.tgz", + "integrity": "sha512-m0SGP0RFO4P3hIBlIor4sBFPe5Y4HUeGgo/UZK/1Zdea5eUiqxroQ3lFqBDDSfWo9z9Q6LLnt2u0JqwacVEd/A==", + "dev": true + }, "common-tags": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.0.tgz", @@ -7543,6 +7549,30 @@ } } }, + "eslint-plugin-jsdoc": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-18.1.3.tgz", + "integrity": "sha512-QmdxsDzGG9eb20VD3V8hw4huehTnU6x1/we9tN56p8MOkJNEiHDFW59stcS2/sk+BSnsJy61qZ+6wCPya8B45w==", + "dev": true, + "requires": { + "comment-parser": "^0.7.0", + "debug": "^4.1.1", + "jsdoctypeparser": "^6.0.0", + "lodash": "^4.17.15", + "object.entries-ponyfill": "^1.0.1", + "regextras": "^0.6.1", + "semver": "^6.3.0", + "spdx-expression-parse": "^3.0.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, "eslint-plugin-jest": { "version": "23.1.1", "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-23.1.1.tgz", @@ -11633,6 +11663,12 @@ } } }, + "jsdoctypeparser": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/jsdoctypeparser/-/jsdoctypeparser-6.0.0.tgz", + "integrity": "sha512-61VtBXLkHfOFSIdp/VDVNMksxK0ID0cPTNvxDR92tPA6K7r2AX0OcJegYxhJIwtpWKU4p3D9L3U02hhlP1kQLQ==", + "dev": true + }, "jsdom": { "version": "11.12.0", "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-11.12.0.tgz", @@ -13519,6 +13555,12 @@ "has": "^1.0.3" } }, + "object.entries-ponyfill": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object.entries-ponyfill/-/object.entries-ponyfill-1.0.1.tgz", + "integrity": "sha1-Kavfd8v70mVm3RqiTp2I9lQz0lY=", + "dev": true + }, "object.fromentries": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.1.tgz", @@ -15949,6 +15991,12 @@ "unicode-match-property-value-ecmascript": "^1.1.0" } }, + "regextras": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/regextras/-/regextras-0.6.1.tgz", + "integrity": "sha512-EzIHww9xV2Kpqx+corS/I7OBmf2rZ0pKKJPsw5Dc+l6Zq1TslDmtRIP9maVn3UH+72MIXmn8zzDgP07ihQogUA==", + "dev": true + }, "registry-auth-token": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.0.0.tgz", diff --git a/package.json b/package.json index cf708e48..76a3abc3 100644 --- a/package.json +++ b/package.json @@ -71,6 +71,7 @@ "eslint-config-airbnb": "^18.0.1", "eslint-loader": "^3.0.2", "eslint-plugin-import": "^2.18.2", + "eslint-plugin-jsdoc": "^18.1.3", "eslint-plugin-jsx-a11y": "^6.2.3", "eslint-plugin-react": "^7.16.0", "eslint-plugin-react-hooks": "^1.7.0", diff --git a/src/assets/styles/includes/_mixin.scss b/src/assets/styles/includes/_mixin.scss new file mode 100644 index 00000000..0738f6c3 --- /dev/null +++ b/src/assets/styles/includes/_mixin.scss @@ -0,0 +1,10 @@ +@mixin title { + margin-top: 18px; + margin-bottom: 8px; + color: #000; + font-weight: 700; + font-size: 24px; + font-family: "Grotesk"; + line-height: 28px; + text-align: center; +} \ No newline at end of file diff --git a/src/components/Button/Button.js b/src/components/Button/Button.js index 522fa169..198a67f6 100644 --- a/src/components/Button/Button.js +++ b/src/components/Button/Button.js @@ -42,7 +42,7 @@ Button.propTypes = { iconPosition: propTypes.bool, type: propTypes.string, disabled: propTypes.bool, - onClick: propTypes.func.isRequired, + onClick: propTypes.func, theme: propTypes.string, size: propTypes.string, }; @@ -54,6 +54,7 @@ Button.defaultProps = { icon: null, iconPosition: false, disabled: false, + onClick: () => {}, }; export default Button; diff --git a/src/components/Decision/Decision.js b/src/components/Decision/Decision.js new file mode 100644 index 00000000..13bed15e --- /dev/null +++ b/src/components/Decision/Decision.js @@ -0,0 +1,49 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { withTranslation } from 'react-i18next'; +import FinPassForm from '../../stores/FormsStore/FinPassForm'; +import FinPassFormWrapper from '../FinPassFormWrapper/FinPassFormWrapper'; + +import styles from './Decision.scss'; + +@withTranslation() +class Decision extends React.Component { + form = new FinPassForm({ + hooks: { + onSuccess() { + return Promise.resolve(); + }, + onError() { + /* eslint-disable-next-line */ + console.error('error'); + }, + }, + }) + + static propTypes = { + t: PropTypes.func.isRequired, + icon: PropTypes.node.isRequired, + title: PropTypes.string.isRequired, + }; + + render() { + const { props, form } = this; + const { t, icon, title } = props; + return ( +
+
+ {icon} +
+

+ {title} +

+

+ {t('other:enterPassForConfirm')} +

+ +
+ ); + } +} + +export default Decision; diff --git a/src/components/Decision/Decision.scss b/src/components/Decision/Decision.scss new file mode 100644 index 00000000..427bb311 --- /dev/null +++ b/src/components/Decision/Decision.scss @@ -0,0 +1,25 @@ +@import '../../assets/styles/includes/mixin'; + +.decision { + width: 100%; + text-align: center; + + &__title { + @include title; + } + + &__subtext { + color: rgba(0, 0, 0, 0.7); + font-size: 14px; + line-height: 16px; + text-align: center; + } + + &__icon { + svg { + width: auto; + height: auto; + margin-top: 47px; + } + } +} \ No newline at end of file diff --git a/src/components/Decision/Decision.test.js b/src/components/Decision/Decision.test.js new file mode 100644 index 00000000..0b78456f --- /dev/null +++ b/src/components/Decision/Decision.test.js @@ -0,0 +1,31 @@ +import React from 'react'; +import { shallow } from 'enzyme'; +import { DecisionReject, DecisionAgree } from '.'; + +describe('DecisionReject', () => { + let wrapper; + + beforeEach(() => { + wrapper = shallow( + , + ).dive(); + }); + + it('should render without error', () => { + expect(wrapper.length).toEqual(1); + }); +}); + +describe('DecisionAgree', () => { + let wrapper; + + beforeEach(() => { + wrapper = shallow( + , + ).dive(); + }); + + it('should render without error', () => { + expect(wrapper.length).toEqual(1); + }); +}); diff --git a/src/components/Decision/DecisionAgree.js b/src/components/Decision/DecisionAgree.js new file mode 100644 index 00000000..984d0c83 --- /dev/null +++ b/src/components/Decision/DecisionAgree.js @@ -0,0 +1,25 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { withTranslation } from 'react-i18next'; +import Decision from './Decision'; +import { VerifyIcon } from '../Icons'; + +@withTranslation() +class DecisionAgree extends React.Component { + static propTypes = { + t: PropTypes.func.isRequired, + }; + + render() { + const { props } = this; + const { t } = props; + return ( + )} + /> + ); + } +} + +export default DecisionAgree; diff --git a/src/components/Decision/DecisionReject.js b/src/components/Decision/DecisionReject.js new file mode 100644 index 00000000..b6e296ff --- /dev/null +++ b/src/components/Decision/DecisionReject.js @@ -0,0 +1,25 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { withTranslation } from 'react-i18next'; +import Decision from './Decision'; +import { RejectIcon } from '../Icons'; + +@withTranslation() +class DecisionReject extends React.Component { + static propTypes = { + t: PropTypes.func.isRequired, + }; + + render() { + const { props } = this; + const { t } = props; + return ( + )} + /> + ); + } +} + +export default DecisionReject; diff --git a/src/components/Decision/index.js b/src/components/Decision/index.js new file mode 100644 index 00000000..9077e969 --- /dev/null +++ b/src/components/Decision/index.js @@ -0,0 +1,11 @@ +import Decision from './Decision'; +import DecisionReject from './DecisionReject'; +import DecisionAgree from './DecisionAgree'; + +export default Decision; + +export { + Decision, + DecisionReject, + DecisionAgree, +}; diff --git a/src/components/Dialog/Dialog.scss b/src/components/Dialog/Dialog.scss index 80c3a289..27d6f623 100644 --- a/src/components/Dialog/Dialog.scss +++ b/src/components/Dialog/Dialog.scss @@ -13,7 +13,7 @@ &__inner { position: relative; z-index: 1; - min-height: 325px; + min-height: 309px; } } diff --git a/src/components/Dialog/index.js b/src/components/Dialog/index.js index 16772f4f..4a07e93e 100644 --- a/src/components/Dialog/index.js +++ b/src/components/Dialog/index.js @@ -1,3 +1,8 @@ import Dialog from './Dialog'; +import DefaultDialogFooter from './DefaultDialogFooter'; export default { Dialog }; + +export { + DefaultDialogFooter, +}; diff --git a/src/components/FinPassFormWrapper/FinPassFormWrapper.js b/src/components/FinPassFormWrapper/FinPassFormWrapper.js new file mode 100644 index 00000000..924f35f4 --- /dev/null +++ b/src/components/FinPassFormWrapper/FinPassFormWrapper.js @@ -0,0 +1,49 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { withTranslation } from 'react-i18next'; +import Input from '../Input'; +import { Password } from '../Icons'; +import Button from '../Button/Button'; + +import styles from './FinPassFormWrapper.scss'; + +@withTranslation() +class FinPassFormWrapper extends React.Component { + static propTypes = { + t: PropTypes.func.isRequired, + form: PropTypes.shape({ + onSubmit: PropTypes.func.isRequired, + $: PropTypes.func.isRequired, + }).isRequired, + }; + + render() { + const { props } = this; + const { t, form } = props; + return ( +
+
+
+ + + +
+
+ +
+
+
+ ); + } +} + +export default FinPassFormWrapper; diff --git a/src/components/FinPassFormWrapper/FinPassFormWrapper.scss b/src/components/FinPassFormWrapper/FinPassFormWrapper.scss new file mode 100644 index 00000000..9e1ed67d --- /dev/null +++ b/src/components/FinPassFormWrapper/FinPassFormWrapper.scss @@ -0,0 +1,21 @@ +.form-fin-pass { + margin-top: 56px; + + .input__wrapper { + .field { + width: 100%; + max-width: 309px; + margin-bottom: 0px; + } + } + + .button__wrapper { + margin-top: 48px; + margin-bottom: 59px; + + button { + width: 100%; + max-width: 309px; + } + } +} diff --git a/src/components/FinPassFormWrapper/FinPassFormWrapper.stories.js b/src/components/FinPassFormWrapper/FinPassFormWrapper.stories.js new file mode 100644 index 00000000..6df33427 --- /dev/null +++ b/src/components/FinPassFormWrapper/FinPassFormWrapper.stories.js @@ -0,0 +1,24 @@ +import React from 'react'; +// eslint-disable-next-line import/no-extraneous-dependencies +import { storiesOf } from '@storybook/react'; +import FinPassFormWrapper from './FinPassFormWrapper'; +import FinPassForm from '../../stores/FormsStore/FinPassForm'; + +const form = new FinPassForm({ + hooks: { + onSuccess() { + return Promise.resolve(); + }, + onError() { + /* eslint-disable-next-line */ + console.error('error'); + }, + }, +}); + +storiesOf('FinPassFormWrapper', module) + .add('Default', () => ( + + )); diff --git a/src/components/Input/index.js b/src/components/Input/index.js index d073daff..42e5c040 100644 --- a/src/components/Input/index.js +++ b/src/components/Input/index.js @@ -40,7 +40,7 @@ Input.propTypes = { children: propTypes.element.isRequired, className: propTypes.string, field: propTypes.shape({ - error: propTypes.string.isRequired, + error: propTypes.string, value: propTypes.string.isRequired, placeholder: propTypes.string.isRequired, bind: propTypes.func.isRequired, diff --git a/src/components/Message/Message.scss b/src/components/Message/Message.scss index e74b429a..1bf06d8a 100644 --- a/src/components/Message/Message.scss +++ b/src/components/Message/Message.scss @@ -58,6 +58,26 @@ } } + &--transfer-error { + .subtext { + color: rgba(0, 0, 0, 0.7); + font-size: 14px; + line-height: 16px; + } + + .message { + &__title { + margin-top: 57px; + margin-bottom: 24px; + } + } + + .footer { + padding-top: 73px; + padding-bottom: 51px; + } + } + &--progress { .message { &__title { @@ -78,4 +98,14 @@ text-align: center; } } + + &--agreed, + &--reject, + &--transfer-success, + &--transfer-error { + button { + width: 100%; + max-width: 309px; + } + } } diff --git a/src/components/Message/TransferSuccessMessage.js b/src/components/Message/TransferSuccessMessage.js index 936a2b1f..3efcf783 100644 --- a/src/components/Message/TransferSuccessMessage.js +++ b/src/components/Message/TransferSuccessMessage.js @@ -6,6 +6,7 @@ import DefaultMessage from './DefaultMessage'; import Button from '../Button/Button'; import styles from './Message.scss'; + /** * Dialog with message about success token transfer */ diff --git a/src/components/Message/index.js b/src/components/Message/index.js index 4e724aae..c506a408 100644 --- a/src/components/Message/index.js +++ b/src/components/Message/index.js @@ -3,6 +3,7 @@ import AgreedMessage from './AgreedMessage'; import RejectMessage from './RejectMessage'; import TransferSuccessMessage from './TransferSuccessMessage'; import TokenInProgressMessage from './TokenInProgressMessage'; +import TransferErrorMessage from './TransferErrorMessage'; export default DefaultMessage; @@ -11,4 +12,5 @@ export { RejectMessage, TransferSuccessMessage, TokenInProgressMessage, + TransferErrorMessage, }; diff --git a/src/components/Messages/TransferErrorMessage.js b/src/components/Messages/TransferErrorMessage.js new file mode 100644 index 00000000..d8e00751 --- /dev/null +++ b/src/components/Messages/TransferErrorMessage.js @@ -0,0 +1,40 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { withTranslation } from 'react-i18next'; +import DefaultMessage from './DefaultMessage'; +import Button from '../Button/Button'; + +import styles from './Message.scss'; + +/** + * Dialog with message about success token transfer + */ +@withTranslation(['dialogs', 'other']) +class TransferErrorMessage extends React.Component { + static propTypes = { + t: PropTypes.func.isRequired, + onButtonClick: PropTypes.func.isRequired, + } + + render() { + const { props: { t, onButtonClick } } = this; + return ( +
+ +

{t('other:notEnoughTokens')}

+
+
+ +
+
+ ); + } +} + +export default TransferErrorMessage; diff --git a/src/components/Messages/TransferErrorMessage.test.js b/src/components/Messages/TransferErrorMessage.test.js new file mode 100644 index 00000000..3dd15293 --- /dev/null +++ b/src/components/Messages/TransferErrorMessage.test.js @@ -0,0 +1,29 @@ +import React from 'react'; +import { shallow } from 'enzyme'; +import TransferErrorMessage from './TransferErrorMessage'; +import Button from '../Button/Button'; + +describe('TransferErrorMessage', () => { + let wrapper; + let mockOnClick; + + beforeEach(() => { + mockOnClick = jest.fn(); + wrapper = shallow( + , + ).dive(); + }); + + it('should render without error', () => { + expect(wrapper.length).toEqual(1); + }); + + it('should call mockOnClick on button onClick', () => { + const button = wrapper.find(Button); + expect(button.length).toEqual(1); + button.prop('onClick')(); + expect(mockOnClick).toHaveBeenCalled(); + }); +}); diff --git a/src/components/TokenTransfer/TokenTransfer.js b/src/components/TokenTransfer/TokenTransfer.js new file mode 100644 index 00000000..c0e2ba57 --- /dev/null +++ b/src/components/TokenTransfer/TokenTransfer.js @@ -0,0 +1,94 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { withTranslation } from 'react-i18next'; +import TransferTokenForm from '../../stores/FormsStore/TransferTokenForm'; +import Input from '../Input'; +import { Password, Address, TokenCount } from '../Icons'; +import Button from '../Button/Button'; +import { EMPTY_DATA_STRING } from '../../constants'; + +import styles from './TokenTransfer.scss'; + +/** + * Component form for transfer token + */ +@withTranslation() +class TokenTransfer extends React.Component { + form = new TransferTokenForm({ + hooks: { + onSuccess(form) { + return Promise.resolve(form); + }, + onError() { + /* eslint-disable-next-line */ + console.error('form error'); + }, + }, + }) + + static propTypes = { + t: PropTypes.func.isRequired, + wallet: PropTypes.string, + } + + static defaultProps = { + wallet: EMPTY_DATA_STRING, + } + + handleClick = () => { + /* eslint-disable-next-line */ + console.log('click'); + } + + render() { + const { form } = this; + const { props } = this; + const { t, wallet } = props; + return ( +
+

+ {t('dialogs:tokenTransfer')} +

+
+
+ +
+ +
+
+ + + +
+
+ + + +
+
+ +
+
{wallet}
+
+
+ +
+
+ ); + } +} + +export default TokenTransfer; diff --git a/src/components/TokenTransfer/TokenTransfer.scss b/src/components/TokenTransfer/TokenTransfer.scss new file mode 100644 index 00000000..f0941416 --- /dev/null +++ b/src/components/TokenTransfer/TokenTransfer.scss @@ -0,0 +1,55 @@ +@import '../../assets/styles/includes/mixin'; + +.token-transfer { + text-align: center; + + .input__wrapper { + margin-bottom: 32px; + + .field { + width: 100%; + max-width: 309px; + } + } + + .button__wrapper { + margin-top: 48px; + margin-bottom: 16px; + + .btn { + width: 100%; + max-width: 298px; + } + } + + .wallet__wrapper { + margin-top: 16px; + margin-bottom: 24px; + color: #808080; + font-size: 14px; + line-height: 16px; + } + + &__title { + @include title; + + margin-top: 72px; + margin-bottom: 73px; + } + + &__button { + // compensate padding in dialog + width: calc(100% + 80px); + margin: 0px -40px -10px -40px; + padding: 15px 20px; + color: #c8c9ca; + font-size: 14px; + line-height: 16px; + text-decoration: underline; + background-color: transparent; + border: unset; + border-top: 1px solid #e1e4e8; + outline: none; + cursor: pointer; + } +} \ No newline at end of file diff --git a/src/components/TokenTransfer/TokenTransfer.stories.js b/src/components/TokenTransfer/TokenTransfer.stories.js new file mode 100644 index 00000000..4de57cb9 --- /dev/null +++ b/src/components/TokenTransfer/TokenTransfer.stories.js @@ -0,0 +1,12 @@ +import React from 'react'; +// eslint-disable-next-line import/no-extraneous-dependencies +import { storiesOf } from '@storybook/react'; +import TokenTransfer from './TokenTransfer'; + +storiesOf('TokenTransfer', module) + .add('Without wallet', () => ( + + )) + .add('With wallet', () => ( + + )); diff --git a/src/components/TokenTransfer/TokenTransfer.test.js b/src/components/TokenTransfer/TokenTransfer.test.js new file mode 100644 index 00000000..62a9d0f9 --- /dev/null +++ b/src/components/TokenTransfer/TokenTransfer.test.js @@ -0,0 +1,22 @@ +import React from 'react'; +import { shallow } from 'enzyme'; +import TokenTransfer from './TokenTransfer'; + +jest.mock('../../utils/Validator'); + +describe('TokenTransfer', () => { + it('should render correct without "wallet" prop', () => { + const wrapper = shallow().dive(); + expect(wrapper.length).toEqual(1); + }); + + it('should render correct with props', () => { + const wrapper = shallow( + , + ).dive(); + expect(wrapper.length).toEqual(1); + expect(wrapper.find('.wallet__wrapper').text()).toEqual('0xD490af05Bf82eF6C6BA034B22D18c39B5D52Cc54'); + }); +}); diff --git a/src/components/TokenTransfer/index.js b/src/components/TokenTransfer/index.js new file mode 100644 index 00000000..2bd64e07 --- /dev/null +++ b/src/components/TokenTransfer/index.js @@ -0,0 +1,3 @@ +import TokenTransfer from './TokenTransfer'; + +export default { TokenTransfer }; diff --git a/src/locales/ENG/buttons.js b/src/locales/ENG/buttons.js index 7303b775..ed308fa5 100644 --- a/src/locales/ENG/buttons.js +++ b/src/locales/ENG/buttons.js @@ -17,5 +17,8 @@ const buttons = { withTokens: 'Connect contract and create project', withoutTokens: 'Create new contract and project', toWallets: 'To wallets', + transfer: 'Transfer', + designateGroupAdministrator: 'designate group administrator', + vote: 'Vote', }; export default buttons; diff --git a/src/locales/ENG/dialogs.js b/src/locales/ENG/dialogs.js index bd2146a9..c107f4dc 100644 --- a/src/locales/ENG/dialogs.js +++ b/src/locales/ENG/dialogs.js @@ -1,10 +1,13 @@ const dialog = { definetelyAgree: 'Do you definitely agree?', + definetelyReject: 'Do you definitely reject?', agreedMessage: 'You agreed', rejectMessage: 'You voted against', transferInProgress: 'Token transfer in progress', someTimeText: 'It will take some time', tokenTransferSuccess: 'Tokens successfully transferred!', + tokenTransfer: 'Transfer token', + tokenTransferError: 'Transfer error', }; export default dialog; diff --git a/src/locales/ENG/fields.js b/src/locales/ENG/fields.js index 80666846..d030d9f1 100644 --- a/src/locales/ENG/fields.js +++ b/src/locales/ENG/fields.js @@ -8,6 +8,8 @@ const placeholders = { quantity: 'Quantity', projectTitle: 'Project title', contractAddress: 'Enter contract address', + address: 'Address', + countTokens: 'Count tokens', }; export default placeholders; diff --git a/src/locales/ENG/other.js b/src/locales/ENG/other.js index 8395020a..3d883139 100644 --- a/src/locales/ENG/other.js +++ b/src/locales/ENG/other.js @@ -14,6 +14,8 @@ const other = { withTokens: 'If you have ERC20 tokens', withoutTokens: "If you don't have ERC20 tokens", yourBalance: 'Your balance', + notEnoughTokens: 'Perhaps there are not enough tokens', + enterPassForConfirm: 'Enter your password to confirm your decision.', RUS: 'Русский', ENG: 'English', }; diff --git a/src/locales/RUS/buttons.js b/src/locales/RUS/buttons.js index 0dba007a..384e5444 100644 --- a/src/locales/RUS/buttons.js +++ b/src/locales/RUS/buttons.js @@ -17,5 +17,8 @@ const buttons = { withTokens: 'Подключить контракт и создать проект', withoutTokens: 'Создать новые токены и проект', toWallets: 'К выбору кошелька', + transfer: 'Перевести', + designateGroupAdministrator: 'назначить администратором группы', + vote: 'Голосовать', }; export default buttons; diff --git a/src/locales/RUS/dialogs.js b/src/locales/RUS/dialogs.js index 4a7ff65b..f6bec45c 100644 --- a/src/locales/RUS/dialogs.js +++ b/src/locales/RUS/dialogs.js @@ -1,10 +1,13 @@ const dialog = { definetelyAgree: 'Вы точно согласны?', + definetelyReject: 'Вы точно против?', agreedMessage: 'Вы выразили согласие', rejectMessage: 'Вы проголосовали против', transferInProgress: 'Переводим токены', someTimeText: 'Это займет некоторое время', tokenTransferSuccess: 'Токены успешно переведены!', + tokenTransfer: 'Перевести токены', + tokenTransferError: 'Ошибка перевода', }; export default dialog; diff --git a/src/locales/RUS/fields.js b/src/locales/RUS/fields.js index 81c14fb6..108f60ed 100644 --- a/src/locales/RUS/fields.js +++ b/src/locales/RUS/fields.js @@ -8,6 +8,8 @@ const placeholders = { quantity: 'Количество', projectTitle: 'Придумайте название проекта', contractAddress: 'Введите адрес контракта', + address: 'Адрес кошелька', + countTokens: 'Количество токенов', }; export default placeholders; diff --git a/src/locales/RUS/other.js b/src/locales/RUS/other.js index 6234e3ae..f35cf2ca 100644 --- a/src/locales/RUS/other.js +++ b/src/locales/RUS/other.js @@ -14,6 +14,8 @@ const other = { withTokens: 'Если есть токены ERC20', withoutTokens: 'Если токенов ERC20 нет', yourBalance: 'Ваш баланс', + notEnoughTokens: 'Возможно не хватает токенов', + enterPassForConfirm: 'Введите пароль, чтобы подтвердить свое решеине', RUS: 'Русский', ENG: 'English', }; diff --git a/src/stores/DialogStore/DialogStore.js b/src/stores/DialogStore/DialogStore.js index 73bf9304..404fba34 100644 --- a/src/stores/DialogStore/DialogStore.js +++ b/src/stores/DialogStore/DialogStore.js @@ -28,7 +28,7 @@ class DialogStore { /** * Actual open state * - * @returns {string, boolean} name dialog or boolean state + * @returns {string|boolean} name dialog or boolean state */ get isOpen() { if (this.open && this.dialog) return this.dialog; @@ -39,7 +39,7 @@ class DialogStore { * Method for getting dialog by name in list * * @param {string} dialogName name dialog - * @return {object} dialog item model + * @returns {object} dialog item model */ getDialog(dialogName) { const { list } = this; @@ -144,6 +144,7 @@ class DialogStore { * Method for adding dialog in history dialogs * * @param {object} dialog dialog item model + * @returns {number} length history */ addToHistory(dialog) { if (dialog.history === false) return false; diff --git a/src/stores/FormsStore/FinPassForm.js b/src/stores/FormsStore/FinPassForm.js index ec5ff96a..1cd7689e 100644 --- a/src/stores/FormsStore/FinPassForm.js +++ b/src/stores/FormsStore/FinPassForm.js @@ -6,10 +6,10 @@ class FinPassForm extends ExtendedForm { setup() { return { fields: [{ - name: 'password', + name: 'fin-password', type: 'password', label: 'Password', - placeholder: i18n.t('fields:enterPassword'), + placeholder: i18n.t('fields:password'), rules: 'required|password', }], }; diff --git a/src/stores/FormsStore/TransferTokenForm.js b/src/stores/FormsStore/TransferTokenForm.js new file mode 100644 index 00000000..87622d79 --- /dev/null +++ b/src/stores/FormsStore/TransferTokenForm.js @@ -0,0 +1,35 @@ +/* eslint-disable class-methods-use-this */ +import i18n from 'i18next'; +import ExtendedForm from '../../models/FormModel'; + +class TransferTokenForm extends ExtendedForm { + setup() { + return { + fields: [ + { + name: 'address', + type: 'text', + label: 'Address', + placeholder: i18n.t('fields:address'), + rules: 'required|string', + }, + { + name: 'count', + type: 'text', + label: 'Count tokens', + placeholder: i18n.t('fields:countTokens'), + rules: 'required|numeric|min:1|max:2147483647 ', + }, + { + name: 'password', + type: 'password', + label: 'Password', + placeholder: i18n.t('fields:password'), + rules: 'required|password', + }, + ], + }; + } +} + +export default TransferTokenForm; diff --git a/src/stores/RootStore/RootStore.js b/src/stores/RootStore/RootStore.js index b564760c..177a6808 100644 --- a/src/stores/RootStore/RootStore.js +++ b/src/stores/RootStore/RootStore.js @@ -42,6 +42,7 @@ class RootStore { /** * initiating project + * * @param {string} address adress of project */ @action initProject(address) { diff --git a/webpack.dev.js b/webpack.dev.js index 616ae052..90ada679 100644 --- a/webpack.dev.js +++ b/webpack.dev.js @@ -40,7 +40,7 @@ module.exports = { loader: 'eslint-loader', options: { failOnError: true, - failOnWarning: true, + failOnWarning: false, }, }], }, {