Skip to content

Commit 9a5ee94

Browse files
authored
Merge pull request #386 from amplication/fix/blog-subscribe-form
fix:blog subscribe form
2 parents 594584e + 3446c58 commit 9a5ee94

File tree

4 files changed

+88
-183
lines changed

4 files changed

+88
-183
lines changed

.vscode/settings.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
11
{
2-
"cSpell.words": ["Microservices"]
2+
"cSpell.words": [
3+
"HUBSPOT",
4+
"Microservices"
5+
]
36
}

components/Common/HubSpotForm/index.jsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ const SKIP_SUBMIT_TEST = false;
77
const HUBSPOT_FORM_BASE_URL =
88
'https://api.hsforms.com/submissions/v3/integration/submit/';
99

10-
const HusSpotForm = ({
10+
const HubSpotForm = ({
1111
children,
1212
hubSpotPortalId,
1313
hubSpotFormId,
@@ -146,12 +146,12 @@ const HusSpotForm = ({
146146
);
147147
};
148148

149-
HusSpotForm.propTypes = {
149+
HubSpotForm.propTypes = {
150150
children: PropTypes.any,
151151
hubSpotPortalId: PropTypes.string,
152152
hubSpotFormId: PropTypes.string,
153153
successMessage: PropTypes.string,
154154
pageName: PropTypes.string,
155155
};
156156

157-
export default HusSpotForm;
157+
export default HubSpotForm;

components/Common/SubscribeForm/index.jsx

Lines changed: 80 additions & 179 deletions
Original file line numberDiff line numberDiff line change
@@ -1,85 +1,76 @@
1-
import {useState} from 'react';
1+
import {useState, useRef} from 'react';
2+
import {useRouter} from 'next/router';
23
import PropTypes from 'prop-types';
34

5+
const SKIP_SUBMIT_TEST = false;
6+
7+
const HUBSPOT_FORM_BASE_URL =
8+
'https://api.hsforms.com/submissions/v3/integration/submit/';
9+
const HUBSPOT_PORTAL_ID = '25691669';
10+
const HUBSPOT_FORM_ID = '3f7e736b-6f89-4a11-94e4-eac111c43486';
11+
12+
const SUCCESS_MESSAGE = 'Thank you for signing up for our mailing list!';
13+
const ERROR_MESSAGE = 'Something went wrong. Please try again later.';
14+
415
const SubscribeForm = ({isCompactView}) => {
5-
const fieldErrorMessage = 'This field is required';
6-
const [email, setEmail] = useState('');
7-
const [emailFieldError, setEmailFieldError] = useState(false);
8-
const [name, setName] = useState('');
9-
const [nameFieldError, setNameFieldError] = useState(false);
10-
const [source, setSource] = useState('');
11-
const [sourceFieldError, setSourceFieldError] = useState(false);
12-
const [formSuccess, setFormSuccess] = useState(null);
13-
const [isWaitingForResponse, setIsWaitingForResponse] = useState(false);
14-
const [afterFormSubmitMessage, setAfterFormSubmitMessage] = useState('');
16+
const [successMsg, setSuccessMsg] = useState('');
17+
const [formIsSending, setFormIsSending] = useState(false);
18+
const router = useRouter();
19+
20+
const form = useRef(null);
1521

1622
const submitSubscriptionForm = async e => {
1723
e.preventDefault();
24+
const formData = new FormData(form.current);
1825

19-
setIsWaitingForResponse(true);
20-
21-
// Validation
22-
let isValid = true;
23-
if (!email) {
24-
isValid = false;
25-
setEmailFieldError(true);
26-
} else {
27-
setEmailFieldError(false);
28-
}
29-
if (!name) {
30-
isValid = false;
31-
setNameFieldError(true);
32-
} else {
33-
setNameFieldError(false);
34-
}
35-
if (!source) {
36-
isValid = false;
37-
setSourceFieldError(true);
38-
} else {
39-
setSourceFieldError(false);
40-
}
41-
if (!isValid) {
42-
setIsWaitingForResponse(false);
43-
return;
44-
}
45-
setAfterFormSubmitMessage('');
46-
setFormSuccess(null);
47-
48-
const host = '/api/subscribe';
49-
const body = {
50-
EMAIL: email,
51-
NAME: name,
52-
SOURCE: source,
53-
};
26+
const fields = [];
27+
[...formData].forEach(item => {
28+
if (item[1]) {
29+
fields.push({
30+
name: item[0],
31+
value: item[1],
32+
});
33+
}
34+
});
5435

55-
try {
56-
const response = await fetch(host, {
57-
method: 'POST',
58-
body: JSON.stringify(body),
59-
});
60-
const data = await response.json();
61-
if (data.result !== 'success' || !('result' in data)) {
62-
setAfterFormSubmitMessage(
63-
'msg' in data ? data.msg : 'Something went wrong'
64-
);
65-
setFormSuccess(false);
66-
} else {
67-
setAfterFormSubmitMessage(
68-
'Thank you for signing up for our mailing list!'
36+
setFormIsSending(true);
37+
if (!SKIP_SUBMIT_TEST) {
38+
try {
39+
const response = await fetch(
40+
`${HUBSPOT_FORM_BASE_URL}/${HUBSPOT_PORTAL_ID}/${HUBSPOT_FORM_ID}`,
41+
{
42+
method: 'POST',
43+
headers: {
44+
'Content-Type': 'application/json',
45+
},
46+
body: JSON.stringify({
47+
submittedAt: Date.now(),
48+
fields: fields,
49+
context: {
50+
pageUri: router.asPath,
51+
pageName: 'Blog Page',
52+
},
53+
}),
54+
}
6955
);
70-
setFormSuccess(true);
56+
const data = await response.json();
57+
if (data.inlineMessage) {
58+
setSuccessMsg(SUCCESS_MESSAGE);
59+
}
60+
61+
setFormIsSending(false);
62+
} catch (e) {
63+
setSuccessMsg(ERROR_MESSAGE);
64+
console.log('error', e);
7165
}
72-
} catch (e) {
73-
console.log('err', e);
74-
setAfterFormSubmitMessage('Something went wrong');
75-
setFormSuccess(false);
66+
} else {
67+
setSuccessMsg(SUCCESS_MESSAGE);
7668
}
77-
setIsWaitingForResponse(false);
7869
};
7970

8071
let loaderClasses =
8172
'w-full h-full absolute l-0 t-0 rounded-2xl transition-all opacity-50 pointer-events-none';
82-
loaderClasses += isWaitingForResponse
73+
loaderClasses += formIsSending
8374
? ' bg-purple-light z-10 pointer-events-auto'
8475
: '';
8576

@@ -88,7 +79,7 @@ const SubscribeForm = ({isCompactView}) => {
8879
if (isCompactView) {
8980
containerClasses +=
9081
' laptop:flex-col laptop:justify-start laptop:items-stretch laptop:px-8';
91-
if (formSuccess) {
82+
if (successMsg) {
9283
containerClasses += ' laptop:py-20';
9384
} else {
9485
containerClasses += ' laptop:pt-20 laptop:pb-[120px]';
@@ -134,120 +125,40 @@ const SubscribeForm = ({isCompactView}) => {
134125
<div className="bg-noise">
135126
<div className={loaderClasses}></div>
136127
<div className={containerClasses}>
137-
{formSuccess && (
128+
{successMsg && (
138129
<h2 className="w-full text-center text-white text-2xl font-bold">
139-
{afterFormSubmitMessage}
130+
{successMsg}
140131
</h2>
141132
)}
142-
{!formSuccess && (
133+
{!successMsg && (
143134
<>
144135
<div className={titleClasses}>
145136
Sign up to stay up-to-date with our latest developments. We
146137
promise not to spam you.
147138
</div>
148139
<form
149140
className={formClasses}
150-
onSubmit={e => submitSubscriptionForm(e)}
141+
onSubmit={submitSubscriptionForm}
142+
ref={form}
151143
>
152-
<div
144+
<input
145+
required
146+
type="email"
147+
name="email"
148+
placeholder="[email protected]"
153149
className={
154-
emailFieldError
155-
? fieldContainerClasses
156-
: fieldContainerClasses + ' pb-5'
150+
'my-2 leading-input focus:border-purple !shadow-hidden block w-full rounded-lg border border-solid bg-purple-dark py-2 pl-3 pr-8 font-poppins text-sm text-white placeholder:text-gray'
157151
}
158-
>
159-
<div className="relative">
160-
<input
161-
type="email"
162-
value={email}
163-
onChange={e => setEmail(e.target.value)}
164-
name="EMAIL"
165-
placeholder="[email protected]"
166-
className={`leading-input focus:border-purple !shadow-hidden block w-full rounded-lg border border-solid bg-purple-dark py-2 pl-3 pr-8 font-poppins text-sm text-white placeholder:text-gray ${
167-
emailFieldError ? '' : 'hover:border-purple'
168-
} ${emailFieldError ? 'border-pink' : 'border-lite'}`}
169-
/>
170-
{email && (
171-
<span
172-
className="absolute right-4 top-[50%] translate-y-[-50%] cursor-pointer text-sm animate-fadeIn text-white"
173-
onClick={() => setEmail('')}
174-
>
175-
176-
</span>
177-
)}
178-
</div>
179-
{emailFieldError && (
180-
<span className="text-left block w-full text-xs text-pink py-0.5 ">
181-
{fieldErrorMessage}
182-
</span>
183-
)}
184-
</div>
185-
<div
152+
/>
153+
<input
154+
type="text"
155+
placeholder="How did you hear about us"
156+
name="how_did_you_hear_about_us
157+
"
186158
className={
187-
nameFieldError
188-
? fieldContainerClasses
189-
: fieldContainerClasses + ' pb-5'
159+
'my-2 leading-input focus:border-purple !shadow-hidden block w-full rounded-lg border border-solid bg-purple-dark py-2 pl-3 pr-8 font-poppins text-sm text-white placeholder:text-gray'
190160
}
191-
>
192-
<div className="relative">
193-
<input
194-
type="text"
195-
value={name}
196-
onChange={e => setName(e.target.value)}
197-
placeholder="Name"
198-
name="NAME"
199-
className={`leading-input focus:border-purple !shadow-hidden block w-full rounded-lg border border-solid bg-purple-dark py-2 pl-3 pr-8 font-poppins text-sm text-white placeholder:text-gray ${
200-
nameFieldError ? '' : 'hover:border-purple'
201-
} ${nameFieldError ? 'border-pink' : 'border-lite'}`}
202-
/>
203-
{name && (
204-
<span
205-
className="absolute right-4 top-[50%] translate-y-[-50%] cursor-pointer text-sm animate-fadeIn text-white"
206-
onClick={() => setName('')}
207-
>
208-
209-
</span>
210-
)}
211-
</div>
212-
{nameFieldError && (
213-
<span className="text-left block w-full text-xs text-pink py-0.5 ">
214-
{fieldErrorMessage}
215-
</span>
216-
)}
217-
</div>
218-
<div
219-
className={
220-
sourceFieldError
221-
? fieldContainerClasses + ' pb-2'
222-
: fieldContainerClasses + ' pb-7'
223-
}
224-
>
225-
<div className="relative">
226-
<input
227-
type="text"
228-
value={source}
229-
onChange={e => setSource(e.target.value)}
230-
placeholder="How did you hear about us"
231-
name="source"
232-
className={`leading-input focus:border-purple !shadow-hidden block w-full rounded-lg border border-solid bg-purple-dark py-2 pl-3 pr-8 font-poppins text-sm text-white placeholder:text-gray ${
233-
sourceFieldError ? '' : 'hover:border-purple'
234-
} ${sourceFieldError ? 'border-pink' : 'border-lite'}`}
235-
/>
236-
{source && (
237-
<span
238-
className="absolute right-4 top-[50%] translate-y-[-50%] cursor-pointer text-sm animate-fadeIn text-white"
239-
onClick={() => setSource('')}
240-
>
241-
242-
</span>
243-
)}
244-
</div>
245-
{sourceFieldError && (
246-
<span className="text-left block w-full text-xs text-pink py-0.5 ">
247-
{fieldErrorMessage}
248-
</span>
249-
)}
250-
</div>
161+
/>
251162
<div
252163
className={
253164
isCompactView
@@ -256,23 +167,13 @@ const SubscribeForm = ({isCompactView}) => {
256167
}
257168
>
258169
<input
259-
type="hidden"
260-
name="b_d4caec21be60d280924827504_49d58a40fc"
261-
tabIndex="-1"
262-
/>
263-
<input
170+
disabled={formIsSending ? 'disabled' : ''}
264171
type="submit"
265172
value="Subscribe"
266173
name="subscribe"
267-
className="w-full cursor-pointer flex justify-center items-center bg-purple-bright text-white font-poppins font-normal text-center transition-all duration-300 rounded py-2 px-5 mt-2 laptop:mt-0 hover:bg-purple-bright-hover"
174+
className="my-2 w-full cursor-pointer flex justify-center items-center bg-purple-bright text-white font-poppins font-normal text-center transition-all duration-300 rounded py-2 px-5 hover:bg-purple-bright-hover"
268175
/>
269176
</div>
270-
{formSuccess === false && (
271-
<div
272-
className="w-full laptop:my-1 text-left text-xs text-pink py-1.5"
273-
dangerouslySetInnerHTML={{__html: afterFormSubmitMessage}}
274-
></div>
275-
)}
276177
</form>
277178
</>
278179
)}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Subproject commit d98eb7c9906423940bc73968297378290d8feecd

0 commit comments

Comments
 (0)