aboutsummaryrefslogtreecommitdiffstats
path: root/packages/website
diff options
context:
space:
mode:
Diffstat (limited to 'packages/website')
-rw-r--r--packages/website/package.json1
-rw-r--r--packages/website/ts/@next/components/blockIconLink.tsx36
-rw-r--r--packages/website/ts/@next/components/button.tsx4
-rw-r--r--packages/website/ts/@next/components/modals/input.tsx65
-rw-r--r--packages/website/ts/@next/components/modals/modal_contact.tsx198
-rw-r--r--packages/website/ts/@next/components/sections/landing/cta.tsx8
-rw-r--r--packages/website/ts/@next/pages/landing.tsx38
7 files changed, 326 insertions, 24 deletions
diff --git a/packages/website/package.json b/packages/website/package.json
index 629cbffc2..fc98a1a1b 100644
--- a/packages/website/package.json
+++ b/packages/website/package.json
@@ -32,6 +32,7 @@
"@0x/typescript-typings": "^3.0.4",
"@0x/utils": "^2.0.6",
"@0x/web3-wrapper": "^3.1.6",
+ "@reach/dialog": "^0.1.2",
"@types/react-lazyload": "^2.3.1",
"@types/react-loadable": "^5.4.2",
"@types/react-syntax-highlighter": "^0.0.8",
diff --git a/packages/website/ts/@next/components/blockIconLink.tsx b/packages/website/ts/@next/components/blockIconLink.tsx
index cc3e88280..42b260731 100644
--- a/packages/website/ts/@next/components/blockIconLink.tsx
+++ b/packages/website/ts/@next/components/blockIconLink.tsx
@@ -1,14 +1,15 @@
import * as React from 'react';
import styled from 'styled-components';
-import {Link} from 'ts/@next/components/button';
+import {Button, Link} from 'ts/@next/components/button';
import {Icon} from 'ts/@next/components/icon';
interface Props {
icon: string;
title: string;
linkLabel: string;
- linkUrl: string;
+ linkUrl?: string;
+ onClick?: () => void;
}
export const BlockIconLink = (props: Props) => (
@@ -24,14 +25,29 @@ export const BlockIconLink = (props: Props) => (
{props.title}
</Title>
- <Link
- isWithArrow={true}
- isTransparent={true}
- isNoBorder={true}
- href={props.linkUrl}
- >
- {props.linkLabel}
- </Link>
+ {props.linkUrl &&
+ <Link
+ isWithArrow={true}
+ isTransparent={true}
+ isNoBorder={true}
+ href={props.linkUrl}
+ onClick={props.onClick}
+ >
+ {props.linkLabel}
+ </Link>
+ }
+
+ {props.onClick &&
+ <Button
+ isWithArrow={true}
+ isTransparent={true}
+ isNoBorder={true}
+ href={props.linkUrl}
+ onClick={props.onClick}
+ >
+ {props.linkLabel}
+ </Button>
+ }
</div>
</Wrap>
);
diff --git a/packages/website/ts/@next/components/button.tsx b/packages/website/ts/@next/components/button.tsx
index 3f14b59bd..5d44f1ce5 100644
--- a/packages/website/ts/@next/components/button.tsx
+++ b/packages/website/ts/@next/components/button.tsx
@@ -16,6 +16,8 @@ interface ButtonInterface {
isWithArrow?: boolean;
isAccentColor?: boolean;
hasIcon?: boolean | string;
+ isInline?: boolean;
+ type?: string;
href?: string;
onClick?: () => any;
theme?: {
@@ -57,7 +59,7 @@ export const Button = styled.button<ButtonInterface>`
}
`;
-export const Link = (props: ButtonInterface) => {
+export const Link: React.ReactNode = (props: ButtonInterface) => {
const {
children,
href,
diff --git a/packages/website/ts/@next/components/modals/input.tsx b/packages/website/ts/@next/components/modals/input.tsx
new file mode 100644
index 000000000..eee2d4102
--- /dev/null
+++ b/packages/website/ts/@next/components/modals/input.tsx
@@ -0,0 +1,65 @@
+import * as React from 'react';
+import styled from 'styled-components';
+
+import { colors } from 'ts/style/colors';
+
+export enum InputWidth {
+ Half,
+ Full,
+}
+
+interface InputProps {
+ name: string;
+ width: InputWidth;
+ label: string;
+ type?: string;
+}
+
+interface LabelProps {
+ string: boolean;
+}
+
+export const Input = React.forwardRef((props: InputProps, ref) => {
+ const { name, label, type } = props;
+ const id = `input-${name}`;
+
+ return (
+ <InputWrapper {...props}>
+ <Label htmlFor={id}>{label}</Label>
+ <StyledInput ref={ref} id={id} placeholder={label} {...props} />
+ </InputWrapper>
+ );
+});
+
+Input.defaultProps = {
+ width: InputWidth.Full,
+};
+
+const StyledInput = styled.input`
+ appearance: none;
+ background-color: #fff;
+ border: 1px solid #D5D5D5;
+ color: #000;
+ font-size: 1.294117647rem;
+ padding: 16px 15px;
+ outline: none;
+ width: 100%;
+
+ &::placeholder {
+ color: #9D9D9D;
+ }
+`;
+
+const InputWrapper = styled.div<InputProps>`
+ position: relative;
+ flex-grow: ${props => props.width === InputWidth.Full && 1};
+ width: ${props => props.width === InputWidth.Half && `calc(50% - 15px)`};
+`;
+
+const Label = styled.label`
+ color: #000;
+ font-size: 1.111111111rem;
+ line-height: 1.4em;
+ margin-bottom: 10px;
+ display: inline-block;
+`;
diff --git a/packages/website/ts/@next/components/modals/modal_contact.tsx b/packages/website/ts/@next/components/modals/modal_contact.tsx
new file mode 100644
index 000000000..cd6335103
--- /dev/null
+++ b/packages/website/ts/@next/components/modals/modal_contact.tsx
@@ -0,0 +1,198 @@
+import * as _ from 'lodash';
+import * as React from 'react';
+import {Link as RouterLink} from 'react-router-dom';
+import styled, {withTheme} from 'styled-components';
+
+import { colors } from 'ts/style/colors';
+
+import {
+ Dialog,
+ DialogOverlay,
+ DialogContent
+ } from "@reach/dialog";
+import "@reach/dialog/styles.css";
+
+import {Button} from 'ts/@next/components/button';
+import {Column, Wrap, WrapGrid} from 'ts/@next/components/layout';
+import { Icon } from 'ts/@next/components/icon';
+import {Input, InputWidth} from 'ts/@next/components/modals/input';
+import {Heading, Paragraph} from 'ts/@next/components/text';
+import {GlobalStyle} from 'ts/@next/constants/globalStyle';
+
+interface Props {
+ theme?: GlobalStyle;
+ isOpen?: boolean;
+ onDismiss?: () => void;
+}
+
+interface FormProps {
+ isSuccessful?: boolean;
+ isSubmitting?: boolean;
+}
+
+export class ModalContact extends React.Component<Props> {
+ public state = {
+ isSubmitting: false,
+ isSuccessful: false,
+ };
+ public constructor(props: Props) {
+ super(props);
+ }
+ public render(): React.ReactNode {
+ const {isOpen, onDismiss} = this.props;
+ const {isSuccessful} = this.state;
+
+ return (
+ <>
+ <DialogOverlay
+ style={{ background: 'rgba(0, 0, 0, 0.75)' }}
+ isOpen={isOpen}
+ >
+ <StyledDialogContent>
+ <Form onSubmit={this._onSubmit.bind(this)} isSuccessful={isSuccessful}>
+ <Heading color={colors.textDarkPrimary} size={34} asElement="h2">Contact the 0x Core Team</Heading>
+ <Paragraph isMuted={true} color={colors.textDarkPrimary}>If you're considering building on 0x, we're happy to answer your questions. Fill out the form so we can connect you with the right person to help you get started.</Paragraph>
+ <InputRow>
+ <Input
+ name="name"
+ label="Your name"
+ type="text"
+ width={InputWidth.Half}
+ />
+ <Input
+ name="email"
+ label="Your email"
+ type="email"
+ width={InputWidth.Half}
+ />
+ </InputRow>
+ <InputRow>
+ <Input
+ name="companyOrProject"
+ label="Name of your project / company"
+ type="text"
+ />
+ </InputRow>
+ <InputRow>
+ <Input
+ name="link"
+ label="Do you have any documentation or a website?"
+ type="text"
+ />
+ </InputRow>
+ <InputRow>
+ <Input
+ name="comments"
+ label="Anything else?"
+ type="text"
+ />
+ </InputRow>
+ <InputRow>
+ <Button
+ color="#5C5C5C"
+ isNoBorder={true}
+ isTransparent={true}
+ type="button"
+ onClick={this.props.onDismiss}
+ >
+ Back
+ </Button>
+ <Button>Submit</Button>
+ </InputRow>
+ </Form>
+ <Confirmation isSuccessful={isSuccessful}>
+ <Icon name="checkmark" size="large" />
+ <Heading color={colors.textDarkPrimary} size={34} asElement="h2">Thanks for contacting us.</Heading>
+ <Paragraph isMuted={true} color={colors.textDarkPrimary}>We'll get back to you soon. If you need quick support in the meantime, reach out to the 0x team on Discord.</Paragraph>
+ <Button onClick={this.props.onDismiss}>Done</Button>
+ </Confirmation>
+ </StyledDialogContent>
+ </DialogOverlay>
+ </>
+ );
+ }
+ private async _onSubmit(e): void {
+ e.preventDefault();
+
+ // const email = this.emailInput.current.value;
+ const email = 'fred@sjelfull.no';
+
+ this.setState({ ...this.state, isSubmitting: true });
+
+ try {
+ const response = await fetch('/email', {
+ method: 'post',
+ headers: {
+ 'content-type': 'application/json; charset=utf-8',
+ },
+ body: JSON.stringify({ email }),
+ });
+ const json = await response.json();
+
+ console.log(response.json());
+ } catch (e) {
+ console.log(e);
+ }
+
+ this.setState({ ...this.state, isSuccessful: true });
+ }
+ private async _onDone(e): void {
+ e.preventDefault();
+
+ this.props.onDismiss();
+ }
+};
+
+const StyledWrap = styled(Wrap)`
+ padding-top: 20px;
+ margin-top: 30px;
+ position: relative;
+
+ &:before {
+ content: '';
+ width: 100%;
+ height: 1px;
+ background-color: ${props => props.theme.dropdownColor};
+ opacity: 0.15;
+ position: absolute;
+ top: 0;
+ left:0;
+ }
+`;
+
+const InputRow = styled.div`
+ display: flex;
+ justify-content: space-between;
+ margin-bottom: 30px;
+ width: 100%;
+ flex: 0 0 auto;
+`;
+
+const StyledDialogContent = styled(DialogContent)`
+ position: relative;
+ max-width: 800px;
+ background-color: #F6F6F6 !important;
+ padding: 60px 60px !important;
+`;
+
+const Form = styled.form<FormProps>`
+ position: relative;
+ transition: opacity 0.30s ease-in-out, visibility 0.30s ease-in-out;
+
+ opacity: ${props => props.isSuccessful && `0`};
+ visibility: ${props => props.isSuccessful && `hidden`};
+`;
+
+const Confirmation = styled.div<FormProps>`
+ position: absolute;
+ top: 50%;
+ text-align: center;
+ width: 100%;
+ left: 0;
+ transition: opacity 0.30s ease-in-out, visibility 0.30s ease-in-out;
+ transition-delay: 0.40s;
+ padding: 60px 60px;
+ transform: translateY(-50%);
+ opacity: ${props => props.isSuccessful ? `1` : `0`};
+ visibility: ${props => props.isSuccessful ? 'visible' : `hidden`};
+`;
diff --git a/packages/website/ts/@next/components/sections/landing/cta.tsx b/packages/website/ts/@next/components/sections/landing/cta.tsx
index 4c06982e4..b90b4070e 100644
--- a/packages/website/ts/@next/components/sections/landing/cta.tsx
+++ b/packages/website/ts/@next/components/sections/landing/cta.tsx
@@ -8,7 +8,11 @@ import {Column, Section} from 'ts/@next/components/newLayout';
import {BlockIconLink} from 'ts/@next/components/blockIconLink';
-export const SectionLandingCta = () => (
+interface Props {
+ onContactClick?: () => void;
+}
+
+export const SectionLandingCta = (props: Props) => (
<Section
isPadded={false}
isFullWidth={true}
@@ -25,7 +29,7 @@ export const SectionLandingCta = () => (
icon="coin"
title="Wat help from the 0x team?"
linkLabel="Get in Touch"
- linkUrl="#"
+ onClick={props.onContactClick}
/>
</Section>
);
diff --git a/packages/website/ts/@next/pages/landing.tsx b/packages/website/ts/@next/pages/landing.tsx
index fab5e62b6..5ead1b6b5 100644
--- a/packages/website/ts/@next/pages/landing.tsx
+++ b/packages/website/ts/@next/pages/landing.tsx
@@ -7,9 +7,7 @@ import {SectionLandingClients} from 'ts/@next/components/sections/landing/client
import {SectionLandingCta} from 'ts/@next/components/sections/landing/cta';
import {SectionLandingHero} from 'ts/@next/components/sections/landing/hero';
-import {Button} from 'ts/@next/components/button';
-import {Hero} from 'ts/@next/components/hero';
-import {LandingAnimation} from 'ts/@next/components/heroImage';
+import { ModalContact } from 'ts/@next/components/modals/modal_contact';
import LogoOutlined from 'ts/@next/icons/illustrations/logo-outlined.svg';
@@ -21,11 +19,29 @@ interface Props {
};
}
-export const NextLanding: React.StatelessComponent<{}> = (props: Props) => (
- <SiteWrap theme="dark">
- <SectionLandingHero />
- <SectionLandingAbout />
- <SectionLandingClients />
- <SectionLandingCta />
- </SiteWrap>
-);
+export class NextLanding extends React.Component<Props> {
+ public state = {
+ isContactModalOpen: false,
+ };
+ public render(): React.ReactNode {
+ return (
+ <SiteWrap theme="dark">
+ <SectionLandingHero />
+ <SectionLandingAbout />
+ <SectionLandingClients />
+ <SectionLandingCta onContactClick={this._onOpenContactModal.bind(this)} />
+ <ModalContact isOpen={this.state.isContactModalOpen} onDismiss={this._onDismissContactModal.bind(this)} />
+ </SiteWrap>
+ );
+ }
+
+ private _onOpenContactModal(e): void {
+ e.preventDefault();
+
+ this.setState({ isContactModalOpen: true });
+ }
+
+ private _onDismissContactModal(): void {
+ this.setState({ isContactModalOpen: false });
+ }
+}