From 5df789bd0512b06d5a83476c7364aea05a1d1701 Mon Sep 17 00:00:00 2001 From: Fred Carlsen Date: Wed, 12 Dec 2018 15:45:38 +0100 Subject: Added contact modal --- .../website/ts/@next/components/blockIconLink.tsx | 36 ++-- packages/website/ts/@next/components/button.tsx | 4 +- .../website/ts/@next/components/modals/input.tsx | 65 +++++++ .../ts/@next/components/modals/modal_contact.tsx | 198 +++++++++++++++++++++ .../ts/@next/components/sections/landing/cta.tsx | 8 +- 5 files changed, 298 insertions(+), 13 deletions(-) create mode 100644 packages/website/ts/@next/components/modals/input.tsx create mode 100644 packages/website/ts/@next/components/modals/modal_contact.tsx (limited to 'packages/website/ts/@next/components') 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} - - {props.linkLabel} - + {props.linkUrl && + + {props.linkLabel} + + } + + {props.onClick && + + } ); 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` } `; -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 ( + + + + + ); +}); + +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` + 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 { + 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 ( + <> + + +
+ Contact the 0x Core Team + 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. + + + + + + + + + + + + + + + + + +
+ + + Thanks for contacting us. + We'll get back to you soon. If you need quick support in the meantime, reach out to the 0x team on Discord. + + +
+
+ + ); + } + 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` + 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` + 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) => (
( icon="coin" title="Wat help from the 0x team?" linkLabel="Get in Touch" - linkUrl="#" + onClick={props.onContactClick} />
); -- cgit