From 3c0571816c8a279712664eebbbdac0f29c0818aa Mon Sep 17 00:00:00 2001 From: Fedor Katurov Date: Sat, 8 Jan 2022 18:01:38 +0700 Subject: [PATCH] removed profile redux items --- src/components/main/Notifications/index.tsx | 5 +- src/components/main/UserButton/index.tsx | 4 +- .../profile/ProfileAvatar/index.tsx | 45 ++++++++++ .../profile/ProfileAvatar/styles.module.scss | 0 .../profile/ProfileDescription/index.tsx | 24 ++---- .../profile/ProfileSettings/index.tsx | 76 ++++++++--------- .../profile/ProfileSidebarInfo/index.tsx | 31 ------- .../ProfileSidebarInfo/styles.module.scss | 41 --------- src/constants/phrases.ts | 1 + src/containers/boris/BorisComments/index.tsx | 20 ++--- .../dialogs/BetterScrollDialog/index.tsx | 10 +-- src/containers/dialogs/EditorDialog/index.tsx | 40 ++++----- src/containers/dialogs/LoginDialog/index.tsx | 6 +- .../dialogs/LoginDialogButtons/index.tsx | 12 +-- .../LoginSocialRegisterButtons/index.tsx | 6 +- .../LoginSocialRegisterDialog/index.tsx | 6 +- src/containers/dialogs/Modal/index.tsx | 12 +-- src/containers/dialogs/PhotoSwipe/index.tsx | 4 +- .../dialogs/ProfileDialog/index.tsx | 84 ++++++------------- .../dialogs/RestorePasswordDialog/index.tsx | 6 +- .../dialogs/RestoreRequestDialog/index.tsx | 32 +++---- src/containers/dialogs/TestDialog/index.tsx | 6 +- src/containers/flow/FlowStamp/index.tsx | 26 +++--- src/containers/lab/LabStats/index.tsx | 18 ++-- src/containers/main/BottomContainer/index.tsx | 6 +- src/containers/main/Container/index.tsx | 6 +- src/containers/main/MainRouter/index.tsx | 22 ++--- src/containers/main/SidebarRouter/index.tsx | 16 ++-- src/containers/node/NodeBottomBlock/index.tsx | 34 ++++---- src/containers/node/NodeComments/index.tsx | 18 ++-- src/containers/player/PlayerView/index.tsx | 6 +- .../profile/ProfileAvatar/index.tsx | 76 ----------------- src/containers/profile/ProfileInfo/index.tsx | 65 +++++++------- .../profile/ProfileLoader/index.tsx | 6 +- .../profile/ProfileMessages/index.tsx | 13 ++- .../profile/ProfilePageLeft/index.tsx | 34 ++++---- .../profile/ProfilePageStats/index.tsx | 8 +- src/containers/profile/ProfileTabs/index.tsx | 11 +-- .../sidebars/ProfileSidebar/index.tsx | 69 --------------- .../ProfileSidebar/styles.module.scss | 33 -------- .../sidebars/SidebarWrapper/index.tsx | 10 +-- src/containers/tags/Tags/index.tsx | 14 ++-- src/hooks/modal/useModal.ts | 4 +- src/hooks/profile/useGetProfile.ts | 34 ++++++++ src/hooks/profile/usePatchProfile.ts | 30 +++++++ src/layouts/ProfileLayout/index.tsx | 22 ++--- src/redux/auth/actions.ts | 18 +--- src/redux/auth/constants.ts | 3 - src/redux/auth/handlers.ts | 9 -- src/redux/auth/index.ts | 1 - src/redux/auth/sagas.ts | 55 +----------- src/redux/auth/selectors.ts | 2 - src/redux/auth/types.ts | 1 - src/types/modal/index.ts | 2 +- src/utils/providers/ProfileProvider.tsx | 55 ++++++++++++ 55 files changed, 488 insertions(+), 710 deletions(-) create mode 100644 src/components/profile/ProfileAvatar/index.tsx rename src/{containers => components}/profile/ProfileAvatar/styles.module.scss (100%) delete mode 100644 src/components/profile/ProfileSidebarInfo/index.tsx delete mode 100644 src/components/profile/ProfileSidebarInfo/styles.module.scss delete mode 100644 src/containers/profile/ProfileAvatar/index.tsx delete mode 100644 src/containers/sidebars/ProfileSidebar/index.tsx delete mode 100644 src/containers/sidebars/ProfileSidebar/styles.module.scss create mode 100644 src/hooks/profile/useGetProfile.ts create mode 100644 src/hooks/profile/usePatchProfile.ts create mode 100644 src/utils/providers/ProfileProvider.tsx diff --git a/src/components/main/Notifications/index.tsx b/src/components/main/Notifications/index.tsx index cf56bb81..6f65f41b 100644 --- a/src/components/main/Notifications/index.tsx +++ b/src/components/main/Notifications/index.tsx @@ -46,10 +46,7 @@ const NotificationsUnconnected: FC = ({ return; } - return authOpenProfile( - (notification as IMessageNotification).content.from!.username, - 'messages' - ); + return authOpenProfile((notification as IMessageNotification).content.from!.username); default: return; } diff --git a/src/components/main/UserButton/index.tsx b/src/components/main/UserButton/index.tsx index 7bd617af..b4e31d51 100644 --- a/src/components/main/UserButton/index.tsx +++ b/src/components/main/UserButton/index.tsx @@ -16,12 +16,12 @@ interface IProps { const UserButton: FC = ({ user: { username, photo }, authOpenProfile, onLogout }) => { const onProfileOpen = useCallback(() => { if (!username) return; - authOpenProfile(username, 'profile'); + authOpenProfile(username); }, [authOpenProfile, username]); const onSettingsOpen = useCallback(() => { if (!username) return; - authOpenProfile(username, 'settings'); + authOpenProfile(username); }, [authOpenProfile, username]); return ( diff --git a/src/components/profile/ProfileAvatar/index.tsx b/src/components/profile/ProfileAvatar/index.tsx new file mode 100644 index 00000000..b5a3ed79 --- /dev/null +++ b/src/components/profile/ProfileAvatar/index.tsx @@ -0,0 +1,45 @@ +import React, { ChangeEvent, FC, useCallback } from 'react'; +import styles from './styles.module.scss'; +import { getURL } from '~/utils/dom'; +import { PRESETS } from '~/constants/urls'; +import { Icon } from '~/components/input/Icon'; +import { IFile } from '~/redux/types'; + +export interface ProfileAvatarProps { + canEdit: boolean; + photo?: IFile; + onChangePhoto: (file: File) => void; +} + +const ProfileAvatar: FC = ({ photo, onChangePhoto, canEdit }) => { + const onInputChange = useCallback( + async (event: ChangeEvent) => { + if (!event.target.files?.length) { + return; + } + + onChangePhoto(event.target.files[0]); + }, + [onChangePhoto] + ); + + const backgroundImage = photo ? `url("${getURL(photo, PRESETS.avatar)}")` : undefined; + + return ( +
+ {canEdit && } + {canEdit && ( +
+ +
+ )} +
+ ); +}; + +export { ProfileAvatar }; diff --git a/src/containers/profile/ProfileAvatar/styles.module.scss b/src/components/profile/ProfileAvatar/styles.module.scss similarity index 100% rename from src/containers/profile/ProfileAvatar/styles.module.scss rename to src/components/profile/ProfileAvatar/styles.module.scss diff --git a/src/components/profile/ProfileDescription/index.tsx b/src/components/profile/ProfileDescription/index.tsx index e083c47a..683ccadb 100644 --- a/src/components/profile/ProfileDescription/index.tsx +++ b/src/components/profile/ProfileDescription/index.tsx @@ -1,39 +1,33 @@ import React, { FC } from 'react'; import { formatText } from '~/utils/dom'; import styles from './styles.module.scss'; -import { connect } from 'react-redux'; -import { selectAuthProfile } from '~/redux/auth/selectors'; import { ProfileLoader } from '~/containers/profile/ProfileLoader'; import { Group } from '~/components/containers/Group'; import markdown from '~/styles/common/markdown.module.scss'; import classNames from 'classnames'; +import { useProfileContext } from '~/utils/providers/ProfileProvider'; -const mapStateToProps = state => ({ - profile: selectAuthProfile(state), -}); +const ProfileDescription: FC = () => { + const { profile, isLoading } = useProfileContext(); -type IProps = ReturnType & {}; - -const ProfileDescriptionUnconnected: FC = ({ profile: { user, is_loading } }) => { - if (is_loading) return ; + if (isLoading) return ; return (
- {!!user?.description && ( + {!!profile?.description && ( )} - {!user?.description && ( + + {!profile?.description && (
- {user?.fullname || user?.username} пока ничего не рассказал о себе + {profile?.fullname || profile?.username} пока ничего не рассказал о себе
)}
); }; -const ProfileDescription = connect(mapStateToProps)(ProfileDescriptionUnconnected); - export { ProfileDescription }; diff --git a/src/components/profile/ProfileSettings/index.tsx b/src/components/profile/ProfileSettings/index.tsx index b7d27c95..4f54e3bb 100644 --- a/src/components/profile/ProfileSettings/index.tsx +++ b/src/components/profile/ProfileSettings/index.tsx @@ -1,35 +1,25 @@ import React, { FC, useCallback, useEffect, useState } from 'react'; import styles from './styles.module.scss'; -import { connect } from 'react-redux'; -import { selectAuthProfile, selectAuthUser } from '~/redux/auth/selectors'; import { Textarea } from '~/components/input/Textarea'; import { Button } from '~/components/input/Button'; import { Group } from '~/components/containers/Group'; import { Filler } from '~/components/containers/Filler'; import { InputText } from '~/components/input/InputText'; -import * as AUTH_ACTIONS from '~/redux/auth/actions'; import { ERROR_LITERAL } from '~/constants/errors'; import { ProfileAccounts } from '~/components/profile/ProfileAccounts'; import classNames from 'classnames'; +import { useUser } from '~/hooks/user/userUser'; +import { useProfileContext } from '~/utils/providers/ProfileProvider'; +import { showErrorToast } from '~/utils/errors/showToast'; +import { getValidationErrors } from '~/utils/errors/getValidationErrors'; +import { showToastSuccess } from '~/utils/toast'; +import { getRandomPhrase } from '~/constants/phrases'; -const mapStateToProps = state => ({ - user: selectAuthUser(state), - profile: selectAuthProfile(state), -}); +const ProfileSettings: FC = () => { + const [errors, setErrors] = useState>({}); + const user = useUser(); + const { updateProfile } = useProfileContext(); -const mapDispatchToProps = { - authPatchUser: AUTH_ACTIONS.authPatchUser, - authSetProfile: AUTH_ACTIONS.authSetProfile, -}; - -type IProps = ReturnType & typeof mapDispatchToProps & {}; - -const ProfileSettingsUnconnected: FC = ({ - user, - profile: { patch_errors, socials }, - authPatchUser, - authSetProfile, -}) => { const [password, setPassword] = useState(''); const [new_password, setNewPassword] = useState(''); @@ -39,28 +29,40 @@ const ProfileSettingsUnconnected: FC = ({ data, setData, ]); + const setEmail = useCallback(email => setData({ ...data, email }), [data, setData]); const setUsername = useCallback(username => setData({ ...data, username }), [data, setData]); const setFullname = useCallback(fullname => setData({ ...data, fullname }), [data, setData]); const onSubmit = useCallback( - event => { - event.preventDefault(); + async event => { + try { + event.preventDefault(); - const fields = { - ...data, - password: password.length > 0 && password ? password : undefined, - new_password: new_password.length > 0 && new_password ? new_password : undefined, - }; + const fields = { + ...data, + password: password.length > 0 && password ? password : undefined, + new_password: new_password.length > 0 && new_password ? new_password : undefined, + }; - authPatchUser(fields); + await updateProfile(fields); + + showToastSuccess(getRandomPhrase('SUCCESS')); + } catch (error) { + showErrorToast(error); + + const validationErrors = getValidationErrors(error); + if (validationErrors) { + setErrors(validationErrors); + } + } }, - [data, password, new_password, authPatchUser] + [data, password, new_password, updateProfile] ); useEffect(() => { - authSetProfile({ patch_errors: {} }); - }, [password, new_password, data, authSetProfile]); + setErrors({}); + }, [password, new_password, data]); return (
@@ -74,7 +76,7 @@ const ProfileSettingsUnconnected: FC = ({ value={data.fullname} handler={setFullname} title="Полное имя" - error={patch_errors.fullname && ERROR_LITERAL[patch_errors.fullname]} + error={errors.fullname && ERROR_LITERAL[errors.fullname]} />