mirror of
https://github.com/status-im/MyCrypto.git
synced 2025-02-22 07:48:30 +00:00
ENS - Tab + General Infomation Panel (#147)
This commit is contained in:
parent
c2c9f39c6b
commit
d05525e682
3
.gitignore
vendored
3
.gitignore
vendored
@ -41,3 +41,6 @@ jspm_packages
|
||||
|
||||
# Optional REPL history
|
||||
.node_repl_history
|
||||
|
||||
# VScode workspace settings
|
||||
.vscode/
|
||||
|
@ -28,6 +28,10 @@ const tabs = [
|
||||
name: 'NAV_ViewWallet'
|
||||
// to: 'view-wallet'
|
||||
},
|
||||
{
|
||||
name: 'NAV_ENS',
|
||||
to: 'ens'
|
||||
},
|
||||
{
|
||||
name: 'NAV_Help',
|
||||
to: 'https://myetherwallet.groovehq.com/help_center',
|
||||
|
48
common/components/ui/NewTabLink.jsx
Normal file
48
common/components/ui/NewTabLink.jsx
Normal file
@ -0,0 +1,48 @@
|
||||
// @flow
|
||||
import * as React from 'react';
|
||||
|
||||
type AAttributes = {
|
||||
charset?: string,
|
||||
coords?: string,
|
||||
download?: string,
|
||||
href: string,
|
||||
hreflang?: string,
|
||||
media?: string,
|
||||
name?: string,
|
||||
rel?:
|
||||
| 'alternate'
|
||||
| 'author'
|
||||
| 'bookmark'
|
||||
| 'external'
|
||||
| 'help'
|
||||
| 'license'
|
||||
| 'next'
|
||||
| 'nofollow'
|
||||
| 'noreferrer'
|
||||
| 'noopener'
|
||||
| 'prev'
|
||||
| 'search'
|
||||
| 'tag',
|
||||
rev?: string,
|
||||
shape?: 'default' | 'rect' | 'circle' | 'poly',
|
||||
target?: '_blank' | '_parent' | '_self' | '_top',
|
||||
type?: string
|
||||
};
|
||||
|
||||
type NewTabLinkProps = {
|
||||
content?: React.Element<any> | string,
|
||||
children?: React.Element<any> | string,
|
||||
rest?: AAttributes
|
||||
};
|
||||
|
||||
const NewTabLink = ({
|
||||
/* eslint-disable */
|
||||
content, // ESLINT: prop-types validation error, to be fixed in #122
|
||||
children /* eslint-enable */,
|
||||
...rest
|
||||
}: NewTabLinkProps) =>
|
||||
<a target="_blank" rel="noopener" {...rest}>
|
||||
{content || children} {/* Keep content for short-hand text insertion */}
|
||||
</a>;
|
||||
|
||||
export default NewTabLink;
|
@ -5,3 +5,4 @@ export { default as Identicon } from './Identicon';
|
||||
export { default as Modal } from './Modal';
|
||||
export { default as UnlockHeader } from './UnlockHeader';
|
||||
export { default as QRCode } from './QRCode';
|
||||
export { default as NewTabLink } from './NewTabLink.jsx';
|
||||
|
28
common/containers/Tabs/ENS/components/ENS.jsx
Normal file
28
common/containers/Tabs/ENS/components/ENS.jsx
Normal file
@ -0,0 +1,28 @@
|
||||
// @flow
|
||||
import * as React from 'react';
|
||||
import Title from './Title';
|
||||
import GeneralInfoPanel from './GeneralInfoPanel';
|
||||
import UnfinishedBanner from './UnfinishedBanner';
|
||||
type ContainerTabPaneActiveProps = {
|
||||
children: React.Element<any>
|
||||
};
|
||||
|
||||
const ContainerTabPaneActive = ({ children }: ContainerTabPaneActiveProps) =>
|
||||
<section className="container">
|
||||
<div className="tab-content">
|
||||
<main className="tab-pane active">
|
||||
<section role="main" className="row">
|
||||
{children}
|
||||
</section>
|
||||
</main>
|
||||
</div>
|
||||
</section>;
|
||||
|
||||
const ENS = () =>
|
||||
<ContainerTabPaneActive>
|
||||
<UnfinishedBanner />
|
||||
<Title />
|
||||
<GeneralInfoPanel />
|
||||
</ContainerTabPaneActive>;
|
||||
|
||||
export default ENS;
|
@ -0,0 +1,52 @@
|
||||
// @flow
|
||||
import * as React from 'react';
|
||||
import type { HeaderProps, ListProps, NodeProps, NodeState } from './types';
|
||||
|
||||
const InfoHeader = ({ children, onClickHandler }: HeaderProps) =>
|
||||
<h6 onClick={onClickHandler}>
|
||||
<span>+</span> {children}
|
||||
</h6>;
|
||||
|
||||
const InfoList = ({ children, isOpen }: ListProps) =>
|
||||
isOpen
|
||||
? <ul>
|
||||
{children}
|
||||
</ul>
|
||||
: null;
|
||||
|
||||
/*
|
||||
TODO: After #122: export default class GeneralInfoNode extends React.Component <
|
||||
NodeProps,
|
||||
NodeState
|
||||
>
|
||||
*/
|
||||
export default class GeneralInfoNode extends React.Component {
|
||||
props: NodeProps;
|
||||
state: NodeState;
|
||||
|
||||
state = {
|
||||
isOpen: false
|
||||
};
|
||||
|
||||
toggleVisibility = () =>
|
||||
this.setState(prevState => ({ isOpen: !prevState.isOpen }));
|
||||
|
||||
render() {
|
||||
const {
|
||||
toggleVisibility,
|
||||
props: { innerList, name, headerContent },
|
||||
state: { isOpen }
|
||||
} = this;
|
||||
|
||||
return (
|
||||
<section>
|
||||
<InfoHeader onClickHandler={toggleVisibility} name={name}>
|
||||
{headerContent}
|
||||
</InfoHeader>
|
||||
<InfoList name={name} isOpen={isOpen}>
|
||||
{innerList}
|
||||
</InfoList>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
}
|
131
common/containers/Tabs/ENS/components/GeneralInfoPanel/index.jsx
Normal file
131
common/containers/Tabs/ENS/components/GeneralInfoPanel/index.jsx
Normal file
@ -0,0 +1,131 @@
|
||||
// @flow
|
||||
import * as React from 'react';
|
||||
import GeneralInfoNode from './GeneralInfoNode';
|
||||
import { NewTabLink } from 'components/ui';
|
||||
import type { InfoNode } from './types';
|
||||
|
||||
const generalInfoNodes: InfoNode[] = [
|
||||
{
|
||||
name: 'ensPrep',
|
||||
headerContent: '1. Preparation',
|
||||
innerList: [
|
||||
<li key="ensPrep-1">
|
||||
Decide which account you wish to own the name & ensure you have multiple
|
||||
backups of that account.
|
||||
</li>,
|
||||
<li key="ensPrep-2">
|
||||
Decide the maximum amount of ETH you are willing to pay for the name
|
||||
(your <u>Bid Amount</u>). Ensure that account has enough to cover your
|
||||
bid + 0.01 ETH for gas.
|
||||
</li>
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'ensAuct',
|
||||
headerContent: '2. Start an Auction / Place a Bid',
|
||||
innerList: [
|
||||
<li key="ensAuct-1">Bidding period lasts 3 days (72 hours).</li>,
|
||||
<li key="ensAuct-2">
|
||||
You will enter the <u>name</u>, <u>Actual Bid Amount</u>,{' '}
|
||||
<u>Bid Mask</u>, which is protected by a <u>Secret Phrase</u>
|
||||
</li>,
|
||||
<li key="ensAuct-3">
|
||||
This places your bid, but this information is kept secret until you
|
||||
reveal it.
|
||||
</li>
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'ensReveal',
|
||||
headerContent: '3. Reveal your Bid',
|
||||
innerList: [
|
||||
<li key="ensReveal-1">
|
||||
<strong>
|
||||
If you do not reveal your bid, you will not be refunded.
|
||||
</strong>
|
||||
</li>,
|
||||
<li key="ensReveal-2"> Reveal Period lasts 2 days (48 hours). </li>,
|
||||
<li key="ensReveal-3">
|
||||
You will unlock your account, enter the <u>Bid Amount</u>, and the{' '}
|
||||
<u>Secret Phrase</u>.
|
||||
</li>,
|
||||
<li key="ensReveal-4">
|
||||
In the event that two parties bid exactly the same amount, the first bid
|
||||
revealed will win.
|
||||
</li>
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'ensFinalize',
|
||||
headerContent: '4. Finalize the Auction',
|
||||
innerList: [
|
||||
<li key="ensFinalize-1">
|
||||
Once the auction has ended (after 5 days / 120 hours), the winner needs
|
||||
to finalize the auction in order to claim their new name.
|
||||
</li>,
|
||||
<li key="ensFinalize-2">
|
||||
The winner will be refunded the difference between their bid and the
|
||||
next-highest bid. If you are the only bidder, you will refunded all but
|
||||
0.01 ETH.
|
||||
</li>
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'ensMore',
|
||||
headerContent: 'More Information',
|
||||
innerList: [
|
||||
<li key="ensMore-1">
|
||||
The auction for this registrar is a blind auction, and is described in
|
||||
<NewTabLink
|
||||
content=" EIP162"
|
||||
href="https://github.com/ethereum/EIPs/issues/162"
|
||||
/>
|
||||
. Basically, no one can see *anything* during the auction.
|
||||
</li>,
|
||||
<li key="ensMore-2">
|
||||
<NewTabLink
|
||||
content="ENS: Read the Docs"
|
||||
href="http://docs.ens.domains/en/latest/userguide.html#registering-a-name-with-the-auction-registrar"
|
||||
/>
|
||||
</li>,
|
||||
<li key="ensMore-3">
|
||||
<NewTabLink
|
||||
content="Announcing the Ethereum Name Service Relaunch Date!"
|
||||
href="https://medium.com/the-ethereum-name-service/announcing-the-ethereum-name-service-relaunch-date-4390af6dd9a2"
|
||||
/>
|
||||
</li>
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
const GeneralInfoList = () =>
|
||||
<section>
|
||||
{generalInfoNodes.map((data: InfoNode) =>
|
||||
<GeneralInfoNode key={data.name} {...data} />
|
||||
)}
|
||||
</section>;
|
||||
|
||||
const GeneralInfoPanel = () =>
|
||||
<article className="block">
|
||||
<div className="cont-md">
|
||||
<h4> What is the process like? </h4>
|
||||
<GeneralInfoList />
|
||||
<h6>
|
||||
<NewTabLink
|
||||
content="Help Center: ENS"
|
||||
href="https://myetherwallet.groovehq.com/knowledge_base/categories/ens"
|
||||
/>
|
||||
·
|
||||
<NewTabLink
|
||||
content="Debugging a [BAD INSTRUCTION] Reveal"
|
||||
href="https://myetherwallet.groovehq.com/knowledge_base/topics/debugging-a-bad-instruction-reveal"
|
||||
/>
|
||||
</h6>
|
||||
<p>
|
||||
Please try the above before relying on support for reveal issues as we
|
||||
are severely backlogged on support tickets. We're so sorry. :(
|
||||
</p>
|
||||
</div>
|
||||
</article>;
|
||||
|
||||
export default GeneralInfoPanel;
|
@ -0,0 +1,30 @@
|
||||
// @flow
|
||||
import * as React from 'react';
|
||||
|
||||
type InfoNode = {
|
||||
name: string,
|
||||
headerContent: string,
|
||||
innerList: React.Element<any>[]
|
||||
};
|
||||
|
||||
type HeaderProps = {
|
||||
children: string,
|
||||
onClickHandler: () => void
|
||||
};
|
||||
|
||||
type NodeProps = {
|
||||
innerList: React.Element<any>[],
|
||||
headerContent: string,
|
||||
name: string
|
||||
};
|
||||
|
||||
type NodeState = {
|
||||
isOpen: boolean
|
||||
};
|
||||
|
||||
type ListProps = {
|
||||
children: React.Element<any>[],
|
||||
isOpen: boolean
|
||||
};
|
||||
|
||||
export type { InfoNode, HeaderProps, NodeProps, NodeState, ListProps };
|
25
common/containers/Tabs/ENS/components/Title.jsx
Normal file
25
common/containers/Tabs/ENS/components/Title.jsx
Normal file
@ -0,0 +1,25 @@
|
||||
// @flow
|
||||
import * as React from 'react';
|
||||
import { NewTabLink } from 'components/ui';
|
||||
import translate from 'translations';
|
||||
|
||||
const ENSDocsLink = () =>
|
||||
<NewTabLink
|
||||
href="http://ens.readthedocs.io/en/latest/introduction.html"
|
||||
content="Ethereum Name Service"
|
||||
/>;
|
||||
|
||||
const ENSTitle = () =>
|
||||
<article className="cont-md">
|
||||
<h1 className="text-center">
|
||||
{translate('NAV_ENS')}
|
||||
</h1>
|
||||
<p>
|
||||
The <ENSDocsLink /> is a distributed, open, and extensible naming system
|
||||
based on the Ethereum blockchain. Once you have a name, you can tell your
|
||||
friends to send ETH to <code>mewtopia.eth</code> instead of
|
||||
<code>0x7cB57B5A97eAbe942.....</code>.
|
||||
</p>
|
||||
</article>;
|
||||
|
||||
export default ENSTitle;
|
@ -0,0 +1,35 @@
|
||||
import React from 'react';
|
||||
import './index.scss';
|
||||
|
||||
export default class UnfinishedBanner extends React.Component {
|
||||
state = {
|
||||
isFading: false,
|
||||
hasAcknowledged: false
|
||||
};
|
||||
|
||||
_continue = () => {
|
||||
this.setState({ isFading: true });
|
||||
|
||||
setTimeout(() => {
|
||||
this.setState({ hasAcknowledged: true });
|
||||
}, 1000);
|
||||
};
|
||||
render() {
|
||||
if (this.state.hasAcknowledged) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const isFading = this.state.isFading ? 'is-fading' : '';
|
||||
|
||||
return (
|
||||
<div className={`UnfinishedBanner ${isFading}`} onClick={this._continue}>
|
||||
<div className="UnfinishedBanner-content">
|
||||
<h2>Under Contruction</h2>
|
||||
<p>The ENS section is still under contruction</p>
|
||||
<p>Expect unfinished components</p>
|
||||
<h3>Click to continue</h3>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,47 @@
|
||||
@import "common/sass/variables";
|
||||
|
||||
.UnfinishedBanner {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: $brand-warning;
|
||||
overflow: auto;
|
||||
z-index: 10000;
|
||||
|
||||
&-content {
|
||||
text-align: center;
|
||||
margin-top: 20%;
|
||||
@media screen and (min-width: 2150px) {
|
||||
margin-top: 15%;
|
||||
}
|
||||
color: #fff;
|
||||
text-shadow: 1px 1px 1px rgba(#000, 0.12);
|
||||
overflow: auto;
|
||||
|
||||
h2 {
|
||||
font-size: 52px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: 30px;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
}
|
||||
|
||||
// Fade out
|
||||
&.is-fading {
|
||||
pointer-events: none;
|
||||
opacity: 0;
|
||||
background: #fff;
|
||||
transition: all 500ms ease 400ms;
|
||||
|
||||
.UnfinishedBanner-content {
|
||||
opacity: 0;
|
||||
transform: translateY(15px);
|
||||
transition: all 500ms ease;
|
||||
}
|
||||
}
|
||||
}
|
7
common/containers/Tabs/ENS/index.jsx
Normal file
7
common/containers/Tabs/ENS/index.jsx
Normal file
@ -0,0 +1,7 @@
|
||||
// @flow
|
||||
import { connect } from 'react-redux';
|
||||
import ENS from './components/ENS';
|
||||
|
||||
const mapStateToProps = state => ({});
|
||||
|
||||
export default connect(mapStateToProps)(ENS);
|
@ -8,8 +8,9 @@ import Help from 'containers/Tabs/Help';
|
||||
import Swap from 'containers/Tabs/Swap';
|
||||
import SendTransaction from 'containers/Tabs/SendTransaction';
|
||||
import Contracts from 'containers/Tabs/Contracts';
|
||||
export const history = getHistory();
|
||||
import ENS from 'containers/Tabs/ENS';
|
||||
|
||||
export const history = getHistory();
|
||||
export const Routing = () =>
|
||||
<Route name="App" path="" component={App}>
|
||||
<Route name="GenerateWallet" path="/" component={GenerateWallet} />
|
||||
@ -18,7 +19,7 @@ export const Routing = () =>
|
||||
<Route name="Swap" path="/swap" component={Swap} />
|
||||
<Route name="Send" path="/send-transaction" component={SendTransaction} />
|
||||
<Route name="Contracts" path="/contracts" component={Contracts} />
|
||||
|
||||
<Route name="ENS" path="/ens" component={ENS} />
|
||||
<Redirect from="/*" to="/" />
|
||||
</Route>;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user