From eff87f26662f293e416dae7d6e875136c1ecf8ba Mon Sep 17 00:00:00 2001 From: GitStart <1501599+gitstart@users.noreply.github.com> Date: Tue, 7 Mar 2023 11:26:56 +0200 Subject: [PATCH] feat: move form into useForm from antd (#2403) Co-authored-by: gitstart Co-authored-by: palashgdev Co-authored-by: Vishal Sharma --- frontend/src/container/Login/index.tsx | 58 ++--- frontend/src/container/Login/styles.ts | 8 +- .../src/container/ResetPassword/index.tsx | 73 +++--- .../src/container/ResetPassword/styles.ts | 8 +- frontend/src/pages/SignUp/SignUp.tsx | 244 +++++++++--------- frontend/src/pages/SignUp/styles.ts | 8 +- 6 files changed, 194 insertions(+), 205 deletions(-) diff --git a/frontend/src/container/Login/index.tsx b/frontend/src/container/Login/index.tsx index a8fda93908..cb9775fbe8 100644 --- a/frontend/src/container/Login/index.tsx +++ b/frontend/src/container/Login/index.tsx @@ -1,4 +1,4 @@ -import { Button, Input, Space, Tooltip, Typography } from 'antd'; +import { Button, Form, Input, Space, Tooltip, Typography } from 'antd'; import getUserVersion from 'api/user/getVersion'; import loginApi from 'api/user/login'; import loginPrecheckApi from 'api/user/loginPrecheck'; @@ -23,6 +23,8 @@ interface LoginProps { withPassword: string; } +type FormValues = { email: string; password: string }; + function Login({ jwt, refreshjwt, @@ -32,8 +34,6 @@ function Login({ }: LoginProps): JSX.Element { const { t } = useTranslation(['login']); const [isLoading, setIsLoading] = useState(false); - const [email, setEmail] = useState(''); - const [password, setPassword] = useState(''); const [precheckResult, setPrecheckResult] = useState({ sso: false, @@ -67,6 +67,8 @@ function Login({ } }, [getUserVersionResponse]); + const [form] = Form.useForm(); + useEffect(() => { if (withPassword === 'Y') { setPrecheckComplete(true); @@ -94,6 +96,7 @@ function Login({ }, [ssoerror, t, notifications]); const onNextHandler = async (): Promise => { + const email = form.getFieldValue('email'); if (!email) { notifications.error({ message: t('invalid_email'), @@ -129,22 +132,11 @@ function Login({ setPrecheckInProcess(false); }; - const onChangeHandler = ( - setFunc: React.Dispatch>, - value: string, - ): void => { - setFunc(value); - }; - const { sso, canSelfRegister } = precheckResult; - const onSubmitHandler: React.FormEventHandler = async ( - event, - ) => { + const onSubmitHandler: () => Promise = async () => { try { - event.preventDefault(); - event.persist(); - + const { email, password } = form.getFieldsValue(); if (!precheckComplete) { onNextHandler(); return; @@ -208,33 +200,27 @@ function Login({ return ( - + {t('login_page_title')} - onChangeHandler(setEmail, event.target.value)} - value={email} - disabled={isLoading} - /> + + + {precheckComplete && !sso && ( - - onChangeHandler(setPassword, event.target.value) - } - disabled={isLoading} - value={password} - /> + + + {t('forgot_password')} diff --git a/frontend/src/container/Login/styles.ts b/frontend/src/container/Login/styles.ts index cfead5fc06..562cd1a7ec 100644 --- a/frontend/src/container/Login/styles.ts +++ b/frontend/src/container/Login/styles.ts @@ -1,4 +1,4 @@ -import { Card } from 'antd'; +import { Card, Form } from 'antd'; import styled from 'styled-components'; export const FormWrapper = styled(Card)` @@ -22,11 +22,15 @@ export const Label = styled.label` line-height: 24px; `; -export const FormContainer = styled.form` +export const FormContainer = styled(Form)` display: flex; flex-direction: column; align-items: flex-start; width: 100%; + + & .ant-form-item { + margin-bottom: 0px; + } `; export const ParentContainer = styled.div` diff --git a/frontend/src/container/ResetPassword/index.tsx b/frontend/src/container/ResetPassword/index.tsx index 5245676866..69e0b7b047 100644 --- a/frontend/src/container/ResetPassword/index.tsx +++ b/frontend/src/container/ResetPassword/index.tsx @@ -1,4 +1,4 @@ -import { Button, Input, Typography } from 'antd'; +import { Button, Form, Input, Typography } from 'antd'; import resetPasswordApi from 'api/user/resetPassword'; import { Logout } from 'api/utils'; import WelcomeLeftContainer from 'components/WelcomeLeftContainer'; @@ -10,13 +10,13 @@ import React, { useEffect, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { useLocation } from 'react-use'; -import { ButtonContainer, FormWrapper } from './styles'; +import { ButtonContainer, FormContainer, FormWrapper } from './styles'; const { Title } = Typography; +type FormValues = { password: string; confirmPassword: string }; + function ResetPassword({ version }: ResetPasswordProps): JSX.Element { - const [password, setPassword] = useState(''); - const [confirmPassword, setConfirmPassword] = useState(''); const [confirmPasswordError, setConfirmPasswordError] = useState( false, ); @@ -27,6 +27,7 @@ function ResetPassword({ version }: ResetPasswordProps): JSX.Element { const token = params.get('token'); const { notifications } = useNotifications(); + const [form] = Form.useForm(); useEffect(() => { if (!token) { Logout(); @@ -34,20 +35,10 @@ function ResetPassword({ version }: ResetPasswordProps): JSX.Element { } }, [token]); - const setState = ( - value: string, - setFunction: React.Dispatch>, - ): void => { - setFunction(value); - }; - - const handleSubmit: React.FormEventHandler = async ( - event, - ): Promise => { + const handleSubmit: () => Promise = async () => { try { setLoading(true); - event.preventDefault(); - event.persist(); + const { password } = form.getFieldsValue(); const response = await resetPasswordApi({ password, @@ -81,40 +72,38 @@ function ResetPassword({ version }: ResetPasswordProps): JSX.Element { }); } }; + const handleValuesChange: (changedValues: FormValues) => void = ( + changedValues, + ) => { + if ('confirmPassword' in changedValues) { + const { confirmPassword } = changedValues; + + const isSamePassword = form.getFieldValue('password') === confirmPassword; + setConfirmPasswordError(!isSamePassword); + } + }; return ( -
+ Reset Your Password
- { - setState(e.target.value, setPassword); - }} - required - id="currentPassword" - /> + + +
- { - const updateValue = e.target.value; - setState(updateValue, setConfirmPassword); - if (password !== updateValue) { - setConfirmPasswordError(true); - } else { - setConfirmPasswordError(false); - } - }} - required - id="UpdatePassword" - /> + + + {confirmPasswordError && ( - + ); diff --git a/frontend/src/container/ResetPassword/styles.ts b/frontend/src/container/ResetPassword/styles.ts index 8405f31669..e59a453695 100644 --- a/frontend/src/container/ResetPassword/styles.ts +++ b/frontend/src/container/ResetPassword/styles.ts @@ -1,4 +1,4 @@ -import { Card } from 'antd'; +import { Card, Form } from 'antd'; import styled from 'styled-components'; export const FormWrapper = styled(Card)` @@ -14,3 +14,9 @@ export const ButtonContainer = styled.div` justify-content: center; align-items: center; `; + +export const FormContainer = styled(Form)` + & .ant-form-item { + margin-bottom: 0px; + } +`; diff --git a/frontend/src/pages/SignUp/SignUp.tsx b/frontend/src/pages/SignUp/SignUp.tsx index 53174a3610..a8c1c1687c 100644 --- a/frontend/src/pages/SignUp/SignUp.tsx +++ b/frontend/src/pages/SignUp/SignUp.tsx @@ -1,4 +1,4 @@ -import { Button, Input, Space, Switch, Typography } from 'antd'; +import { Button, Form, Input, Space, Switch, Typography } from 'antd'; import editOrg from 'api/user/editOrg'; import getInviteDetails from 'api/user/getInviteDetails'; import loginApi from 'api/user/login'; @@ -16,11 +16,27 @@ import { SuccessResponse } from 'types/api'; import { PayloadProps } from 'types/api/user/getUser'; import * as loginPrecheck from 'types/api/user/loginPrecheck'; -import { ButtonContainer, FormWrapper, Label, MarginTop } from './styles'; +import { + ButtonContainer, + FormContainer, + FormWrapper, + Label, + MarginTop, +} from './styles'; import { isPasswordNotValidMessage, isPasswordValid } from './utils'; const { Title } = Typography; +type FormValues = { + firstName: string; + email: string; + organizationName: string; + password: string; + confirmPassword: string; + hasOptedUpdates: boolean; + isAnonymous: boolean; +}; + function SignUp({ version }: SignUpProps): JSX.Element { const { t } = useTranslation(['signup']); const [loading, setLoading] = useState(false); @@ -30,13 +46,6 @@ function SignUp({ version }: SignUpProps): JSX.Element { isUser: false, }); - const [firstName, setFirstName] = useState(''); - const [email, setEmail] = useState(''); - const [organizationName, setOrganizationName] = useState(''); - const [hasOptedUpdates, setHasOptedUpdates] = useState(true); - const [isAnonymous, setIsAnonymous] = useState(false); - const [password, setPassword] = useState(''); - const [confirmPassword, setConfirmPassword] = useState(''); const [confirmPasswordError, setConfirmPasswordError] = useState( false, ); @@ -58,6 +67,7 @@ function SignUp({ version }: SignUpProps): JSX.Element { }); const { notifications } = useNotifications(); + const [form] = Form.useForm(); useEffect(() => { if ( @@ -66,9 +76,9 @@ function SignUp({ version }: SignUpProps): JSX.Element { ) { const responseDetails = getInviteDetailsResponse.data.payload; if (responseDetails.precheck) setPrecheck(responseDetails.precheck); - setFirstName(responseDetails.name); - setEmail(responseDetails.email); - setOrganizationName(responseDetails.organization); + form.setFieldValue('firstName', responseDetails.name); + form.setFieldValue('email', responseDetails.email); + form.setFieldValue('organizationName', responseDetails.organization); setIsDetailsDisable(true); } if ( @@ -86,21 +96,17 @@ function SignUp({ version }: SignUpProps): JSX.Element { getInviteDetailsResponse.status, getInviteDetailsResponse, notifications, + form, ]); - const setState = ( - value: string, - setFunction: React.Dispatch>, - ): void => { - setFunction(value); - }; - const isPreferenceVisible = token === null; const commonHandler = async ( + values: FormValues, callback: (e: SuccessResponse) => Promise | VoidFunction, ): Promise => { try { + const { organizationName, password, firstName, email } = values; const response = await signUpApi({ email, name: firstName, @@ -145,6 +151,11 @@ function SignUp({ version }: SignUpProps): JSX.Element { const onAdminAfterLogin = async ( userResponse: SuccessResponse, ): Promise => { + const { + organizationName, + isAnonymous, + hasOptedUpdates, + } = form.getFieldsValue(); const editResponse = await editOrg({ isAnonymous, name: organizationName, @@ -159,9 +170,7 @@ function SignUp({ version }: SignUpProps): JSX.Element { }); } }; - const handleSubmitSSO = async ( - e: React.FormEvent, - ): Promise => { + const handleSubmitSSO = async (): Promise => { if (!params.get('token')) { notifications.error({ message: t('token_required'), @@ -171,12 +180,12 @@ function SignUp({ version }: SignUpProps): JSX.Element { setLoading(true); try { - e.preventDefault(); + const values = form.getFieldsValue(); const response = await signUpApi({ - email, - name: firstName, - orgName: organizationName, - password, + email: values.email, + name: values.firstName, + orgName: values.organizationName, + password: values.password, token: params.get('token') || undefined, sourceUrl: encodeURIComponent(window.location.href), }); @@ -207,22 +216,23 @@ function SignUp({ version }: SignUpProps): JSX.Element { setLoading(false); }; - const handleSubmit = (e: React.FormEvent): void => { + const handleSubmit = (): void => { (async (): Promise => { try { - e.preventDefault(); + const values = form.getFieldsValue(); setLoading(true); - if (!isPasswordValid(password)) { + if (!isPasswordValid(values.password)) { setIsPasswordPolicyError(true); setLoading(false); return; } if (isPreferenceVisible) { - await commonHandler(onAdminAfterLogin); + await commonHandler(values, onAdminAfterLogin); } else { await commonHandler( + values, async (): Promise => { history.push(ROUTES.APPLICATION); }, @@ -239,108 +249,101 @@ function SignUp({ version }: SignUpProps): JSX.Element { })(); }; - const onSwitchHandler = ( - value: boolean, - setFunction: React.Dispatch>, - ): void => { - setFunction(value); - }; - const getIsNameVisible = (): boolean => - !(firstName.length === 0 && !isPreferenceVisible); + !(form.getFieldValue('firstName') === 0 && !isPreferenceVisible); const isNameVisible = getIsNameVisible(); - useEffect(() => { - if (!isPasswordValid(password) && password.length) { - setIsPasswordPolicyError(true); - } else { - setIsPasswordPolicyError(false); - } + const handleValuesChange: (changedValues: Partial) => void = ( + changedValues, + ) => { + if ('password' in changedValues || 'confirmPassword' in changedValues) { + const { password, confirmPassword } = form.getFieldsValue(); - if (password !== confirmPassword) { - setConfirmPasswordError(true); - } else { - setConfirmPasswordError(false); + const isInvalidPassword = !isPasswordValid(password) && password.length > 0; + setIsPasswordPolicyError(isInvalidPassword); + + const isSamePassword = password === confirmPassword; + setConfirmPasswordError(!isSamePassword); } - }, [password, confirmPassword]); + }; + + const isValidForm: () => boolean = () => { + const values = form.getFieldsValue(); + return ( + loading || + !values.email || + !values.organizationName || + (!precheck.sso && (!values.password || !values.confirmPassword)) || + (!isDetailsDisable && !values.firstName) || + confirmPasswordError || + isPasswordPolicyError + ); + }; return ( -
+ Create your account
- { - setState(e.target.value, setEmail); - }} - required - id="signupEmail" - disabled={isDetailsDisable} - /> + + +
{isNameVisible && (
- - { - setState(e.target.value, setFirstName); - }} - required - id="signupFirstName" - disabled={isDetailsDisable} - /> + {' '} + + +
)}
- - { - setState(e.target.value, setOrganizationName); - }} - required - id="organizationName" - disabled={isDetailsDisable} - /> + {' '} + + +
{!precheck.sso && (
- - { - setState(e.target.value, setPassword); - }} - required - id="currentPassword" - /> + {' '} + + +
)} {!precheck.sso && (
- - { - const updateValue = e.target.value; - setState(updateValue, setConfirmPassword); - }} - required - id="confirmPassword" - /> - + {' '} + + + {confirmPasswordError && ( - onSwitchHandler(value, setHasOptedUpdates)} - checked={hasOptedUpdates} - /> + + + + {t('prompt_keepme_posted')} - onSwitchHandler(value, setIsAnonymous)} - checked={isAnonymous} - /> + + + {t('prompt_anonymise')} @@ -410,20 +416,12 @@ function SignUp({ version }: SignUpProps): JSX.Element { htmlType="submit" data-attr="signup" loading={loading} - disabled={ - loading || - !email || - !organizationName || - (!precheck.sso && (!password || !confirmPassword)) || - (!isDetailsDisable && !firstName) || - confirmPasswordError || - isPasswordPolicyError - } + disabled={isValidForm()} > {t('button_get_started')} - + ); diff --git a/frontend/src/pages/SignUp/styles.ts b/frontend/src/pages/SignUp/styles.ts index 3e6064f6f7..f8224e7dbd 100644 --- a/frontend/src/pages/SignUp/styles.ts +++ b/frontend/src/pages/SignUp/styles.ts @@ -1,4 +1,4 @@ -import { Card } from 'antd'; +import { Card, Form } from 'antd'; import React from 'react'; import styled from 'styled-components'; @@ -31,3 +31,9 @@ interface Props { export const MarginTop = styled.div` margin-top: ${({ marginTop = 0 }): number | string => marginTop}; `; + +export const FormContainer = styled(Form)` + & .ant-form-item { + margin-bottom: 0px; + } +`;