From 60e1e5e31fc891f7d6a91c98fe68e396af9ac613 Mon Sep 17 00:00:00 2001 From: WildScotsmen Date: Sun, 18 Nov 2018 01:10:04 -0500 Subject: [PATCH] Added contact form to application. Sends requests through EmailJS. --- package-lock.json | 15 +++ package.json | 1 + src/App.css | 5 + src/components/ContactForm.js | 227 ++++++++++++++++++++++++++++++++++ src/components/Main.js | 15 ++- src/emailjs.js | 5 + src/pages/Contact.js | 14 +++ 7 files changed, 278 insertions(+), 4 deletions(-) create mode 100644 src/components/ContactForm.js create mode 100644 src/emailjs.js create mode 100644 src/pages/Contact.js diff --git a/package-lock.json b/package-lock.json index d358b66..1fbb236 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4246,6 +4246,21 @@ "minimalistic-crypto-utils": "^1.0.0" } }, + "emailjs-com": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/emailjs-com/-/emailjs-com-2.2.4.tgz", + "integrity": "sha512-Pm29HoSxEIKLv7p6rxOPpKFqLnf2JaHTl6coql59r8MNRNW49Mim65s7yoWAqQhZ+Mk4GFmQsiPSFXD6Gnm4BQ==", + "requires": { + "promise-polyfill": "7.1.0" + }, + "dependencies": { + "promise-polyfill": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/promise-polyfill/-/promise-polyfill-7.1.0.tgz", + "integrity": "sha512-P6NJ2wU/8fac44ENORsuqT8TiolKGB2u0fEClPtXezn7w5cmLIjM/7mhPlTebke2EPr6tmqZbXvnX0TxwykGrg==" + } + } + }, "emoji-regex": { "version": "6.5.1", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-6.5.1.tgz", diff --git a/package.json b/package.json index c98fd28..4e7b120 100644 --- a/package.json +++ b/package.json @@ -7,6 +7,7 @@ "@material-ui/icons": "^3.0.1", "ajv": "^6.0.0", "disqus-react": "^1.0.5", + "emailjs-com": "^2.2.4", "firebase": "^5.5.2", "firebase-admin": "^6.1.0", "flamelink": "^0.19.6", diff --git a/src/App.css b/src/App.css index b5b1e22..d1e1bd6 100644 --- a/src/App.css +++ b/src/App.css @@ -42,6 +42,11 @@ body { height: 300px !important; } +.contact-form { + max-width: 100%; + overflow: hidden; +} + @media (min-width: 960px) { .sighting-detail-google-map-container > div { width: calc(100% - 50% - 120px) !important; diff --git a/src/components/ContactForm.js b/src/components/ContactForm.js new file mode 100644 index 0000000..779a8b1 --- /dev/null +++ b/src/components/ContactForm.js @@ -0,0 +1,227 @@ +import React, { Fragment } from 'react'; +import PropTypes from 'prop-types'; +import Grid from '@material-ui/core/Grid'; +import emailjs from '../emailjs.js' +import { withStyles } from '@material-ui/core/styles'; +import TextField from '@material-ui/core/TextField'; +import CheckCircleIcon from '@material-ui/icons/CheckCircle'; +import Snackbar from '@material-ui/core/Snackbar'; +import IconButton from '@material-ui/core/IconButton'; +import CloseIcon from '@material-ui/icons/Close'; +import Button from '@material-ui/core/Button'; +import { Typography } from '@material-ui/core'; + +/** + * Styles that the different + * Material UI components pull + * in. Mostly used for spacing. + */ +const styles = theme => ({ + container: { + display: 'flex', + flexWrap: 'wrap' + }, + textField: { + marginLeft: theme.spacing.unit, + marginRight: theme.spacing.unit, + marginTop: theme.spacing.unit, + flexBasis: 280, + width: '90%' + }, + button: { + marginLeft: theme.spacing.unit, + marginRight: theme.spacing.unit, + marginTop: theme.spacing.unit, + }, + close: { + padding: theme.spacing.unit / 2, + }, + icon: { + fontSize: 20, + marginRight: theme.spacing.unit, + }, + message: { + display: 'flex', + alignItems: 'center', + }, + menu: { + width: 200, + }, + paper: { + position: 'absolute', + width: theme.spacing.unit * 50, + backgroundColor: theme.palette.background.paper, + boxShadow: theme.shadows[5], + padding: theme.spacing.unit * 4, + } +}); + +/** + * The form component. + */ +class ContactForm extends React.Component { + + /** + * State of form components. + */ + state = { + name: "", + email: "", + comments: "", + open: false + }; + + /** + * Handles state change in form + * components. + */ + handleChange = name => event => { + this.setState({ + [name]: event.target.value, + }); + }; + + /** + * Handles closing the toast. + */ + handleClose = (event, reason) => { + if (reason === 'clickaway') { + return; + } + + this.setState({ open: false }); + }; + + /** + * Event listener for form. + * When the form is submitted, + * this function passes the + * data along to EmailJS. + */ + handleSubmit = e => { + e.preventDefault(); + + const templateParams = { + from_name: this.state.name, + from_email: this.state.email, + message_html: this.state.comments + }; + + emailjs.send('default_service', 'template_XaKOJGSf', templateParams); + + this.setState({ + name: "", + email: "", + comments: "", + open: true + }); + }; + + /** + * The render method for this component. + */ + render() { + const { classes } = this.props; + + /** + * The actual form. + */ + return ( + + + {
} + Send us an email! + +
+ + + + + + + + + + + + + + +
+
+ Message sent.} + action={[ + + + , + ]} + /> +
+ ); + } +} + +ContactForm.propTypes = { + classes: PropTypes.object.isRequired, +}; + +export default withStyles(styles)(ContactForm); \ No newline at end of file diff --git a/src/components/Main.js b/src/components/Main.js index 8ecb20a..38906fd 100644 --- a/src/components/Main.js +++ b/src/components/Main.js @@ -14,6 +14,7 @@ import Hidden from '@material-ui/core/Hidden'; import Divider from '@material-ui/core/Divider'; import MenuIcon from '@material-ui/icons/Menu'; import HomeIcon from '@material-ui/icons/Home'; +import EmailIcon from '@material-ui/icons/Email'; import AssignmentIcon from '@material-ui/icons/Assignment'; import MapIcon from '@material-ui/icons/Map'; import InfoIcon from '@material-ui/icons/Info'; @@ -23,6 +24,7 @@ import Home from '../pages/Home'; import ViewMap from '../pages/ViewMap'; import Info from '../pages/Info'; import Quiz from '../pages/QuizPage'; +import Contact from '../pages/Contact'; import SightingList from '../pages/SightingList'; import Report from '../pages/Report'; import CssBaseline from '@material-ui/core/CssBaseline'; @@ -112,10 +114,6 @@ class ResponsiveDrawer extends React.Component { - this.nav('About')}> - - - @@ -136,6 +134,14 @@ class ResponsiveDrawer extends React.Component { + this.nav('Contact')}> + + + + this.nav('About')}> + + + @@ -196,6 +202,7 @@ class ResponsiveDrawer extends React.Component { {this.state.key === 'Map' && } {this.state.key === 'List' && } {this.state.key === 'About' && } + {this.state.key === 'Contact' && } {this.state.key === 'Easy-Quiz' && } {this.state.key === 'Medium-Quiz' && } {this.state.key === 'Hard-Quiz' && } diff --git a/src/emailjs.js b/src/emailjs.js new file mode 100644 index 0000000..b2c9193 --- /dev/null +++ b/src/emailjs.js @@ -0,0 +1,5 @@ +import * as emailjs from 'emailjs-com' + +emailjs.init("user_4d5R86dmu6vgeJP4euxSA"); + +export default emailjs; \ No newline at end of file diff --git a/src/pages/Contact.js b/src/pages/Contact.js new file mode 100644 index 0000000..20d4407 --- /dev/null +++ b/src/pages/Contact.js @@ -0,0 +1,14 @@ +import React, { Component } from 'react'; +import ContactForm from '../components/ContactForm.js' + +class Contact extends Component { + componentDidMount() { + document.title = 'Marten Tracker | Contact'; + } + + render() { + return ; + } +} + +export default Contact;