mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-17 21:30:31 +00:00
fix hot bugs.
This commit is contained in:
@@ -2,14 +2,14 @@ import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { IntlProvider } from 'react-intl';
|
||||
import { connect } from 'react-redux';
|
||||
import { Router } from 'react-router';
|
||||
import { Router, Switch } from 'react-router';
|
||||
import { createBrowserHistory } from 'history';
|
||||
import PrivateRoute from 'components/PrivateRoute';
|
||||
import Authentication from 'components/Authentication';
|
||||
import Dashboard from 'components/Dashboard/Dashboard';
|
||||
import { isAuthenticated } from 'store/authentication/authentication.reducer'
|
||||
import messages from 'lang/en';
|
||||
import 'style/App.scss';
|
||||
import { createBrowserHistory } from 'history';
|
||||
|
||||
function App(props) {
|
||||
const history = createBrowserHistory();
|
||||
|
||||
@@ -1,12 +1,27 @@
|
||||
import React from 'react';
|
||||
import React, { useMemo, useCallback } from 'react';
|
||||
import {connect} from 'react-redux';
|
||||
import {Menu, MenuItem, MenuDivider, Button, Popover} from '@blueprintjs/core';
|
||||
import {useHistory} from 'react-router-dom';
|
||||
import {
|
||||
Menu,
|
||||
MenuItem,
|
||||
MenuDivider,
|
||||
Button,
|
||||
Popover
|
||||
} from '@blueprintjs/core';
|
||||
import t from 'store/types';
|
||||
|
||||
function DashboardTopbarUser({ logout }) {
|
||||
const onClickLogout = () => { logout(); };
|
||||
const history = useHistory();
|
||||
|
||||
const onClickLogout = useCallback(() => {
|
||||
logout();
|
||||
|
||||
const userAvatarDropMenu = (
|
||||
setTimeout(() => {
|
||||
history.push('/auth/login');
|
||||
}, 100);
|
||||
}, [history, logout]);
|
||||
|
||||
const userAvatarDropMenu = useMemo(() => (
|
||||
<Menu>
|
||||
<MenuItem icon="graph" text="Graph" />
|
||||
<MenuItem icon="map" text="Map" />
|
||||
@@ -15,7 +30,7 @@ function DashboardTopbarUser({ logout }) {
|
||||
<MenuDivider />
|
||||
<MenuItem icon="cog" text="Logout" onClick={onClickLogout} />
|
||||
</Menu>
|
||||
);
|
||||
), [onClickLogout]);
|
||||
|
||||
return (
|
||||
<Popover content={userAvatarDropMenu}>
|
||||
|
||||
@@ -15,6 +15,7 @@ function PrivateRoute({
|
||||
return (
|
||||
<Route
|
||||
{...rest}
|
||||
path="/dashboard"
|
||||
render={_props =>
|
||||
isAuthenticated ? (<Component {..._props} />) :
|
||||
(
|
||||
|
||||
@@ -23,30 +23,18 @@ function Invite({ requestSubmitInvite }) {
|
||||
|
||||
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 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',
|
||||
})
|
||||
),
|
||||
first_name: Yup.string().required(),
|
||||
last_name: Yup.string().required(),
|
||||
email: Yup.string().email().required(),
|
||||
phone_number: Yup.string().matches(phoneRegExp).required(),
|
||||
language: Yup.string().required(),
|
||||
password: Yup.string()
|
||||
.min(4, 'Password has to be longer than 4 characters!')
|
||||
.required('Password is required!'),
|
||||
@@ -63,54 +51,58 @@ function Invite({ requestSubmitInvite }) {
|
||||
}),
|
||||
[]
|
||||
);
|
||||
const formik = useFormik({
|
||||
const {
|
||||
handleSubmit,
|
||||
errors,
|
||||
values,
|
||||
touched,
|
||||
getFieldProps,
|
||||
} = 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);
|
||||
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(() => <span class='required'>*</span>, []);
|
||||
|
||||
return (
|
||||
<div className={'invite-form'}>
|
||||
<form onSubmit={formik.handleSubmit}>
|
||||
<form onSubmit={handleSubmit}>
|
||||
<FormGroup
|
||||
label={'First Name'}
|
||||
labelInfo={requiredSpan}
|
||||
className={'form-group--first_name'}
|
||||
intent={errors.first_name && touched.first_name && Intent.DANGER}
|
||||
helperText={<ErrorMessage name={'first_name'} {...formik} />}
|
||||
helperText={<ErrorMessage name={'first_name'} />}
|
||||
>
|
||||
<InputGroup
|
||||
intent={errors.first_name && touched.first_name && Intent.DANGER}
|
||||
{...formik.getFieldProps('first_name')}
|
||||
{...getFieldProps('first_name')}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
<FormGroup
|
||||
label={'Last Name'}
|
||||
labelInfo={requiredSpan}
|
||||
className={'form-group--last_name'}
|
||||
intent={errors.last_name && touched.last_name && Intent.DANGER}
|
||||
helperText={<ErrorMessage name={'last_name'} {...formik} />}
|
||||
helperText={<ErrorMessage name={'last_name'} />}
|
||||
>
|
||||
<InputGroup
|
||||
intent={errors.last_name && touched.last_name && Intent.DANGER}
|
||||
{...formik.getFieldProps('last_name')}
|
||||
{...getFieldProps('last_name')}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
@@ -119,13 +111,11 @@ function Invite({ requestSubmitInvite }) {
|
||||
labelInfo={requiredSpan}
|
||||
className={'form-group--phone_number'}
|
||||
intent={errors.phone_number && touched.phone_number && Intent.DANGER}
|
||||
helperText={<ErrorMessage name={'phone_number'} {...formik} />}
|
||||
helperText={<ErrorMessage name={'phone_number'} />}
|
||||
>
|
||||
<InputGroup
|
||||
intent={
|
||||
errors.phone_number && touched.phone_number && Intent.DANGER
|
||||
}
|
||||
{...formik.getFieldProps('phone_number')}
|
||||
intent={(errors.phone_number && touched.phone_number) && Intent.DANGER}
|
||||
{...getFieldProps('phone_number')}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
@@ -133,13 +123,13 @@ function Invite({ requestSubmitInvite }) {
|
||||
label={'Language'}
|
||||
labelInfo={requiredSpan}
|
||||
className={'form-group--language'}
|
||||
intent={errors.language && touched.language && Intent.DANGER}
|
||||
helperText={<ErrorMessage name={'language'} {...formik} />}
|
||||
intent={(errors.language && touched.language) && Intent.DANGER}
|
||||
helperText={<ErrorMessage name={'language'} />}
|
||||
>
|
||||
<HTMLSelect
|
||||
fill={true}
|
||||
options={language}
|
||||
{...formik.getFieldProps('language')}
|
||||
{...getFieldProps('language')}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
@@ -147,26 +137,27 @@ function Invite({ requestSubmitInvite }) {
|
||||
label={'Email'}
|
||||
labelInfo={requiredSpan}
|
||||
className={'form-group--email'}
|
||||
intent={errors.email && touched.email && Intent.DANGER}
|
||||
helperText={<ErrorMessage name={'email'} {...formik} />}
|
||||
intent={(errors.email && touched.email) && Intent.DANGER}
|
||||
helperText={<ErrorMessage name={'email'} />}
|
||||
>
|
||||
<InputGroup
|
||||
intent={errors.email && touched.email && Intent.DANGER}
|
||||
{...formik.getFieldProps('email')}
|
||||
{...getFieldProps('email')}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
<FormGroup
|
||||
label={'Password'}
|
||||
labelInfo={requiredSpan}
|
||||
className={'form-group--password'}
|
||||
intent={errors.password && touched.password && Intent.DANGER}
|
||||
helperText={<ErrorMessage name={'password'} {...formik} />}
|
||||
intent={(errors.password && touched.password) && Intent.DANGER}
|
||||
helperText={<ErrorMessage name={'password'} />}
|
||||
>
|
||||
<InputGroup
|
||||
lang={true}
|
||||
type={'password'}
|
||||
intent={errors.password && touched.password && Intent.DANGER}
|
||||
{...formik.getFieldProps('password')}
|
||||
intent={(errors.password && touched.password) && Intent.DANGER}
|
||||
{...getFieldProps('password')}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React, { useEffect } from "react";
|
||||
import {Link} from 'react-router-dom';
|
||||
import {Link, useHistory} from 'react-router-dom';
|
||||
import * as Yup from 'yup';
|
||||
import {useFormik} from 'formik';
|
||||
import {connect} from 'react-redux';
|
||||
@@ -11,7 +11,7 @@ import {
|
||||
FormGroup,
|
||||
} from "@blueprintjs/core";
|
||||
import login from 'store/authentication/authentication.actions';
|
||||
import {hasErrorType} from 'store/authentication/authentication.reducer';
|
||||
import {hasErrorType, isAuthenticated} from 'store/authentication/authentication.reducer';
|
||||
import AuthenticationToaster from 'components/AppToaster';
|
||||
import t from 'store/types';
|
||||
|
||||
@@ -26,6 +26,7 @@ function Login({
|
||||
hasError,
|
||||
}) {
|
||||
const intl = useIntl();
|
||||
const history = useHistory();
|
||||
|
||||
// Validation schema.
|
||||
const loginValidationSchema = Yup.object().shape({
|
||||
@@ -110,7 +111,7 @@ function Login({
|
||||
{...formik.getFieldProps('password')} />
|
||||
</FormGroup>
|
||||
|
||||
<Button
|
||||
<Button
|
||||
type="submit"
|
||||
fill={true}
|
||||
large={true}>
|
||||
@@ -119,9 +120,13 @@ function Login({
|
||||
</form>
|
||||
|
||||
<div className="authentication-page__footer">
|
||||
<Link to="/auth/reset_password">
|
||||
<Link to="/auth/send_reset_password">
|
||||
{intl.formatMessage({'id': 'reset_password '})}
|
||||
</Link>
|
||||
|
||||
<Link to="/auth/register">
|
||||
{intl.formatMessage({'id': 'register '})}
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -9,37 +9,27 @@ import {
|
||||
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';
|
||||
import { compose, regExpCollection } from 'utils';
|
||||
|
||||
function Register({ requestSubmitRegister }) {
|
||||
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 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' })),
|
||||
organization_name: Yup.string().required(),
|
||||
first_name: Yup.string().required(),
|
||||
last_name: Yup.string().required(),
|
||||
email: Yup.string().email().required(),
|
||||
phone_number: Yup.string()
|
||||
.matches(phoneRegExp)
|
||||
.matches(regExpCollection.phoneNumber)
|
||||
.required(intl.formatMessage({ id: 'required' })),
|
||||
password: Yup.string()
|
||||
.min(4, 'Password has to be longer than 8 characters!')
|
||||
@@ -47,20 +37,24 @@ function Register({ requestSubmitRegister }) {
|
||||
country: Yup.string().required(intl.formatMessage({ id: 'required' })),
|
||||
});
|
||||
|
||||
const initialValues = useMemo(
|
||||
() => ({
|
||||
organization_name: '',
|
||||
first_name: '',
|
||||
last_name: '',
|
||||
email: '',
|
||||
phone_number: '',
|
||||
password: '',
|
||||
country: '',
|
||||
}),
|
||||
[]
|
||||
);
|
||||
const initialValues = useMemo(() => ({
|
||||
organization_name: '',
|
||||
first_name: '',
|
||||
last_name: '',
|
||||
email: '',
|
||||
phone_number: '',
|
||||
password: '',
|
||||
country: '',
|
||||
}), []);
|
||||
|
||||
const formik = useFormik({
|
||||
const {
|
||||
getFieldProps,
|
||||
getFieldMeta,
|
||||
errors,
|
||||
values,
|
||||
touched,
|
||||
handleSubmit,
|
||||
} = useFormik({
|
||||
enableReinitialize: true,
|
||||
validationSchema: ValidationSchema,
|
||||
initialValues: {
|
||||
@@ -80,30 +74,28 @@ function Register({ requestSubmitRegister }) {
|
||||
},
|
||||
});
|
||||
|
||||
const { errors, values, touched } = useMemo(() => formik, [formik]);
|
||||
const requiredSpan = useMemo(() => <span class='required'>*</span>, []);
|
||||
|
||||
return (
|
||||
<div className={'register-form'}>
|
||||
<form onSubmit={formik.handleSubmit}>
|
||||
<form onSubmit={handleSubmit}>
|
||||
<FormGroup
|
||||
label={'Organization Name'}
|
||||
labelInfo={requiredSpan}
|
||||
className={'form-group--name'}
|
||||
intent={
|
||||
errors.organization_name &&
|
||||
touched.organization_name &&
|
||||
(errors.organization_name && touched.organization_name) &&
|
||||
Intent.DANGER
|
||||
}
|
||||
helperText={<ErrorMessage name={'organization_name'} {...formik} />}
|
||||
helperText={<ErrorMessage name={'organization_name'} />}
|
||||
>
|
||||
<InputGroup
|
||||
intent={
|
||||
errors.organization_name &&
|
||||
touched.organization_name &&
|
||||
(errors.organization_name &&
|
||||
touched.organization_name) &&
|
||||
Intent.DANGER
|
||||
}
|
||||
{...formik.getFieldProps('organization_name')}
|
||||
{...getFieldProps('organization_name')}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
@@ -111,24 +103,25 @@ function Register({ requestSubmitRegister }) {
|
||||
label={'First Name'}
|
||||
labelInfo={requiredSpan}
|
||||
className={'form-group--first_name'}
|
||||
intent={errors.first_name && touched.first_name && Intent.DANGER}
|
||||
helperText={<ErrorMessage name={'first_name'} {...formik} />}
|
||||
intent={(errors.first_name && touched.first_name) && Intent.DANGER}
|
||||
helperText={<ErrorMessage name={'first_name'} />}
|
||||
>
|
||||
<InputGroup
|
||||
intent={errors.first_name && touched.first_name && Intent.DANGER}
|
||||
{...formik.getFieldProps('first_name')}
|
||||
{...getFieldProps('first_name')}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
<FormGroup
|
||||
label={'Last Name'}
|
||||
labelInfo={requiredSpan}
|
||||
className={'form-group--last_name'}
|
||||
intent={errors.last_name && touched.last_name && Intent.DANGER}
|
||||
helperText={<ErrorMessage name={'last_name'} {...formik} />}
|
||||
helperText={<ErrorMessage name={'last_name'} />}
|
||||
>
|
||||
<InputGroup
|
||||
intent={errors.last_name && touched.last_name && Intent.DANGER}
|
||||
{...formik.getFieldProps('last_name')}
|
||||
{...getFieldProps('last_name')}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
@@ -136,13 +129,13 @@ function Register({ requestSubmitRegister }) {
|
||||
label={'Country'}
|
||||
labelInfo={requiredSpan}
|
||||
className={'form-group--country'}
|
||||
intent={errors.country && touched.country && Intent.DANGER}
|
||||
helperText={<ErrorMessage name={'country'} {...formik} />}
|
||||
intent={(errors.country && touched.country) && Intent.DANGER}
|
||||
helperText={<ErrorMessage name={'country'} />}
|
||||
>
|
||||
<HTMLSelect
|
||||
fill={true}
|
||||
options={Country}
|
||||
{...formik.getFieldProps('country')}
|
||||
{...getFieldProps('country')}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
@@ -150,26 +143,25 @@ function Register({ requestSubmitRegister }) {
|
||||
label={'Phone Number'}
|
||||
labelInfo={requiredSpan}
|
||||
className={'form-group--phone_number'}
|
||||
intent={errors.phone_number && touched.phone_number && Intent.DANGER}
|
||||
helperText={<ErrorMessage name={'phone_number'} {...formik} />}
|
||||
intent={(errors.phone_number && touched.phone_number) && Intent.DANGER}
|
||||
helperText={<ErrorMessage name={'phone_number'} />}
|
||||
>
|
||||
<InputGroup
|
||||
intent={
|
||||
errors.phone_number && touched.phone_number && Intent.DANGER
|
||||
}
|
||||
{...formik.getFieldProps('phone_number')}
|
||||
intent={(errors.phone_number && touched.phone_number) && Intent.DANGER}
|
||||
{...getFieldProps('phone_number')}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
<FormGroup
|
||||
label={'Email'}
|
||||
labelInfo={requiredSpan}
|
||||
className={'form-group--email'}
|
||||
intent={errors.email && touched.email && Intent.DANGER}
|
||||
helperText={<ErrorMessage name={'email'} {...formik} />}
|
||||
intent={(errors.email && touched.email) && Intent.DANGER}
|
||||
helperText={<ErrorMessage name={'email'} />}
|
||||
>
|
||||
<InputGroup
|
||||
intent={errors.email && touched.email && Intent.DANGER}
|
||||
{...formik.getFieldProps('email')}
|
||||
{...getFieldProps('email')}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
@@ -177,14 +169,14 @@ function Register({ requestSubmitRegister }) {
|
||||
label={'Password'}
|
||||
labelInfo={requiredSpan}
|
||||
className={'form-group--password'}
|
||||
intent={errors.password && touched.password && Intent.DANGER}
|
||||
helperText={<ErrorMessage name={'password'} {...formik} />}
|
||||
intent={(errors.password && touched.password) && Intent.DANGER}
|
||||
helperText={<ErrorMessage name={'password'} />}
|
||||
>
|
||||
<InputGroup
|
||||
lang={true}
|
||||
type={'password'}
|
||||
intent={errors.password && touched.password && Intent.DANGER}
|
||||
{...formik.getFieldProps('password')}
|
||||
intent={(errors.password && touched.password) && Intent.DANGER}
|
||||
{...getFieldProps('password')}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
@@ -198,4 +190,6 @@ function Register({ requestSubmitRegister }) {
|
||||
);
|
||||
}
|
||||
|
||||
export default compose(RegisterFromConnect)(Register);
|
||||
export default compose(
|
||||
RegisterFromConnect,
|
||||
)(Register);
|
||||
|
||||
@@ -14,26 +14,32 @@ import AppToaster from 'components/AppToaster';
|
||||
import { compose } from 'utils';
|
||||
import SendResetPasswordConnect from 'connectors/ResetPassword.connect';
|
||||
|
||||
function ResetPassword({ requestSendResetPassword }) {
|
||||
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({
|
||||
const initialValues = useMemo(() => ({
|
||||
password: '',
|
||||
confirm_password: '',
|
||||
}), []);
|
||||
|
||||
const {
|
||||
errors,
|
||||
values,
|
||||
touched,
|
||||
getFieldMeta,
|
||||
getFieldProps,
|
||||
handleSubmit,
|
||||
} = useFormik({
|
||||
enableReinitialize: true,
|
||||
validationSchema: ValidationSchema,
|
||||
initialValues: {
|
||||
@@ -53,26 +59,26 @@ function ResetPassword({ requestSendResetPassword }) {
|
||||
},
|
||||
});
|
||||
|
||||
const { errors, values, touched } = useMemo(() => formik, [formik]);
|
||||
const requiredSpan = useMemo(() => <span class='required'>*</span>, []);
|
||||
|
||||
return (
|
||||
<div className={'sendRestPassword-form'}>
|
||||
<form onSubmit={formik.handleSubmit}>
|
||||
<form onSubmit={handleSubmit}>
|
||||
<FormGroup
|
||||
label={'Password'}
|
||||
labelInfo={requiredSpan}
|
||||
className={'form-group--password'}
|
||||
intent={errors.password && touched.password && Intent.DANGER}
|
||||
helperText={<ErrorMessage name={'password'} {...formik} />}
|
||||
helperText={<ErrorMessage name={'password'} />}
|
||||
>
|
||||
<InputGroup
|
||||
lang={true}
|
||||
type={'password'}
|
||||
intent={errors.password && touched.password && Intent.DANGER}
|
||||
{...formik.getFieldProps('password')}
|
||||
{...getFieldProps('password')}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
<FormGroup
|
||||
label={'Confirm Password'}
|
||||
labelInfo={requiredSpan}
|
||||
@@ -80,7 +86,7 @@ function ResetPassword({ requestSendResetPassword }) {
|
||||
intent={
|
||||
errors.confirm_password && touched.confirm_password && Intent.DANGER
|
||||
}
|
||||
helperText={<ErrorMessage name={'confirm_password'} {...formik} />}
|
||||
helperText={<ErrorMessage name={'confirm_password'} />}
|
||||
>
|
||||
<InputGroup
|
||||
lang={true}
|
||||
@@ -90,9 +96,10 @@ function ResetPassword({ requestSendResetPassword }) {
|
||||
touched.confirm_password &&
|
||||
Intent.DANGER
|
||||
}
|
||||
{...formik.getFieldProps('confirm_password')}
|
||||
{...getFieldProps('confirm_password')}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
<div class='form__floating-footer'>
|
||||
<Button intent={Intent.PRIMARY} type='submit'>
|
||||
Reset Password
|
||||
|
||||
@@ -1,81 +0,0 @@
|
||||
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 InviteFormConnect from 'connectors/InviteForm.connect';
|
||||
|
||||
import { compose } from 'utils';
|
||||
import {
|
||||
Button,
|
||||
InputGroup,
|
||||
Intent,
|
||||
FormGroup,
|
||||
HTMLSelect,
|
||||
} from '@blueprintjs/core';
|
||||
|
||||
function SendInvite({ requestSendInvite }) {
|
||||
const intl = useIntl();
|
||||
const ValidationSchema = Yup.object().shape({
|
||||
email: Yup.string()
|
||||
.email()
|
||||
.required(intl.formatMessage({ id: 'required' })),
|
||||
});
|
||||
|
||||
const initialValues = useMemo(
|
||||
() => ({
|
||||
email: '',
|
||||
}),
|
||||
[]
|
||||
);
|
||||
|
||||
const formik = useFormik({
|
||||
enableReinitialize: true,
|
||||
validationSchema: ValidationSchema,
|
||||
initialValues: {
|
||||
...initialValues,
|
||||
},
|
||||
onSubmit: (values, { setSubmitting }) => {
|
||||
requestSendInvite(values)
|
||||
.then((response) => {
|
||||
AppToaster.show({
|
||||
message: 'success',
|
||||
});
|
||||
setSubmitting(false);
|
||||
})
|
||||
.catch((error) => {
|
||||
setSubmitting(false);
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
const { errors, values, touched } = useMemo(() => formik, [formik]);
|
||||
const requiredSpan = useMemo(() => <span class='required'>*</span>, []);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<form onSubmit={formik.handleSubmit}>
|
||||
<FormGroup
|
||||
label={'Email'}
|
||||
labelInfo={requiredSpan}
|
||||
className={'form-group--email'}
|
||||
intent={errors.email && touched.email && Intent.DANGER}
|
||||
helperText={<ErrorMessage name={'email'} {...formik} />}
|
||||
>
|
||||
<InputGroup
|
||||
intent={errors.email && touched.email && Intent.DANGER}
|
||||
{...formik.getFieldProps('email')}
|
||||
/>
|
||||
</FormGroup>
|
||||
<div class='form__floating-footer'>
|
||||
<Button intent={Intent.PRIMARY} type='submit'>
|
||||
Send Invite
|
||||
</Button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default compose(InviteFormConnect)(SendInvite);
|
||||
@@ -126,7 +126,7 @@ function AccountsChart({
|
||||
addAccountsTableQueries({
|
||||
...(sortBy.length > 0) ? {
|
||||
column_sort_by: sortBy[0].id,
|
||||
sort_by: sortBy[0].desc ? 'desc' : 'asc',
|
||||
sort_order: sortBy[0].desc ? 'desc' : 'asc',
|
||||
} : {},
|
||||
});
|
||||
fetchAccountsHook.execute();
|
||||
|
||||
@@ -17,7 +17,6 @@ export default [
|
||||
loader: () => import('containers/Authentication/Register'),
|
||||
}),
|
||||
},
|
||||
|
||||
{
|
||||
path: `${BASE_URL}/send_reset_password`,
|
||||
name: 'auth.reset_password',
|
||||
@@ -25,7 +24,6 @@ export default [
|
||||
loader: () => import('containers/Authentication/SendResetPassword'),
|
||||
}),
|
||||
},
|
||||
|
||||
{
|
||||
path: `${BASE_URL}/reset_password`,
|
||||
name: 'auth.send.reset_password',
|
||||
@@ -34,17 +32,10 @@ export default [
|
||||
}),
|
||||
},
|
||||
{
|
||||
path: `${BASE_URL}/send_invite`,
|
||||
name: 'auth.send_invite',
|
||||
path: `${BASE_URL}/invite/:token/accept`,
|
||||
name: 'auth.invite.accept',
|
||||
component: LazyLoader({
|
||||
loader: () => import('containers/Authentication/SendInvite'),
|
||||
}),
|
||||
},
|
||||
{
|
||||
path: `${BASE_URL}/invite/:token`,
|
||||
name: 'auth.invite',
|
||||
component: LazyLoader({
|
||||
loader: () => import('containers/Authentication/Invite'),
|
||||
loader: () => import('containers/Authentication/InviteAccept'),
|
||||
}),
|
||||
},
|
||||
];
|
||||
|
||||
@@ -106,8 +106,6 @@ export default [
|
||||
})
|
||||
},
|
||||
|
||||
|
||||
|
||||
// Financial Reports.
|
||||
{
|
||||
path: `${BASE_URL}/accounting/general-ledger`,
|
||||
|
||||
@@ -5,12 +5,15 @@ const http = axios.create();
|
||||
|
||||
http.interceptors.request.use((request) => {
|
||||
const state = store.getState();
|
||||
const token = state.authentication.token;
|
||||
const { token, organization } = state.authentication;
|
||||
const locale = 'en';
|
||||
|
||||
if (token) {
|
||||
request.headers.common['x-access-token'] = token;
|
||||
}
|
||||
if (organization) {
|
||||
request.headers.common['organization-id'] = organization;
|
||||
}
|
||||
if (locale) {
|
||||
request.headers.common['Accept-Language'] = locale;
|
||||
}
|
||||
|
||||
@@ -7,12 +7,14 @@ export default function login({ form }) {
|
||||
ApiService.post('auth/login', form).then(response => {
|
||||
const { data } = response;
|
||||
|
||||
dispatch({type: t.LOGIN_CLEAR_ERRORS});
|
||||
dispatch({ type: t.LOGIN_CLEAR_ERRORS });
|
||||
if (data.token && data.user) {
|
||||
dispatch({
|
||||
type: t.LOGIN_SUCCESS,
|
||||
user: data.user,
|
||||
token: data.token,
|
||||
payload: {
|
||||
user: data.user,
|
||||
token: data.token,
|
||||
},
|
||||
});
|
||||
}
|
||||
resolve(response);
|
||||
|
||||
@@ -3,6 +3,7 @@ import t from 'store/types';
|
||||
|
||||
const initialState = {
|
||||
token: '',
|
||||
organization: '',
|
||||
user: '',
|
||||
locale: '',
|
||||
errors: [],
|
||||
@@ -10,8 +11,10 @@ const initialState = {
|
||||
|
||||
export default createReducer(initialState, {
|
||||
[t.LOGIN_SUCCESS]: (state, action) => {
|
||||
state.token = action.token;
|
||||
state.user = action.user;
|
||||
const { token, user } = action.payload;
|
||||
state.token = token;
|
||||
state.user = user;
|
||||
state.organization = user.tenant.organization_id;
|
||||
},
|
||||
|
||||
[t.LOGIN_FAILURE]: (state, action) => {
|
||||
@@ -21,6 +24,7 @@ export default createReducer(initialState, {
|
||||
[t.LOGOUT]: (state) => {
|
||||
state.token = '';
|
||||
state.user = {};
|
||||
state.organization = '';
|
||||
},
|
||||
|
||||
[t.LOGIN_CLEAR_ERRORS]: (state) => {
|
||||
|
||||
@@ -48,9 +48,7 @@ const createStore = (initialState = {
|
||||
|
||||
store.subscribe(() => {
|
||||
saveState({
|
||||
authentication: {
|
||||
token: store.getState().authentication.token,
|
||||
},
|
||||
authentication: store.getState().authentication,
|
||||
});
|
||||
});
|
||||
return store;
|
||||
|
||||
Reference in New Issue
Block a user