Skip to content

Commit

Permalink
Hubspot forms API (aptible#260)
Browse files Browse the repository at this point in the history
* Update node-version

* Hubspot forms helper library

* Update forms to use Hubspot library
  • Loading branch information
mjp authored Mar 21, 2022
1 parent b4f6d5c commit ff54e88
Show file tree
Hide file tree
Showing 7 changed files with 129 additions and 103 deletions.
2 changes: 1 addition & 1 deletion .node-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
10.24.1
12.22.9
33 changes: 7 additions & 26 deletions src/components/aws-activate-form/ActivateForm.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,13 @@ import { Helmet } from 'react-helmet';
import cn from 'classnames';
import styles from './ActivateForm.module.css';
import buttonStyles from '../buttons/Button.module.css';
import { event, identify, trackOnLinkedIn } from '../../lib/aptible/analytics';
import { querystring } from '../../lib/util';
import { event } from '../../lib/aptible/analytics';
import { submitHubspotForm, HUBSPOT_FORM_AWS_ACTIVATE } from '../../lib/hubspot.js';

const AWS_ACTIVATE_UNIQUE_CODE = `A3POPC`;

const injectedQueryParams = [
'utm_campaign',
'utm_medium',
'utm_source',
'utm_term',
AWS_ACTIVATE_UNIQUE_CODE,
];

Expand All @@ -28,11 +25,6 @@ const options = [
'None',
];

const validateEmail = email => {
if (!email) return { ok: false, message: 'email cannot be empty' };
return { ok: true, message: '' };
};

export const ActivateForm = ({
id,
eventName='AWS Activate Application Submitted',
Expand All @@ -55,13 +47,12 @@ export const ActivateForm = ({
const queryParams = queryString.parse(querystring());

const onSubmit = () => {
const result = validateEmail(email);
const result = submitHubspotForm(HUBSPOT_FORM_AWS_ACTIVATE, email, true);
if (!result.ok) {
setError(result.message);
return;
}
identify(email);
event('Email Collected', { formId: id });

event(eventName, {
name,
email,
Expand All @@ -72,7 +63,6 @@ export const ActivateForm = ({
});
setSubmitted(true);
setError('');
trackOnLinkedIn();
setTimeout(onSuccess, 500);
};

Expand All @@ -88,14 +78,6 @@ export const ActivateForm = ({
/>
</Helmet>

<iframe
title="AWS Activate Capture Form"
name="captureFrame"
height="0"
width="0"
style={{ display: 'none' }}
/>

{submitted && (
<div className={styles.submissionNotification}>{successText}</div>
)}
Expand All @@ -104,10 +86,8 @@ export const ActivateForm = ({
className={styles.leadFormContainer}
style={{ opacity: submitted ? 0 : 1 }}
>
<form
<div
id={id}
onSubmit={onSubmit}
target="captureFrame"
className={styles.leadForm}
>
<h5>Submit Your Application</h5>
Expand Down Expand Up @@ -229,6 +209,7 @@ export const ActivateForm = ({
<button
className={cn(buttonStyles.button, styles.button)}
type="submit"
onClick={onSubmit}
>
{btnText}
</button>
Expand All @@ -242,7 +223,7 @@ export const ActivateForm = ({
<p class="S">{disclaimer}</p>
)}

</form>
</div>
<div className={styles.error}>{error ? error : ''}</div>
</div>
</div>
Expand Down
4 changes: 2 additions & 2 deletions src/components/aws-activate-form/ActivateForm.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
overflow-y: scroll;
}

.leadFormContainer form {
.leadFormContainer > div {
display: flex;
flex-direction: column;
width: 100%;
Expand Down Expand Up @@ -134,7 +134,7 @@
}

@media (--mobile) {
.leadFormContainer form {
.leadFormContainer > div {
flex-direction: column;
justify-content: flex-start;
width: 100%;
Expand Down
42 changes: 12 additions & 30 deletions src/components/lead-form/LeadForm.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,9 @@
import * as queryString from 'query-string';
import React, { useState } from 'react';
import { navigate } from 'gatsby'
import cn from 'classnames';
import styles from './LeadForm.module.css';
import buttonStyles from '../buttons/Button.module.css';
import { event, identify, trackOnLinkedIn } from '../../lib/aptible/analytics';
import { querystring } from '../../lib/util';

const utmKeywords = ['utm_campaign', 'utm_medium', 'utm_source', 'utm_term'];

const validateEmail = email => {
if (!email) return { ok: false, message: 'email cannot be empty' };
return { ok: true, message: '' };
};
import { submitHubspotForm, HUBSPOT_FORM_DEMO } from '../../lib/hubspot.js';

export const LeadForm = ({
id,
Expand All @@ -26,20 +17,22 @@ export const LeadForm = ({
const [submitted, setSubmitted] = useState(false);
const [email, setEmail] = useState('');
const [error, setError] = useState('');
const queryParams = queryString.parse(querystring());
const shouldShowSuccessMessage = !scheduleDemoOnSubmit && submitted;

const onKeypress = (e) => {
if (e.key === 'Enter') {
onSubmit();
}
};

const onSubmit = () => {
const result = validateEmail(email);
const result = submitHubspotForm(HUBSPOT_FORM_DEMO, email, true);
if (!result.ok) {
setError(result.message);
return;
}
identify(email);
event('Email Collected', { formId: id });
setSubmitted(true);
setError('');
trackOnLinkedIn();
onSuccess();

if (scheduleDemoOnSubmit) {
Expand All @@ -49,41 +42,30 @@ export const LeadForm = ({

return (
<div>
<iframe
title="Lead Form"
name="captureFrame"
height="0"
width="0"
style={{ display: 'none' }}
/>

<div
className={styles.leadFormContainer}
style={{ opacity: submitted ? 0 : 1 }}
>
<form
<div
id={id}
onSubmit={onSubmit}
target="captureFrame"
className={styles.leadForm}
>
{utmKeywords.map(k => (
<input hidden readOnly name={k} key={k} value={queryParams[k]} />
))}
<input
required
className={styles.leadFormInput}
onKeyPress={onKeypress}
onChange={e => setEmail(e.target.value)}
type="email"
placeholder={inputPlaceholder}
/>
<button
className={cn(buttonStyles.button, styles.button)}
type="submit"
onClick={onSubmit}
>
{btnText}
</button>
</form>
</div>
<div className={styles.error}>{error ? error : ''}</div>
</div>

Expand Down
55 changes: 13 additions & 42 deletions src/components/signup-form/SignupForm.js
Original file line number Diff line number Diff line change
@@ -1,26 +1,8 @@
import * as queryString from 'query-string';
import React, { useState } from 'react';
import cn from 'classnames';
import styles from './SignupForm.module.css';
import buttonStyles from '../buttons/Button.module.css';
import { event, identify, trackOnLinkedIn } from '../../lib/aptible/analytics';
import { querystring } from '../../lib/util';

const utmKeywords = ['utm_campaign', 'utm_medium', 'utm_source', 'utm_term'];
const freeEmailDomains = ['gmail.com', 'yahoo.com', 'hotmail.com'];

const validateEmail = (email, allowPersonalEmails) => {
if (!email) return { ok: false, message: 'email cannot be empty' };

if (!allowPersonalEmails) {
const emailTokens = email.split('@');
if (emailTokens.length > 1 && freeEmailDomains.indexOf(emailTokens[1]) !== -1) {
return { ok: false, message: 'Please use your work email address' };
}
}

return { ok: true, message: '' };
};
import { submitHubspotForm, HUBSPOT_FORM_PRODUCT_SIGNUP } from '../../lib/hubspot.js';

export const SignupForm = ({
id,
Expand All @@ -32,19 +14,22 @@ export const SignupForm = ({
const [submitted, setSubmitted] = useState(false);
const [email, setEmail] = useState('');
const [error, setError] = useState('');
const queryParams = queryString.parse(querystring());

const onKeypress = (e) => {
if (e.key === 'Enter') {
onSubmit();
}
};

const onSubmit = () => {
const result = validateEmail(email, allowPersonalEmails);
const result = submitHubspotForm(HUBSPOT_FORM_PRODUCT_SIGNUP, email, allowPersonalEmails);
if (!result.ok) {
setError(result.message);
return;
}
identify(email);
event('Email Collected', { formId: id });

setSubmitted(true);
setError('');
trackOnLinkedIn();
onSuccess();

// Give time for HubSpot & analytics to fire
Expand All @@ -55,41 +40,27 @@ export const SignupForm = ({

return (
<div>
<iframe
title="Signup Form"
name="captureFrame"
height="0"
width="0"
style={{ display: 'none' }}
/>

<div
className={styles.signupFormContainer}
style={{ opacity: submitted ? 0 : 1 }}
>
<form
id={id}
onSubmit={onSubmit}
target="captureFrame"
className={styles.signupForm}
>
{utmKeywords.map(k => (
<input hidden readOnly name={k} key={k} value={queryParams[k]} />
))}
<div className={styles.signupForm} id={id}>
<input
required
className={styles.signupFormInput}
onKeyPress={onKeypress}
onChange={e => setEmail(e.target.value)}
type="email"
placeholder={inputPlaceholder}
/>
<button
className={cn(buttonStyles.button, styles.button)}
type="submit"
onClick={onSubmit}
>
{btnText}
</button>
</form>
</div>
<div className={styles.error}>{error ? error : ''}</div>
</div>
</div>
Expand Down
4 changes: 2 additions & 2 deletions src/components/signup-form/SignupForm.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
margin: 0;
transition: opacity 300ms;
}
.signupFormContainer form {
.signupFormContainer > div {
display: flex;
flex-direction: row;
justify-content: space-between;
Expand Down Expand Up @@ -57,7 +57,7 @@
border-radius: 8px
}

.signupFormContainer form {
.signupFormContainer > div {
flex-direction: column;
justify-content: flex-start;
width: 100%;
Expand Down
Loading

0 comments on commit ff54e88

Please sign in to comment.