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 { Heading, Paragraph } from 'ts/components/text';
import { GlobalStyle } from 'ts/constants/globalStyle'; import { GlobalStyle } from 'ts/constants/globalStyle';
export enum ModalContactType {
General = 'GENERAL',
MarketMaker = 'MARKET_MAKER',
}
interface Props { interface Props {
theme?: GlobalStyle; theme?: GlobalStyle;
isOpen?: boolean; isOpen?: boolean;
onDismiss?: () => void; onDismiss?: () => void;
modalContactType: ModalContactType;
} }
interface FormProps { interface FormProps {
@@ -39,23 +45,30 @@ interface ErrorProps {
} }
export class ModalContact extends React.Component<Props> { export class ModalContact extends React.Component<Props> {
public static defaultProps = {
modalContactType: ModalContactType.General,
};
public state = { public state = {
isSubmitting: false, isSubmitting: false,
isSuccessful: false, isSuccessful: false,
errors: {}, errors: {},
}; };
// shared fields
public nameRef: React.RefObject<HTMLInputElement> = React.createRef(); public nameRef: React.RefObject<HTMLInputElement> = React.createRef();
public emailRef: React.RefObject<HTMLInputElement> = React.createRef(); public emailRef: React.RefObject<HTMLInputElement> = React.createRef();
public companyProjectRef: 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(); 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) { public constructor(props: Props) {
super(props); super(props);
} }
public render(): React.ReactNode { public render(): React.ReactNode {
const { isOpen, onDismiss } = this.props; const { isOpen, onDismiss } = this.props;
const { isSuccessful, errors } = this.state; const { isSuccessful, errors } = this.state;
return ( return (
<> <>
<DialogOverlay <DialogOverlay
@@ -68,9 +81,121 @@ export class ModalContact extends React.Component<Props> {
<Heading color={colors.textDarkPrimary} size={34} asElement="h2"> <Heading color={colors.textDarkPrimary} size={34} asElement="h2">
Contact the 0x Core Team Contact the 0x Core Team
</Heading> </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}> <Paragraph isMuted={true} color={colors.textDarkPrimary}>
If you're considering building on 0x, we're happy to answer your questions. Fill out the We'll get back to you soon. If you need quick support in the meantime, reach out to the
form so we can connect you with the right person to help you get started. 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> </Paragraph>
<InputRow> <InputRow>
<Input <Input
@@ -120,57 +245,48 @@ export class ModalContact extends React.Component<Props> {
errors={errors} errors={errors}
/> />
</InputRow> </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> { private async _onSubmitAsync(e: Event): Promise<void> {
e.preventDefault(); e.preventDefault();
const name = this.nameRef.current.value; let jsonBody;
const email = this.emailRef.current.value; if (this.props.modalContactType === ModalContactType.MarketMaker) {
const projectOrCompany = this.companyProjectRef.current.value; jsonBody = {
const link = this.linkRef.current.value; name: this.nameRef.current.value,
const comments = this.commentsRef.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 }); this.setState({ ...this.state, errors: [], isSubmitting: true });
const endpoint =
this.props.modalContactType === ModalContactType.MarketMaker ? '/market_maker_leads' : '/leads';
try { try {
// Disabling no-unbound method b/c no reason for _.isEmpty to be bound // Disabling no-unbound method b/c no reason for _.isEmpty to be bound
// tslint:disable:no-unbound-method // 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', method: 'post',
mode: 'cors', mode: 'cors',
credentials: 'same-origin', credentials: 'same-origin',
headers: { headers: {
'content-type': 'application/json; charset=utf-8', '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) { 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"}]} // Handle errors: {"errors":[{"location":"body","param":"name","msg":"Invalid value"},{"location":"body","param":"email","msg":"Invalid value"}]}
const InputRow = styled.div` const InputRow = styled.div`

View File

@@ -5,7 +5,7 @@ import { Banner } from 'ts/components/banner';
import { Button } from 'ts/components/button'; import { Button } from 'ts/components/button';
import { Action, Definition } from 'ts/components/definition'; import { Action, Definition } from 'ts/components/definition';
import { Hero } from 'ts/components/hero'; 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 { Section } from 'ts/components/newLayout';
import { SiteWrap } from 'ts/components/siteWrap'; import { SiteWrap } from 'ts/components/siteWrap';
import { WebsitePaths } from 'ts/types'; 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` }} mainCta={{ text: 'Explore the Docs', href: `${WebsitePaths.Wiki}#Market-Making-on-0x` }}
secondaryCta={{ text: 'Get in Touch', onClick: this._onOpenContactModal.bind(this) }} 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> </SiteWrap>
); );
} }