feat(server): remove the phone number from users management

This commit is contained in:
a.bouhuolia
2023-04-06 03:08:51 +02:00
parent e4a647376c
commit 950b5407c3
8 changed files with 127 additions and 149 deletions

View File

@@ -4,7 +4,6 @@ import intl from 'react-intl-universal';
import { Formik } from 'formik';
import { useHistory } from 'react-router-dom';
import { Intent, Position } from '@blueprintjs/core';
import { FormattedMessage as T } from '@/components';
import { isEmpty } from 'lodash';
import { useInviteAcceptContext } from './InviteAcceptProvider';
@@ -13,6 +12,14 @@ import { InviteAcceptSchema } from './utils';
import InviteAcceptFormContent from './InviteAcceptFormContent';
import { AuthInsiderCard } from './_components';
const initialValues = {
organization_name: '',
invited_email: '',
first_name: '',
last_name: '',
password: '',
};
export default function InviteAcceptForm() {
const history = useHistory();
@@ -20,9 +27,8 @@ export default function InviteAcceptForm() {
const { inviteAcceptMutate, inviteMeta, token } = useInviteAcceptContext();
// Invite value.
const inviteValue = {
organization_name: '',
invited_email: '',
const inviteFormValue = {
...initialValues,
...(!isEmpty(inviteMeta)
? {
invited_email: inviteMeta.email,
@@ -34,19 +40,17 @@ export default function InviteAcceptForm() {
// Handle form submitting.
const handleSubmit = (values, { setSubmitting, setErrors }) => {
inviteAcceptMutate([values, token])
.then((response) => {
.then(() => {
AppToaster.show({
message: intl.getHTML(
'congrats_your_account_has_been_created_and_invited',
{
organization_name: inviteValue.organization_name,
organization_name: inviteMeta.organizationName,
},
),
intent: Intent.SUCCESS,
});
history.push('/auth/login');
setSubmitting(false);
})
.catch(
({
@@ -84,7 +88,7 @@ export default function InviteAcceptForm() {
<AuthInsiderCard>
<Formik
validationSchema={InviteAcceptSchema}
initialValues={inviteValue}
initialValues={inviteFormValue}
onSubmit={handleSubmit}
component={InviteAcceptFormContent}
/>

View File

@@ -1,34 +1,45 @@
// @ts-nocheck
import React from 'react';
import React, { useState } from 'react';
import intl from 'react-intl-universal';
import { InputGroup, Intent } from '@blueprintjs/core';
import { Button, InputGroup, Intent } from '@blueprintjs/core';
import { Form, useFormikContext } from 'formik';
import { Link } from 'react-router-dom';
import { Tooltip2 } from '@blueprintjs/popover2';
import styled from 'styled-components';
import { Col, FFormGroup, Row, FormattedMessage as T } from '@/components';
import {
Col,
FFormGroup,
FInputGroup,
Row,
FormattedMessage as T,
} from '@/components';
import { useInviteAcceptContext } from './InviteAcceptProvider';
import { PasswordRevealer } from './components';
import { AuthSubmitButton } from './_components';
/**
* Invite user form.
*/
export default function InviteUserFormContent() {
// Invite accept context.
const { inviteMeta } = useInviteAcceptContext();
const [showPassword, setShowPassword] = useState<boolean>(false);
// Formik context.
const { inviteMeta } = useInviteAcceptContext();
const { isSubmitting } = useFormikContext();
const [passwordType, setPasswordType] = React.useState('password');
// Handle password revealer changing.
const handlePasswordRevealerChange = React.useCallback(
(shown) => {
const type = shown ? 'text' : 'password';
setPasswordType(type);
},
[setPasswordType],
const handleLockClick = () => {
setShowPassword(!showPassword);
};
const lockButton = (
<Tooltip2 content={`${showPassword ? 'Hide' : 'Show'} Password`}>
<Button
icon={showPassword ? 'unlock' : 'lock'}
intent={Intent.WARNING}
minimal={true}
onClick={handleLockClick}
small={true}
/>
</Tooltip2>
);
return (
@@ -36,26 +47,27 @@ export default function InviteUserFormContent() {
<Row>
<Col md={6}>
<FFormGroup name={'first_name'} label={<T id={'first_name'} />}>
<InputGroup name={'first_name'} />
<FInputGroup name={'first_name'} large={true} />
</FFormGroup>
</Col>
<Col md={6}>
<FFormGroup name={'last_name'} label={<T id={'last_name'} />}>
<InputGroup name={'last_name'} />
<FInputGroup name={'last_name'} large={true} />
</FFormGroup>
</Col>
</Row>
<FFormGroup
name={'password'}
label={<T id={'password'} />}
labelInfo={<PasswordRevealer onChange={handlePasswordRevealerChange} />}
>
<InputGroup name={'password'} />
<FFormGroup name={'password'} label={<T id={'password'} />}>
<FInputGroup
name={'password'}
large={true}
rightElement={lockButton}
type={showPassword ? 'text' : 'password'}
/>
</FFormGroup>
<div className={'invite-form__statement-section'}>
<InviteAcceptFooterParagraphs>
<p>
<T id={'you_email_address_is'} /> <b>{inviteMeta.email},</b> <br />
<T id={'you_will_use_this_address_to_sign_in_to_bigcapital'} />
@@ -66,16 +78,25 @@ export default function InviteUserFormContent() {
privacy: (msg) => <Link>{msg}</Link>,
})}
</p>
</div>
</InviteAcceptFooterParagraphs>
<AuthSubmitButton
<InviteAuthSubmitButton
intent={Intent.PRIMARY}
type="submit"
fill={true}
large={true}
loading={isSubmitting}
>
<T id={'create_account'} />
</AuthSubmitButton>
</InviteAuthSubmitButton>
</Form>
);
}
const InviteAcceptFooterParagraphs = styled.div`
opacity: 0.8;
`;
const InviteAuthSubmitButton = styled(AuthSubmitButton)`
margin-top: 1.6rem;
`;

View File

@@ -1,8 +1,8 @@
// @ts-nocheck
import React, { createContext, useContext } from 'react';
import React, { createContext, useContext, useEffect } from 'react';
import { useHistory } from 'react-router-dom';
import { useInviteMetaByToken, useAuthInviteAccept } from '@/hooks/query';
import { InviteAcceptLoading } from './components';
import { useHistory } from 'react-router-dom';
const InviteAcceptContext = createContext();
@@ -22,11 +22,10 @@ function InviteAcceptProvider({ token, ...props }) {
const { mutateAsync: inviteAcceptMutate } = useAuthInviteAccept({
retry: false,
});
// History context.
const history = useHistory();
React.useEffect(() => {
useEffect(() => {
if (inviteMetaError) { history.push('/auth/login'); }
}, [history, inviteMetaError]);

View File

@@ -1,51 +1,42 @@
// @ts-nocheck
import React from 'react';
import ContentLoader from 'react-content-loader';
import { If, Icon, FormattedMessage as T } from '@/components';
import { saveInvoke } from '@/utils';
export function PasswordRevealer({ defaultShown = false, onChange }) {
const [shown, setShown] = React.useState(defaultShown);
const handleClick = () => {
setShown(!shown);
saveInvoke(onChange, !shown);
};
return (
<span class="password-revealer" onClick={handleClick}>
<If condition={shown}>
<Icon icon="eye-slash" />{' '}
</If>
<If condition={!shown}>
<Icon icon="eye" />{' '}
</If>
</span>
);
}
import styled from 'styled-components';
import { AuthInsiderCard } from './_components';
import { Skeleton } from '@/components';
/**
* Invite accept loading space.
*/
export function InviteAcceptLoading({ isLoading, children, ...props }) {
export function InviteAcceptLoading({ isLoading, children }) {
return isLoading ? (
<ContentLoader
speed={2}
width={400}
height={280}
viewBox="0 0 400 280"
backgroundColor="#f3f3f3"
foregroundColor="#e6e6e6"
{...props}
>
<rect x="0" y="80" rx="2" ry="2" width="200" height="20" />
<rect x="0" y="0" rx="2" ry="2" width="250" height="30" />
<rect x="0" y="38" rx="2" ry="2" width="300" height="15" />
<rect x="0" y="175" rx="2" ry="2" width="200" height="20" />
<rect x="1" y="205" rx="2" ry="2" width="385" height="38" />
<rect x="0" y="110" rx="2" ry="2" width="385" height="38" />
</ContentLoader>
<AuthInsiderCard>
<Fields>
<SkeletonField />
<SkeletonField />
<SkeletonField />
</Fields>
</AuthInsiderCard>
) : (
children
);
}
function SkeletonField() {
return (
<SkeletonFieldRoot>
<Skeleton>XXXX XXXX</Skeleton>
<Skeleton minWidth={100}>XXXX XXXX XXXX XXXX</Skeleton>
</SkeletonFieldRoot>
);
}
const Fields = styled.div`
display: flex;
flex-direction: column;
gap: 20px;
`;
const SkeletonFieldRoot = styled.div`
display: flex;
flex-direction: column;
gap: 8px;
`;

View File

@@ -42,10 +42,6 @@ export const SendResetPasswordSchema = Yup.object().shape({
export const InviteAcceptSchema = Yup.object().shape({
first_name: Yup.string().required().label(intl.get('first_name_')),
last_name: Yup.string().required().label(intl.get('last_name_')),
phone_number: Yup.string()
.matches()
.required()
.label(intl.get('phone_number')),
password: Yup.string().min(4).required().label(intl.get('password')),
});