ENS - Tab + General Infomation Panel (#147)

This commit is contained in:
HenryNguyen5 2017-09-03 20:04:27 -04:00 committed by Daniel Ternyak
parent c2c9f39c6b
commit d05525e682
13 changed files with 414 additions and 2 deletions

3
.gitignore vendored
View File

@ -41,3 +41,6 @@ jspm_packages
# Optional REPL history
.node_repl_history
# VScode workspace settings
.vscode/

View File

@ -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',

View 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;

View File

@ -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';

View 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;

View File

@ -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>
);
}
}

View 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"
/>
&nbsp;&middot;&nbsp;
<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;

View File

@ -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 };

View 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;

View File

@ -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>
);
}
}

View File

@ -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;
}
}
}

View File

@ -0,0 +1,7 @@
// @flow
import { connect } from 'react-redux';
import ENS from './components/ENS';
const mapStateToProps = state => ({});
export default connect(mapStateToProps)(ENS);

View File

@ -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>;