Added contact form to application. Sends requests through EmailJS.
This commit is contained in:
parent
17410d3eec
commit
60e1e5e31f
|
@ -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",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
|
@ -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'/>}
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
import * as emailjs from 'emailjs-com'
|
||||
|
||||
emailjs.init("user_4d5R86dmu6vgeJP4euxSA");
|
||||
|
||||
export default emailjs;
|
|
@ -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;
|
Loading…
Reference in New Issue