From 82bb0e7440b7b840081fe7ba515cdd3ad2f73466 Mon Sep 17 00:00:00 2001 From: Aizizi Yigaimu Date: Fri, 13 Dec 2019 13:47:38 -0500 Subject: [PATCH 1/3] Add form validation, mailchimp subscription --- src/AddressSearch.js | 174 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 165 insertions(+), 9 deletions(-) diff --git a/src/AddressSearch.js b/src/AddressSearch.js index 10c96d579..51712cf9a 100644 --- a/src/AddressSearch.js +++ b/src/AddressSearch.js @@ -1,8 +1,9 @@ -import React from "react"; -import { Row, Col, Button} from 'reactstrap'; +import React, { useState } from "react"; +import { Row, Col, Button, Input, Modal, ModalHeader, ModalBody, ModalFooter } from 'reactstrap'; import './index.css'; import Geocoder from 'react-mapbox-gl-geocoder'; import location from './utils/images/location.svg'; // with import +import jsonp from "jsonp"; const mapAccess = { mapboxApiAccessToken: process.env.REACT_APP_MAPBOX_TOKEN @@ -21,6 +22,14 @@ export default class AddressSearch extends React.Component { answer: this.props.answer, loadingAddressSearchBtn: false, disabledAddressSearchBtn: true, + showModal: true, + form: { + FNAME: '', + LNAME: '', + EMAIL: '', + PHONE: '', + }, + subscribed: false, }; } componentDidMount () { @@ -54,6 +63,7 @@ export default class AddressSearch extends React.Component { this.setState({ loadingAddressSearchBtn: true, disabledAddressSearchBtn: true, + showModal: true, }); this.props.nextQuestion('addressSearch', this.state.answer, this.state.answer); } @@ -65,8 +75,82 @@ export default class AddressSearch extends React.Component { }); } + validateContact() { + const emptyFields = []; + const invalidFields = []; + const errorMessage = []; + const validFirstName = /^[a-zA-Z ]{2,30}$/; + const validLastName = /^[a-zA-Z ]{2,30}$/; + const validEmail = /^$|^[a-zA-Z0-9]+@[a-zA-Z0-9]+\.[A-Za-z]+$/; + const validPhone = /^$|^\(?(\d{3})\)?[- ]?(\d{3})[- ]?(\d{4})$/; + + if (this.state.form.FNAME.toString().replace(/^\s+|\s+$/g, '') === '') { + emptyFields.push('First Name'); + } + if (this.state.form.LNAME.toString().replace(/^\s+|\s+$/g, '') === '') { + emptyFields.push('Last Name'); + } + if (this.state.form.EMAIL.toString().replace(/^\s+|\s+$/g, '') === '') { + emptyFields.push('Email address'); + } + if (emptyFields.length > 0) { + errorMessage.push(`Please fill in:\n${emptyFields.join('\n')}`); + alert(errorMessage); + return false; + } + if (this.state.form.PHONE.toString().replace(/^\s+|\s+$/g, '') !== '' && + !(validPhone.test(this.state.form.PHONE))) { + invalidFields.push('Phone number'); + } + if (!(validFirstName.test(this.state.form.FNAME))) { + invalidFields.push('First Name'); + } + if (!(validLastName.test(this.state.form.LNAME))) { + invalidFields.push('Last Name'); + } + if (!(validEmail.test(this.state.form.EMAIL))) { + invalidFields.push('Email address'); + } + if (invalidFields.length > 0) { + errorMessage.push(`\nInvalid input in:\n${invalidFields.join('\n')}`); + alert(errorMessage); + return false; + } + return true; + } + + handleInputChange = (event) => { + const val = event.target.value; + const name = event.target.name; + this.setState({ + form: { + ...this.state.form, + [name]: val, + }, + }); + } + + subscribe = () => { + if (this.validateContact()) { + const action = process.env.REACT_APP_MAILCHIMP_URL; + const fields = ['FNAME', 'LNAME', 'EMAIL', 'PHONE']; + const values = fields.map(field => { + return `${field}=${encodeURIComponent(this.state.form[field])}`; + }).join("&"); + const path = `${action}&${values}`; + const url = path.replace('/post?', '/post-json?'); + jsonp(url, { param: "c" }); + this.setState({ subscribed: true }); + } + } + + closeModal = () => { + this.setState({ + showModal: false, + }) + } + render() { - let addressData = ""; const {viewport} = this.state; if(this.state.addressFound === false){ @@ -79,7 +163,7 @@ export default class AddressSearch extends React.Component { queryParams={queryParams} /> ) - } + } else { addressData = ( - Sorry. {this.props.message}! + let modalHeader = 'Oops, something is wrong'; + let modalBody = this.props.message; + let modalFooter = ( +
+ +
+ ); + + if (this.props.message === 'Area not covered.') { + modalHeader = this.state.subscribed ? 'Congratulations!' : 'Sorry, we\'re not in your city yet!'; + modalBody = this.state.subscribed ? 'You have been successfully subscribed.' : ( +
+
+ We apologize, your area isn't covered by BlocPower yet, but we will get in touch once we introduce service there. +
+ + + this.handleInputChange(e)} + /> + + + this.handleInputChange(e)} + /> + + + + + this.handleInputChange(e)} + /> + + + + + this.handleInputChange(e)} + /> + + +
+ ); + modalFooter = this.state.subscribed ? ( +
+ +
+ ) : ( +
+ {' '} +
); } + let message = ( + + + {modalHeader} + + + {modalBody} + + + {modalFooter} + + + ); + const content = (
{message} -- GitLab From ba86f20e50d4da587cb4b7273c97443208d924d7 Mon Sep 17 00:00:00 2001 From: RujitRaval Date: Fri, 13 Dec 2019 14:32:41 -0500 Subject: [PATCH 2/3] Change message to match with the bloclink --- src/AddressSearch.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/AddressSearch.js b/src/AddressSearch.js index 51712cf9a..e89a3dfd0 100644 --- a/src/AddressSearch.js +++ b/src/AddressSearch.js @@ -179,7 +179,7 @@ export default class AddressSearch extends React.Component {
); - if (this.props.message === 'Area not covered.') { + if (this.props.message === 'Sorry! Area not covered at the moment.') { modalHeader = this.state.subscribed ? 'Congratulations!' : 'Sorry, we\'re not in your city yet!'; modalBody = this.state.subscribed ? 'You have been successfully subscribed.' : (
-- GitLab From 33035e14d6f158f2d9ee1b7e789f5176615c5a6e Mon Sep 17 00:00:00 2001 From: Aizizi Yigaimu Date: Fri, 13 Dec 2019 15:13:07 -0500 Subject: [PATCH 3/3] Remove garbage code --- src/AddressSearch.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/AddressSearch.js b/src/AddressSearch.js index 51712cf9a..ce7ba53b9 100644 --- a/src/AddressSearch.js +++ b/src/AddressSearch.js @@ -1,4 +1,4 @@ -import React, { useState } from "react"; +import React from "react"; import { Row, Col, Button, Input, Modal, ModalHeader, ModalBody, ModalFooter } from 'reactstrap'; import './index.css'; import Geocoder from 'react-mapbox-gl-geocoder'; @@ -140,7 +140,9 @@ export default class AddressSearch extends React.Component { const path = `${action}&${values}`; const url = path.replace('/post?', '/post-json?'); jsonp(url, { param: "c" }); - this.setState({ subscribed: true }); + this.setState({ + subscribed: true, + }); } } -- GitLab