Files
AG2L-pwa/pages/contact.js
T
2019-02-11 14:58:45 +01:00

295 lines
9.5 KiB
JavaScript

import Layout from '../components/MyLayout.js'
import axios from 'axios'
import { withStyles } from '@material-ui/core/styles'
import Slide from '@material-ui/core/Slide';
import Paper from '@material-ui/core/Paper';
import TextField from '@material-ui/core/TextField';
import Button from '@material-ui/core/Button';
import CircularProgress from '@material-ui/core/CircularProgress';
import Snackbar from '@material-ui/core/Snackbar';
import Typography from '@material-ui/core/Typography';
import ReCAPTCHA from "react-google-recaptcha";
import green from '@material-ui/core/colors/green';
import orange from '@material-ui/core/colors/orange';
import SnackbarContent from '@material-ui/core/SnackbarContent';
import { Transition, config } from 'react-spring'
import getConfig from 'next/config'
import Head from 'next/head'
const {publicRuntimeConfig} = getConfig()
//variable for client side only import
let back = ''
const styles = theme => ({
root: {
margin: theme.spacing.unit,
maxWidth: '400px', [theme.breakpoints.down('md')]: {
maxWidth: `${100 - (theme.spacing.unit)}vw`
},
},
wrapper: {
maxWidth: '400px',
[theme.breakpoints.down('md')]: {
maxWidth: `${100 - (theme.spacing.unit)}vw`
},
},
paper: {
'& form':{
[theme.breakpoints.down('md')]: {
width: `${100 - (theme.spacing.unit)}vw`
},
padding: theme.spacing.unit * 2,
display:'flex',
flexWrap: 'wrap',
}
},
website: {
width: 400,
[theme.breakpoints.down('md')]: {
width: `${100 - (theme.spacing.unit)}vw`
},
},
textField: {
width: '100%'
},
button: {
margin: theme.spacing.unit,
alignSelf:'flex-end'
},
link: {
cursor: 'pointer'
},
success: {
backgroundColor: green[600],
},
error: {
backgroundColor: theme.palette.error.dark,
},
warning: {
backgroundColor: orange[600],
},
spock: {
display: 'inline'
},
errorCaptcha: {
border: '2px',
borderColor: 'red',
borderStyle: 'solid'
}
});
let spring = { ...config.default, precision: 0.1 }
const recaptchaRef = React.createRef();
class Contact extends React.Component {
state = {
nom:"",
prenom:"",
mail:"",
tel:"",
message: "",
checked: false,
openSnack: false,
loading: false,
error: false,
warning: false,
success: false,
snackMessage: ""
};
handleMessage = event => {
this.setState({ success: false, message: event.target.value })
}
handleField = e => {
this.setState({ success: false, [e.target.name]: e.target.value })
}
sendMessage = (recaptchaValue) => {
axios.post("/feedback", {
nom:this.state.nom,
prenom:this.state.prenom,
tel:this.state.tel,
mail:this.state.mail,
message: this.state.message,
recaptchaValue: recaptchaValue
}).then(response => {
this.setState({ success: true, error: false, warning: false, message: '', snackMessage: "Votre message à bien été envoyé.", loading: false, openSnack: true })
}).catch(error => {
if (error.status != 500) {
if (process.browser) {
// client-side-only code
back.saveEventDataLocally([{ message: this.state.message, recaptchaValue }]);
}
this.setState({ success: false, error: false, warning: true,
snackMessage: "📴 Votre message n'a pas pu aboutir, mais a été sauvegardé. Nous l'enverrons lorsque nous aurons une meilleure connectivité.",
loading: false, openSnack: true })
}
else
this.setState({ success: false, error: true, warning: false,
snackMessage: "Une erreur système est survenue.",
loading: false, openSnack: true })
});
}
handleClose = () => {
this.setState({ openSnack: false });
}
handleSubmit = e => {
e.preventDefault();
const recaptchaValue = recaptchaRef.current.getValue();
if (this.state.mail === '' || this.state.message === '' || recaptchaValue === '')
this.setState({ success: false, error: true, warning: false,
snackMessage: "Veuillez entrer les champs necessaires et valider le Captcha.",
loading: false, openSnack: true })
else
this.setState({ success: false, error: false, warning: false, loading: true }, this.sendMessage(recaptchaValue))
}
config = (item, state) => (state === 'leave' ? [{ duration: 1000 }, spring] : [{ duration: 5000 }, spring])
async componentDidMount() {
//loading lib for client side only
let result = await import("../src/backSync.js")
back = result.default
}
render() {
const { classes } = this.props;
return (
<Layout menu={this.props.menu}>
<Head>
<title>Devis Développement PWA</title>
<meta name="description" content="Vous souhaitez créer une PWA, développer des fonctionnalités à votre site web et améliorer l'expérience utilisateur sur votre site internet? Contactez-nous pour parler de votre projet." />
<link rel="canonical" href="https://www.application.bzh/contact"/>
</Head>
<div className={classes.root}>
<div className={classes.wrapper}>
<Slide direction="right" in={true} mountOnEnter unmountOnExit timeout={800}>
<Paper elevation={4} className={classes.paper}>
{this.state.loading && (
<div className="alert alert-info">
<CircularProgress color="secondary" />Validating your inputs...
</div>
)}
{!this.state.loading &&
(<form onSubmit={this.handleSubmit}>
<TextField
id="prenom"
name="prenom"
label="Prénom"
value={this.state.prenom}
onChange={this.handleField}
className={classes.textField}
margin="normal"
/>
<TextField
id="nom"
name="nom"
label="Nom"
value={this.state.nom}
onChange={this.handleField}
className={classes.textField}
margin="normal"
/>
<TextField
id="mail"
name="mail"
label="Email*"
value={this.state.mail}
onChange={this.handleField}
className={classes.textField}
margin="normal"
error={this.state.error}
/>
<TextField
id="tel"
name="tel"
label="Tel"
value={this.state.tel}
onChange={this.handleField}
className={classes.textField}
margin="normal"
/>
<TextField
id="standard-multiline-flexible"
label="Message*"
multiline
rowsMax={10}
rows={4}
value={this.state.message}
onChange={this.handleMessage}
className={classes.textField}
margin="normal"
error={this.state.error}
/>
<div className={this.state.error ? classes.errorCaptcha : ''}>
<ReCAPTCHA
id="component-outlined"
ref={recaptchaRef}
sitekey={publicRuntimeConfig.ReCAPTCHA.siteKey}
size="normal"
/>
</div>
<Button type="submit" variant="outlined" color="secondary" className={classes.button}>
Send
</Button>
<Transition
config={this.config}
items={this.state.success}
from={{ opacity: 0 }}
enter={{ opacity: 1 }}
leave={{ opacity: 0 }}>
{show =>
show && (props => <div style={props} className={classes.spock}>🖖</div>)
}
</Transition>
</form>)
}
</Paper>
</Slide>
</div>
<br></br>
<div>
<Paper elevation={4} className={classes.website}>
<a href={publicRuntimeConfig.eDeclicUrl} >
<Typography variant="subtitle1" color="secondary" className={classes.link} >
www.e-declic.com
</Typography>
</a>
</Paper>
</div>
</div>
<Snackbar
anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }}
open={this.state.openSnack}
onClose={this.handleClose}
autoHideDuration={6000}
TransitionComponent={(props)=><Slide {...props} direction="left" />}
ContentProps={{
'aria-describedby': 'message-id',
}}
>
<SnackbarContent
aria-describedby="message-id"
className={classes[this.state.error ? 'error' : this.state.warning ? 'warning' : 'success']}
message={<span id="message-id">{this.state.snackMessage}</span>}
/>
</Snackbar>
</Layout>
);
}
}
export default withStyles(styles)(Contact)