295 lines
9.5 KiB
JavaScript
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) |