Skip to content

Commit

Permalink
Redesign login form, Profile card header
Browse files Browse the repository at this point in the history
  • Loading branch information
nothing9537 committed Oct 30, 2023
1 parent 05462c4 commit a3a9a18
Show file tree
Hide file tree
Showing 7 changed files with 168 additions and 63 deletions.
2 changes: 1 addition & 1 deletion json-server/db.json
Original file line number Diff line number Diff line change
Expand Up @@ -1209,7 +1209,7 @@
"isAppRedesigned": true
},
"jsonSettings": {
"theme": "app_sand_theme",
"theme": "app_light_theme",
"isArticlesPageWasOpenedOnce": true
},
"avatar": "https://source.boringavatars.com/pixel/120/Stefan?colors=26a653,2a1d8f,79646a"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
.LoginForm {
width: 500px;
display: flex;
flex-direction: column;
gap: 10px;
width: 400px;
}

.loginBtn {
Expand Down
112 changes: 80 additions & 32 deletions src/features/AuthByUserName/ui/LoginForm/LoginForm.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
import { FC, memo, useCallback } from 'react';
import { useTranslation } from 'react-i18next';
import { Input } from '@/shared/ui/deprecated/Input';
import { Text, TextTheme } from '@/shared/ui/deprecated/Text';
import { useAppTranslation } from '@/shared/lib/hooks/useAppTranslation';
import { Input as InputDeprecated } from '@/shared/ui/deprecated/Input';
import { Text as TextDeprecated, TextTheme as TextThemeDeprecated } from '@/shared/ui/deprecated/Text';
import { Button as ButtonDeprecated, ButtonTheme as ButtonThemeDeprecated } from '@/shared/ui/deprecated/Button';
import { VStack } from '@/shared/ui/redesigned/Stack';
import { Button, ButtonTheme } from '@/shared/ui/deprecated/Button';
import { Text } from '@/shared/ui/redesigned/Text';
import { Input } from '@/shared/ui/redesigned/Input';
import { Button } from '@/shared/ui/redesigned/Button';
import { classNames } from '@/shared/lib/classNames/classNames';
import { useAppDispatch } from '@/shared/lib/hooks/useAppDispatch';
import { useAppSelector } from '@/shared/lib/hooks/useAppSelector';
import { DynamicModuleWrapper, ReducersList } from '@/shared/lib/components/DynamicModuleWrapper';
import { ToggleFeatures } from '@/shared/lib/features';

import { loginActions, loginReducer } from '../../model/slices/loginSlice';
import { getLoginState } from '../../model/selectors/getLoginState/getLoginState';
import { loginByUsername } from '../../model/services/loginByUsername/loginByUsername';
Expand All @@ -23,7 +28,7 @@ const initialReducers: ReducersList = {
};

const LoginForm: FC<LoginFormProps> = memo(({ className, onSuccess }) => {
const { t } = useTranslation('navbar');
const { t } = useAppTranslation('navbar');
const { username, password, isLoading, error } = useAppSelector(getLoginState);
const dispatch = useAppDispatch();

Expand All @@ -39,39 +44,82 @@ const LoginForm: FC<LoginFormProps> = memo(({ className, onSuccess }) => {
const result = await dispatch(loginByUsername({ username, password }));

if (result.meta.requestStatus === 'fulfilled') {
// dispatch(initAuthData());
onSuccess();
}
}, [dispatch, username, password, onSuccess]);

/**
* @deprecated
*/
const LoginFormDeprecated = (
<VStack component="form" className={classNames(cls.LoginForm, {}, [className])}>
<TextDeprecated title={t('auth-form')} />
{error && (
<TextDeprecated text={t(error)} theme={TextThemeDeprecated.ERROR} />
)}
<InputDeprecated
autoFocus
placeholder={t('enter-username')}
type="text"
onChange={onChangeUsername}
value={username}
/>
<InputDeprecated
placeholder={t('enter-password')}
type="text"
onChange={onChangePassword}
value={password}
/>
<ButtonDeprecated
className={cls.loginBtn}
theme={ButtonThemeDeprecated.OUTLINE}
onClick={onLogin}
disabled={isLoading}
type="submit"
>
{t('login')}
</ButtonDeprecated>
</VStack>
);

const LoginFormRedesigned = (
<VStack component="form" className={classNames(cls.LoginForm, {}, [className])} gap={16}>
<Text title={t('auth-form')} />
{error && <Text text={t(error)} variant="error" />}
<Input
size="m"
autoFocus
placeholder={t('enter-username')}
type="text"
onChange={onChangeUsername}
value={username}
/>
<Input
size="m"
placeholder={t('enter-password')}
type="password"
onChange={onChangePassword}
value={password}
/>
<Button
className={cls.loginBtn}
variant="outlined"
onClick={onLogin}
disabled={isLoading}
type="submit"
>
{t('login')}
</Button>
</VStack>
);

return (
<DynamicModuleWrapper reducers={initialReducers}>
<VStack component="form" className={classNames(cls.LoginForm, {}, [className])}>
<Text title={t('auth-form')} />
{error && <Text text={t(error)} theme={TextTheme.ERROR} />}
<Input
autoFocus
placeholder={t('enter-username')}
type="text"
onChange={onChangeUsername}
value={username}
/>
<Input
placeholder={t('enter-password')}
type="text"
onChange={onChangePassword}
value={password}
/>
<Button
className={cls.loginBtn}
theme={ButtonTheme.OUTLINE}
onClick={onLogin}
disabled={isLoading}
type="submit"
>
{t('login')}
</Button>
</VStack>
<ToggleFeatures
name="isAppRedesigned"
on={LoginFormRedesigned}
off={LoginFormDeprecated}
/>
</DynamicModuleWrapper>
);
});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
/* eslint-disable react-hooks/rules-of-hooks */
import { FC, useCallback } from 'react';
import { useForm } from 'react-hook-form';
import { DynamicModuleWrapper, ReducersList } from '@/shared/lib/components/DynamicModuleWrapper';
Expand Down Expand Up @@ -63,7 +62,7 @@ export const EditableProfileCard: FC<EditableProfileCardProps> = ({ className, i

return (
<DynamicModuleWrapper reducers={reducers}>
<VStack gap={24} className={className} height="90vh">
<VStack gap={16} className={className}>
<EditableProfileCardHeader
profileData={formData}
readonly={readonly}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
import { FC, memo, useCallback } from 'react';
import { useTranslation } from 'react-i18next';
import { UseFormGetValues, UseFormReset } from 'react-hook-form';
import { useAppTranslation } from '@/shared/lib/hooks/useAppTranslation';
import { useAppSelector } from '@/shared/lib/hooks/useAppSelector';
import { useAppDispatch } from '@/shared/lib/hooks/useAppDispatch';
import { Button, ButtonTheme } from '@/shared/ui/deprecated/Button';
import { Button as ButtonDeprecated, ButtonTheme as ButtonThemeDeprecated } from '@/shared/ui/deprecated/Button';
import { Text as TextDeprecated } from '@/shared/ui/deprecated/Text';
import { HStack } from '@/shared/ui/redesigned/Stack';
import { Text } from '@/shared/ui/deprecated/Text';
import { Text } from '@/shared/ui/redesigned/Text';
import { Button } from '@/shared/ui/redesigned/Button';
import { getUserAuthData } from '@/entities/User';
import { Profile } from '@/entities/Profile';
import { ToggleFeatures } from '@/shared/lib/features';
import { Card } from '@/shared/ui/redesigned/Card';

import { updateProfileData } from '../../model/services/updateProfileData/updateProfileData';
import { useProfileActions } from '../../model/slice/profileSlice';

Expand All @@ -21,7 +26,7 @@ interface EditableProfileCardHeaderProps {
}

export const EditableProfileCardHeader: FC<EditableProfileCardHeaderProps> = memo((props) => {
const { t } = useTranslation('profile');
const { t } = useAppTranslation('profile');

const { className, getValues, reset, isValid, profileData, readonly } = props;
const { updateProfile, setReadonly, cancelEdit } = useProfileActions();
Expand All @@ -46,39 +51,89 @@ export const EditableProfileCardHeader: FC<EditableProfileCardHeaderProps> = mem
dispatch(updateProfileData());
}, [dispatch, getValues, setReadonly, updateProfile]);

return (
<HStack justify="space-between" className={className}>
<Text title={t('profile')} />
/**
* @deprecated
*/
const EditableProfileCardHeaderDeprecated = (
<>
<TextDeprecated title={t('profile')} />
{canEdit && (readonly
? (
<Button
theme={ButtonTheme.OUTLINE}
<ButtonDeprecated
onClick={onEdit}
data-testid="EditableProfileCardHeader.EditButton"
>
{t('edit')}
</Button>
</ButtonDeprecated>
)
: (
<HStack gap={12} width="fit-content">
<Button
theme={ButtonTheme.OUTLINE_RED}
<ButtonDeprecated
theme={ButtonThemeDeprecated.OUTLINE_RED}
onClick={onCancelEdit}
data-testid="EditableProfileCardHeader.CancelButton"
>
{t('cancel-edit')}
</Button>
<Button
theme={ButtonTheme.OUTLINE}
</ButtonDeprecated>
<ButtonDeprecated
onClick={onSave}
disabled={!isValid}
data-testid="EditableProfileCardHeader.SaveButton"
>
{t('save')}
</Button>
</ButtonDeprecated>
</HStack>
)
)}
</>
);

const EditableProfileCardHeaderRedesigned = (
<Card fullWidth padding="24">
<HStack justify="space-between">
<Text title={t('profile')} />
{canEdit && (readonly
? (
<Button
variant="outlined"
onClick={onEdit}
data-testid="EditableProfileCardHeader.EditButton"
>
{t('edit')}
</Button>
)
: (
<HStack gap={12} width="fit-content">
<Button
variant="outlined"
color="cancel"
onClick={onCancelEdit}
data-testid="EditableProfileCardHeader.CancelButton"
>
{t('cancel-edit')}
</Button>
<Button
variant="outlined"
color="success"
disabled={!isValid}
data-testid="EditableProfileCardHeader.SaveButton"
>
{t('save')}
</Button>
</HStack>
)
)}
</HStack>
</Card>
);

return (
<HStack justify="space-between" className={className}>
<ToggleFeatures
name="isAppRedesigned"
on={EditableProfileCardHeaderRedesigned}
off={EditableProfileCardHeaderDeprecated}
/>
</HStack>
);
});
19 changes: 11 additions & 8 deletions src/shared/ui/redesigned/Button/Button.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -28,22 +28,25 @@
}

.outlined {
border: 2px solid var(--icon);
background: transparent;
outline: none;
border-radius: 32px;

&.normal {
border: 2px solid var(--icon);
}

&:hover {
border: 2px solid var(--accent) !important;
}
}

.success {
border: 2px solid var(--save) !important;
}

.cancel {
border: 2px solid var(--cancel) !important;
&.success {
border: 2px solid var(--save);
}

&.cancel {
border: 2px solid var(--cancel);
}
}

.addon-left, .addon-right {
Expand Down
6 changes: 3 additions & 3 deletions src/shared/ui/redesigned/Button/Button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { classNames, Mods } from '@/shared/lib/classNames/classNames';
import cls from './Button.module.scss';

export type ButtonVariant = 'clear' | 'outlined' | 'contained';
export type ButtonColor = 'success' | 'cancel';
export type ButtonColor = 'success' | 'cancel' | 'normal';
export type ButtonSize = 's' | 'm' | 'l';

interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
Expand All @@ -31,7 +31,7 @@ export const Button: FC<ButtonProps> = memo<ButtonProps>(forwardRef<HTMLButtonEl
size = 'm',
addonLeft,
addonRight,
color,
color = 'normal',
...restProps
} = props;

Expand All @@ -46,7 +46,7 @@ export const Button: FC<ButtonProps> = memo<ButtonProps>(forwardRef<HTMLButtonEl
{...restProps}
type={type || 'button'}
ref={ref}
className={classNames(cls.Button, mods, [className, cls[variant], cls[size], cls[color || '']])}
className={classNames(cls.Button, mods, [className, cls[variant], cls[size], cls[color]])}
>
{addonLeft && <span className={cls['addon-left']}>{addonLeft}</span>}
{children}
Expand Down

0 comments on commit a3a9a18

Please sign in to comment.