diff --git a/.gitignore b/.gitignore index efa180355..c3cd7a3c4 100644 --- a/.gitignore +++ b/.gitignore @@ -127,4 +127,7 @@ docker_environment_init.sh .envrc # Exclude Makefiles -Makefile \ No newline at end of file +Makefile + +# Exclude files create at runtime - by webpack and storybook +common/static/ \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 4439a5983..941286b45 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,13 @@ # https://hub.docker.com/r/nikolaik/python-nodejs FROM nikolaik/python-nodejs:python3.10-nodejs16 +# Refresh Yarn repo GPG key (old key 62D54FD4003F6525 expired; fetch the +# current one so apt-get update succeeds on bookworm-based images). +RUN curl -fsSL https://dl.yarnpkg.com/debian/pubkey.gpg \ + | gpg --dearmor -o /usr/share/keyrings/yarn-archive-keyring.gpg \ + && sed -i 's|^deb \[.*\] https://dl.yarnpkg.com|deb [signed-by=/usr/share/keyrings/yarn-archive-keyring.gpg] https://dl.yarnpkg.com|;s|^deb https://dl.yarnpkg.com|deb [signed-by=/usr/share/keyrings/yarn-archive-keyring.gpg] https://dl.yarnpkg.com|' \ + /etc/apt/sources.list.d/yarn.list 2>/dev/null || true + # This to get GDAL thanks to https://stackoverflow.com/questions/62546706/how-do-i-install-gdal-in-a-python-docker-environment RUN apt-get update && apt-get install diff --git a/common/components/common/integrations/NewsletterSignup.jsx b/common/components/common/integrations/NewsletterSignup.jsx index 0090b51ff..f81ba5f11 100644 --- a/common/components/common/integrations/NewsletterSignup.jsx +++ b/common/components/common/integrations/NewsletterSignup.jsx @@ -1,51 +1,19 @@ // @flow import React from "react"; - +// In mailchimp go to forms > other forms choose the subscription landing page to get the url class NewsletterSignup extends React.Component { render() { return (
-
-
-
-
-
-
-
-
- -
- + Subscribe +
); } diff --git a/common/components/controllers/SignUpController.jsx b/common/components/controllers/SignUpController.jsx index 3ea63e636..15e367d16 100644 --- a/common/components/controllers/SignUpController.jsx +++ b/common/components/controllers/SignUpController.jsx @@ -2,6 +2,7 @@ import DjangoCSRFToken from "django-react-csrftoken"; import React from "react"; +import ReCAPTCHA from "react-google-recaptcha"; import type { Validator } from "../forms/FormValidation.jsx"; import FormValidation from "../forms/FormValidation.jsx"; import metrics from "../utils/metrics.js"; @@ -27,6 +28,7 @@ type State = {| validations: $ReadOnlyArray, termsOpen: boolean, didCheckTerms: boolean, + reCaptchaValue: ?string, isValid: boolean, |}; @@ -50,6 +52,7 @@ class SignUpController extends React.Component { password2: "", termsOpen: false, didCheckTerms: false, + reCaptchaValue: null, isValid: false, validations: [ { @@ -88,10 +91,23 @@ class SignUpController extends React.Component { checkFunc: (state: State) => state.didCheckTerms, errorMessage: "Agree to terms of service", }, + { + checkFunc: (state: State) => + !this.isCaptchaEnabled() || !_.isEmpty(state.reCaptchaValue), + errorMessage: "Please complete the captcha", + }, ], }; } + isCaptchaEnabled(): boolean { + return !_.isEmpty(window.GR_SITEKEY); + } + + reCaptchaOnChange(value: ?string): void { + this.setState({ reCaptchaValue: value }); + } + onValidationCheck(isValid: boolean): void { if (isValid !== this.state.isValid) { this.setState({ isValid }); @@ -153,6 +169,11 @@ class SignUpController extends React.Component { />
+
@@ -206,6 +227,15 @@ class SignUpController extends React.Component { formState={this.state} /> + {this.isCaptchaEnabled() ? ( +
+ +
+ ) : null} +