Added contact form to application. Sends requests through EmailJS.

This commit is contained in:
WildScotsmen 2018-11-18 01:10:04 -05:00
parent 17410d3eec
commit 60e1e5e31f
7 changed files with 278 additions and 4 deletions

15
package-lock.json generated
View File

@ -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",

View File

@ -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",

View File

@ -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;

View File

@ -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 (
<Fragment>
<Typography variant="headline" align="center">
{<br/>}
Send us an email!
<form className={classes.container} autoComplete="off" onSubmit={this.handleSubmit}>
<Grid container className="contact-form">
<Grid item xs={12}>
<Grid container spacing={8}>
<Grid item xs={12}>
<TextField
id="name"
required
label="Name"
name="message-name"
placeholder="John Doe"
value={this.state.name}
className={classes.textField}
onChange={this.handleChange('name')}
margin="normal"
variant="outlined"
/>
<TextField
id="email"
required
label="Email"
name="message-email"
type="email"
autoComplete="email"
placeholder="example@mail.com"
value={this.state.email}
className={classes.textField}
onChange={this.handleChange('email')}
margin="normal"
variant="outlined"
/>
<TextField
id="comments"
required
label="Comments"
name="message-comments"
multiline
rows="5"
placeholder="The message you would like to send us."
value={this.state.comments}
className={classes.textField}
onChange={this.handleChange('comments')}
margin="normal"
variant="outlined"
InputLabelProps={{
shrink: true,
}}
/>
</Grid>
<Grid item xs={12}>
<Button variant="contained" type="submit" color="primary" className={classes.button}>
Submit
</Button>
</Grid>
</Grid>
</Grid>
</Grid>
</form>
</Typography>
<Snackbar
anchorOrigin={{
vertical: 'bottom',
horizontal: 'left',
}}
open={this.state.open}
autoHideDuration={6000}
onClose={this.handleClose}
ContentProps={{
'aria-describedby': 'message-id',
}}
message={<span id="message-id" className={classes.message}><CheckCircleIcon className={classes.icon} />Message sent.</span>}
action={[
<IconButton
key="close"
aria-label="Close"
color="inherit"
className={classes.close}
onClick={this.handleClose}
>
<CloseIcon />
</IconButton>,
]}
/>
</Fragment>
);
}
}
ContactForm.propTypes = {
classes: PropTypes.object.isRequired,
};
export default withStyles(styles)(ContactForm);

View File

@ -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 {
<ListItemIcon><ListIcon /></ListItemIcon>
<ListItemText primary='List' />
</ListItem>
<ListItem button key='About' onClick={() => this.nav('About')}>
<ListItemIcon><InfoIcon /></ListItemIcon>
<ListItemText primary='About' />
</ListItem>
<ListItem button onClick={this.handleClick}>
<ListItemIcon>
<SlideshowIcon />
@ -136,6 +134,14 @@ class ResponsiveDrawer extends React.Component {
</ListItem>
</List>
</Collapse>
<ListItem button key='Contact' onClick={() => this.nav('Contact')}>
<ListItemIcon><EmailIcon /></ListItemIcon>
<ListItemText primary='Contact' />
</ListItem>
<ListItem button key='About' onClick={() => this.nav('About')}>
<ListItemIcon><InfoIcon /></ListItemIcon>
<ListItemText primary='About' />
</ListItem>
</List>
<Divider />
</div>
@ -196,6 +202,7 @@ class ResponsiveDrawer extends React.Component {
{this.state.key === 'Map' && <ViewMap />}
{this.state.key === 'List' && <SightingList />}
{this.state.key === 'About' && <Info />}
{this.state.key === 'Contact' && <Contact />}
{this.state.key === 'Easy-Quiz' && <Quiz difficulty='Easy'/>}
{this.state.key === 'Medium-Quiz' && <Quiz difficulty='Medium'/>}
{this.state.key === 'Hard-Quiz' && <Quiz difficulty='Hard'/>}

5
src/emailjs.js Normal file
View File

@ -0,0 +1,5 @@
import * as emailjs from 'emailjs-com'
emailjs.init("user_4d5R86dmu6vgeJP4euxSA");
export default emailjs;

14
src/pages/Contact.js Normal file
View File

@ -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 <ContactForm />;
}
}
export default Contact;