feat(website): implement market maker form

This commit is contained in:
Brandon Millman 2019-01-06 20:45:46 -08:00
parent 99b6ca5b4f
commit 5e8da70eae
2 changed files with 184 additions and 63 deletions

View File

@ -13,10 +13,16 @@ import { Input, InputWidth } from 'ts/components/modals/input';
import { Heading, Paragraph } from 'ts/components/text';
import { GlobalStyle } from 'ts/constants/globalStyle';
export enum ModalContactType {
General = 'GENERAL',
MarketMaker = 'MARKET_MAKER',
}
interface Props {
theme?: GlobalStyle;
isOpen?: boolean;
onDismiss?: () => void;
modalContactType: ModalContactType;
}
interface FormProps {
@ -39,23 +45,30 @@ interface ErrorProps {
}
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 linkRef: 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
@ -68,9 +81,121 @@ export class ModalContact extends React.Component<Props> {
<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}>
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.
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 youre considering market making on 0x, were 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
@ -120,57 +245,48 @@ export class ModalContact extends React.Component<Props> {
errors={errors}
/>
</InputRow>
<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>
</>
);
}
private async _onSubmitAsync(e: Event): Promise<void> {
e.preventDefault();
const name = this.nameRef.current.value;
const email = this.emailRef.current.value;
const projectOrCompany = this.companyProjectRef.current.value;
const link = this.linkRef.current.value;
const comments = this.commentsRef.current.value;
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('https://website-api.0xproject.com/leads', {
const response = await fetch(`https://website-api.0xproject.com${endpoint}`, {
method: 'post',
mode: 'cors',
credentials: 'same-origin',
headers: {
'content-type': 'application/json; charset=utf-8',
},
body: JSON.stringify(_.omitBy({ name, email, projectOrCompany, link, comments }, _.isEmpty)),
body: JSON.stringify(_.omitBy(jsonBody, _.isEmpty)),
});
if (!response.ok) {
@ -201,6 +317,7 @@ export class ModalContact extends React.Component<Props> {
);
}
}
// Handle errors: {"errors":[{"location":"body","param":"name","msg":"Invalid value"},{"location":"body","param":"email","msg":"Invalid value"}]}
const InputRow = styled.div`

View File

@ -5,7 +5,7 @@ import { Banner } from 'ts/components/banner';
import { Button } from 'ts/components/button';
import { Action, Definition } from 'ts/components/definition';
import { Hero } from 'ts/components/hero';
import { ModalContact } from 'ts/components/modals/modal_contact';
import { ModalContact, ModalContactType } from 'ts/components/modals/modal_contact';
import { Section } from 'ts/components/newLayout';
import { SiteWrap } from 'ts/components/siteWrap';
import { WebsitePaths } from 'ts/types';
@ -125,7 +125,11 @@ export class NextMarketMaker extends React.Component<NextMarketMakerProps> {
mainCta={{ text: 'Explore the Docs', href: `${WebsitePaths.Wiki}#Market-Making-on-0x` }}
secondaryCta={{ text: 'Get in Touch', onClick: this._onOpenContactModal.bind(this) }}
/>
<ModalContact isOpen={this.state.isContactModalOpen} onDismiss={this._onDismissContactModal} />
<ModalContact
isOpen={this.state.isContactModalOpen}
onDismiss={this._onDismissContactModal}
modalContactType={ModalContactType.MarketMaker}
/>
</SiteWrap>
);
}