aboutsummaryrefslogtreecommitdiffstats
path: root/packages/website/ts/components/modals
diff options
context:
space:
mode:
Diffstat (limited to 'packages/website/ts/components/modals')
-rw-r--r--packages/website/ts/components/modals/input.tsx92
-rw-r--r--packages/website/ts/components/modals/modal_contact.tsx390
2 files changed, 0 insertions, 482 deletions
diff --git a/packages/website/ts/components/modals/input.tsx b/packages/website/ts/components/modals/input.tsx
deleted file mode 100644
index c72e53aa0..000000000
--- a/packages/website/ts/components/modals/input.tsx
+++ /dev/null
@@ -1,92 +0,0 @@
-import * as React from 'react';
-import styled from 'styled-components';
-
-export enum InputWidth {
- Half,
- Full,
-}
-
-interface InputProps {
- name: string;
- width?: InputWidth;
- label: string;
- type?: string;
- errors?: ErrorProps;
- isErrors?: boolean;
- required?: boolean;
-}
-
-interface ErrorProps {
- [key: string]: string;
-}
-
-export const Input = React.forwardRef((props: InputProps, ref?: React.Ref<HTMLInputElement>) => {
- const { name, label, type, errors } = props;
- const id = `input-${name}`;
- const componentType = type === 'textarea' ? 'textarea' : 'input';
- const isErrors = errors.hasOwnProperty(name) && errors[name] !== null;
- const errorMessage = isErrors ? errors[name] : null;
-
- return (
- <InputWrapper {...props}>
- <Label htmlFor={id}>{label}</Label>
- <StyledInput as={componentType} ref={ref} id={id} isErrors={isErrors} {...props} />
- {isErrors && <Error>{errorMessage}</Error>}
- </InputWrapper>
- );
-});
-
-Input.defaultProps = {
- width: InputWidth.Full,
- errors: {},
-};
-
-const StyledInput = styled.input`
- appearance: none;
- background-color: #fff;
- border: 1px solid #d5d5d5;
- color: #000;
- font-size: 1.294117647rem;
- padding: 16px 15px 14px;
- outline: none;
- width: 100%;
- min-height: ${props => props.type === 'textarea' && `120px`};
-
- background-color: ${(props: InputProps) => props.isErrors && `#FDEDED`};
- border-color: ${(props: InputProps) => props.isErrors && `#FD0000`};
-
- &::placeholder {
- color: #c3c3c3;
- }
-`;
-
-const InputWrapper = styled.div<InputProps>`
- position: relative;
- flex-grow: ${props => props.width === InputWidth.Full && 1};
- width: ${props => props.width === InputWidth.Half && `calc(50% - 15px)`};
-
- @media (max-width: 768px) {
- width: 100%;
- margin-bottom: 30px;
- }
-`;
-
-const Label = styled.label`
- color: #000;
- font-size: 1.111111111rem;
- line-height: 1.4em;
- margin-bottom: 10px;
- display: inline-block;
-`;
-
-const Error = styled.span`
- color: #fd0000;
- font-size: 0.833333333rem;
- line-height: 1em;
- display: inline-block;
- position: absolute;
- bottom: 0;
- left: 0;
- width: 100%;
- transform: translateY(24px);
-`;
diff --git a/packages/website/ts/components/modals/modal_contact.tsx b/packages/website/ts/components/modals/modal_contact.tsx
deleted file mode 100644
index 62c1062a3..000000000
--- a/packages/website/ts/components/modals/modal_contact.tsx
+++ /dev/null
@@ -1,390 +0,0 @@
-import * as _ from 'lodash';
-import * as React from 'react';
-import styled from 'styled-components';
-
-import { colors } from 'ts/style/colors';
-
-import { DialogContent, DialogOverlay } from '@reach/dialog';
-import '@reach/dialog/styles.css';
-
-import { Button } from 'ts/components/button';
-import { Icon } from 'ts/components/icon';
-import { Input, InputWidth } from 'ts/components/modals/input';
-import { Heading, Paragraph } from 'ts/components/text';
-import { GlobalStyle } from 'ts/constants/globalStyle';
-import { utils } from 'ts/utils/utils';
-
-export enum ModalContactType {
- General = 'GENERAL',
- MarketMaker = 'MARKET_MAKER',
-}
-
-interface Props {
- theme?: GlobalStyle;
- isOpen?: boolean;
- onDismiss?: () => void;
- modalContactType: ModalContactType;
-}
-
-interface FormProps {
- isSuccessful?: boolean;
- isSubmitting?: boolean;
-}
-
-interface ErrorResponseProps {
- param: string;
- location: string;
- msg: string;
-}
-
-interface ErrorResponse {
- errors: ErrorResponseProps[];
-}
-
-interface ErrorProps {
- [key: string]: string;
-}
-
-export class ModalContact extends React.Component<Props> {
- public static defaultProps = {
- modalContactType: ModalContactType.General,
- };
- public state = {
- isSubmitting: false,
- isSuccessful: false,
- errors: {},
- };
- // shared fields
- public nameRef: React.RefObject<HTMLInputElement> = React.createRef();
- public emailRef: React.RefObject<HTMLInputElement> = React.createRef();
- public companyProjectRef: React.RefObject<HTMLInputElement> = React.createRef();
- public commentsRef: React.RefObject<HTMLInputElement> = React.createRef();
- // general lead fields
- public linkRef: React.RefObject<HTMLInputElement> = React.createRef();
- // market maker lead fields
- public countryRef: React.RefObject<HTMLInputElement> = React.createRef();
- public fundSizeRef: React.RefObject<HTMLInputElement> = React.createRef();
- public constructor(props: Props) {
- super(props);
- }
- public render(): React.ReactNode {
- const { isOpen, onDismiss } = this.props;
- const { isSuccessful, errors } = this.state;
- return (
- <>
- <DialogOverlay
- style={{ background: 'rgba(0, 0, 0, 0.75)', zIndex: 30 }}
- isOpen={isOpen}
- onDismiss={onDismiss}
- >
- <StyledDialogContent>
- <Form onSubmit={this._onSubmitAsync.bind(this)} isSuccessful={isSuccessful}>
- <Heading color={colors.textDarkPrimary} size={34} asElement="h2">
- Contact the 0x Core Team
- </Heading>
- {this._renderFormContent(errors)}
- <ButtonRow>
- <Button
- color="#5C5C5C"
- isNoBorder={true}
- isTransparent={true}
- type="button"
- onClick={this.props.onDismiss}
- >
- Back
- </Button>
- <Button>Submit</Button>
- </ButtonRow>
- </Form>
- <Confirmation isSuccessful={isSuccessful}>
- <Icon name="rocketship" size="large" margin={[0, 0, 'default', 0]} />
- <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>
- </>
- );
- }
- public _renderFormContent(errors: ErrorProps): React.ReactNode {
- switch (this.props.modalContactType) {
- case ModalContactType.MarketMaker:
- return this._renderMarketMakerFormContent(errors);
- case ModalContactType.General:
- default:
- return this._renderGeneralFormContent(errors);
- }
- }
- private _renderMarketMakerFormContent(errors: ErrorProps): React.ReactNode {
- return (
- <>
- <Paragraph isMuted={true} color={colors.textDarkPrimary}>
- If you’re considering market making 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}
- ref={this.nameRef}
- required={true}
- errors={errors}
- />
- <Input
- name="email"
- label="Your email"
- type="email"
- ref={this.emailRef}
- required={true}
- errors={errors}
- width={InputWidth.Half}
- />
- </InputRow>
- <InputRow>
- <Input
- name="country"
- label="Country of Location"
- type="text"
- ref={this.countryRef}
- required={true}
- errors={errors}
- />
- </InputRow>
- <InputRow>
- <Input
- name="fundSize"
- label="Fund Size"
- type="text"
- ref={this.fundSizeRef}
- required={true}
- errors={errors}
- />
- </InputRow>
- <InputRow>
- <Input
- name="companyOrProject"
- label="Name of your project / company"
- type="text"
- ref={this.companyProjectRef}
- required={false}
- errors={errors}
- />
- </InputRow>
- <InputRow>
- <Input
- name="comments"
- label="What is prompting you to reach out?"
- type="textarea"
- ref={this.commentsRef}
- required={false}
- errors={errors}
- />
- </InputRow>
- </>
- );
- }
- private _renderGeneralFormContent(errors: ErrorProps): React.ReactNode {
- return (
- <>
- <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}
- ref={this.nameRef}
- required={true}
- errors={errors}
- />
- <Input
- name="email"
- label="Your email"
- type="email"
- ref={this.emailRef}
- required={true}
- errors={errors}
- width={InputWidth.Half}
- />
- </InputRow>
- <InputRow>
- <Input
- name="companyOrProject"
- label="Name of your project / company"
- type="text"
- ref={this.companyProjectRef}
- required={true}
- errors={errors}
- />
- </InputRow>
- <InputRow>
- <Input
- name="link"
- label="Do you have any documentation or a website?"
- type="text"
- ref={this.linkRef}
- errors={errors}
- />
- </InputRow>
- <InputRow>
- <Input
- name="comments"
- label="Anything else?"
- type="textarea"
- ref={this.commentsRef}
- errors={errors}
- />
- </InputRow>
- </>
- );
- }
- private async _onSubmitAsync(e: Event): Promise<void> {
- e.preventDefault();
-
- let jsonBody;
- if (this.props.modalContactType === ModalContactType.MarketMaker) {
- jsonBody = {
- name: this.nameRef.current.value,
- email: this.emailRef.current.value,
- country: this.countryRef.current.value,
- fundSize: this.fundSizeRef.current.value,
- projectOrCompany: this.companyProjectRef.current.value,
- comments: this.commentsRef.current.value,
- };
- } else {
- jsonBody = {
- name: this.nameRef.current.value,
- email: this.emailRef.current.value,
- projectOrCompany: this.companyProjectRef.current.value,
- link: this.linkRef.current.value,
- comments: this.commentsRef.current.value,
- };
- }
-
- this.setState({ ...this.state, errors: [], isSubmitting: true });
-
- const endpoint =
- this.props.modalContactType === ModalContactType.MarketMaker ? '/market_maker_leads' : '/leads';
-
- try {
- // Disabling no-unbound method b/c no reason for _.isEmpty to be bound
- // tslint:disable:no-unbound-method
- const response = await fetch(`${utils.getBackendBaseUrl()}${endpoint}`, {
- method: 'post',
- mode: 'cors',
- credentials: 'same-origin',
- headers: {
- 'content-type': 'application/json; charset=utf-8',
- },
- body: JSON.stringify(_.omitBy(jsonBody, _.isEmpty)),
- });
-
- if (!response.ok) {
- const errorResponse: ErrorResponse = await response.json();
- const errors = this._parseErrors(errorResponse.errors);
- this.setState({ ...this.state, isSubmitting: false, errors });
-
- throw new Error('Request failed');
- }
-
- this.setState({ ...this.state, isSuccessful: true });
- } catch (e) {
- // Empty block
- }
- }
- private _parseErrors(errors: ErrorResponseProps[]): ErrorProps {
- const initialValue: {} = {};
- return _.reduce(
- errors,
- (hash: ErrorProps, error: ErrorResponseProps) => {
- const { param, msg } = error;
- const key = param;
- hash[key] = msg;
-
- return hash;
- },
- initialValue,
- );
- }
-}
-
-// Handle errors: {"errors":[{"location":"body","param":"name","msg":"Invalid value"},{"location":"body","param":"email","msg":"Invalid value"}]}
-
-const InputRow = styled.div`
- width: 100%;
- flex: 0 0 auto;
-
- @media (min-width: 768px) {
- display: flex;
- justify-content: space-between;
- margin-bottom: 30px;
- }
-`;
-
-const ButtonRow = styled(InputRow)`
- @media (max-width: 768px) {
- display: flex;
- flex-direction: column;
-
- button:nth-child(1) {
- order: 2;
- }
-
- button:nth-child(2) {
- order: 1;
- margin-bottom: 10px;
- }
- }
-`;
-
-const StyledDialogContent = styled(DialogContent)`
- position: relative;
- max-width: 800px;
- background-color: #f6f6f6 !important;
- padding: 60px 60px !important;
-
- @media (max-width: 768px) {
- width: calc(100vw - 40px) !important;
- margin: 40px auto !important;
- padding: 30px 30px !important;
- }
-`;
-
-const Form = styled.form<FormProps>`
- position: relative;
- transition: opacity 0.3s ease-in-out, visibility 0.3s 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.3s ease-in-out, visibility 0.3s ease-in-out;
- transition-delay: 0.4s;
- padding: 60px 60px;
- transform: translateY(-50%);
- opacity: ${props => (props.isSuccessful ? `1` : `0`)};
- visibility: ${props => (props.isSuccessful ? 'visible' : `hidden`)};
-
- p {
- max-width: 492px;
- margin-left: auto;
- margin-right: auto;
- }
-`;