diff options
Diffstat (limited to 'src/pages')
| -rw-r--r-- | src/pages/FormPage.tsx | 52 | 
1 files changed, 49 insertions, 3 deletions
diff --git a/src/pages/FormPage.tsx b/src/pages/FormPage.tsx index e9306e3..c06b33c 100644 --- a/src/pages/FormPage.tsx +++ b/src/pages/FormPage.tsx @@ -2,10 +2,11 @@  import { jsx, css } from "@emotion/react";  import { Link } from "react-router-dom"; -import React, { SyntheticEvent, useEffect, useState, createRef } from "react"; +import React, {SyntheticEvent, useEffect, useState, createRef, useRef} from "react";  import { useParams } from "react-router";  import { PropagateLoader } from "react-spinners";  import { useDispatch, useSelector } from "react-redux"; +import HCaptcha from "@hcaptcha/react-hcaptcha";  import HeaderBar from "../components/HeaderBar";  import ConnectedRenderedQuestion, { RenderedQuestion } from "../components/Question"; @@ -18,7 +19,7 @@ import { unselectable }  from "../commonStyles";  import { Question, QuestionType } from "../api/question";  import ApiClient from "../api/client";  import { FormState } from "../store/form/types"; -import { clean } from "../store/form/actions"; +import { clean, setCaptchaToken } from "../store/form/actions";  interface PathParams {      id: string @@ -157,6 +158,14 @@ const closedHeaderStyles = css`    }  `; +const captchaStyles = css` +  text-align: center; +   +  @media (max-width: 850px) { +    padding-bottom: 1.2rem; +  } +`; +  function FormPage(): JSX.Element {      const { id } = useParams<PathParams>(); @@ -166,6 +175,9 @@ function FormPage(): JSX.Element {      const values = useSelector<FormState, FormState["values"]>(          state => state.values      ); +    const captchaToken = useSelector<FormState, FormState["captchaToken"]>( +        state => state.captchaToken +    );      const dispatch = useDispatch(); @@ -173,6 +185,9 @@ function FormPage(): JSX.Element {      const [sending, setSending] = useState<boolean>();      const [sent, setSent] = useState<boolean>(); +    // eslint-disable-next-line @typescript-eslint/no-explicit-any +    const captchaRef = useRef<any>(); +      useEffect(() => {          dispatch(clean());          getForm(id).then(form => { @@ -255,6 +270,14 @@ function FormPage(): JSX.Element {              return;          } +        // eslint-disable-next-line @typescript-eslint/no-non-null-assertion +        if (!(FormFeatures.DisableAntispam in form!.features) && captchaToken === null) { +            if (captchaRef && captchaRef.current) { +                captchaRef.current.execute(); +            } +            return; +        } +          setSending(true);          const answers: { [key: string]: unknown } = {}; @@ -294,7 +317,14 @@ function FormPage(): JSX.Element {              }          }); -        await ApiClient.post(`forms/submit/${id}`, {response: answers}); +        const data: { [key: string]: unknown } = {response: answers}; + +        // eslint-disable-next-line @typescript-eslint/no-non-null-assertion +        if (!(FormFeatures.DisableAntispam in form!.features)) { +            data["captcha"] = captchaToken; +        } + +        await ApiClient.post(`forms/submit/${id}`, data);          setSending(false);          setSent(true);      } @@ -306,6 +336,21 @@ function FormPage(): JSX.Element {          closed_header = <div css={closedHeaderStyles}>This form is now closed. You will not be able to submit your response.</div>;      } +    let captcha = null; +    if (!(FormFeatures.DisableAntispam in form.features)) { +        captcha = ( +            <div css={captchaStyles}> +                <HCaptcha +                    sitekey={process.env.HCAPTCHA_SITEKEY ? process.env.HCAPTCHA_SITEKEY : ""} +                    theme={"dark"} +                    onVerify={(token) => dispatch(setCaptchaToken(token))} +                    onExpire={() => dispatch(setCaptchaToken(null))} +                    ref={captchaRef} +                /> +            </div> +        ); +    } +      return (          <div>              <HeaderBar title={form.name} description={form.description}/> @@ -314,6 +359,7 @@ function FormPage(): JSX.Element {                  <form id="form" onSubmit={handleSubmit} css={[formStyles, unselectable]}>                      { closed_header }                      { questions } +                    { captcha }                  </form>                  <Navigation form_state={open}/>              </div>  |