recaptcha integration

This commit is contained in:
merelendor 2022-07-26 08:19:26 +03:00
parent a89c0808e2
commit e7a32efe35
6 changed files with 3124 additions and 15 deletions

View File

@ -16,7 +16,7 @@ if(process.browser)
}; };
} }
export const sendLeasingOrder = ({ name, phone, email, company }) => export const sendLeasingOrder = ({ name, phone, email, company, recaptcha_token }) =>
{ {
return new Promise((resolve, reject) => return new Promise((resolve, reject) =>
{ {
@ -28,6 +28,7 @@ export const sendLeasingOrder = ({ name, phone, email, company }) =>
formData.append("FORM_FIELD_COMPANY", company); formData.append("FORM_FIELD_COMPANY", company);
formData.append("FORM_FIELD_PAGE_NAME", document.title); formData.append("FORM_FIELD_PAGE_NAME", document.title);
formData.append("FORM_FIELD_PAGE_URL", window.location.href); formData.append("FORM_FIELD_PAGE_URL", window.location.href);
formData.append("recaptcha_token", recaptcha_token);
axios.post(`${ process.env.NEXT_PUBLIC_API_HOST }/api/forms/`, formData) axios.post(`${ process.env.NEXT_PUBLIC_API_HOST }/api/forms/`, formData)
.then((response) => .then((response) =>
@ -38,7 +39,7 @@ export const sendLeasingOrder = ({ name, phone, email, company }) =>
} }
else else
{ {
reject(); reject(response.data);
} }
}) })
.catch((error) => .catch((error) =>

File diff suppressed because one or more lines are too long

View File

@ -3350,3 +3350,5 @@ main .dropdown_blocks_list .dropdown_block .block_body {
border-top: 1px solid #EDEFF5; border-top: 1px solid #EDEFF5;
} }
} }
.grecaptcha-badge { visibility: hidden; }

View File

@ -31,6 +31,7 @@
"react": "17.0.2", "react": "17.0.2",
"react-cookie": "^4.1.1", "react-cookie": "^4.1.1",
"react-dom": "17.0.2", "react-dom": "17.0.2",
"react-google-recaptcha-v3": "^1.10.0",
"react-redux": "^7.2.6", "react-redux": "^7.2.6",
"react-widgets": "^5.5.1", "react-widgets": "^5.5.1",
"redux": "^4.1.2", "redux": "^4.1.2",

View File

@ -1,8 +1,10 @@
import React from "react"; import React from "react";
import { SpinnerCircular } from 'spinners-react';
import { GoogleReCaptchaProvider, GoogleReCaptcha, withGoogleReCaptcha } from 'react-google-recaptcha-v3';
import { sendLeasingOrder } from "../../../actions"; import { sendLeasingOrder } from "../../../actions";
export default class FormRequest extends React.Component class FormContent extends React.Component
{ {
constructor(props) constructor(props)
{ {
@ -14,6 +16,7 @@ export default class FormRequest extends React.Component
company: "", company: "",
accept: true, accept: true,
success: false, success: false,
fail: false,
leasing_form_submitting: false, leasing_form_submitting: false,
errors: {}, errors: {},
}; };
@ -70,18 +73,36 @@ export default class FormRequest extends React.Component
if(accept && !leasing_form_submitting && this.checkErrors()) if(accept && !leasing_form_submitting && this.checkErrors())
{ {
const { executeRecaptcha } = this.props.googleReCaptchaProps;
this.setState({ leasing_form_submitting: true }, () => this.setState({ leasing_form_submitting: true }, () =>
{ {
sendLeasingOrder(this.state) executeRecaptcha()
.then(() => .then((token) =>
{ {
this.setState({ leasing_form_submitting: false, success: true }); sendLeasingOrder({ ...this.state, ...{ recaptcha_token: token } })
.then(() =>
{
this.setState({ leasing_form_submitting: false, success: true, fail: false });
})
.catch((response) =>
{
if(response.message === "recaptcha_error")
{
this.setState({ leasing_form_submitting: false, success: false, fail: true });
}
else
{
this.setState({ leasing_form_submitting: false, success: false, fail: false });
}
});
}) })
.catch(() => .catch((error) =>
{ {
this.setState({ leasing_form_submitting: false, success: false }); console.error("error", error);
this.setState({ leasing_form_submitting: false });
}); });
}); });
} }
} }
@ -122,7 +143,7 @@ export default class FormRequest extends React.Component
render() render()
{ {
const { name, phone, email, company, accept, success, errors } = this.state; const { name, phone, email, company, accept, success, fail, errors, leasing_form_submitting } = this.state;
return ( return (
<section id="order"> <section id="order">
@ -132,8 +153,8 @@ export default class FormRequest extends React.Component
<div className="order_email"> <div className="order_email">
<p>Напишите на <a href="mailto:">buy@evoleasing.ru</a> или заполните форму</p> <p>Напишите на <a href="mailto:">buy@evoleasing.ru</a> или заполните форму</p>
</div> </div>
<form onSubmit={ (event) => this._onFormSubmit(event) }> <form onSubmit={ (event) => this._onFormSubmit(event) } style={ !fail ? {} : { backgroundColor: "#2C2D2E" }}>
{ !success ? ( { !success ? !fail ? (
<> <>
<div className={`form_field ${ errors['name'] !== undefined ? 'error' : '' }`} data-error={ errors['name'] !== undefined ? errors['name'] : null }> <div className={`form_field ${ errors['name'] !== undefined ? 'error' : '' }`} data-error={ errors['name'] !== undefined ? errors['name'] : null }>
<input type="text" value={ name } placeholder="Имя" onChange={ (event) => this._handle_onChange_name(event.target.value) }/> <input type="text" value={ name } placeholder="Имя" onChange={ (event) => this._handle_onChange_name(event.target.value) }/>
@ -151,7 +172,17 @@ export default class FormRequest extends React.Component
<input type="checkbox" name="policy" id="policy" hidden checked={ accept } onChange={ (event) => this._handle_onChange_accept(event.target.checked) }/> <input type="checkbox" name="policy" id="policy" hidden checked={ accept } onChange={ (event) => this._handle_onChange_accept(event.target.checked) }/>
<label htmlFor="policy">Даю свое согласие на обработку {`\u00A0`}<u onClick={ () => this._handle_onPersonaData() }>моих персональных данных</u></label> <label htmlFor="policy">Даю свое согласие на обработку {`\u00A0`}<u onClick={ () => this._handle_onPersonaData() }>моих персональных данных</u></label>
</div> </div>
<button className="button" disabled={ !accept }>Отправить</button> <button className="button" disabled={ !accept } style={{ minWidth: "100px" }}>
{ leasing_form_submitting ? (
<SpinnerCircular size={24} thickness={100} speed={100} color="rgba(28, 1, 169, 1)" secondaryColor="rgba(236, 239, 244, 1)" style={{ marginTop: "4px" }}/>
) : "Отправить" }
</button>
<div style={{ position: "absolute", left: "10px", bottom: "9px", fontSize: "9px", color: "#FFF", opacity: "0.5", lineHeight: "11px" }}>защита от спама reCAPTCHA<br/><a href="https://policies.google.com/privacy" target="_blank" style={{ fontSize: "9px", color: "#FFF", textDecoration: "underline" }}>Конфиденциальность</a> - <a href="https://policies.google.com/terms" target="_blank" style={{ fontSize: "9px", color: "#FFF", textDecoration: "underline" }}>Условия использования</a></div>
</>
) : (<>
<div style={{ minHeight: "400px", alignItems: "center", justifyContent: "center", display: "flex" }}>
<p style={{ color: "#fff", fontSize: "24px", lineHeight: "34px" }}>Сожалеем, запросы, отправляемые с Вашего устройства похожи на автоматические. Пожалуйста, воспользуйтесь другим браузером/подключением или попробуйте позднее.</p>
</div>
</> </>
) : ( ) : (
<div style={{ minHeight: "400px", alignItems: "center", justifyContent: "center", display: "flex" }}> <div style={{ minHeight: "400px", alignItems: "center", justifyContent: "center", display: "flex" }}>
@ -164,4 +195,60 @@ export default class FormRequest extends React.Component
</section> </section>
) )
} }
} }
export const FormContentWithRecaptcha = withGoogleReCaptcha(FormContent);
export default class FormRequest extends React.Component
{
constructor(props)
{
super(props);
this.state = {
};
}
render()
{
return (
<GoogleReCaptchaProvider reCaptchaKey={ process.env.NEXT_PUBLIC_RECAPTCHA_SITE_KEY }>
<FormContentWithRecaptcha/>
</GoogleReCaptchaProvider>
)
}
}
/*
export default class FormRequest extends React.Component
{
constructor(props)
{
super(props);
this.state = {
recaptcha_token: null,
};
}
componentDidMount()
{
setTimeout(() =>
{
this.setState({ recaptcha_token: null });
}, 120000);
}
render()
{
const { recaptcha_token } = this.state;
return (
<GoogleReCaptchaProvider reCaptchaKey={ process.env.NEXT_PUBLIC_RECAPTCHA_SITE_KEY }>
{ recaptcha_token === null && (
<GoogleReCaptcha onVerify={ (token) => { console.log("GoogleReCaptcha", "token response", token); this.setState({ recaptcha_token: token })} }/>
) }
<FormContent recaptcha_token={ recaptcha_token }/>
</GoogleReCaptchaProvider>
)
}
}
*/

View File

@ -2949,6 +2949,13 @@ react-dom@17.0.2:
object-assign "^4.1.1" object-assign "^4.1.1"
scheduler "^0.20.2" scheduler "^0.20.2"
react-google-recaptcha-v3@^1.10.0:
version "1.10.0"
resolved "https://registry.yarnpkg.com/react-google-recaptcha-v3/-/react-google-recaptcha-v3-1.10.0.tgz#1ec46825fe9b857d7f4ef08ee89fea05e629a9f9"
integrity sha512-JBoqU107X8klQmS8tQSbQh1IMsT1fH3kVoArIqnia0rtn0rPNG9Ld+9rD/dHJMculIczSZpGvIJTXXwtsolMcg==
dependencies:
hoist-non-react-statics "^3.3.2"
react-is@17.0.2, react-is@^17.0.2: react-is@17.0.2, react-is@^17.0.2:
version "17.0.2" version "17.0.2"
resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0" resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0"