Add i18n translation (#85)
* Fix redux store configuration * Setup i18n * Add welcome page french and english translation * Rename languages files * Add optimized translation * Add Ethereum network error message translation * Add top navbar translation * Add constants translation * Add move domain translation * Add translation to add domain * Add name lookup translation * Add display box translation * Add edit options translation * Add register sub domain translation * Add release domain translation * Add setup ens translation * Add update controller translation * Add test token translation * Add erc20 token translation * Add ens sub management translation * Add admin mode translation * Add terms translation
This commit is contained in:
parent
6dc98d1db9
commit
8d4d00396e
|
@ -4,6 +4,7 @@
|
|||
"react"
|
||||
],
|
||||
"rules": {
|
||||
"react/jsx-filename-extension": 0,
|
||||
"react/prop-types": 0
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import lang from 'i18n-js';
|
||||
import React, { Fragment } from 'react';
|
||||
import { Tabs, Tab } from 'react-bootstrap';
|
||||
import TopNavbar from './topnavbar';
|
||||
|
@ -11,16 +12,16 @@ const AdminMode = () => (
|
|||
<Fragment>
|
||||
<TopNavbar />
|
||||
<Tabs defaultActiveKey={1} id="uncontrolled-tab-example">
|
||||
<Tab eventKey={1} title="TestToken">
|
||||
<Tab eventKey={1} title={lang.t('admin.tab.test_token')}>
|
||||
<TestTokenUI />
|
||||
</Tab>
|
||||
<Tab eventKey={2} title="ERC20Token">
|
||||
<Tab eventKey={2} title={lang.t('admin.tab.erc20_token')}>
|
||||
<ERC20TokenUI />
|
||||
</Tab>
|
||||
<Tab eventKey={3} title="ENS Management">
|
||||
<Tab eventKey={3} title={lang.t('admin.tab.ens_management')}>
|
||||
<ENSSubManagement />
|
||||
</Tab>
|
||||
<Tab eventKey={4} title="Name Lookup">
|
||||
<Tab eventKey={4} title={lang.t('admin.tab.name_lookup')}>
|
||||
<NameLookup />
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import lang from 'i18n-js';
|
||||
import React from 'react';
|
||||
import Typography from '@material-ui/core/Typography';
|
||||
import styled from "styled-components";
|
||||
import styled from 'styled-components';
|
||||
|
||||
const DisplayLabel = styled.div`
|
||||
font-size: 14px;
|
||||
|
@ -29,7 +30,9 @@ const BlueBox = styled.div`
|
|||
color: #4360df;
|
||||
`;
|
||||
|
||||
const DisplayBox = ({ displayType, text, onClick, showBlueBox }) => (
|
||||
const DisplayBox = ({
|
||||
displayType, text, onClick, showBlueBox,
|
||||
}) => (
|
||||
<div>
|
||||
<DisplayLabel>
|
||||
{displayType}
|
||||
|
@ -37,14 +40,12 @@ const DisplayBox = ({ displayType, text, onClick, showBlueBox }) => (
|
|||
<DisplayBoxDiv showBlueBox={showBlueBox} onClick={onClick}>
|
||||
<InnerDisplayBox>
|
||||
{
|
||||
showBlueBox && onClick ?
|
||||
<BlueBox>
|
||||
Grant access
|
||||
</BlueBox>
|
||||
showBlueBox && onClick ?
|
||||
<BlueBox>{lang.t('action.grant_access')}</BlueBox>
|
||||
:
|
||||
<Typography type='body1'>
|
||||
{text}
|
||||
</Typography>
|
||||
<Typography type="body1">
|
||||
{text}
|
||||
</Typography>
|
||||
}
|
||||
</InnerDisplayBox>
|
||||
</DisplayBoxDiv>
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import lang from 'i18n-js';
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { withStyles } from '@material-ui/core/styles';
|
||||
|
@ -47,13 +48,13 @@ class SimpleDialog extends React.Component {
|
|||
<ListItemIcon>
|
||||
<EditIcon />
|
||||
</ListItemIcon>
|
||||
<ListItemText primary="Edit Contact Code" />
|
||||
<ListItemText primary={lang.t('action.edit_contact_code')} />
|
||||
</ListItem>
|
||||
{canBeReleased && <ListItem button onClick={() => this.handleListItemClick('release')}>
|
||||
<ListItemIcon>
|
||||
<DeleteOutline />
|
||||
</ListItemIcon>
|
||||
<ListItemText primary="Release Name" />
|
||||
<ListItemText primary={lang.t('action.release_name')} />
|
||||
</ListItem>}
|
||||
</List>
|
||||
</Dialog>
|
||||
|
@ -69,4 +70,3 @@ SimpleDialog.propTypes = {
|
|||
|
||||
const SimpleDialogWrapped = withStyles(styles)(SimpleDialog);
|
||||
export default SimpleDialogWrapped;
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import lang from 'i18n-js';
|
||||
import React from 'react';
|
||||
import { withStyles } from '@material-ui/core/styles';
|
||||
import Button from '@material-ui/core/Button';
|
||||
|
@ -7,37 +8,36 @@ import DialogContent from '@material-ui/core/DialogContent';
|
|||
import DialogContentText from '@material-ui/core/DialogContentText';
|
||||
import DialogTitle from '@material-ui/core/DialogTitle';
|
||||
import Slide from '@material-ui/core/Slide';
|
||||
import classNames from "classnames";
|
||||
import classNames from 'classnames';
|
||||
|
||||
function Transition(props) {
|
||||
return <Slide direction="up" {...props} />;
|
||||
}
|
||||
|
||||
const styles = theme => ({
|
||||
dialog: {
|
||||
textAlign: 'center',
|
||||
},
|
||||
actions: {
|
||||
background: 'rgba(255, 255, 255, 0.8)',
|
||||
margin: 0,
|
||||
borderTop: 'solid 1px #ccc',
|
||||
},
|
||||
button: {
|
||||
margin: '0',
|
||||
fontSize: '17px',
|
||||
color: '#007AFF',
|
||||
width: '50%',
|
||||
borderRight: 'solid 1px #ccc',
|
||||
borderRadius: 0,
|
||||
padding: '15px',
|
||||
}
|
||||
const styles = () => ({
|
||||
dialog: {
|
||||
textAlign: 'center',
|
||||
},
|
||||
actions: {
|
||||
background: 'rgba(255, 255, 255, 0.8)',
|
||||
margin: 0,
|
||||
borderTop: 'solid 1px #ccc',
|
||||
},
|
||||
button: {
|
||||
margin: '0',
|
||||
fontSize: '17px',
|
||||
color: '#007AFF',
|
||||
width: '50%',
|
||||
borderRight: 'solid 1px #ccc',
|
||||
borderRadius: 0,
|
||||
padding: '15px',
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
const ReleaseDomainAlert = ({ classes, open, handleClose }) => (
|
||||
<div>
|
||||
<Dialog
|
||||
className={classNames(classes.dialog)}
|
||||
className={classNames(classes.dialog)}
|
||||
open={open}
|
||||
TransitionComponent={Transition}
|
||||
keepMounted
|
||||
|
@ -46,19 +46,19 @@ const ReleaseDomainAlert = ({ classes, open, handleClose }) => (
|
|||
aria-describedby="alert-dialog-slide-description"
|
||||
>
|
||||
<DialogTitle id="alert-dialog-slide-title">
|
||||
{"Release domain?"}
|
||||
{lang.t('domain.release.alert.title')}
|
||||
</DialogTitle>
|
||||
<DialogContent>
|
||||
<DialogContentText id="alert-dialog-slide-description">
|
||||
Your SNT deposit will be returned and name will be available to other users.
|
||||
{lang.t('domain.release.alert.text')}
|
||||
</DialogContentText>
|
||||
</DialogContent>
|
||||
<DialogActions className={classNames(classes.actions)}>
|
||||
<Button onClick={() => handleClose(null)} className={classNames(classes.button)} color="primary">
|
||||
<strong>Cancel</strong>
|
||||
<strong>{lang.t('action.cancel')}</strong>
|
||||
</Button>
|
||||
<Button onClick={() => handleClose(true)} className={classNames(classes.button)} color="primary">
|
||||
Yes
|
||||
{lang.t('action.yes')}
|
||||
</Button>
|
||||
</DialogActions>
|
||||
</Dialog>
|
||||
|
@ -66,4 +66,4 @@ const ReleaseDomainAlert = ({ classes, open, handleClose }) => (
|
|||
);
|
||||
|
||||
|
||||
export default withStyles(styles)(ReleaseDomainAlert);
|
||||
export default withStyles(styles)(ReleaseDomainAlert);
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import lang from 'i18n-js';
|
||||
import UsernameRegistrar from 'Embark/contracts/UsernameRegistrar';
|
||||
import web3 from 'web3';
|
||||
import ENSRegistry from 'Embark/contracts/ENSRegistry';
|
||||
|
@ -36,7 +37,7 @@ const InnerForm = ({
|
|||
id="registryName"
|
||||
name="registryName"
|
||||
type="text"
|
||||
label="Registry Name"
|
||||
label={lang.t('registry.name.label')}
|
||||
onChange={handleChange}
|
||||
onBlur={handleBlur}
|
||||
value={values.registryName}
|
||||
|
@ -46,13 +47,13 @@ const InnerForm = ({
|
|||
id="registryPrice"
|
||||
name="registryPrice"
|
||||
type="number"
|
||||
label="Registry Price"
|
||||
placeholder="(Optional) Registry will be free if left blank"
|
||||
label={lang.t('registry.price.label')}
|
||||
placeholder={lang.t('registry.price.placeholder')}
|
||||
onChange={handleChange}
|
||||
onBlur={handleBlur}
|
||||
value={values.registryPrice}
|
||||
/>
|
||||
<Button bsStyle="primary" type="submit" disabled={isSubmitting || !!Object.keys(errors).length}>{!isSubmitting ? 'Submit' : 'Submitting to the Blockchain - (this may take awhile)'}</Button>
|
||||
<Button bsStyle="primary" type="submit" disabled={isSubmitting || !!Object.keys(errors).length}>{!isSubmitting ? lang.t('action.submit') : lang.t('action.submitting_to_blockchain')}</Button>
|
||||
</form>
|
||||
)
|
||||
|
||||
|
@ -61,8 +62,8 @@ const AddRegistry = withFormik({
|
|||
async validate(values) {
|
||||
const { registryName } = values;
|
||||
const errors = {};
|
||||
if (!registryName) errors.registryName = 'Required';
|
||||
if (registryName && !await getAndIsOwner(registryName)) errors.registryName = 'This registry is not owned by registry';
|
||||
if (!registryName) errors.registryName = lang.t('registry.error.name.required');
|
||||
if (registryName && !await getAndIsOwner(registryName)) errors.registryName = lang.t('registry.error.name.owned');
|
||||
if (Object.keys(errors).length) throw errors;
|
||||
},
|
||||
async handleSubmit(values, { setSubmitting }) {
|
||||
|
|
|
@ -1,2 +1,4 @@
|
|||
export const YOUR_CONTACT_CODE = 'Your contact code';
|
||||
export const YOUR_WALLET_ADDRESS = 'Your wallet address';
|
||||
import lang from 'i18n-js';
|
||||
|
||||
export const YOUR_CONTACT_CODE = lang.t('constants.contact_code');
|
||||
export const YOUR_WALLET_ADDRESS = lang.t('constants.wallet_address');
|
||||
|
|
|
@ -1,23 +0,0 @@
|
|||
export default {
|
||||
release: {
|
||||
title: {
|
||||
sub: 'Done!',
|
||||
body: 'The released username will be available to other users'
|
||||
},
|
||||
subheading: 'Follow the progress in the Transaction History section of your wallet.'
|
||||
},
|
||||
registered: {
|
||||
title: {
|
||||
sub: 'Nice!',
|
||||
body: 'The name is yours once the transaction is complete'
|
||||
},
|
||||
subheading: 'Follow the progress in the Transaction History section of your wallet.'
|
||||
},
|
||||
edit: {
|
||||
title: {
|
||||
sub: 'Done!',
|
||||
body: 'Your changes will be saved when the transaction is complete'
|
||||
},
|
||||
subheading: 'Follow the progress in the Transaction History section of your wallet.'
|
||||
}
|
||||
}
|
|
@ -1,3 +1,4 @@
|
|||
import lang from 'i18n-js';
|
||||
import UsernameRegistrar from 'Embark/contracts/UsernameRegistrar';
|
||||
import web3 from 'web3';
|
||||
import React from 'react';
|
||||
|
@ -18,13 +19,13 @@ const InnerForm = ({
|
|||
id="newAddress"
|
||||
name="newAddress"
|
||||
type="text"
|
||||
label="New Controller Address"
|
||||
label={lang.t('domain.new_address.label')}
|
||||
onChange={handleChange}
|
||||
onBlur={handleBlur}
|
||||
value={values.newAddress}
|
||||
error={errors.newAddress}
|
||||
/>
|
||||
<Button bsStyle="primary" type="submit" disabled={isSubmitting || !!Object.keys(errors).length}>{!isSubmitting ? 'Submit' : 'Submitting to the Blockchain - (this may take awhile)'}</Button>
|
||||
<Button bsStyle="primary" type="submit" disabled={isSubmitting || !!Object.keys(errors).length}>{!isSubmitting ? lang.t('action.submit') : lang.t('action.submitting_to_blockchain')}</Button>
|
||||
</form>
|
||||
)
|
||||
|
||||
|
@ -34,7 +35,7 @@ const MoveDomain = withFormik({
|
|||
const { utils: { isAddress } } = web3;
|
||||
const { newAddress } = values;
|
||||
const errors = {};
|
||||
if (!isAddress(newAddress)) errors.newAddress = 'Please enter a valid address'
|
||||
if (!isAddress(newAddress)) errors.newAddress = lang.t('error.valid_address')
|
||||
if (Object.keys(errors).length) throw errors;
|
||||
},
|
||||
async handleSubmit(values, { setSubmitting }) {
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import lang from 'i18n-js';
|
||||
import React, { Fragment, PureComponent } from 'react';
|
||||
import web3 from 'web3';
|
||||
import EmbarkJS from 'Embark/EmbarkJS';
|
||||
|
@ -27,7 +28,6 @@ import Warning from '../../ui/components/Warning';
|
|||
const { getPrice, getExpirationTime, getCreationTime, release } = UsernameRegistrar.methods;
|
||||
import NotInterested from '@material-ui/icons/NotInterested';
|
||||
import Face from '@material-ui/icons/Face';
|
||||
import Copy from './copy';
|
||||
import IDNANormalizer from 'idna-normalize';
|
||||
import { nullAddress, getResolver } from './utils/domain';
|
||||
import { YOUR_CONTACT_CODE } from './constants';
|
||||
|
@ -208,11 +208,11 @@ const RegisterInfoCard = ({ formattedDomain, domainPrice, registryOwnsDomain })
|
|||
const TransactionComplete = ({ type, setStatus }) => (
|
||||
<div style={{ textAlign: 'center', margin: '40% 15 10' }}>
|
||||
<Typography variant="title" style={{ marginBottom: '1rem' }}>
|
||||
{Copy[type]['title']['sub']}<br/>
|
||||
{Copy[type]['title']['body']}
|
||||
{lang.t(`copy.${type}.title.sub`)}<br/>
|
||||
{lang.t(`copy.${type}.title.body`)}
|
||||
</Typography>
|
||||
<Typography variant="subheading" style={{ color: '#939BA1' }}>
|
||||
{Copy[type]['subheading']}
|
||||
{lang.t('copy.subheading')}
|
||||
</Typography>
|
||||
<MobileButton text="Main Page" style={{ marginTop: '12rem' }} onClick={() => { setStatus(null) } } />
|
||||
</div>
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import lang from 'i18n-js';
|
||||
import web3 from "Embark/web3"
|
||||
import UsernameRegistrar from 'Embark/contracts/UsernameRegistrar';
|
||||
import TestToken from 'Embark/contracts/TestToken';
|
||||
|
@ -63,7 +64,7 @@ class InnerForm extends React.Component {
|
|||
id="subDomain"
|
||||
name="subDomain"
|
||||
type="text"
|
||||
label="Sub Domain"
|
||||
label={lang.t('sub_domain.label')}
|
||||
onChange={handleChange}
|
||||
onBlur={handleBlur}
|
||||
value={values.subDomain}
|
||||
|
@ -74,7 +75,7 @@ class InnerForm extends React.Component {
|
|||
id="domainName"
|
||||
name="domainName"
|
||||
type="text"
|
||||
label="Domain Name"
|
||||
label={lang.t('domain.name.label')}
|
||||
onChange={handleChange}
|
||||
onBlur={handleBlur}
|
||||
value={values.domainName}
|
||||
|
@ -97,7 +98,7 @@ class InnerForm extends React.Component {
|
|||
<FieldGroup
|
||||
id="price"
|
||||
name="price"
|
||||
label="Domain Price"
|
||||
label={lang.t('domain.price.label')}
|
||||
disabled
|
||||
value={values.price ? `${formatPrice(values.price)} SNT` : ''}/>}
|
||||
<Hidden mdDown>
|
||||
|
@ -105,7 +106,7 @@ class InnerForm extends React.Component {
|
|||
id="statusAddress"
|
||||
name="statusAddress"
|
||||
type="text"
|
||||
label="Status messenger address domain resolves to"
|
||||
label={lang.t('domain.status_address.label')}
|
||||
onChange={handleChange}
|
||||
onBlur={handleBlur}
|
||||
value={values.statusAddress}
|
||||
|
@ -116,15 +117,20 @@ class InnerForm extends React.Component {
|
|||
id="address"
|
||||
name="address"
|
||||
type="text"
|
||||
label="Ethereum address domain resolves to"
|
||||
label={lang.t('domain.ethereum_address.label')}
|
||||
onChange={handleChange}
|
||||
onBlur={handleBlur}
|
||||
value={values.address}
|
||||
error={errors.address}
|
||||
button={<Button mode="strong"
|
||||
style={{padding: '5px 15px 5px 15px', marginTop: '5px'}}
|
||||
onClick={() => setFieldValue('address', web3.eth.defaultAccount)}>Use My Primary
|
||||
Address</Button>}
|
||||
button={
|
||||
<Button
|
||||
mode="strong"
|
||||
style={{padding: '5px 15px 5px 15px', marginTop: '5px'}}
|
||||
onClick={() => setFieldValue('address', web3.eth.defaultAccount)}
|
||||
>
|
||||
{lang.t('action.use_my_primary_address')}
|
||||
</Button>
|
||||
}
|
||||
/>
|
||||
{!isSubmitting ? <Button wide mode="strong" type="submit"
|
||||
disabled={isSubmitting || !!Object.keys(errors).length}>{!isSubmitting ? 'Submit' : 'Submitting to the Blockchain - (this may take awhile)'}</Button> :
|
||||
|
@ -143,22 +149,22 @@ class InnerForm extends React.Component {
|
|||
onClick={() => requestStatusContactCode()}/>
|
||||
</Fragment> :
|
||||
<Fragment>
|
||||
<Field label="Your Wallet Address">
|
||||
<Field label={YOUR_WALLET_ADDRESS}>
|
||||
<MobileSearch
|
||||
name="address"
|
||||
style={{ marginTop: '10px' }}
|
||||
placeholder="Your wallet address"
|
||||
placeholder={YOUR_WALLET_ADDRESS}
|
||||
value={values.address}
|
||||
onChange={handleChange}
|
||||
onClick={() => setFieldValue('address', '')}
|
||||
required
|
||||
wide />
|
||||
</Field>
|
||||
<Field label="Your contact code">
|
||||
<Field label={YOUR_CONTACT_CODE}>
|
||||
<MobileSearch
|
||||
name="statusAddress"
|
||||
style={{ marginTop: '10px' }}
|
||||
placeholder="Enter Your Status Messenger Address Here"
|
||||
placeholder={lang.t('domain.status_address.placeholder')}
|
||||
value={values.statusAddress}
|
||||
onChange={handleChange}
|
||||
onClick={() => setFieldValue('statusAddress', '')}
|
||||
|
@ -172,7 +178,7 @@ class InnerForm extends React.Component {
|
|||
this.onRegisterClick(this.props);
|
||||
}}>
|
||||
<div>
|
||||
{`${editAccount ? 'Update' : 'Register'}`}
|
||||
{`${editAccount ? lang.t('action.update') : lang.t('action.register')}`}
|
||||
</div>
|
||||
</ArrowButton>
|
||||
:
|
||||
|
@ -203,8 +209,8 @@ const RegisterSubDomain = withFormik({
|
|||
const errors = {};
|
||||
const { address } = values;
|
||||
const { subDomain } = props || values;
|
||||
if (address && !web3.utils.isAddress(address)) errors.address = 'Not a valid address';
|
||||
if (!subDomain) errors.subDomain = 'Required';
|
||||
if (address && !web3.utils.isAddress(address)) errors.address = lang.t('domain.ethereum_address.error');
|
||||
if (!subDomain) errors.subDomain = lang.t('sub_domain.error.required');
|
||||
return errors;
|
||||
},
|
||||
async handleSubmit(values, { setSubmitting, props }) {
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
import lang from 'i18n-js';
|
||||
import React, { Fragment } from 'react';
|
||||
import { Form, FormGroup, FormControl, HelpBlock, Button, ControlLabel } from 'react-bootstrap';
|
||||
import { Button } from 'react-bootstrap';
|
||||
import UsernameRegistrar from 'Embark/contracts/UsernameRegistrar';
|
||||
import web3Utils from 'web3-utils'
|
||||
import { hash } from 'eth-ens-namehash'
|
||||
|
||||
const zeroBytes32 = "0x0000000000000000000000000000000000000000000000000000000000000000";
|
||||
const zeroBytes32 = '0x0000000000000000000000000000000000000000000000000000000000000000';
|
||||
const getUserAddress = contract => contract._provider.publicConfigStore._state.selectedAddress;
|
||||
const dispatchSetup = (ENSRegistry) => {
|
||||
const { methods: { setSubnodeOwner } } = ENSRegistry;
|
||||
|
@ -21,8 +22,13 @@ const dispatchSetup = (ENSRegistry) => {
|
|||
}
|
||||
const SetupEns = ({ ENSRegistry }) => (
|
||||
<Fragment>
|
||||
<Button bsStyle="primary" onClick={() => dispatchSetup(ENSRegistry)}>ADD INITIAL NODES TO ENS</Button>
|
||||
<Button
|
||||
bsStyle="primary"
|
||||
onClick={() => dispatchSetup(ENSRegistry)}
|
||||
>
|
||||
{lang.t('action.setup_ens')}
|
||||
</Button>
|
||||
</Fragment>
|
||||
)
|
||||
);
|
||||
|
||||
export default SetupEns;
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
import lang from 'i18n-js';
|
||||
import styled from 'styled-components';
|
||||
import React from 'react';
|
||||
import Dialog from '@material-ui/core/Dialog';
|
||||
import {ArrowButton} from '../../ui/components';
|
||||
import styled from "styled-components";
|
||||
import { ArrowButton } from '../../ui/components';
|
||||
|
||||
const TermsContainer = styled.div`
|
||||
word-wrap: break-word;
|
||||
|
@ -36,31 +37,34 @@ const ListContainer = styled.ul`
|
|||
const Terms = ({ open, onSubmit }) => (
|
||||
<Dialog fullScreen open={open}>
|
||||
<TermsContainer>
|
||||
<InfoHeading className="ens-terms__title">Terms of name registration</InfoHeading>
|
||||
|
||||
<InfoHeading className="ens-terms__title">{lang.t('terms.title')}</InfoHeading>
|
||||
<TermsDescription>
|
||||
<ListContainer>
|
||||
<li>Funds are deposited for 1 year. Your SNT will be locked, but not spent.</li>
|
||||
<li>After 1 year, you can release the name and get your deposit back. The name is yours until you release it.</li>
|
||||
<li>Names are created as a subdomain of <i>stateofus.eth</i>. They are property of Status and may be subject to new terms.</li>
|
||||
<li>If the <i>stateofus.eth</i> contract terms change—e.g. Status makes contract upgrades—you have the right to get your deposit back, even for names held less than 1 year.</li>
|
||||
<li> Names may not:
|
||||
<li>{lang.t('terms.funds_deposit')}</li>
|
||||
<li>{lang.t('terms.funds_release')}</li>
|
||||
<li>{lang.t('terms.names_creation', { stateofus: <i>stateofus.eth</i> })}</li>
|
||||
<li>{lang.t('terms.contract', { stateofus: <i>stateofus.eth</i> })}</li>
|
||||
<li>{lang.t('terms.rule.title')}
|
||||
<ol type="1">
|
||||
<li>contain less than 4 characters;</li>
|
||||
<li>n non-alphanumeric characters;</li>
|
||||
<li>contain uppercase letters;</li>
|
||||
<li>appear on this <a href="https://github.com/status-im/ens-usernames/blob/master/config/ens-usernames/reservedNames.js">reserved list</a></li>
|
||||
<li>mimic an Ethereum address (start with <code>Ox</code> and contain only hexadecimal characters in the first 12 digits)</li>
|
||||
<li>{lang.t('terms.rule.one')}</li>
|
||||
<li>{lang.t('terms.rule.two')}</li>
|
||||
<li>{lang.t('terms.rule.three')}</li>
|
||||
<li>{lang.t('terms.rule.four', { reserved_list_link: <a href="https://github.com/status-im/ens-usernames/blob/master/config/ens-usernames/reservedNames.js">{lang.t('terms.reserved_list')}</a> })}</li>
|
||||
<li>{lang.t('terms.rule.five', { eth_address: <code>Ox</code> })}</li>
|
||||
</ol>
|
||||
</li>
|
||||
<li>Registering an illegal name via the registry contract will result in the loss of your SNT deposit and removal of the name.</li>
|
||||
<li>Contact codes and wallet addresses associated with your name are publicly available information.</li>
|
||||
<li>{lang.t('terms.illegal_name')}</li>
|
||||
<li>{lang.t('terms.contact')}</li>
|
||||
</ListContainer>
|
||||
</TermsDescription>
|
||||
|
||||
<div style={{display: 'flex', flexDirection: 'row-reverse', marginBottom: '16px', marginRight: '8px'}}>
|
||||
<div
|
||||
style={{
|
||||
display: 'flex', flexDirection: 'row-reverse', marginBottom: '16px', marginRight: '8px',
|
||||
}}
|
||||
>
|
||||
<ArrowButton type="submit" onClick={onSubmit}>
|
||||
<div>Send SNT</div>
|
||||
<div>{lang.t('action.send_snt')}</div>
|
||||
</ArrowButton>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import lang from 'i18n-js';
|
||||
import UsernameRegistrar from 'Embark/contracts/UsernameRegistrar';
|
||||
import web3 from 'web3';
|
||||
import React from 'react';
|
||||
|
@ -18,23 +19,29 @@ const InnerForm = ({
|
|||
id="newAddress"
|
||||
name="newAddress"
|
||||
type="text"
|
||||
label="New Controller Address"
|
||||
label={lang.t('domain.new_address.label')}
|
||||
onChange={handleChange}
|
||||
onBlur={handleBlur}
|
||||
value={values.newAddress}
|
||||
error={errors.newAddress}
|
||||
/>
|
||||
<Button bsStyle="primary" type="submit" disabled={isSubmitting || !!Object.keys(errors).length}>{!isSubmitting ? 'Submit' : 'Submitting to the Blockchain - (this may take awhile)'}</Button>
|
||||
<Button
|
||||
bsStyle="primary"
|
||||
type="submit"
|
||||
disabled={isSubmitting || !!Object.keys(errors).length}
|
||||
>
|
||||
{!isSubmitting ? lang.t('action.submit') : lang.t('action.submitting_to_blockchain')}
|
||||
</Button>
|
||||
</form>
|
||||
)
|
||||
);
|
||||
|
||||
const UpdateController = withFormik({
|
||||
mapPropsToValues: props => ({ newAddress: '' }),
|
||||
mapPropsToValues: () => ({ newAddress: '' }),
|
||||
async validate(values) {
|
||||
const { utils: { isAddress } } = web3;
|
||||
const { newAddress } = values;
|
||||
const errors = {};
|
||||
if (!isAddress(newAddress)) errors.newAddress = 'Please enter a valid address'
|
||||
if (!isAddress(newAddress)) errors.newAddress = lang.t('error.valid_address');
|
||||
if (Object.keys(errors).length) throw errors;
|
||||
},
|
||||
async handleSubmit(values, { setSubmitting }) {
|
||||
|
@ -49,8 +56,8 @@ const UpdateController = withFormik({
|
|||
.catch((err) => {
|
||||
setSubmitting(false);
|
||||
console.log(err);
|
||||
})
|
||||
}
|
||||
});
|
||||
},
|
||||
})(InnerForm);
|
||||
|
||||
export default UpdateController;
|
||||
|
|
|
@ -1,33 +1,36 @@
|
|||
import lang from 'i18n-js';
|
||||
import React from 'react';
|
||||
import {StyledButton} from '../../ui/components';
|
||||
import { Link } from 'react-router-dom';
|
||||
|
||||
import { StyledButton } from '../../ui/components';
|
||||
import StatusCards from '../../ui/icons/svg/intro_name.svg';
|
||||
import {Link} from "react-router-dom";
|
||||
|
||||
import './welcome.css';
|
||||
|
||||
const WelcomeContent = () => (
|
||||
<div>
|
||||
<div className="ens-welcome__guide"><span>How it works</span></div>
|
||||
<div className="ens-welcome__guide"><span>{lang.t('welcome.how')}</span></div>
|
||||
|
||||
<ol className="ens-welcome__list">
|
||||
<li className="item">
|
||||
<div className="title">Simplify your ETH address</div>
|
||||
<div className="text">Your complex wallet address (0x...) becomes an easy to read, remember & share URL: <span
|
||||
className="ens-welcome__highlight">myname.stateofus.eth</span></div>
|
||||
</li>
|
||||
<li className="item">
|
||||
<div className="title">10 SNT to register</div>
|
||||
<div className="text">Register once to keep the name forever. After 1 year, you can release the name and get
|
||||
your SNT back.
|
||||
<div className="title">{lang.t('welcome.step.one.title')}</div>
|
||||
<div className="text">
|
||||
{lang.t('welcome.step.one.subtitle')}{' '}
|
||||
<span className="ens-welcome__highlight">{lang.t('welcome.eth_address_example')}</span>
|
||||
</div>
|
||||
</li>
|
||||
<li className="item">
|
||||
<div className="title">Connect & get paid</div>
|
||||
<div className="text">Share your name to chat on Status or receive ETH and tokens.</div>
|
||||
<div className="title">{lang.t('welcome.step.two.title')}</div>
|
||||
<div className="text">{lang.t('welcome.step.two.subtitle')}
|
||||
</div>
|
||||
</li>
|
||||
<li className="item">
|
||||
<div className="title">{lang.t('welcome.step.three.title')}</div>
|
||||
<div className="text">{lang.t('welcome.step.three.subtitle')}</div>
|
||||
</li>
|
||||
</ol>
|
||||
<div className="text-light">
|
||||
<small>Powered by Ethereum Name Services</small>
|
||||
<small>{lang.t('welcome.disclaimer')}</small>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
@ -35,15 +38,13 @@ const WelcomeContent = () => (
|
|||
const Welcome = () => (
|
||||
<div className="ens-welcome">
|
||||
<img className="ens-welcome__img" src={StatusCards} />
|
||||
<h2 className="ens-welcome__title">
|
||||
ENS names transform those crazy-long addresses into unique usernames
|
||||
</h2>
|
||||
<h2 className="ens-welcome__title">{lang.t('welcome.title')}</h2>
|
||||
<Link to="/search">
|
||||
<StyledButton>
|
||||
<div>Let's Go</div>
|
||||
<div>{lang.t('welcome.cta')}</div>
|
||||
</StyledButton>
|
||||
</Link>
|
||||
<WelcomeContent/>
|
||||
<WelcomeContent />
|
||||
</div>
|
||||
);
|
||||
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
import EmbarkJS from 'Embark/EmbarkJS';
|
||||
import lang from 'i18n-js';
|
||||
import ENSRegistry from 'Embark/contracts/ENSRegistry';
|
||||
import UsernameRegistrar from 'Embark/contracts/UsernameRegistrar';
|
||||
import TestToken from 'Embark/contracts/TestToken';
|
||||
import React, { Fragment } from 'react';
|
||||
import { Form, FormGroup, FormControl, HelpBlock, Button, ControlLabel } from 'react-bootstrap';
|
||||
import AddDomain from './ens/addDomain';
|
||||
import MoveDomain from './ens/moveDomain';
|
||||
import RegisterSubDomain from './ens/registerSubDomain';
|
||||
|
@ -11,34 +10,27 @@ import TokenPermissions from './standard/TokenPermission';
|
|||
import SetupENS from './ens/setupENS';
|
||||
import UpdateController from './ens/updateController';
|
||||
|
||||
const FieldGroup = ({ id, label, help, ...props }) => (
|
||||
<FormGroup controlId={id}>
|
||||
<ControlLabel>{label}</ControlLabel>
|
||||
<FormControl {...props} />
|
||||
{help && <HelpBlock>{help}</HelpBlock>}
|
||||
</FormGroup>
|
||||
)
|
||||
|
||||
const ENSSubManagement = props => (
|
||||
const ENSSubManagement = () => (
|
||||
<Fragment>
|
||||
<h2 style={{ textAlign: 'center' }}>Subdomain Management</h2>
|
||||
<h3>Change Registry Controller</h3>
|
||||
<h2 style={{ textAlign: 'center' }}>{lang.t('sub_domain.management.title')}</h2>
|
||||
<h3>{lang.t('sub_domain.management.change_registry')}</h3>
|
||||
<UpdateController />
|
||||
<h3>Activate Registry/Update Registry Price</h3>
|
||||
<h3>{lang.t('sub_domain.management.activate_registry')}</h3>
|
||||
<AddDomain />
|
||||
<h3>Move Domain To Another Registry</h3>
|
||||
<h3>{lang.t('sub_domain.management.move_domain')}</h3>
|
||||
<MoveDomain />
|
||||
<hr/>
|
||||
<h3>Register Sub-Domain</h3>
|
||||
<hr />
|
||||
<h3>{lang.t('sub_domain.management.register_sub_domain')}</h3>
|
||||
<RegisterSubDomain />
|
||||
<hr/>
|
||||
<hr />
|
||||
<TokenPermissions
|
||||
symbol='SNT'
|
||||
symbol="SNT"
|
||||
spender={UsernameRegistrar._address}
|
||||
methods={TestToken.methods} />
|
||||
<hr/>
|
||||
methods={TestToken.methods}
|
||||
/>
|
||||
<hr />
|
||||
<SetupENS ENSRegistry={ENSRegistry} />
|
||||
</Fragment>
|
||||
)
|
||||
);
|
||||
|
||||
export default ENSSubManagement;
|
||||
|
|
|
@ -1,128 +1,128 @@
|
|||
import lang from 'i18n-js';
|
||||
import EmbarkJS from 'Embark/EmbarkJS';
|
||||
import ERC20Token from 'Embark/contracts/ERC20Token';
|
||||
import React from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { Form, FormGroup, FormControl, HelpBlock, Button } from 'react-bootstrap';
|
||||
import { getCurrentAccount, accountsIsLoading } from '../reducers/accounts';
|
||||
|
||||
|
||||
class ERC20TokenUI extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
ERC20Token.options.address = props.address;
|
||||
this.state = {
|
||||
balanceOf: 0,
|
||||
transferTo: '',
|
||||
transferAmount: 0,
|
||||
accountB: web3.eth.defaultAccount,
|
||||
};
|
||||
}
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
ERC20Token.options.address = props.address;
|
||||
this.state = {
|
||||
balanceOf: 0,
|
||||
transferTo: "",
|
||||
transferAmount: 0,
|
||||
accountBalance: 0,
|
||||
accountB: web3.eth.defaultAccount,
|
||||
}
|
||||
}
|
||||
|
||||
update_transferTo(e){
|
||||
this.setState({transferTo: e.target.value});
|
||||
}
|
||||
update_transferTo(e) {
|
||||
this.setState({ transferTo: e.target.value });
|
||||
}
|
||||
|
||||
update_transferAmount(e){
|
||||
this.setState({transferAmount: e.target.value});
|
||||
}
|
||||
update_transferAmount(e) {
|
||||
this.setState({ transferAmount: e.target.value });
|
||||
}
|
||||
|
||||
transfer(e){
|
||||
var to = this.state.transferTo;
|
||||
var amount = this.state.transferAmount;
|
||||
var tx = ERC20Token.methods.transfer(to, amount).send({from: web3.eth.defaultAccount});
|
||||
this._addToLog(ERC20Token.options.address+".transfer(" + to + ", "+amount+")");
|
||||
}
|
||||
transfer(e){
|
||||
var to = this.state.transferTo;
|
||||
var amount = this.state.transferAmount;
|
||||
var tx = ERC20Token.methods.transfer(to, amount).send({from: web3.eth.defaultAccount});
|
||||
this._addToLog(ERC20Token.options.address+".transfer(" + to + ", "+amount+")");
|
||||
}
|
||||
|
||||
approve(e){
|
||||
var to = this.state.transferTo;
|
||||
var amount = this.state.transferAmount;
|
||||
var tx = ERC20Token.methods.approve(to, amount).send({from: web3.eth.defaultAccount});
|
||||
this._addToLog(ERC20Token.options.address+".approve(" + to + ", "+amount+")");
|
||||
}
|
||||
approve(e){
|
||||
var to = this.state.transferTo;
|
||||
var amount = this.state.transferAmount;
|
||||
var tx = ERC20Token.methods.approve(to, amount).send({from: web3.eth.defaultAccount});
|
||||
this._addToLog(ERC20Token.options.address+".approve(" + to + ", "+amount+")");
|
||||
}
|
||||
|
||||
balanceOf(e){
|
||||
e.preventDefault();
|
||||
var who = e.target.value;
|
||||
if (EmbarkJS.isNewWeb3()) {
|
||||
ERC20Token.methods.balanceOf(who).call()
|
||||
.then(_value => this.setState({balanceOf: _value}))
|
||||
} else {
|
||||
ERC20Token.balanceOf(who)
|
||||
.then(_value => this.x({balanceOf: _value}));
|
||||
}
|
||||
this._addToLog(ERC20Token.options.address+".balanceOf(" + who + ")");
|
||||
}
|
||||
|
||||
getDefaultAccountBalance(){
|
||||
if (EmbarkJS.isNewWeb3()) {
|
||||
ERC20Token.methods.balanceOf(web3.eth.defaultAccount).call()
|
||||
.then(_value => this.setState({accountBalance: _value}))
|
||||
} else {
|
||||
ERC20Token.balanceOf(web3.eth.defaultAccount)
|
||||
.then(_value => this.x({valueGet: _value}))
|
||||
}
|
||||
this._addToLog(ERC20Token.options.address + ".balanceOf(" + web3.eth.defaultAccount + ")");
|
||||
balanceOf(e){
|
||||
e.preventDefault();
|
||||
var who = e.target.value;
|
||||
if (EmbarkJS.isNewWeb3()) {
|
||||
ERC20Token.methods.balanceOf(who).call()
|
||||
.then(_value => this.setState({balanceOf: _value}))
|
||||
} else {
|
||||
ERC20Token.balanceOf(who)
|
||||
.then(_value => this.x({balanceOf: _value}));
|
||||
}
|
||||
this._addToLog(ERC20Token.options.address+".balanceOf(" + who + ")");
|
||||
}
|
||||
|
||||
_addToLog(txt){
|
||||
console.log(txt);
|
||||
getDefaultAccountBalance(){
|
||||
if (EmbarkJS.isNewWeb3()) {
|
||||
ERC20Token.methods.balanceOf(web3.eth.defaultAccount).call()
|
||||
.then(_value => this.setState({accountBalance: _value}))
|
||||
} else {
|
||||
ERC20Token.balanceOf(web3.eth.defaultAccount)
|
||||
.then(_value => this.x({valueGet: _value}))
|
||||
}
|
||||
|
||||
this._addToLog(ERC20Token.options.address + ".balanceOf(" + web3.eth.defaultAccount + ")");
|
||||
}
|
||||
|
||||
_addToLog(txt){
|
||||
console.log(txt);
|
||||
}
|
||||
|
||||
render() {
|
||||
const { account, isLoading } = this.props;
|
||||
return (
|
||||
<React.Fragment>
|
||||
<h3> Read your account token balance </h3>
|
||||
<h3>{lang.t('account.read_your_token_balance')}</h3>
|
||||
<Form inline>
|
||||
<FormGroup>
|
||||
{!isLoading && <HelpBlock>Your test token balance is <span className="accountBalance">{account.SNTBalance}</span></HelpBlock>}
|
||||
{!isLoading && <HelpBlock>{lang.t('account.your_test_token_balance')} <span className="accountBalance">{account.SNTBalance}</span></HelpBlock>}
|
||||
</FormGroup>
|
||||
</Form>
|
||||
|
||||
<h3> Read account token balance</h3>
|
||||
|
||||
<h3>{lang.t('account.read_token_balance')}</h3>
|
||||
<Form inline>
|
||||
<FormGroup>
|
||||
<label>
|
||||
Of:
|
||||
{lang.t('account.of')}{':'}
|
||||
<FormControl
|
||||
type="text"
|
||||
defaultValue={this.state.accountB}
|
||||
onChange={(e) => this.balanceOf(e)} />
|
||||
onChange={e => this.balanceOf(e)}
|
||||
/>
|
||||
</label>
|
||||
<label>
|
||||
<HelpBlock><span className="balanceOf">{this.state.balanceOf}</span></HelpBlock>
|
||||
</label>
|
||||
|
||||
</FormGroup>
|
||||
</Form>
|
||||
|
||||
<h3> Transfer/Approve token balance</h3>
|
||||
<h3>{lang.t('account.transfer_approve_token_balance')}</h3>
|
||||
<Form inline>
|
||||
<FormGroup>
|
||||
<label>
|
||||
To:
|
||||
{lang.t('account.to')}{':'}
|
||||
<FormControl
|
||||
type="text"
|
||||
defaultValue={this.state.transferTo}
|
||||
onChange={(e) => this.update_transferTo(e) } />
|
||||
onChange={e => this.update_transferTo(e)}
|
||||
/>
|
||||
</label>
|
||||
<label>
|
||||
Amount:
|
||||
{lang.t('account.amount')}{':'}
|
||||
<FormControl
|
||||
type="text"
|
||||
defaultValue={this.state.transferAmount}
|
||||
onChange={(e) => this.update_transferAmount(e) } />
|
||||
onChange={e => this.update_transferAmount(e)}
|
||||
/>
|
||||
</label>
|
||||
<Button bsStyle="primary" onClick={(e) => this.transfer(e)}>Transfer</Button>
|
||||
<Button bsStyle="primary" onClick={(e) => this.approve(e)}>Approve</Button>
|
||||
<Button bsStyle="primary" onClick={e => this.transfer(e)}>{lang.t('action.transfer')}</Button>
|
||||
<Button bsStyle="primary" onClick={e => this.approve(e)}>{lang.t('action.approve')}</Button>
|
||||
</FormGroup>
|
||||
</Form>
|
||||
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const mapStateToProps = state => ({
|
||||
account: getCurrentAccount(state),
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import lang from 'i18n-js';
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { withStyles } from '@material-ui/core/styles';
|
||||
|
@ -32,7 +33,7 @@ function ButtonAppBar(props) {
|
|||
<AppBar position="static">
|
||||
<Toolbar>
|
||||
<Typography variant="title" color="inherit" className={classes.flex}>
|
||||
This site is optimized for Status. Get the App to enable all features and get the best experience.
|
||||
{lang.t('optimized')}
|
||||
</Typography>
|
||||
<IconButton color="inherit" aria-label="iPhone" href="https://status.im/success.html" target="_blank">
|
||||
<IPhone />
|
||||
|
|
|
@ -1,9 +1,13 @@
|
|||
import lang from 'i18n-js';
|
||||
import React, { Fragment } from 'react';
|
||||
import Warning from '../../ui/components/Warning';
|
||||
|
||||
const Web3Render = ({ ready, children, network }) => (
|
||||
<Fragment>
|
||||
{ready ? <Fragment>{children}</Fragment> : <Warning>Please connect to Ethereum {network}<br />to continue.</Warning>}
|
||||
{ready
|
||||
? <Fragment>{children}</Fragment>
|
||||
: <Warning>{lang.t('error.connect', { network })}</Warning>
|
||||
}
|
||||
</Fragment>
|
||||
);
|
||||
|
||||
|
|
|
@ -1,60 +1,62 @@
|
|||
import lang from 'i18n-js';
|
||||
import EmbarkJS from 'Embark/EmbarkJS';
|
||||
import TestToken from 'Embark/contracts/TestToken';
|
||||
import React from 'react';
|
||||
import { Form, FormGroup, FormControl, HelpBlock, Button } from 'react-bootstrap';
|
||||
import ERC20TokenUI from './erc20token';
|
||||
import { Form, FormGroup, FormControl, Button } from 'react-bootstrap';
|
||||
import { connect } from 'react-redux';
|
||||
import web3 from 'web3';
|
||||
|
||||
import ERC20TokenUI from './erc20token';
|
||||
import { actions as accountActions } from '../reducers/accounts';
|
||||
|
||||
class TestTokenUI extends React.Component {
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
amountToMint: 100,
|
||||
}
|
||||
}
|
||||
|
||||
handleMintAmountChange(e){
|
||||
this.setState({amountToMint: e.target.value});
|
||||
}
|
||||
|
||||
mint(e){
|
||||
const { addToBalance } = this.props;
|
||||
e.preventDefault();
|
||||
|
||||
var value = parseInt(this.state.amountToMint, 10);
|
||||
|
||||
if (EmbarkJS.isNewWeb3()) {
|
||||
TestToken.methods.mint(value).send({from: web3.eth.defaultAccount})
|
||||
.then(r => { addToBalance(value) });
|
||||
} else {
|
||||
TestToken.mint(value).send({from: web3.eth.defaultAccount})
|
||||
.then(r => { addToBalance(value) });
|
||||
}
|
||||
console.log(TestToken.options.address +".mint("+value+").send({from: " + web3.eth.defaultAccount + "})");
|
||||
}
|
||||
|
||||
render(){
|
||||
return (<React.Fragment>
|
||||
<h3> Mint Test Token</h3>
|
||||
<Form inline>
|
||||
<FormGroup>
|
||||
<FormControl
|
||||
type="text"
|
||||
defaultValue={this.state.amountToMint}
|
||||
onChange={(e) => this.handleMintAmountChange(e)} />
|
||||
<Button bsStyle="primary" onClick={(e) => this.mint(e)}>Mint</Button>
|
||||
</FormGroup>
|
||||
</Form>
|
||||
|
||||
<ERC20TokenUI address={ TestToken.options.address } />
|
||||
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
amountToMint: 100,
|
||||
};
|
||||
}
|
||||
|
||||
handleMintAmountChange(e) {
|
||||
this.setState({ amountToMint: e.target.value });
|
||||
}
|
||||
|
||||
mint(e) {
|
||||
const { addToBalance } = this.props;
|
||||
e.preventDefault();
|
||||
|
||||
const value = parseInt(this.state.amountToMint, 10);
|
||||
|
||||
if (EmbarkJS.isNewWeb3()) {
|
||||
TestToken.methods.mint(value).send({ from: web3.eth.defaultAccount })
|
||||
.then(() => { addToBalance(value); });
|
||||
} else {
|
||||
TestToken.mint(value).send({ from: web3.eth.defaultAccount })
|
||||
.then(() => { addToBalance(value); });
|
||||
}
|
||||
console.log(TestToken.options.address +".mint("+value+").send({from: " + web3.eth.defaultAccount + "})");
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<React.Fragment>
|
||||
<h3>{lang.t('action.mint_test_token')}</h3>
|
||||
<Form inline>
|
||||
<FormGroup>
|
||||
<FormControl
|
||||
type="text"
|
||||
defaultValue={this.state.amountToMint}
|
||||
onChange={e => this.handleMintAmountChange(e)}
|
||||
/>
|
||||
<Button bsStyle="primary" onClick={e => this.mint(e)}>{lang.t('action.mint')}</Button>
|
||||
</FormGroup>
|
||||
</Form>
|
||||
<ERC20TokenUI address={TestToken.options.address} />
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const mapDispatchToProps = dispatch => ({
|
||||
addToBalance(amount) {
|
||||
dispatch(accountActions.addToSntTokenBalance(amount));
|
||||
|
|
|
@ -1,33 +1,29 @@
|
|||
import EmbarkJS from 'Embark/EmbarkJS';
|
||||
import lang from 'i18n-js';
|
||||
import React from 'react';
|
||||
import { Navbar, NavItem, Nav, MenuItem , NavDropdown} from 'react-bootstrap';
|
||||
import AccountList from './accountList';
|
||||
import { Navbar } from 'react-bootstrap';
|
||||
import AccountList from './accountList';
|
||||
|
||||
class TopNavbar extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
};
|
||||
}
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
render(){
|
||||
|
||||
return (
|
||||
render() {
|
||||
return (
|
||||
<React.Fragment>
|
||||
<Navbar>
|
||||
<Navbar>
|
||||
<Navbar.Header>
|
||||
<Navbar.Brand>
|
||||
<a href="#home">Status.im Demo</a>
|
||||
<a href="#home">{lang.t('navbar.brand')}</a>
|
||||
</Navbar.Brand>
|
||||
</Navbar.Header>
|
||||
<AccountList classNameNavDropdown="pull-right" />
|
||||
</Navbar>
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default TopNavbar;
|
||||
export default TopNavbar;
|
||||
|
|
11
app/index.js
11
app/index.js
|
@ -1,11 +1,20 @@
|
|||
import lang from 'i18n-js';
|
||||
import React from 'react';
|
||||
import { render } from 'react-dom';
|
||||
import { Provider } from 'react-redux';
|
||||
import store from './store/configureStore';
|
||||
import App from './dapp';
|
||||
import init from './store/init'
|
||||
import init from './store/init';
|
||||
import translations from './languages';
|
||||
import './dapp.css';
|
||||
|
||||
// Init i18n translation
|
||||
lang.defaultLocale = 'en';
|
||||
lang.locale = navigator.language;
|
||||
lang.fallbacks = true;
|
||||
lang.translations = translations;
|
||||
|
||||
// Init Redux store
|
||||
init();
|
||||
|
||||
render(
|
||||
|
|
|
@ -0,0 +1,163 @@
|
|||
{
|
||||
"account": {
|
||||
"amount": "Amount",
|
||||
"from": "From",
|
||||
"of": "Of",
|
||||
"read_token_balance": "Read account token balance",
|
||||
"read_your_token_balance": "Read your account token balance",
|
||||
"to": "To",
|
||||
"transfer_approve_token_balance": "Transfer/Approve token balance",
|
||||
"your_test_token_balance": "Your test token balance is"
|
||||
},
|
||||
"action" : {
|
||||
"approve": "Approve",
|
||||
"cancel": "Cancel",
|
||||
"edit_contact_code": "Edit Contact Code",
|
||||
"grant_access": "Grant access",
|
||||
"mint_test_token": "Mint Test Token",
|
||||
"mint": "Mint",
|
||||
"register": "Register",
|
||||
"release_name": "Release Name",
|
||||
"send_snt": "Send SNT",
|
||||
"setup_ens": "ADD INITIAL NODES TO ENS",
|
||||
"submit": "Submit",
|
||||
"submitting_to_blockchain": "Submitting to the Blockchain - (this may take awhile)",
|
||||
"transfer": "Transfer",
|
||||
"update": "Update",
|
||||
"use_my_primary_address": "Use My Primary Address",
|
||||
"yes": "Yes"
|
||||
},
|
||||
"admin": {
|
||||
"tab": {
|
||||
"ens_management": "ENS Management",
|
||||
"erc20_token": "ERC20Token",
|
||||
"name_lookup": "Name Lookup",
|
||||
"test_token": "TestToken"
|
||||
}
|
||||
},
|
||||
"constants" : {
|
||||
"contact_code": "Your contact code",
|
||||
"wallet_address": "Your wallet address"
|
||||
},
|
||||
"copy": {
|
||||
"release": {
|
||||
"title": {
|
||||
"sub": "Done!",
|
||||
"body": "The released username will be available to other users"
|
||||
}
|
||||
},
|
||||
"registered": {
|
||||
"title": {
|
||||
"sub": "Nice!",
|
||||
"body": "The name is yours once the transaction is complete"
|
||||
}
|
||||
},
|
||||
"edit": {
|
||||
"title": {
|
||||
"sub": "Done!",
|
||||
"body": "Your changes will be saved when the transaction is complete"
|
||||
}
|
||||
},
|
||||
"subheading": "Follow the progress in the Transaction History section of your wallet."
|
||||
},
|
||||
"domain": {
|
||||
"ethereum_address": {
|
||||
"error": "Not a valid address",
|
||||
"label": "Ethereum address domain resolves to"
|
||||
},
|
||||
"name": {
|
||||
"label": "Domain Name"
|
||||
},
|
||||
"new_address": {
|
||||
"label": "New Controller Address"
|
||||
},
|
||||
"price": {
|
||||
"label": "Domain Price"
|
||||
},
|
||||
"release": {
|
||||
"alert": {
|
||||
"text": "Your SNT deposit will be returned and name will be available to other users.",
|
||||
"title": "Release domain?"
|
||||
}
|
||||
},
|
||||
"status_address": {
|
||||
"label": "Status messenger address domain resolves to",
|
||||
"placeholder": "Enter Your Status Messenger Address Here"
|
||||
}
|
||||
},
|
||||
"error": {
|
||||
"connect": "Please connect to Ethereum %{network} to continue.",
|
||||
"valid_address": "Please enter a valid address"
|
||||
},
|
||||
"navbar":{
|
||||
"brand": "Status.im Demo"
|
||||
},
|
||||
"optimized": "This site is optimized for Status. Get the App to enable all features and get the best experience.",
|
||||
"registry": {
|
||||
"error": {
|
||||
"name": {
|
||||
"owned": "This registry is not owned by registry",
|
||||
"required": "Required"
|
||||
}
|
||||
},
|
||||
"name": {
|
||||
"label": "Registry Name"
|
||||
},
|
||||
"price": {
|
||||
"label": "Registry Price",
|
||||
"placeholder": "(Optional) Registry will be free if left blank"
|
||||
}
|
||||
},
|
||||
"sub_domain": {
|
||||
"error": {
|
||||
"required": "Required"
|
||||
},
|
||||
"label": "Sub Domain",
|
||||
"management": {
|
||||
"activate_registry": "Activate Registry/Update Registry Price",
|
||||
"change_registry": "Change Registry Controller",
|
||||
"move_domain": "Move Domain To Another Registry",
|
||||
"register_sub_domain": "Register Sub-Domain",
|
||||
"title": "Subdomain Management"
|
||||
}
|
||||
},
|
||||
"terms": {
|
||||
"title": "Terms of name registration",
|
||||
"funds_deposit": "Funds are deposited for 1 year. Your SNT will be locked, but not spent.",
|
||||
"funds_release": "After 1 year, you can release the name and get your deposit back. The name is yours until you release it.",
|
||||
"names_creation": "Names are created as a subdomain of %{stateofus}. They are property of Status and may be subject to new terms.",
|
||||
"contract": "If the %{stateofus} contract terms change—e.g. Status makes contract upgrades—you have the right to get your deposit back, even for names held less than 1 year.",
|
||||
"reserved_list": "reserved list",
|
||||
"rule": {
|
||||
"title": "Names may not:",
|
||||
"one": "contain less than 4 characters;",
|
||||
"two": "n non-alphanumeric characters;",
|
||||
"three": "contain uppercase letters;",
|
||||
"four": "appear on this %{reserved_list_link}",
|
||||
"five": "mimic an Ethereum address (start with %{eth_address} and contain only hexadecimal characters in the first 12 digits)"
|
||||
},
|
||||
"illegal_name": "Registering an illegal name via the registry contract will result in the loss of your SNT deposit and removal of the name.",
|
||||
"contact": "Contact codes and wallet addresses associated with your name are publicly available information."
|
||||
},
|
||||
"welcome": {
|
||||
"cta": "Let's Go",
|
||||
"disclaimer": "Powered by Ethereum Name Services",
|
||||
"eth_address_example": "myname.stateofus.eth",
|
||||
"how": "How it works",
|
||||
"step": {
|
||||
"one": {
|
||||
"title": "Simplify your ETH address",
|
||||
"subtitle": "Your complex wallet address (0x...) becomes an easy to read, remember & share URL:"
|
||||
},
|
||||
"two": {
|
||||
"title": "10 SNT to register",
|
||||
"subtitle": "Register once to keep the name forever. After 1 year, you can release the name and get your SNT back."
|
||||
},
|
||||
"three": {
|
||||
"title": "Connect & get paid",
|
||||
"subtitle": "Share your name to chat on Status or receive ETH and tokens."
|
||||
}
|
||||
},
|
||||
"title": "ENS names transform those crazy-long addresses into unique usernames"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,163 @@
|
|||
{
|
||||
"account": {
|
||||
"amount": "Montant",
|
||||
"from": "De",
|
||||
"of": "De",
|
||||
"read_token_balance": "Lire le solde de tokens du compte",
|
||||
"read_your_token_balance": "Lisez le solde de tokens de votre compte",
|
||||
"to": "Vers",
|
||||
"transfer_approve_token_balance": "Transférer/Approuver le solde de tokens",
|
||||
"your_test_token_balance": "Votre solde de tokens de test est"
|
||||
},
|
||||
"action" : {
|
||||
"approve": "Approuver",
|
||||
"cancel": "Annuler",
|
||||
"edit_contact_code": "Editez le code de contact",
|
||||
"grant_access": "Donnez l'accès",
|
||||
"mint_test_token": "Mintez Jeton de Test",
|
||||
"mint": "Minter",
|
||||
"register": "Enregistrer",
|
||||
"release_name": "Libérez le nom",
|
||||
"send_snt": "Envoyer SNT",
|
||||
"setup_ens": "AJOUTEZ LES NODES INITIAUX À ENS",
|
||||
"submit": "Envoyer",
|
||||
"submitting_to_blockchain": "En cours d'envoie à la Blockchain - (ceci peut prendre quelque temps)",
|
||||
"transfer": "Transférer",
|
||||
"update": "Mettre à jour",
|
||||
"use_my_primary_address": "Utiliser mon adresse principale",
|
||||
"yes": "Oui"
|
||||
},
|
||||
"admin": {
|
||||
"tab": {
|
||||
"ens_management": "Gestion ENS",
|
||||
"erc20_token": "Token ERC20",
|
||||
"name_lookup": "Recherche de nom",
|
||||
"test_token": "Token de test"
|
||||
}
|
||||
},
|
||||
"constants" : {
|
||||
"contact_code": "Votre code de contact",
|
||||
"wallet_address": "Votre adresse de portefeuille"
|
||||
},
|
||||
"copy": {
|
||||
"release": {
|
||||
"title": {
|
||||
"sub": "Fait!",
|
||||
"body": "Le nom d'utilisateur publié sera disponible pour les autres utilisateurs"
|
||||
}
|
||||
},
|
||||
"registered": {
|
||||
"title": {
|
||||
"sub": "Sympa!",
|
||||
"body": "Le nom est le votre une fois que la transaction est complétée"
|
||||
}
|
||||
},
|
||||
"edit": {
|
||||
"title": {
|
||||
"sub": "Fait!",
|
||||
"body": "Your changes will be saved when the transaction is complete"
|
||||
}
|
||||
},
|
||||
"subheading": "Suivez le progrès dans la rubrique Historique de Transactions de votre portefeuille."
|
||||
},
|
||||
"domain": {
|
||||
"ethereum_address": {
|
||||
"error": "Adresse invalide",
|
||||
"label": "Adresse Ethereum du domaine résout vers"
|
||||
},
|
||||
"name": {
|
||||
"label": "Nom du domaine"
|
||||
},
|
||||
"new_address": {
|
||||
"label": "Nouvelle adresse du contrôleur"
|
||||
},
|
||||
"price": {
|
||||
"label": "Prix du domaine"
|
||||
},
|
||||
"release": {
|
||||
"alert": {
|
||||
"text": "Votre dépot de SNT vous sera retourné et le nom sera disponible pour d'autres utilisateurs.",
|
||||
"title": "Libérez le domaine ?"
|
||||
}
|
||||
},
|
||||
"status_address": {
|
||||
"label": "Adresse Status messenger du domaine résout vers",
|
||||
"placeholder": "Entrez votre adresse Status Messenger ici"
|
||||
}
|
||||
},
|
||||
"error": {
|
||||
"connect": "Veuillez vous connecter au réseau Ethereum %{network} pour continuer.",
|
||||
"valid_address": "Veuillez entrer une adresse valide"
|
||||
},
|
||||
"navbar":{
|
||||
"brand": "Démo Status.im"
|
||||
},
|
||||
"optimized": "Ce site est optimisé pour Status. Téléchargez l'application pour activer toutes les fonctionnalitées et profiter d'une meilleure expérience.",
|
||||
"registry": {
|
||||
"error": {
|
||||
"name": {
|
||||
"owned": "Cet enregistrement n'est pas possédé par un enregistrement",
|
||||
"required": "Requis"
|
||||
}
|
||||
},
|
||||
"name": {
|
||||
"label": "Nom de l'enregistrement"
|
||||
},
|
||||
"price": {
|
||||
"label": "Prix de l'enregistrement",
|
||||
"placeholder": "(Optionnel) Si laissé vide, l'enregistrement sera gratuit"
|
||||
}
|
||||
},
|
||||
"sub_domain": {
|
||||
"error": {
|
||||
"required": "Requis"
|
||||
},
|
||||
"label": "Sous-Domaine",
|
||||
"management": {
|
||||
"activate_registry": "Activer le registre/Mettre à jour le prix du registre",
|
||||
"change_registry": "Changer le contrôleur du registre",
|
||||
"move_domain": "Déplacer le domaine vers un autre registre",
|
||||
"register_sub_domain": "Enregistrer le sous domaine",
|
||||
"title": "Gestion du sous-domaine"
|
||||
}
|
||||
},
|
||||
"terms": {
|
||||
"title": "Conditions d'enregistrement du nom",
|
||||
"funds_deposit": "Les fonds sont déposés pour une durée d'un an. Vos SNT sont bloqués mais non dépensés.",
|
||||
"funds_release": "Après une année, vous pouvez libérer votre nom et ainsi récupérer votre dépôt. Le nom vous appartient tant que vous ne l'avez pas libéré.",
|
||||
"names_creation": "Les noms sont créés en tant que sous-domaines de %{stateofus}. Ils sont la propriété de Status et peuvent êtres soumis à de nouvelles conditions.",
|
||||
"contract": "Si les conditions du contrat %{stateofus} changent—e.g. Status met à jour le contrat—vous avez le droit de récupérer votre dépôt you, ainsi que vos noms de domaines que vous avez gardé moins d'un an.",
|
||||
"reserved_list": "liste réservée",
|
||||
"rule": {
|
||||
"title": "Les noms ne peuvent pas:",
|
||||
"one": "contenir moins de 4 caractères;",
|
||||
"two": "n caractères non-alphanumérique;",
|
||||
"three": "contenir des lettres majuscules;",
|
||||
"four": "apparaitre sur cette %{reserved_list_link}",
|
||||
"five": "copier une adresse Ethereum (commençant par %{eth_address} et contenant seulement des caractères hexadécimaux parmis les 12 premiers caractères)"
|
||||
},
|
||||
"illegal_name": "Enregistrer un nom illégal via le contrat du registre entraine la perte de votre dépôt de SNT et la supression du nom.",
|
||||
"contact": "Les codes de contact ainsi que l'adresse du portefeuille associé à votre nom sont des informations publiquement disponibles."
|
||||
},
|
||||
"welcome": {
|
||||
"cta": "Allons-y",
|
||||
"disclaimer": "Propulsé par Ethereum Name Services",
|
||||
"eth_address_example": "myname.stateofus.eth",
|
||||
"how": "Comment ça marche",
|
||||
"step": {
|
||||
"one": {
|
||||
"title": "Simplifiez votre adresse ETH",
|
||||
"subtitle": "Votre complexe adresse de portefeuille (0x...) devient facile à lire, à mémoriser et à partager l'URL:"
|
||||
},
|
||||
"two": {
|
||||
"title": "10 SNT pour l'enregister",
|
||||
"subtitle": "Enregistrez le nom pour toujours. Après une année, vous pouvez libérer le nom et recevoir vos SNT en retour."
|
||||
},
|
||||
"three": {
|
||||
"title": "Connectez-vous et recevez des paiements",
|
||||
"subtitle": "Partagez votre nom sur le chat de Status ou recevez des ETH ainsi que des tokens."
|
||||
}
|
||||
},
|
||||
"title": "Les noms ENS transforment vos très longues adresses en d'unique noms d'utilisateur"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
import en from './en.json';
|
||||
import fr from './fr.json';
|
||||
|
||||
const translations = {
|
||||
en,
|
||||
fr,
|
||||
};
|
||||
|
||||
export default translations;
|
|
@ -1,11 +1,13 @@
|
|||
import { createStore, applyMiddleware } from 'redux';
|
||||
import { applyMiddleware, compose, createStore } from 'redux';
|
||||
import rootReducer from '../reducers/rootReducer';
|
||||
import thunk from 'redux-thunk';
|
||||
|
||||
const store = createStore(
|
||||
rootReducer,
|
||||
window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__(),
|
||||
applyMiddleware(thunk)
|
||||
compose(
|
||||
applyMiddleware(thunk),
|
||||
window.devToolsExtension ? window.devToolsExtension() : f => f,
|
||||
),
|
||||
);
|
||||
|
||||
export default store;
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
"elliptic": "^6.4.1",
|
||||
"eth-ens-namehash": "^2.0.8",
|
||||
"formik": "^0.11.11",
|
||||
"i18n-js": "^3.1.0",
|
||||
"idna-normalize": "^1.0.0",
|
||||
"install": "^0.11.0",
|
||||
"npm": "^6.1.0",
|
||||
|
|
Loading…
Reference in New Issue