feat: move form into useForm from antd (#2403)

Co-authored-by: gitstart <gitstart@users.noreply.github.com>
Co-authored-by: palashgdev <palashgdev@gmail.com>
Co-authored-by: Vishal Sharma <makeavish786@gmail.com>
This commit is contained in:
GitStart 2023-03-07 11:26:56 +02:00 committed by GitHub
parent 3f5171dc69
commit eff87f2666
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 194 additions and 205 deletions

View File

@ -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 getUserVersion from 'api/user/getVersion';
import loginApi from 'api/user/login'; import loginApi from 'api/user/login';
import loginPrecheckApi from 'api/user/loginPrecheck'; import loginPrecheckApi from 'api/user/loginPrecheck';
@ -23,6 +23,8 @@ interface LoginProps {
withPassword: string; withPassword: string;
} }
type FormValues = { email: string; password: string };
function Login({ function Login({
jwt, jwt,
refreshjwt, refreshjwt,
@ -32,8 +34,6 @@ function Login({
}: LoginProps): JSX.Element { }: LoginProps): JSX.Element {
const { t } = useTranslation(['login']); const { t } = useTranslation(['login']);
const [isLoading, setIsLoading] = useState<boolean>(false); const [isLoading, setIsLoading] = useState<boolean>(false);
const [email, setEmail] = useState<string>('');
const [password, setPassword] = useState<string>('');
const [precheckResult, setPrecheckResult] = useState<PrecheckResultType>({ const [precheckResult, setPrecheckResult] = useState<PrecheckResultType>({
sso: false, sso: false,
@ -67,6 +67,8 @@ function Login({
} }
}, [getUserVersionResponse]); }, [getUserVersionResponse]);
const [form] = Form.useForm<FormValues>();
useEffect(() => { useEffect(() => {
if (withPassword === 'Y') { if (withPassword === 'Y') {
setPrecheckComplete(true); setPrecheckComplete(true);
@ -94,6 +96,7 @@ function Login({
}, [ssoerror, t, notifications]); }, [ssoerror, t, notifications]);
const onNextHandler = async (): Promise<void> => { const onNextHandler = async (): Promise<void> => {
const email = form.getFieldValue('email');
if (!email) { if (!email) {
notifications.error({ notifications.error({
message: t('invalid_email'), message: t('invalid_email'),
@ -129,22 +132,11 @@ function Login({
setPrecheckInProcess(false); setPrecheckInProcess(false);
}; };
const onChangeHandler = (
setFunc: React.Dispatch<React.SetStateAction<string>>,
value: string,
): void => {
setFunc(value);
};
const { sso, canSelfRegister } = precheckResult; const { sso, canSelfRegister } = precheckResult;
const onSubmitHandler: React.FormEventHandler<HTMLFormElement> = async ( const onSubmitHandler: () => Promise<void> = async () => {
event,
) => {
try { try {
event.preventDefault(); const { email, password } = form.getFieldsValue();
event.persist();
if (!precheckComplete) { if (!precheckComplete) {
onNextHandler(); onNextHandler();
return; return;
@ -208,33 +200,27 @@ function Login({
return ( return (
<FormWrapper> <FormWrapper>
<FormContainer onSubmit={onSubmitHandler}> <FormContainer form={form} onFinish={onSubmitHandler}>
<Title level={4}>{t('login_page_title')}</Title> <Title level={4}>{t('login_page_title')}</Title>
<ParentContainer> <ParentContainer>
<Label htmlFor="signupEmail">{t('label_email')}</Label> <Label htmlFor="signupEmail">{t('label_email')}</Label>
<Input <FormContainer.Item name="email">
placeholder={t('placeholder_email')} <Input
type="email" type="email"
autoFocus id="loginEmail"
required required
id="loginEmail" placeholder={t('placeholder_email')}
onChange={(event): void => onChangeHandler(setEmail, event.target.value)} autoFocus
value={email} disabled={isLoading}
disabled={isLoading} />
/> </FormContainer.Item>
</ParentContainer> </ParentContainer>
{precheckComplete && !sso && ( {precheckComplete && !sso && (
<ParentContainer> <ParentContainer>
<Label htmlFor="Password">{t('label_password')}</Label> <Label htmlFor="Password">{t('label_password')}</Label>
<Input.Password <FormContainer.Item name="password">
required <Input.Password required id="currentPassword" disabled={isLoading} />
id="currentPassword" </FormContainer.Item>
onChange={(event): void =>
onChangeHandler(setPassword, event.target.value)
}
disabled={isLoading}
value={password}
/>
<Tooltip title={t('prompt_forgot_password')}> <Tooltip title={t('prompt_forgot_password')}>
<Typography.Link>{t('forgot_password')}</Typography.Link> <Typography.Link>{t('forgot_password')}</Typography.Link>
</Tooltip> </Tooltip>

View File

@ -1,4 +1,4 @@
import { Card } from 'antd'; import { Card, Form } from 'antd';
import styled from 'styled-components'; import styled from 'styled-components';
export const FormWrapper = styled(Card)` export const FormWrapper = styled(Card)`
@ -22,11 +22,15 @@ export const Label = styled.label`
line-height: 24px; line-height: 24px;
`; `;
export const FormContainer = styled.form` export const FormContainer = styled(Form)`
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: flex-start; align-items: flex-start;
width: 100%; width: 100%;
& .ant-form-item {
margin-bottom: 0px;
}
`; `;
export const ParentContainer = styled.div` export const ParentContainer = styled.div`

View File

@ -1,4 +1,4 @@
import { Button, Input, Typography } from 'antd'; import { Button, Form, Input, Typography } from 'antd';
import resetPasswordApi from 'api/user/resetPassword'; import resetPasswordApi from 'api/user/resetPassword';
import { Logout } from 'api/utils'; import { Logout } from 'api/utils';
import WelcomeLeftContainer from 'components/WelcomeLeftContainer'; import WelcomeLeftContainer from 'components/WelcomeLeftContainer';
@ -10,13 +10,13 @@ import React, { useEffect, useState } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { useLocation } from 'react-use'; import { useLocation } from 'react-use';
import { ButtonContainer, FormWrapper } from './styles'; import { ButtonContainer, FormContainer, FormWrapper } from './styles';
const { Title } = Typography; const { Title } = Typography;
type FormValues = { password: string; confirmPassword: string };
function ResetPassword({ version }: ResetPasswordProps): JSX.Element { function ResetPassword({ version }: ResetPasswordProps): JSX.Element {
const [password, setPassword] = useState<string>('');
const [confirmPassword, setConfirmPassword] = useState<string>('');
const [confirmPasswordError, setConfirmPasswordError] = useState<boolean>( const [confirmPasswordError, setConfirmPasswordError] = useState<boolean>(
false, false,
); );
@ -27,6 +27,7 @@ function ResetPassword({ version }: ResetPasswordProps): JSX.Element {
const token = params.get('token'); const token = params.get('token');
const { notifications } = useNotifications(); const { notifications } = useNotifications();
const [form] = Form.useForm<FormValues>();
useEffect(() => { useEffect(() => {
if (!token) { if (!token) {
Logout(); Logout();
@ -34,20 +35,10 @@ function ResetPassword({ version }: ResetPasswordProps): JSX.Element {
} }
}, [token]); }, [token]);
const setState = ( const handleSubmit: () => Promise<void> = async () => {
value: string,
setFunction: React.Dispatch<React.SetStateAction<string>>,
): void => {
setFunction(value);
};
const handleSubmit: React.FormEventHandler<HTMLFormElement> = async (
event,
): Promise<void> => {
try { try {
setLoading(true); setLoading(true);
event.preventDefault(); const { password } = form.getFieldsValue();
event.persist();
const response = await resetPasswordApi({ const response = await resetPasswordApi({
password, 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 ( return (
<WelcomeLeftContainer version={version}> <WelcomeLeftContainer version={version}>
<FormWrapper> <FormWrapper>
<form onSubmit={handleSubmit}> <FormContainer
form={form}
onValuesChange={handleValuesChange}
onFinish={handleSubmit}
>
<Title level={4}>Reset Your Password</Title> <Title level={4}>Reset Your Password</Title>
<div> <div>
<Label htmlFor="Password">Password</Label> <Label htmlFor="Password">Password</Label>
<Input.Password <FormContainer.Item noStyle name="password">
value={password} <Input.Password required id="currentPassword" />
onChange={(e): void => { </FormContainer.Item>
setState(e.target.value, setPassword);
}}
required
id="currentPassword"
/>
</div> </div>
<div> <div>
<Label htmlFor="ConfirmPassword">Confirm Password</Label> <Label htmlFor="ConfirmPassword">Confirm Password</Label>
<Input.Password <FormContainer.Item noStyle name="confirmPassword">
value={confirmPassword} <Input.Password required id="UpdatePassword" />
onChange={(e): void => { </FormContainer.Item>
const updateValue = e.target.value;
setState(updateValue, setConfirmPassword);
if (password !== updateValue) {
setConfirmPasswordError(true);
} else {
setConfirmPasswordError(false);
}
}}
required
id="UpdatePassword"
/>
{confirmPasswordError && ( {confirmPasswordError && (
<Typography.Paragraph <Typography.Paragraph
@ -137,8 +126,8 @@ function ResetPassword({ version }: ResetPasswordProps): JSX.Element {
loading={loading} loading={loading}
disabled={ disabled={
loading || loading ||
!password || !form.getFieldValue('password') ||
!confirmPassword || !form.getFieldValue('confirmPassword') ||
confirmPasswordError || confirmPasswordError ||
token === null token === null
} }
@ -146,7 +135,7 @@ function ResetPassword({ version }: ResetPasswordProps): JSX.Element {
Get Started Get Started
</Button> </Button>
</ButtonContainer> </ButtonContainer>
</form> </FormContainer>
</FormWrapper> </FormWrapper>
</WelcomeLeftContainer> </WelcomeLeftContainer>
); );

View File

@ -1,4 +1,4 @@
import { Card } from 'antd'; import { Card, Form } from 'antd';
import styled from 'styled-components'; import styled from 'styled-components';
export const FormWrapper = styled(Card)` export const FormWrapper = styled(Card)`
@ -14,3 +14,9 @@ export const ButtonContainer = styled.div`
justify-content: center; justify-content: center;
align-items: center; align-items: center;
`; `;
export const FormContainer = styled(Form)`
& .ant-form-item {
margin-bottom: 0px;
}
`;

View File

@ -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 editOrg from 'api/user/editOrg';
import getInviteDetails from 'api/user/getInviteDetails'; import getInviteDetails from 'api/user/getInviteDetails';
import loginApi from 'api/user/login'; import loginApi from 'api/user/login';
@ -16,11 +16,27 @@ import { SuccessResponse } from 'types/api';
import { PayloadProps } from 'types/api/user/getUser'; import { PayloadProps } from 'types/api/user/getUser';
import * as loginPrecheck from 'types/api/user/loginPrecheck'; 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'; import { isPasswordNotValidMessage, isPasswordValid } from './utils';
const { Title } = Typography; 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 { function SignUp({ version }: SignUpProps): JSX.Element {
const { t } = useTranslation(['signup']); const { t } = useTranslation(['signup']);
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
@ -30,13 +46,6 @@ function SignUp({ version }: SignUpProps): JSX.Element {
isUser: false, isUser: false,
}); });
const [firstName, setFirstName] = useState<string>('');
const [email, setEmail] = useState<string>('');
const [organizationName, setOrganizationName] = useState<string>('');
const [hasOptedUpdates, setHasOptedUpdates] = useState<boolean>(true);
const [isAnonymous, setIsAnonymous] = useState<boolean>(false);
const [password, setPassword] = useState<string>('');
const [confirmPassword, setConfirmPassword] = useState<string>('');
const [confirmPasswordError, setConfirmPasswordError] = useState<boolean>( const [confirmPasswordError, setConfirmPasswordError] = useState<boolean>(
false, false,
); );
@ -58,6 +67,7 @@ function SignUp({ version }: SignUpProps): JSX.Element {
}); });
const { notifications } = useNotifications(); const { notifications } = useNotifications();
const [form] = Form.useForm<FormValues>();
useEffect(() => { useEffect(() => {
if ( if (
@ -66,9 +76,9 @@ function SignUp({ version }: SignUpProps): JSX.Element {
) { ) {
const responseDetails = getInviteDetailsResponse.data.payload; const responseDetails = getInviteDetailsResponse.data.payload;
if (responseDetails.precheck) setPrecheck(responseDetails.precheck); if (responseDetails.precheck) setPrecheck(responseDetails.precheck);
setFirstName(responseDetails.name); form.setFieldValue('firstName', responseDetails.name);
setEmail(responseDetails.email); form.setFieldValue('email', responseDetails.email);
setOrganizationName(responseDetails.organization); form.setFieldValue('organizationName', responseDetails.organization);
setIsDetailsDisable(true); setIsDetailsDisable(true);
} }
if ( if (
@ -86,21 +96,17 @@ function SignUp({ version }: SignUpProps): JSX.Element {
getInviteDetailsResponse.status, getInviteDetailsResponse.status,
getInviteDetailsResponse, getInviteDetailsResponse,
notifications, notifications,
form,
]); ]);
const setState = (
value: string,
setFunction: React.Dispatch<React.SetStateAction<string>>,
): void => {
setFunction(value);
};
const isPreferenceVisible = token === null; const isPreferenceVisible = token === null;
const commonHandler = async ( const commonHandler = async (
values: FormValues,
callback: (e: SuccessResponse<PayloadProps>) => Promise<void> | VoidFunction, callback: (e: SuccessResponse<PayloadProps>) => Promise<void> | VoidFunction,
): Promise<void> => { ): Promise<void> => {
try { try {
const { organizationName, password, firstName, email } = values;
const response = await signUpApi({ const response = await signUpApi({
email, email,
name: firstName, name: firstName,
@ -145,6 +151,11 @@ function SignUp({ version }: SignUpProps): JSX.Element {
const onAdminAfterLogin = async ( const onAdminAfterLogin = async (
userResponse: SuccessResponse<PayloadProps>, userResponse: SuccessResponse<PayloadProps>,
): Promise<void> => { ): Promise<void> => {
const {
organizationName,
isAnonymous,
hasOptedUpdates,
} = form.getFieldsValue();
const editResponse = await editOrg({ const editResponse = await editOrg({
isAnonymous, isAnonymous,
name: organizationName, name: organizationName,
@ -159,9 +170,7 @@ function SignUp({ version }: SignUpProps): JSX.Element {
}); });
} }
}; };
const handleSubmitSSO = async ( const handleSubmitSSO = async (): Promise<void> => {
e: React.FormEvent<HTMLFormElement>,
): Promise<void> => {
if (!params.get('token')) { if (!params.get('token')) {
notifications.error({ notifications.error({
message: t('token_required'), message: t('token_required'),
@ -171,12 +180,12 @@ function SignUp({ version }: SignUpProps): JSX.Element {
setLoading(true); setLoading(true);
try { try {
e.preventDefault(); const values = form.getFieldsValue();
const response = await signUpApi({ const response = await signUpApi({
email, email: values.email,
name: firstName, name: values.firstName,
orgName: organizationName, orgName: values.organizationName,
password, password: values.password,
token: params.get('token') || undefined, token: params.get('token') || undefined,
sourceUrl: encodeURIComponent(window.location.href), sourceUrl: encodeURIComponent(window.location.href),
}); });
@ -207,22 +216,23 @@ function SignUp({ version }: SignUpProps): JSX.Element {
setLoading(false); setLoading(false);
}; };
const handleSubmit = (e: React.FormEvent<HTMLFormElement>): void => { const handleSubmit = (): void => {
(async (): Promise<void> => { (async (): Promise<void> => {
try { try {
e.preventDefault(); const values = form.getFieldsValue();
setLoading(true); setLoading(true);
if (!isPasswordValid(password)) { if (!isPasswordValid(values.password)) {
setIsPasswordPolicyError(true); setIsPasswordPolicyError(true);
setLoading(false); setLoading(false);
return; return;
} }
if (isPreferenceVisible) { if (isPreferenceVisible) {
await commonHandler(onAdminAfterLogin); await commonHandler(values, onAdminAfterLogin);
} else { } else {
await commonHandler( await commonHandler(
values,
async (): Promise<void> => { async (): Promise<void> => {
history.push(ROUTES.APPLICATION); history.push(ROUTES.APPLICATION);
}, },
@ -239,108 +249,101 @@ function SignUp({ version }: SignUpProps): JSX.Element {
})(); })();
}; };
const onSwitchHandler = (
value: boolean,
setFunction: React.Dispatch<React.SetStateAction<boolean>>,
): void => {
setFunction(value);
};
const getIsNameVisible = (): boolean => const getIsNameVisible = (): boolean =>
!(firstName.length === 0 && !isPreferenceVisible); !(form.getFieldValue('firstName') === 0 && !isPreferenceVisible);
const isNameVisible = getIsNameVisible(); const isNameVisible = getIsNameVisible();
useEffect(() => { const handleValuesChange: (changedValues: Partial<FormValues>) => void = (
if (!isPasswordValid(password) && password.length) { changedValues,
setIsPasswordPolicyError(true); ) => {
} else { if ('password' in changedValues || 'confirmPassword' in changedValues) {
setIsPasswordPolicyError(false); const { password, confirmPassword } = form.getFieldsValue();
}
if (password !== confirmPassword) { const isInvalidPassword = !isPasswordValid(password) && password.length > 0;
setConfirmPasswordError(true); setIsPasswordPolicyError(isInvalidPassword);
} else {
setConfirmPasswordError(false); 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 ( return (
<WelcomeLeftContainer version={version}> <WelcomeLeftContainer version={version}>
<FormWrapper> <FormWrapper>
<form onSubmit={!precheck.sso ? handleSubmit : handleSubmitSSO}> <FormContainer
onFinish={!precheck.sso ? handleSubmit : handleSubmitSSO}
onValuesChange={handleValuesChange}
initialValues={{ hasOptedUpdates: true, isAnonymous: false }}
form={form}
>
<Title level={4}>Create your account</Title> <Title level={4}>Create your account</Title>
<div> <div>
<Label htmlFor="signupEmail">{t('label_email')}</Label> <Label htmlFor="signupEmail">{t('label_email')}</Label>
<Input <FormContainer.Item noStyle name="email">
placeholder={t('placeholder_email')} <Input
type="email" placeholder={t('placeholder_email')}
autoFocus type="email"
value={email} autoFocus
onChange={(e): void => { required
setState(e.target.value, setEmail); id="signupEmail"
}} disabled={isDetailsDisable}
required />
id="signupEmail" </FormContainer.Item>
disabled={isDetailsDisable}
/>
</div> </div>
{isNameVisible && ( {isNameVisible && (
<div> <div>
<Label htmlFor="signupFirstName">{t('label_firstname')}</Label> <Label htmlFor="signupFirstName">{t('label_firstname')}</Label>{' '}
<Input <FormContainer.Item noStyle name="firstName">
placeholder={t('placeholder_firstname')} <Input
value={firstName} placeholder={t('placeholder_firstname')}
onChange={(e): void => { required
setState(e.target.value, setFirstName); id="signupFirstName"
}} disabled={isDetailsDisable}
required />
id="signupFirstName" </FormContainer.Item>
disabled={isDetailsDisable}
/>
</div> </div>
)} )}
<div> <div>
<Label htmlFor="organizationName">{t('label_orgname')}</Label> <Label htmlFor="organizationName">{t('label_orgname')}</Label>{' '}
<Input <FormContainer.Item noStyle name="organizationName">
placeholder={t('placeholder_orgname')} <Input
value={organizationName} placeholder={t('placeholder_orgname')}
onChange={(e): void => { required
setState(e.target.value, setOrganizationName); id="organizationName"
}} disabled={isDetailsDisable}
required />
id="organizationName" </FormContainer.Item>
disabled={isDetailsDisable}
/>
</div> </div>
{!precheck.sso && ( {!precheck.sso && (
<div> <div>
<Label htmlFor="Password">{t('label_password')}</Label> <Label htmlFor="Password">{t('label_password')}</Label>{' '}
<Input.Password <FormContainer.Item noStyle name="password">
value={password} <Input.Password required id="currentPassword" />
onChange={(e): void => { </FormContainer.Item>
setState(e.target.value, setPassword);
}}
required
id="currentPassword"
/>
</div> </div>
)} )}
{!precheck.sso && ( {!precheck.sso && (
<div> <div>
<Label htmlFor="ConfirmPassword">{t('label_confirm_password')}</Label> <Label htmlFor="ConfirmPassword">{t('label_confirm_password')}</Label>{' '}
<Input.Password <FormContainer.Item noStyle name="confirmPassword">
value={confirmPassword} <Input.Password required id="confirmPassword" />
onChange={(e): void => { </FormContainer.Item>
const updateValue = e.target.value;
setState(updateValue, setConfirmPassword);
}}
required
id="confirmPassword"
/>
{confirmPasswordError && ( {confirmPasswordError && (
<Typography.Paragraph <Typography.Paragraph
italic italic
@ -371,20 +374,23 @@ function SignUp({ version }: SignUpProps): JSX.Element {
<> <>
<MarginTop marginTop="2.4375rem"> <MarginTop marginTop="2.4375rem">
<Space> <Space>
<Switch <FormContainer.Item
onChange={(value): void => onSwitchHandler(value, setHasOptedUpdates)} noStyle
checked={hasOptedUpdates} name="hasOptedUpdates"
/> valuePropName="checked"
>
<Switch />
</FormContainer.Item>
<Typography>{t('prompt_keepme_posted')} </Typography> <Typography>{t('prompt_keepme_posted')} </Typography>
</Space> </Space>
</MarginTop> </MarginTop>
<MarginTop marginTop="0.5rem"> <MarginTop marginTop="0.5rem">
<Space> <Space>
<Switch <FormContainer.Item noStyle name="isAnonymous" valuePropName="checked">
onChange={(value): void => onSwitchHandler(value, setIsAnonymous)} <Switch />
checked={isAnonymous} </FormContainer.Item>
/>
<Typography>{t('prompt_anonymise')}</Typography> <Typography>{t('prompt_anonymise')}</Typography>
</Space> </Space>
</MarginTop> </MarginTop>
@ -410,20 +416,12 @@ function SignUp({ version }: SignUpProps): JSX.Element {
htmlType="submit" htmlType="submit"
data-attr="signup" data-attr="signup"
loading={loading} loading={loading}
disabled={ disabled={isValidForm()}
loading ||
!email ||
!organizationName ||
(!precheck.sso && (!password || !confirmPassword)) ||
(!isDetailsDisable && !firstName) ||
confirmPasswordError ||
isPasswordPolicyError
}
> >
{t('button_get_started')} {t('button_get_started')}
</Button> </Button>
</ButtonContainer> </ButtonContainer>
</form> </FormContainer>
</FormWrapper> </FormWrapper>
</WelcomeLeftContainer> </WelcomeLeftContainer>
); );

View File

@ -1,4 +1,4 @@
import { Card } from 'antd'; import { Card, Form } from 'antd';
import React from 'react'; import React from 'react';
import styled from 'styled-components'; import styled from 'styled-components';
@ -31,3 +31,9 @@ interface Props {
export const MarginTop = styled.div<Props>` export const MarginTop = styled.div<Props>`
margin-top: ${({ marginTop = 0 }): number | string => marginTop}; margin-top: ${({ marginTop = 0 }): number | string => marginTop};
`; `;
export const FormContainer = styled(Form)`
& .ant-form-item {
margin-bottom: 0px;
}
`;