Chore: Added recaptcha to Apply form (#2619)
* Added recaptcha v2 to Apply form * fix * fix import * add recaptcha data in request payload --------- Co-authored-by: Vasco Bettencourt <vasco.bettencourt@algolia.com>
This commit is contained in:
parent
0fc01a5c14
commit
67fcc5e656
3 changed files with 87 additions and 35 deletions
|
|
@ -27,7 +27,8 @@
|
|||
"postcss-preset-env": "10.1.3",
|
||||
"prism-react-renderer": "2.4.1",
|
||||
"react": "^18.0.0",
|
||||
"react-dom": "^18.0.0"
|
||||
"react-dom": "^18.0.0",
|
||||
"react-google-recaptcha": "^3.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"tailwindcss": "3.4.17"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import { Button, Card, Heading1, InlineLink, Input, LabelText, Text } from '@algolia/ui-library';
|
||||
import { useBaseUrlUtils } from '@docusaurus/useBaseUrl';
|
||||
import React, { useState } from 'react';
|
||||
import React, { useState, useRef } from 'react';
|
||||
import { ReCAPTCHA } from 'react-google-recaptcha';
|
||||
|
||||
function ApplyForm() {
|
||||
const { withBaseUrl } = useBaseUrlUtils();
|
||||
|
|
@ -8,6 +9,7 @@ function ApplyForm() {
|
|||
const [url, setUrl] = useState('');
|
||||
const [email, setEmail] = useState('');
|
||||
const [repo, setRepo] = useState('');
|
||||
const recaptchaRef = useRef(null);
|
||||
|
||||
const handleSetUrl = (event) => {
|
||||
setUrl(event.target.value);
|
||||
|
|
@ -18,50 +20,68 @@ function ApplyForm() {
|
|||
const handleSetRepo = (event) => {
|
||||
setRepo(event.target.value);
|
||||
};
|
||||
const onSubmit = (event) => {
|
||||
|
||||
const onSubmit = async (event) => {
|
||||
event.preventDefault();
|
||||
|
||||
if (state.status === 'loading') {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if reCAPTCHA is completed
|
||||
const recaptchaValue = recaptchaRef.current?.getValue?.();
|
||||
if (!recaptchaValue) {
|
||||
setState({
|
||||
status: 'failed',
|
||||
message: 'Please complete the reCAPTCHA verification.',
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
setState({ status: 'loading' });
|
||||
|
||||
const applyForm = event.target;
|
||||
const method = applyForm.getAttribute('method');
|
||||
const action = applyForm.getAttribute('action');
|
||||
const formData = new FormData(applyForm);
|
||||
const data = {};
|
||||
formData.forEach(function (value, key) {
|
||||
data[key] = value;
|
||||
});
|
||||
if (!data.repoURL) {
|
||||
data.repoURL = 'https://www.github.com/algolia/docsearch';
|
||||
}
|
||||
const body = JSON.stringify(data);
|
||||
try {
|
||||
const applyForm = event.target;
|
||||
const method = applyForm.getAttribute('method');
|
||||
const action = applyForm.getAttribute('action');
|
||||
const formData = new FormData(applyForm);
|
||||
const data = {};
|
||||
formData.forEach(function (value, key) {
|
||||
data[key] = value;
|
||||
});
|
||||
if (!data.repoURL) {
|
||||
data.repoURL = 'https://www.github.com/algolia/docsearch';
|
||||
}
|
||||
|
||||
fetch(action, {
|
||||
method,
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body,
|
||||
})
|
||||
.then((response) => response.json())
|
||||
.then(({ success, message }) => {
|
||||
if (!success) {
|
||||
return setState({
|
||||
status: 'failed',
|
||||
message: 'Unable to submit your request.',
|
||||
});
|
||||
}
|
||||
data['g-recaptcha-response'] = recaptchaValue;
|
||||
|
||||
return setState({ status: 'succeed', message });
|
||||
})
|
||||
.catch(() =>
|
||||
const body = JSON.stringify(data);
|
||||
|
||||
const response = await fetch(action, {
|
||||
method,
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body,
|
||||
});
|
||||
const { success, message } = await response.json();
|
||||
|
||||
if (!success) {
|
||||
recaptchaRef.current?.reset();
|
||||
setState({
|
||||
status: 'failed',
|
||||
message: 'Unable to submit your request.',
|
||||
}),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
// Reset reCAPTCHA after successful submission
|
||||
recaptchaRef.current?.reset();
|
||||
setState({ status: 'succeed', message });
|
||||
} catch {
|
||||
recaptchaRef.current?.reset();
|
||||
setState({
|
||||
status: 'failed',
|
||||
message: 'Unable to submit your request.',
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
if (state.status === 'succeed' && state.message) {
|
||||
|
|
@ -201,6 +221,12 @@ function ApplyForm() {
|
|||
.
|
||||
</LabelText>
|
||||
|
||||
<div className="uil-mt-16 uil-mb-16 uil-d-flex uil-jc-center uil-ai-center">
|
||||
<div style={{ display: 'inline-block' }}>
|
||||
<ReCAPTCHA ref={recaptchaRef} sitekey="6LeE9VcrAAAAAJ-MxCRdgKI0lxJIJs2PIVWlw-0z" theme="light" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Button
|
||||
primary={true}
|
||||
disabled={state.status === 'loading'}
|
||||
|
|
|
|||
29
yarn.lock
29
yarn.lock
|
|
@ -2248,6 +2248,7 @@ __metadata:
|
|||
prism-react-renderer: "npm:2.4.1"
|
||||
react: "npm:^18.0.0"
|
||||
react-dom: "npm:^18.0.0"
|
||||
react-google-recaptcha: "npm:^3.1.0"
|
||||
tailwindcss: "npm:3.4.17"
|
||||
languageName: unknown
|
||||
linkType: soft
|
||||
|
|
@ -12014,7 +12015,7 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"hoist-non-react-statics@npm:^3.1.0, hoist-non-react-statics@npm:^3.3.1":
|
||||
"hoist-non-react-statics@npm:^3.1.0, hoist-non-react-statics@npm:^3.3.0, hoist-non-react-statics@npm:^3.3.1":
|
||||
version: 3.3.2
|
||||
resolution: "hoist-non-react-statics@npm:3.3.2"
|
||||
dependencies:
|
||||
|
|
@ -18872,7 +18873,7 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"prop-types@npm:^15.6.2, prop-types@npm:^15.7.2, prop-types@npm:^15.8.1":
|
||||
"prop-types@npm:^15.5.0, prop-types@npm:^15.6.2, prop-types@npm:^15.7.2, prop-types@npm:^15.8.1":
|
||||
version: 15.8.1
|
||||
resolution: "prop-types@npm:15.8.1"
|
||||
dependencies:
|
||||
|
|
@ -19076,6 +19077,18 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"react-async-script@npm:^1.2.0":
|
||||
version: 1.2.0
|
||||
resolution: "react-async-script@npm:1.2.0"
|
||||
dependencies:
|
||||
hoist-non-react-statics: "npm:^3.3.0"
|
||||
prop-types: "npm:^15.5.0"
|
||||
peerDependencies:
|
||||
react: ">=16.4.1"
|
||||
checksum: 10c0/89450912110c380abc08258ce17d2fb18d31d6b7179a74f6bc504c0761a4ca271edb671e402fa8e5ea4250b5c17fa953af80a9f1c4ebb26c9e81caee8476c903
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"react-dev-utils@npm:^12.0.1":
|
||||
version: 12.0.1
|
||||
resolution: "react-dev-utils@npm:12.0.1"
|
||||
|
|
@ -19169,6 +19182,18 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"react-google-recaptcha@npm:^3.1.0":
|
||||
version: 3.1.0
|
||||
resolution: "react-google-recaptcha@npm:3.1.0"
|
||||
dependencies:
|
||||
prop-types: "npm:^15.5.0"
|
||||
react-async-script: "npm:^1.2.0"
|
||||
peerDependencies:
|
||||
react: ">=16.4.1"
|
||||
checksum: 10c0/5ecaa6b88f238defd939012cb2671b4cbda59fe03f059158994b8c5215db482412e905eae6a67d23cef220d77cfe0430ab91ce7849d476515cda72f3a8a0a746
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"react-helmet-async@npm:@slorber/react-helmet-async@*, react-helmet-async@npm:@slorber/react-helmet-async@1.3.0":
|
||||
version: 1.3.0
|
||||
resolution: "@slorber/react-helmet-async@npm:1.3.0"
|
||||
|
|
|
|||
Loading…
Reference in a new issue