1- import { useState } from 'react' ;
1+ import { useState , useRef } from 'react' ;
2+ import { useRouter } from 'next/router' ;
23import 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+
415const 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+ 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- 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 ) }
0 commit comments