diff --git a/client/src/connectors/InviteForm.connect.js b/client/src/connectors/InviteForm.connect.js
new file mode 100644
index 000000000..83c5b7699
--- /dev/null
+++ b/client/src/connectors/InviteForm.connect.js
@@ -0,0 +1,13 @@
+import { connect } from 'react-redux';
+import { submitInvite, submitSendInvite } from 'store/Invite/invite.action';
+
+export const mapStateToProps = (state, props) => {
+ return {};
+};
+
+export const mapDispatchToProps = (dispatch) => ({
+ requestSubmitInvite: (form, token) => dispatch(submitInvite({ form, token })),
+ requestSendInvite: (form) => dispatch(submitSendInvite({ form })),
+});
+
+export default connect(mapStateToProps, mapDispatchToProps);
diff --git a/client/src/connectors/RegisterForm.connect.js b/client/src/connectors/RegisterForm.connect.js
new file mode 100644
index 000000000..a82e601ac
--- /dev/null
+++ b/client/src/connectors/RegisterForm.connect.js
@@ -0,0 +1,12 @@
+import { connect } from 'react-redux';
+import { submitRegister } from 'store/registers/register.action';
+
+export const mapStateToProps = (state, props) => {
+ return {};
+};
+
+export const mapDispatchToProps = (dispatch) => ({
+ requestSubmitRegister: (form) => dispatch(submitRegister({ form })),
+});
+
+export default connect(mapStateToProps, mapDispatchToProps);
diff --git a/client/src/connectors/ResetPassword.connect.js b/client/src/connectors/ResetPassword.connect.js
new file mode 100644
index 000000000..5dc209556
--- /dev/null
+++ b/client/src/connectors/ResetPassword.connect.js
@@ -0,0 +1,13 @@
+import { connect } from 'react-redux';
+import { submitResetPassword } from 'store/resetPassword/resetPassword.action';
+
+export const mapStateToProps = (state, props) => {
+ return {};
+};
+
+export const mapDispatchToProps = (dispatch) => ({
+ requestResetPassword: (password) =>
+ dispatch(submitResetPassword({password})),
+});
+
+export default connect(mapStateToProps, mapDispatchToProps);
diff --git a/client/src/containers/Authentication/Invite.js b/client/src/containers/Authentication/Invite.js
new file mode 100644
index 000000000..7837881e9
--- /dev/null
+++ b/client/src/containers/Authentication/Invite.js
@@ -0,0 +1,183 @@
+import React, { useEffect, useMemo } from 'react';
+import * as Yup from 'yup';
+import { useFormik } from 'formik';
+import { useIntl } from 'react-intl';
+import ErrorMessage from 'components/ErrorMessage';
+import AppToaster from 'components/AppToaster';
+import { compose } from 'utils';
+import InviteFormConnect from 'connectors/InviteForm.connect';
+import { useParams } from 'react-router-dom';
+import {
+ Button,
+ InputGroup,
+ Intent,
+ FormGroup,
+ HTMLSelect,
+} from '@blueprintjs/core';
+
+function Invite({ requestSubmitInvite }) {
+ const intl = useIntl();
+ let params = useParams('accept/:token');
+
+ const { token } = params;
+
+ const phoneRegExp = /^((\\+[1-9]{1,4}[ \\-]*)|(\\([0-9]{2,3}\\)[ \\-]*)|([0-9]{2,4})[ \\-]*)*?[0-9]{3,4}?[ \\-]*[0-9]{3,4}?$/;
+
+ const language = useMemo(
+ () => [
+ { value: null, label: 'Select Country' },
+ { value: 'Arabic', label: 'Arabic' },
+ { value: 'English', label: 'English' },
+ ],
+ []
+ );
+ const ValidationSchema = Yup.object().shape({
+ first_name: Yup.string().required(intl.formatMessage({ id: 'required' })),
+
+ last_name: Yup.string().required(intl.formatMessage({ id: 'required' })),
+
+ email: Yup.string()
+ .email()
+ .required(intl.formatMessage({ id: 'required' })),
+ phone_number: Yup.string()
+ .matches(phoneRegExp)
+ .required(intl.formatMessage({ id: 'required' })),
+ language: Yup.string().required(
+ intl.formatMessage({
+ id: 'required',
+ })
+ ),
+ password: Yup.string()
+ .min(4, 'Password has to be longer than 4 characters!')
+ .required('Password is required!'),
+ });
+
+ const initialValues = useMemo(
+ () => ({
+ first_name: '',
+ last_name: '',
+ email: '',
+ phone_number: '',
+ language: '',
+ password: '',
+ }),
+ []
+ );
+ const formik = useFormik({
+ enableReinitialize: true,
+ validationSchema: ValidationSchema,
+ initialValues: {
+ ...initialValues,
+ },
+ onSubmit: (values, { setSubmitting }) => {
+ requestSubmitInvite(values, token)
+ .then((response) => {
+ AppToaster.show({
+ message: 'success',
+ });
+ setSubmitting(false);
+ })
+ .catch((error) => {
+ setSubmitting(false);
+ });
+ },
+ });
+
+ const { errors, values, touched } = useMemo(() => formik, [formik]);
+ const requiredSpan = useMemo(() => *, []);
+
+ return (
+
+
+
+ );
+}
+
+export default compose(InviteFormConnect)(Invite);
diff --git a/client/src/containers/Authentication/Register.js b/client/src/containers/Authentication/Register.js
new file mode 100644
index 000000000..3189db91a
--- /dev/null
+++ b/client/src/containers/Authentication/Register.js
@@ -0,0 +1,201 @@
+import React, { useEffect, useMemo } from 'react';
+import * as Yup from 'yup';
+import { useFormik } from 'formik';
+import { useIntl } from 'react-intl';
+import {
+ Button,
+ InputGroup,
+ Intent,
+ FormGroup,
+ HTMLSelect,
+} from '@blueprintjs/core';
+
+import RegisterFromConnect from 'connectors/RegisterForm.connect';
+import ErrorMessage from 'components/ErrorMessage';
+import AppToaster from 'components/AppToaster';
+import { compose } from 'utils';
+
+function Register({ requestSubmitRegister }) {
+ const intl = useIntl();
+
+ const phoneRegExp = /^((\\+[1-9]{1,4}[ \\-]*)|(\\([0-9]{2,3}\\)[ \\-]*)|([0-9]{2,4})[ \\-]*)*?[0-9]{3,4}?[ \\-]*[0-9]{3,4}?$/;
+
+ const Country = useMemo(
+ () => [
+ { value: null, label: 'Select Country' },
+ { value: 'libya', label: 'Libya' },
+ ],
+ []
+ );
+
+ const ValidationSchema = Yup.object().shape({
+ organization_name: Yup.string().required(
+ intl.formatMessage({ id: 'required' })
+ ),
+ first_name: Yup.string().required(intl.formatMessage({ id: 'required' })),
+
+ last_name: Yup.string().required(intl.formatMessage({ id: 'required' })),
+ email: Yup.string()
+ .email()
+ .required(intl.formatMessage({ id: 'required' })),
+ phone_number: Yup.string()
+ .matches(phoneRegExp)
+ .required(intl.formatMessage({ id: 'required' })),
+ password: Yup.string()
+ .min(4, 'Password has to be longer than 8 characters!')
+ .required('Password is required!'),
+ country: Yup.string().required(intl.formatMessage({ id: 'required' })),
+ });
+
+ const initialValues = useMemo(
+ () => ({
+ organization_name: '',
+ first_name: '',
+ last_name: '',
+ email: '',
+ phone_number: '',
+ password: '',
+ country: '',
+ }),
+ []
+ );
+
+ const formik = useFormik({
+ enableReinitialize: true,
+ validationSchema: ValidationSchema,
+ initialValues: {
+ ...initialValues,
+ },
+ onSubmit: (values, { setSubmitting }) => {
+ requestSubmitRegister(values)
+ .then((response) => {
+ AppToaster.show({
+ message: 'success',
+ });
+ setSubmitting(false);
+ })
+ .catch((error) => {
+ setSubmitting(false);
+ });
+ },
+ });
+
+ const { errors, values, touched } = useMemo(() => formik, [formik]);
+ const requiredSpan = useMemo(() => *, []);
+
+ return (
+
+
+
+ );
+}
+
+export default compose(RegisterFromConnect)(Register);
diff --git a/client/src/containers/Authentication/ResetPassword.js b/client/src/containers/Authentication/ResetPassword.js
index 7abe691b6..421143528 100644
--- a/client/src/containers/Authentication/ResetPassword.js
+++ b/client/src/containers/Authentication/ResetPassword.js
@@ -1,29 +1,106 @@
-import * as React from "react";
-import { Link } from 'react-router-dom';
-import {Button, InputGroup} from "@blueprintjs/core";
-import { FormattedMessage } from 'react-intl';
+import React, { useEffect, useMemo } from 'react';
+import * as Yup from 'yup';
+import { useFormik } from 'formik';
+import { useIntl } from 'react-intl';
+import {
+ Button,
+ InputGroup,
+ Intent,
+ FormGroup,
+ HTMLSelect,
+} from '@blueprintjs/core';
+import ErrorMessage from 'components/ErrorMessage';
+import AppToaster from 'components/AppToaster';
+import { compose } from 'utils';
+import SendResetPasswordConnect from 'connectors/ResetPassword.connect';
+
+function ResetPassword({ requestSendResetPassword }) {
+ const intl = useIntl();
+ const ValidationSchema = Yup.object().shape({
+ password: Yup.string()
+ .min(4, 'Password has to be longer than 4 characters!')
+ .required('Password is required!'),
+
+ confirm_password: Yup.string()
+ .oneOf([Yup.ref('password'), null], 'Passwords must match')
+ .required('Confirm Password is required'),
+ });
+
+ const initialValues = useMemo(
+ () => ({
+ password: '',
+ confirm_password: '',
+ }),
+ []
+ );
+ const formik = useFormik({
+ enableReinitialize: true,
+ validationSchema: ValidationSchema,
+ initialValues: {
+ ...initialValues,
+ },
+ onSubmit: (values, { setSubmitting }) => {
+ requestSendResetPassword(values.password)
+ .then((response) => {
+ AppToaster.show({
+ message: 'success',
+ });
+ setSubmitting(false);
+ })
+ .catch((error) => {
+ setSubmitting(false);
+ });
+ },
+ });
+
+ const { errors, values, touched } = useMemo(() => formik, [formik]);
+ const requiredSpan = useMemo(() => *, []);
-export default function Login() {
return (
-