feat: move all @next files to non @next directory
@@ -1,168 +0,0 @@
|
|||||||
import { Link as SmartLink } from '@0x/react-shared';
|
|
||||||
import * as _ from 'lodash';
|
|
||||||
import * as React from 'react';
|
|
||||||
import MediaQuery from 'react-responsive';
|
|
||||||
import styled from 'styled-components';
|
|
||||||
|
|
||||||
import { Logo } from 'ts/@next/components/logo';
|
|
||||||
import { Column, FlexWrap, WrapGrid } from 'ts/@next/components/newLayout';
|
|
||||||
import { NewsletterForm } from 'ts/@next/components/newsletter_form';
|
|
||||||
import { WebsitePaths } from 'ts/types';
|
|
||||||
import { constants } from 'ts/utils/constants';
|
|
||||||
|
|
||||||
interface LinkInterface {
|
|
||||||
text: string;
|
|
||||||
url: string;
|
|
||||||
shouldOpenInNewTab?: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface LinkRows {
|
|
||||||
heading: string;
|
|
||||||
isOnMobile?: boolean;
|
|
||||||
links: LinkInterface[];
|
|
||||||
}
|
|
||||||
|
|
||||||
interface LinkListProps {
|
|
||||||
links: LinkInterface[];
|
|
||||||
}
|
|
||||||
|
|
||||||
const linkRows: LinkRows[] = [
|
|
||||||
{
|
|
||||||
heading: 'Products',
|
|
||||||
isOnMobile: true,
|
|
||||||
links: [
|
|
||||||
{ url: WebsitePaths.Instant, text: '0x Instant' },
|
|
||||||
{ url: WebsitePaths.LaunchKit, text: '0x Launch Kit' },
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
heading: 'Developers',
|
|
||||||
links: [
|
|
||||||
{ url: WebsitePaths.Docs, text: 'Documentation' },
|
|
||||||
{ url: constants.URL_GITHUB_ORG, text: 'GitHub', shouldOpenInNewTab: true },
|
|
||||||
{ url: constants.URL_PROTOCOL_SPECIFICATION, text: 'Protocol Spec', shouldOpenInNewTab: true },
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
heading: 'About',
|
|
||||||
isOnMobile: true,
|
|
||||||
links: [
|
|
||||||
{ url: WebsitePaths.AboutMission, text: 'Mission' },
|
|
||||||
{ url: WebsitePaths.AboutTeam, text: 'Team' },
|
|
||||||
{ url: WebsitePaths.AboutJobs, text: 'Jobs' },
|
|
||||||
{ url: WebsitePaths.AboutPress, text: 'Press' },
|
|
||||||
{ url: WebsitePaths.Ecosystem, text: 'Grant Program' },
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
heading: 'Community',
|
|
||||||
isOnMobile: true,
|
|
||||||
links: [
|
|
||||||
{ url: constants.URL_TWITTER, text: 'Twitter', shouldOpenInNewTab: true },
|
|
||||||
{ url: constants.URL_ZEROEX_CHAT, text: 'Discord Chat', shouldOpenInNewTab: true },
|
|
||||||
{ url: constants.URL_FACEBOOK, text: 'Facebook', shouldOpenInNewTab: true },
|
|
||||||
{ url: constants.URL_REDDIT, text: 'Reddit', shouldOpenInNewTab: true },
|
|
||||||
],
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
export const Footer: React.StatelessComponent = () => (
|
|
||||||
<FooterWrap>
|
|
||||||
<FlexWrap>
|
|
||||||
<FooterColumn width="35%">
|
|
||||||
<Logo />
|
|
||||||
<NewsletterForm />
|
|
||||||
</FooterColumn>
|
|
||||||
|
|
||||||
<FooterColumn width="55%">
|
|
||||||
<WrapGrid isCentered={false} isWrapped={true}>
|
|
||||||
{_.map(linkRows, (row: LinkRows, index) => (
|
|
||||||
<MediaQuery minWidth={row.isOnMobile ? 0 : 768} key={`fc-${index}`}>
|
|
||||||
<FooterSectionWrap>
|
|
||||||
<RowHeading>{row.heading}</RowHeading>
|
|
||||||
|
|
||||||
<LinkList links={row.links} />
|
|
||||||
</FooterSectionWrap>
|
|
||||||
</MediaQuery>
|
|
||||||
))}
|
|
||||||
</WrapGrid>
|
|
||||||
</FooterColumn>
|
|
||||||
</FlexWrap>
|
|
||||||
</FooterWrap>
|
|
||||||
);
|
|
||||||
|
|
||||||
const LinkList = (props: LinkListProps) => (
|
|
||||||
<List>
|
|
||||||
{_.map(props.links, (link, index) => (
|
|
||||||
<li key={`fl-${index}`}>
|
|
||||||
<Link to={link.url} shouldOpenInNewTab={link.shouldOpenInNewTab}>
|
|
||||||
{link.text}
|
|
||||||
</Link>
|
|
||||||
</li>
|
|
||||||
))}
|
|
||||||
</List>
|
|
||||||
);
|
|
||||||
|
|
||||||
const FooterWrap = styled.footer`
|
|
||||||
padding: 40px 30px 30px 30px;
|
|
||||||
margin-top: 30px;
|
|
||||||
background-color: ${props => props.theme.footerBg};
|
|
||||||
color: ${props => props.theme.footerColor};
|
|
||||||
|
|
||||||
path {
|
|
||||||
fill: ${props => props.theme.footerColor};
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (min-width: 768px) {
|
|
||||||
height: 350px;
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
const FooterColumn = styled(Column)`
|
|
||||||
@media (min-width: 768px) {
|
|
||||||
width: ${props => props.width};
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 768px) {
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
const FooterSectionWrap = styled(FooterColumn)`
|
|
||||||
@media (max-width: 768px) {
|
|
||||||
width: 50%;
|
|
||||||
|
|
||||||
& + & {
|
|
||||||
margin-top: 0;
|
|
||||||
margin-bottom: 30px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
const RowHeading = styled.h3`
|
|
||||||
color: inherit;
|
|
||||||
font-weight: 700;
|
|
||||||
font-size: 16px;
|
|
||||||
margin-bottom: 1.25em;
|
|
||||||
opacity: 0.75;
|
|
||||||
`;
|
|
||||||
|
|
||||||
const List = styled.ul`
|
|
||||||
li + li {
|
|
||||||
margin-top: 8px;
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
const Link = styled(SmartLink)`
|
|
||||||
color: inherit;
|
|
||||||
opacity: 0.5;
|
|
||||||
display: block;
|
|
||||||
font-size: 16px;
|
|
||||||
line-height: 20px;
|
|
||||||
transition: opacity 0.25s;
|
|
||||||
text-decoration: none;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
opacity: 0.8;
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
@@ -1,183 +0,0 @@
|
|||||||
import * as React from 'react';
|
|
||||||
import * as CopyToClipboard from 'react-copy-to-clipboard';
|
|
||||||
import SyntaxHighlighter from 'react-syntax-highlighter';
|
|
||||||
|
|
||||||
import { Button } from 'ts/@next/components/button';
|
|
||||||
import { Container } from 'ts/components/ui/container';
|
|
||||||
import { styled } from 'ts/style/theme';
|
|
||||||
import { zIndex } from 'ts/style/z_index';
|
|
||||||
|
|
||||||
const CustomPre = styled.pre`
|
|
||||||
margin: 0px;
|
|
||||||
line-height: 24px;
|
|
||||||
overflow: scroll;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
max-height: 800px;
|
|
||||||
border-radius: 4px;
|
|
||||||
code {
|
|
||||||
background-color: inherit !important;
|
|
||||||
border-radius: 0px;
|
|
||||||
font-family: 'Roboto Mono', sans-serif;
|
|
||||||
border: none;
|
|
||||||
}
|
|
||||||
code:first-of-type {
|
|
||||||
background-color: #060d0d !important;
|
|
||||||
color: #999;
|
|
||||||
min-height: 100%;
|
|
||||||
text-align: center;
|
|
||||||
margin-right: 15px;
|
|
||||||
line-height: 25px;
|
|
||||||
padding: 10px 7px !important;
|
|
||||||
}
|
|
||||||
code:last-of-type {
|
|
||||||
position: relative;
|
|
||||||
top: 10px;
|
|
||||||
top: 0;
|
|
||||||
padding-top: 11px;
|
|
||||||
display: inline-block;
|
|
||||||
line-height: 25px;
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
const customStyle = {
|
|
||||||
'hljs-comment': {
|
|
||||||
color: '#7e7887',
|
|
||||||
},
|
|
||||||
'hljs-quote': {
|
|
||||||
color: '#7e7887',
|
|
||||||
},
|
|
||||||
'hljs-variable': {
|
|
||||||
color: '#be4678',
|
|
||||||
},
|
|
||||||
'hljs-template-variable': {
|
|
||||||
color: '#be4678',
|
|
||||||
},
|
|
||||||
'hljs-attribute': {
|
|
||||||
color: '#be4678',
|
|
||||||
},
|
|
||||||
'hljs-regexp': {
|
|
||||||
color: '#be4678',
|
|
||||||
},
|
|
||||||
'hljs-link': {
|
|
||||||
color: '#be4678',
|
|
||||||
},
|
|
||||||
'hljs-tag': {
|
|
||||||
color: '#61f5ff',
|
|
||||||
},
|
|
||||||
'hljs-name': {
|
|
||||||
color: '#61f5ff',
|
|
||||||
},
|
|
||||||
'hljs-selector-id': {
|
|
||||||
color: '#be4678',
|
|
||||||
},
|
|
||||||
'hljs-selector-class': {
|
|
||||||
color: '#be4678',
|
|
||||||
},
|
|
||||||
'hljs-number': {
|
|
||||||
color: '#c994ff',
|
|
||||||
},
|
|
||||||
'hljs-meta': {
|
|
||||||
color: '#61f5ff',
|
|
||||||
},
|
|
||||||
'hljs-built_in': {
|
|
||||||
color: '#aa573c',
|
|
||||||
},
|
|
||||||
'hljs-builtin-name': {
|
|
||||||
color: '#aa573c',
|
|
||||||
},
|
|
||||||
'hljs-literal': {
|
|
||||||
color: '#aa573c',
|
|
||||||
},
|
|
||||||
'hljs-type': {
|
|
||||||
color: '#aa573c',
|
|
||||||
},
|
|
||||||
'hljs-params': {
|
|
||||||
color: '#aa573c',
|
|
||||||
},
|
|
||||||
'hljs-string': {
|
|
||||||
color: '#bcff88',
|
|
||||||
},
|
|
||||||
'hljs-symbol': {
|
|
||||||
color: '#2a9292',
|
|
||||||
},
|
|
||||||
'hljs-bullet': {
|
|
||||||
color: '#2a9292',
|
|
||||||
},
|
|
||||||
'hljs-title': {
|
|
||||||
color: '#576ddb',
|
|
||||||
},
|
|
||||||
'hljs-section': {
|
|
||||||
color: '#576ddb',
|
|
||||||
},
|
|
||||||
'hljs-keyword': {
|
|
||||||
color: '#955ae7',
|
|
||||||
},
|
|
||||||
'hljs-selector-tag': {
|
|
||||||
color: '#955ae7',
|
|
||||||
},
|
|
||||||
'hljs-deletion': {
|
|
||||||
color: '#19171c',
|
|
||||||
display: 'inline-block',
|
|
||||||
width: '100%',
|
|
||||||
backgroundColor: '#be4678',
|
|
||||||
},
|
|
||||||
'hljs-addition': {
|
|
||||||
color: '#19171c',
|
|
||||||
display: 'inline-block',
|
|
||||||
width: '100%',
|
|
||||||
backgroundColor: '#2a9292',
|
|
||||||
},
|
|
||||||
hljs: {
|
|
||||||
display: 'block',
|
|
||||||
overflowX: 'hidden',
|
|
||||||
background: '#1B2625',
|
|
||||||
color: 'white',
|
|
||||||
fontSize: '12px',
|
|
||||||
},
|
|
||||||
'hljs-emphasis': {
|
|
||||||
fontStyle: 'italic',
|
|
||||||
},
|
|
||||||
'hljs-strong': {
|
|
||||||
fontWeight: 'bold',
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
export interface CodeDemoProps {
|
|
||||||
children: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface CodeDemoState {
|
|
||||||
didCopyCode: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class CodeDemo extends React.Component<CodeDemoProps, CodeDemoState> {
|
|
||||||
public state: CodeDemoState = {
|
|
||||||
didCopyCode: false,
|
|
||||||
};
|
|
||||||
public render(): React.ReactNode {
|
|
||||||
const copyButtonText = this.state.didCopyCode ? 'Copied!' : 'Copy';
|
|
||||||
return (
|
|
||||||
<Container position="relative" height="100%">
|
|
||||||
<Container position="absolute" top="10px" right="10px" zIndex={zIndex.overlay - 1}>
|
|
||||||
<CopyToClipboard text={this.props.children} onCopy={this._handleCopyClick}>
|
|
||||||
<StyledButton>{copyButtonText}</StyledButton>
|
|
||||||
</CopyToClipboard>
|
|
||||||
</Container>
|
|
||||||
<SyntaxHighlighter language="html" style={customStyle} showLineNumbers={true} PreTag={CustomPre}>
|
|
||||||
{this.props.children}
|
|
||||||
</SyntaxHighlighter>
|
|
||||||
</Container>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
private readonly _handleCopyClick = () => {
|
|
||||||
this.setState({ didCopyCode: true });
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
const StyledButton = styled(Button)`
|
|
||||||
border-radius: 4px;
|
|
||||||
font-size: 15px;
|
|
||||||
font-weight: 400;
|
|
||||||
padding: 9px 21px 7px;
|
|
||||||
`;
|
|
||||||
@@ -1,84 +0,0 @@
|
|||||||
import { addressUtils } from '@0x/utils';
|
|
||||||
import * as _ from 'lodash';
|
|
||||||
import * as React from 'react';
|
|
||||||
import styled from 'styled-components';
|
|
||||||
|
|
||||||
import { colors } from 'ts/style/colors';
|
|
||||||
|
|
||||||
import { Container } from 'ts/components/ui/container';
|
|
||||||
|
|
||||||
import { Paragraph } from 'ts/@next/components/text';
|
|
||||||
|
|
||||||
export interface ConfigGeneratorAddressInputProps {
|
|
||||||
value?: string;
|
|
||||||
onChange?: (address: string, isValid: boolean) => void;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface ConfigGeneratorAddressInputState {
|
|
||||||
errMsg: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface InputProps {
|
|
||||||
className?: string;
|
|
||||||
value?: string;
|
|
||||||
width?: string;
|
|
||||||
fontSize?: string;
|
|
||||||
fontColor?: string;
|
|
||||||
padding?: string;
|
|
||||||
placeholderColor?: string;
|
|
||||||
placeholder?: string;
|
|
||||||
backgroundColor?: string;
|
|
||||||
onChange?: (event: React.ChangeEvent<HTMLInputElement>) => void;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class ConfigGeneratorAddressInput extends React.Component<
|
|
||||||
ConfigGeneratorAddressInputProps,
|
|
||||||
ConfigGeneratorAddressInputState
|
|
||||||
> {
|
|
||||||
public state = {
|
|
||||||
errMsg: '',
|
|
||||||
};
|
|
||||||
public render(): React.ReactNode {
|
|
||||||
const { errMsg } = this.state;
|
|
||||||
const hasError = !_.isEmpty(errMsg);
|
|
||||||
return (
|
|
||||||
<Container height="80px">
|
|
||||||
<Input value={this.props.value} onChange={this._handleChange} placeholder="0xe99...aa8da4" />
|
|
||||||
<Container marginTop="5px" isHidden={!hasError} height="25px">
|
|
||||||
<Paragraph size="small" isNoMargin={true}>
|
|
||||||
{errMsg}
|
|
||||||
</Paragraph>
|
|
||||||
</Container>
|
|
||||||
</Container>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
private readonly _handleChange = (event: React.ChangeEvent<HTMLInputElement>): void => {
|
|
||||||
const address = event.target.value;
|
|
||||||
const isValidAddress = addressUtils.isAddress(address.toLowerCase()) || address === '';
|
|
||||||
const errMsg = isValidAddress ? '' : 'Please enter a valid Ethereum address';
|
|
||||||
this.setState({
|
|
||||||
errMsg,
|
|
||||||
});
|
|
||||||
this.props.onChange(address, isValidAddress);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
const PlainInput: React.StatelessComponent<InputProps> = ({ value, className, placeholder, onChange }) => (
|
|
||||||
<input className={className} value={value} onChange={onChange} placeholder={placeholder} />
|
|
||||||
);
|
|
||||||
|
|
||||||
export const Input = styled(PlainInput)`
|
|
||||||
background-color: ${colors.white};
|
|
||||||
color: ${colors.textDarkSecondary};
|
|
||||||
font-size: 1rem;
|
|
||||||
width: 100%;
|
|
||||||
padding: 16px 20px 18px;
|
|
||||||
border-radius: 4px;
|
|
||||||
border: 1px solid transparent;
|
|
||||||
outline: none;
|
|
||||||
&::placeholder {
|
|
||||||
color: #333333;
|
|
||||||
opacity: 0.5;
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
@@ -1,228 +1,168 @@
|
|||||||
import { ALink, colors, Link } from '@0x/react-shared';
|
import { Link as SmartLink } from '@0x/react-shared';
|
||||||
import { ObjectMap } from '@0x/types';
|
|
||||||
import * as _ from 'lodash';
|
import * as _ from 'lodash';
|
||||||
import DropDownMenu from 'material-ui/DropDownMenu';
|
|
||||||
import MenuItem from 'material-ui/MenuItem';
|
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
|
import MediaQuery from 'react-responsive';
|
||||||
|
import styled from 'styled-components';
|
||||||
|
|
||||||
import { Dispatcher } from 'ts/redux/dispatcher';
|
import { Logo } from 'ts/@next/components/logo';
|
||||||
import { Deco, Key, Language, WebsitePaths } from 'ts/types';
|
import { Column, FlexWrap, WrapGrid } from 'ts/@next/components/newLayout';
|
||||||
|
import { NewsletterForm } from 'ts/@next/components/newsletter_form';
|
||||||
|
import { WebsitePaths } from 'ts/types';
|
||||||
import { constants } from 'ts/utils/constants';
|
import { constants } from 'ts/utils/constants';
|
||||||
import { Translate } from 'ts/utils/translate';
|
|
||||||
|
|
||||||
const ICON_DIMENSION = 16;
|
interface LinkInterface {
|
||||||
|
text: string;
|
||||||
const languageToMenuTitle = {
|
url: string;
|
||||||
[Language.English]: 'English',
|
shouldOpenInNewTab?: boolean;
|
||||||
[Language.Russian]: 'Русский',
|
|
||||||
[Language.Spanish]: 'Español',
|
|
||||||
[Language.Korean]: '한국어',
|
|
||||||
[Language.Chinese]: '中文',
|
|
||||||
};
|
|
||||||
|
|
||||||
export interface FooterProps {
|
|
||||||
translate: Translate;
|
|
||||||
dispatcher: Dispatcher;
|
|
||||||
backgroundColor?: string;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
interface FooterState {
|
interface LinkRows {
|
||||||
selectedLanguage: Language;
|
heading: string;
|
||||||
|
isOnMobile?: boolean;
|
||||||
|
links: LinkInterface[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Footer extends React.Component<FooterProps, FooterState> {
|
interface LinkListProps {
|
||||||
public static defaultProps = {
|
links: LinkInterface[];
|
||||||
backgroundColor: colors.darkerGrey,
|
}
|
||||||
};
|
|
||||||
constructor(props: FooterProps) {
|
const linkRows: LinkRows[] = [
|
||||||
super(props);
|
{
|
||||||
this.state = {
|
heading: 'Products',
|
||||||
selectedLanguage: props.translate.getLanguage(),
|
isOnMobile: true,
|
||||||
};
|
links: [
|
||||||
}
|
{ url: WebsitePaths.Instant, text: '0x Instant' },
|
||||||
public render(): React.ReactNode {
|
{ url: WebsitePaths.LaunchKit, text: '0x Launch Kit' },
|
||||||
const sectionNameToLinks: ObjectMap<ALink[]> = {
|
],
|
||||||
[Key.Documentation]: [
|
},
|
||||||
{
|
{
|
||||||
title: 'Developer Home',
|
heading: 'Developers',
|
||||||
to: WebsitePaths.Docs,
|
links: [
|
||||||
},
|
{ url: WebsitePaths.Docs, text: 'Documentation' },
|
||||||
{
|
{ url: constants.URL_GITHUB_ORG, text: 'GitHub', shouldOpenInNewTab: true },
|
||||||
title: '0x.js',
|
{ url: constants.URL_PROTOCOL_SPECIFICATION, text: 'Protocol Spec', shouldOpenInNewTab: true },
|
||||||
to: WebsitePaths.ZeroExJs,
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: this.props.translate.get(Key.SmartContracts, Deco.Cap),
|
heading: 'About',
|
||||||
to: WebsitePaths.SmartContracts,
|
isOnMobile: true,
|
||||||
},
|
links: [
|
||||||
{
|
{ url: WebsitePaths.AboutMission, text: 'Mission' },
|
||||||
title: this.props.translate.get(Key.Connect, Deco.Cap),
|
{ url: WebsitePaths.AboutTeam, text: 'Team' },
|
||||||
to: WebsitePaths.Connect,
|
{ url: WebsitePaths.AboutJobs, text: 'Jobs' },
|
||||||
},
|
{ url: WebsitePaths.AboutPress, text: 'Press' },
|
||||||
{
|
{ url: WebsitePaths.Ecosystem, text: 'Grant Program' },
|
||||||
title: this.props.translate.get(Key.Whitepaper, Deco.Cap),
|
],
|
||||||
to: WebsitePaths.Whitepaper,
|
},
|
||||||
shouldOpenInNewTab: true,
|
{
|
||||||
},
|
heading: 'Community',
|
||||||
{
|
isOnMobile: true,
|
||||||
title: this.props.translate.get(Key.Wiki, Deco.Cap),
|
links: [
|
||||||
to: WebsitePaths.Wiki,
|
{ url: constants.URL_TWITTER, text: 'Twitter', shouldOpenInNewTab: true },
|
||||||
},
|
{ url: constants.URL_ZEROEX_CHAT, text: 'Discord Chat', shouldOpenInNewTab: true },
|
||||||
],
|
{ url: constants.URL_FACEBOOK, text: 'Facebook', shouldOpenInNewTab: true },
|
||||||
[Key.Community]: [
|
{ url: constants.URL_REDDIT, text: 'Reddit', shouldOpenInNewTab: true },
|
||||||
{
|
],
|
||||||
title: this.props.translate.get(Key.Discord, Deco.Cap),
|
},
|
||||||
to: constants.URL_ZEROEX_CHAT,
|
];
|
||||||
shouldOpenInNewTab: true,
|
|
||||||
},
|
export const Footer: React.StatelessComponent = () => (
|
||||||
{
|
<FooterWrap>
|
||||||
title: this.props.translate.get(Key.Blog, Deco.Cap),
|
<FlexWrap>
|
||||||
to: constants.URL_BLOG,
|
<FooterColumn width="35%">
|
||||||
shouldOpenInNewTab: true,
|
<Logo />
|
||||||
},
|
<NewsletterForm />
|
||||||
{
|
</FooterColumn>
|
||||||
title: 'Twitter',
|
|
||||||
to: constants.URL_TWITTER,
|
<FooterColumn width="55%">
|
||||||
shouldOpenInNewTab: true,
|
<WrapGrid isCentered={false} isWrapped={true}>
|
||||||
},
|
{_.map(linkRows, (row: LinkRows, index) => (
|
||||||
{
|
<MediaQuery minWidth={row.isOnMobile ? 0 : 768} key={`fc-${index}`}>
|
||||||
title: 'Reddit',
|
<FooterSectionWrap>
|
||||||
to: constants.URL_REDDIT,
|
<RowHeading>{row.heading}</RowHeading>
|
||||||
shouldOpenInNewTab: true,
|
|
||||||
},
|
<LinkList links={row.links} />
|
||||||
{
|
</FooterSectionWrap>
|
||||||
title: this.props.translate.get(Key.Forum, Deco.Cap),
|
</MediaQuery>
|
||||||
to: constants.URL_DISCOURSE_FORUM,
|
))}
|
||||||
shouldOpenInNewTab: true,
|
</WrapGrid>
|
||||||
},
|
</FooterColumn>
|
||||||
],
|
</FlexWrap>
|
||||||
[Key.Organization]: [
|
</FooterWrap>
|
||||||
{
|
);
|
||||||
title: this.props.translate.get(Key.About, Deco.Cap),
|
|
||||||
to: WebsitePaths.About,
|
const LinkList = (props: LinkListProps) => (
|
||||||
},
|
<List>
|
||||||
{
|
{_.map(props.links, (link, index) => (
|
||||||
title: this.props.translate.get(Key.Careers, Deco.Cap),
|
<li key={`fl-${index}`}>
|
||||||
to: WebsitePaths.Careers,
|
<Link to={link.url} shouldOpenInNewTab={link.shouldOpenInNewTab}>
|
||||||
},
|
{link.text}
|
||||||
{
|
|
||||||
title: this.props.translate.get(Key.Contact, Deco.Cap),
|
|
||||||
to: 'mailto:team@0x.org',
|
|
||||||
shouldOpenInNewTab: true,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
||||||
const languageMenuItems = _.map(languageToMenuTitle, (menuTitle: string, language: Language) => {
|
|
||||||
return <MenuItem key={menuTitle} value={language} primaryText={menuTitle} />;
|
|
||||||
});
|
|
||||||
return (
|
|
||||||
<div className="relative pb4 pt2" style={{ backgroundColor: this.props.backgroundColor }}>
|
|
||||||
<div className="mx-auto max-width-4 md-px2 lg-px0 py4 clearfix" style={{ color: colors.white }}>
|
|
||||||
<div className="col lg-col-4 md-col-4 col-12 left">
|
|
||||||
<div className="sm-mx-auto" style={{ width: 148 }}>
|
|
||||||
<div>
|
|
||||||
<img src="/images/protocol_logo_white.png" height="30" />
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
fontSize: 11,
|
|
||||||
color: colors.grey,
|
|
||||||
paddingLeft: 37,
|
|
||||||
paddingTop: 2,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
© ZeroEx, Intl.
|
|
||||||
</div>
|
|
||||||
<div className="pt4 center">
|
|
||||||
<DropDownMenu
|
|
||||||
labelStyle={{ color: colors.white }}
|
|
||||||
value={this.state.selectedLanguage}
|
|
||||||
onChange={this._updateLanguage.bind(this)}
|
|
||||||
>
|
|
||||||
{languageMenuItems}
|
|
||||||
</DropDownMenu>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="col lg-col-8 md-col-8 col-12 lg-pl4 md-pl4">
|
|
||||||
<div className="col lg-col-4 md-col-4 col-12">
|
|
||||||
<div className="lg-right md-right sm-center">
|
|
||||||
{this._renderHeader(Key.Documentation)}
|
|
||||||
{_.map(sectionNameToLinks[Key.Documentation], this._renderMenuItem.bind(this))}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="col lg-col-4 md-col-4 col-12 lg-pr2 md-pr2">
|
|
||||||
<div className="lg-right md-right sm-center">
|
|
||||||
{this._renderHeader(Key.Community)}
|
|
||||||
{_.map(sectionNameToLinks[Key.Community], this._renderMenuItem.bind(this))}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="col lg-col-4 md-col-4 col-12">
|
|
||||||
<div className="lg-right md-right sm-center">
|
|
||||||
{this._renderHeader(Key.Organization)}
|
|
||||||
{_.map(sectionNameToLinks[Key.Organization], this._renderMenuItem.bind(this))}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
private _renderIcon(fileName: string): React.ReactNode {
|
|
||||||
return (
|
|
||||||
<div style={{ height: ICON_DIMENSION, width: ICON_DIMENSION }}>
|
|
||||||
<img src={`/images/social/${fileName}`} style={{ width: ICON_DIMENSION }} />
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
private _renderMenuItem(link: ALink): React.ReactNode {
|
|
||||||
const titleToIcon: { [title: string]: string } = {
|
|
||||||
[this.props.translate.get(Key.Discord, Deco.Cap)]: 'discord.png',
|
|
||||||
[this.props.translate.get(Key.Blog, Deco.Cap)]: 'medium.png',
|
|
||||||
Twitter: 'twitter.png',
|
|
||||||
Reddit: 'reddit.png',
|
|
||||||
[this.props.translate.get(Key.Forum, Deco.Cap)]: 'discourse.png',
|
|
||||||
};
|
|
||||||
const iconIfExists = titleToIcon[link.title];
|
|
||||||
return (
|
|
||||||
<div key={link.title} className="sm-center" style={{ fontSize: 13, paddingTop: 25 }}>
|
|
||||||
<Link
|
|
||||||
to={link.to}
|
|
||||||
shouldOpenInNewTab={link.shouldOpenInNewTab}
|
|
||||||
fontColor={colors.white}
|
|
||||||
className="text-decoration-none"
|
|
||||||
>
|
|
||||||
<div>
|
|
||||||
{!_.isUndefined(iconIfExists) ? (
|
|
||||||
<div className="inline-block">
|
|
||||||
<div className="pr1 table-cell">{this._renderIcon(iconIfExists)}</div>
|
|
||||||
<div className="table-cell">{link.title}</div>
|
|
||||||
</div>
|
|
||||||
) : (
|
|
||||||
link.title
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</li>
|
||||||
);
|
))}
|
||||||
|
</List>
|
||||||
|
);
|
||||||
|
|
||||||
|
const FooterWrap = styled.footer`
|
||||||
|
padding: 40px 30px 30px 30px;
|
||||||
|
margin-top: 30px;
|
||||||
|
background-color: ${props => props.theme.footerBg};
|
||||||
|
color: ${props => props.theme.footerColor};
|
||||||
|
|
||||||
|
path {
|
||||||
|
fill: ${props => props.theme.footerColor};
|
||||||
}
|
}
|
||||||
private _renderHeader(key: Key): React.ReactNode {
|
|
||||||
const headerStyle = {
|
@media (min-width: 768px) {
|
||||||
color: colors.grey400,
|
height: 350px;
|
||||||
letterSpacing: 2,
|
|
||||||
fontFamily: 'Roboto Mono',
|
|
||||||
fontSize: 13,
|
|
||||||
};
|
|
||||||
return (
|
|
||||||
<div className="lg-pb2 md-pb2 sm-pt4" style={headerStyle}>
|
|
||||||
{this.props.translate.get(key, Deco.Upper)}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
private _updateLanguage(_event: any, _index: number, value: Language): void {
|
`;
|
||||||
this.setState({
|
|
||||||
selectedLanguage: value,
|
const FooterColumn = styled(Column)`
|
||||||
});
|
@media (min-width: 768px) {
|
||||||
this.props.dispatcher.updateSelectedLanguage(value);
|
width: ${props => props.width};
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const FooterSectionWrap = styled(FooterColumn)`
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
width: 50%;
|
||||||
|
|
||||||
|
& + & {
|
||||||
|
margin-top: 0;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const RowHeading = styled.h3`
|
||||||
|
color: inherit;
|
||||||
|
font-weight: 700;
|
||||||
|
font-size: 16px;
|
||||||
|
margin-bottom: 1.25em;
|
||||||
|
opacity: 0.75;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const List = styled.ul`
|
||||||
|
li + li {
|
||||||
|
margin-top: 8px;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const Link = styled(SmartLink)`
|
||||||
|
color: inherit;
|
||||||
|
opacity: 0.5;
|
||||||
|
display: block;
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 20px;
|
||||||
|
transition: opacity 0.25s;
|
||||||
|
text-decoration: none;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
opacity: 0.8;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 198 B After Width: | Height: | Size: 198 B |
|
Before Width: | Height: | Size: 7.7 KiB After Width: | Height: | Size: 7.7 KiB |
|
Before Width: | Height: | Size: 749 B After Width: | Height: | Size: 749 B |
|
Before Width: | Height: | Size: 826 B After Width: | Height: | Size: 826 B |
|
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 7.4 KiB After Width: | Height: | Size: 7.4 KiB |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 3.8 KiB |
|
Before Width: | Height: | Size: 493 B After Width: | Height: | Size: 493 B |
|
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.2 KiB |
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 2.4 KiB |
|
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 3.2 KiB |
|
Before Width: | Height: | Size: 786 B After Width: | Height: | Size: 786 B |
|
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.9 KiB |
|
Before Width: | Height: | Size: 5.0 KiB After Width: | Height: | Size: 5.0 KiB |
|
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.0 KiB |
|
Before Width: | Height: | Size: 955 B After Width: | Height: | Size: 955 B |
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 921 B After Width: | Height: | Size: 921 B |
|
Before Width: | Height: | Size: 630 B After Width: | Height: | Size: 630 B |
|
Before Width: | Height: | Size: 1013 B After Width: | Height: | Size: 1013 B |
|
Before Width: | Height: | Size: 7.9 KiB After Width: | Height: | Size: 7.9 KiB |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 2.4 KiB |
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 730 B After Width: | Height: | Size: 730 B |
|
Before Width: | Height: | Size: 5.2 KiB After Width: | Height: | Size: 5.2 KiB |
|
Before Width: | Height: | Size: 7.3 KiB After Width: | Height: | Size: 7.3 KiB |
|
Before Width: | Height: | Size: 670 B After Width: | Height: | Size: 670 B |
|
Before Width: | Height: | Size: 615 B After Width: | Height: | Size: 615 B |
|
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 3.3 KiB |
|
Before Width: | Height: | Size: 684 B After Width: | Height: | Size: 684 B |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 554 B After Width: | Height: | Size: 554 B |
|
Before Width: | Height: | Size: 8.2 KiB After Width: | Height: | Size: 8.2 KiB |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 2.0 KiB |
|
Before Width: | Height: | Size: 545 B After Width: | Height: | Size: 545 B |
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 470 B After Width: | Height: | Size: 470 B |
|
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 3.1 KiB |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.9 KiB |
|
Before Width: | Height: | Size: 650 B After Width: | Height: | Size: 650 B |
|
Before Width: | Height: | Size: 857 B After Width: | Height: | Size: 857 B |
|
Before Width: | Height: | Size: 4.1 KiB After Width: | Height: | Size: 4.1 KiB |
|
Before Width: | Height: | Size: 4.0 KiB After Width: | Height: | Size: 4.0 KiB |
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.0 KiB |