diff --git a/frontend/web/components/PasswordRequirements.js b/frontend/web/components/PasswordRequirements.js
new file mode 100644
index 000000000000..0e0454025cbf
--- /dev/null
+++ b/frontend/web/components/PasswordRequirements.js
@@ -0,0 +1,39 @@
+import React, { useEffect } from 'react';
+import PropTypes from 'prop-types';
+import { close, checkmark } from 'ionicons/icons'
+import { IonIcon } from '@ionic/react'
+
+const PasswordRequirements = ({ password, onRequirementsMet}) => {
+ const requirements = [
+ { label: 'At least 8 characters', test: password.length >= 8 },
+ { label: 'Contains a number', test: /\d/.test(password) },
+ { label: 'Contains a special character', test: /[!@#$%^&*(),.?":{}|<>[\]\\\/_+=-]/.test(password) },
+ { label: 'Contains an uppercase letter', test: /[A-Z]/.test(password) },
+ { label: 'Contains a lowercase letter', test: /[a-z]/.test(password) },
+ ];
+
+ const allRequirementsMet = requirements.every(req => req.test);
+
+ useEffect(() => {
+ onRequirementsMet(allRequirementsMet);
+ }, [allRequirementsMet, onRequirementsMet]);
+
+ return (
+
+
+ {requirements.map((req, index) => (
+
+ {req.label}
+
+ ))}
+
+
+ );
+};
+
+PasswordRequirements.propTypes = {
+ password: PropTypes.string.isRequired,
+ onRequirementsMet: PropTypes.func.isRequired,
+ };
+
+export default PasswordRequirements;
diff --git a/frontend/web/components/pages/HomePage.js b/frontend/web/components/pages/HomePage.js
index e58a5bc88572..83b5eb739b86 100644
--- a/frontend/web/components/pages/HomePage.js
+++ b/frontend/web/components/pages/HomePage.js
@@ -10,6 +10,7 @@ import ConfigProvider from 'common/providers/ConfigProvider'
import Constants from 'common/constants'
import ErrorMessage from 'components/ErrorMessage'
import Button from 'components/base/forms/Button'
+import PasswordRequirements from 'components/PasswordRequirements'
import { informationCircleOutline } from 'ionicons/icons'
import { IonIcon } from '@ionic/react'
import classNames from 'classnames'
@@ -32,8 +33,16 @@ const HomePage = class extends React.Component {
// can handle always setting the marketing consent.
API.setCookie('marketing_consent_given', 'true')
this.state = {
+ email: '',
+ first_name: '',
+ last_name: '',
+ password: '',
marketing_consent_given: true,
+ allRequirementsMet: false,
}
+
+ this.handlePasswordChange = this.handlePasswordChange.bind(this);
+ this.handleRequirementsMet = this.handleRequirementsMet.bind(this);
}
addAlbacross() {
@@ -131,6 +140,14 @@ const HomePage = class extends React.Component {
}
}
+ handlePasswordChange(e) {
+ this.setState({ password: e.target.value });
+ }
+
+ handleRequirementsMet(allRequirementsMet) {
+ this.setState({ allRequirementsMet });
+ }
+
showForgotPassword = (e) => {
e.preventDefault()
openModal(
@@ -607,11 +624,15 @@ const HomePage = class extends React.Component {
name='password'
id='password'
/>
+