1
0
Fork 0
mirror of https://github.com/muerwre/vault-frontend.git synced 2025-05-06 10:06:41 +07:00

removed profile redux items

This commit is contained in:
Fedor Katurov 2022-01-08 18:01:38 +07:00
parent 5b28313afd
commit 3c0571816c
55 changed files with 488 additions and 710 deletions
src/containers/profile
ProfileAvatar
ProfileInfo
ProfileLoader
ProfileMessages
ProfilePageLeft
ProfilePageStats
ProfileTabs

View file

@ -1,76 +0,0 @@
import React, { ChangeEvent, FC, useCallback } from 'react';
import styles from './styles.module.scss';
import { connect } from 'react-redux';
import { getURL } from '~/utils/dom';
import { pick } from 'ramda';
import { selectAuthProfile, selectAuthUser } from '~/redux/auth/selectors';
import { PRESETS } from '~/constants/urls';
import { UploadSubject, UploadTarget } from '~/constants/uploads';
import * as AUTH_ACTIONS from '~/redux/auth/actions';
import { Icon } from '~/components/input/Icon';
import { useUploader } from '~/hooks/data/useUploader';
import { observer } from 'mobx-react-lite';
import { showErrorToast } from '~/utils/errors/showToast';
const mapStateToProps = state => ({
user: pick(['id'], selectAuthUser(state)),
profile: pick(['is_loading', 'user'], selectAuthProfile(state)),
});
const mapDispatchToProps = {
authPatchUser: AUTH_ACTIONS.authPatchUser,
};
type IProps = ReturnType<typeof mapStateToProps> & typeof mapDispatchToProps & {};
const ProfileAvatarUnconnected: FC<IProps> = observer(
({ user: { id }, profile: { is_loading, user }, authPatchUser }) => {
const uploader = useUploader(
UploadSubject.Avatar,
UploadTarget.Profiles,
user?.photo ? [] : []
);
const onInputChange = useCallback(
async (event: ChangeEvent<HTMLInputElement>) => {
try {
if (!event.target.files?.length) {
return;
}
const photo = await uploader.uploadFile(event.target.files[0]);
authPatchUser({ photo });
} catch (error) {
showErrorToast(error);
}
},
[uploader, authPatchUser]
);
const can_edit = !is_loading && id && id === user?.id;
const backgroundImage = is_loading
? undefined
: `url("${user && getURL(user.photo, PRESETS.avatar)}")`;
return (
<div
className={styles.avatar}
style={{
backgroundImage,
}}
>
{can_edit && <input type="file" onInput={onInputChange} />}
{can_edit && (
<div className={styles.can_edit}>
<Icon icon="photo_add" />
</div>
)}
</div>
);
}
);
const ProfileAvatar = connect(mapStateToProps, mapDispatchToProps)(ProfileAvatarUnconnected);
export { ProfileAvatar };

View file

@ -1,55 +0,0 @@
@import "src/styles/variables";
.avatar {
@include outer_shadow();
border-radius: $radius;
width: 100px;
height: 100px;
background: $content_bg 50% 50% no-repeat;
background-size: cover;
position: absolute;
bottom: 0;
left: $gap;
cursor: pointer;
input {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
opacity: 0;
}
&:hover {
svg {
fill: $red;
}
}
}
.can_edit {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
pointer-events: none;
touch-action: none;
// background: red;
display: flex;
align-items: flex-end;
justify-content: flex-end;
padding: $gap / 2;
box-sizing: border-box;
background: linear-gradient(330deg, $content_bg, transparentize($content_bg, 1));
border-radius: $radius;
svg {
width: 32px;
height: 32px;
fill: white;
transition: fill 0.25s;
}
}

View file

@ -1,44 +1,39 @@
import React, { FC, ReactNode } from 'react';
import { IAuthState, IUser } from '~/redux/auth/types';
import styles from './styles.module.scss';
import { Group } from '~/components/containers/Group';
import { Placeholder } from '~/components/placeholders/Placeholder';
import { getPrettyDate } from '~/utils/dom';
import { ProfileTabs } from '../ProfileTabs';
import { ProfileAvatar } from '../ProfileAvatar';
import React, { FC } from "react";
import styles from "./styles.module.scss";
import { Group } from "~/components/containers/Group";
import { Placeholder } from "~/components/placeholders/Placeholder";
import { getPrettyDate } from "~/utils/dom";
import { ProfileTabs } from "../ProfileTabs";
import { ProfileAvatar } from "~/components/profile/ProfileAvatar";
import { useProfileContext } from "~/utils/providers/ProfileProvider";
interface IProps {
user?: IUser;
tab: string;
is_loading?: boolean;
is_own?: boolean;
setTab?: (tab: IAuthState['profile']['tab']) => void;
content?: ReactNode;
isLoading?: boolean;
isOwn: boolean;
}
const ProfileInfo: FC<IProps> = ({ user, tab, is_loading, is_own, setTab, content = null }) => (
<div>
<Group className={styles.wrap} horizontal>
<ProfileAvatar />
const ProfileInfo: FC<IProps> = ({ isOwn }) => {
const { updatePhoto, profile, isLoading } = useProfileContext();
<div className={styles.field}>
<div className={styles.name}>
{is_loading ? <Placeholder width="80%" /> : user?.fullname || user?.username}
return (
<div>
<Group className={styles.wrap} horizontal>
<ProfileAvatar canEdit={isOwn} onChangePhoto={updatePhoto} photo={profile.photo} />
<div className={styles.field}>
<div className={styles.name}>
{isLoading ? <Placeholder width="80%" /> : profile?.fullname || profile?.username}
</div>
<div className={styles.description}>
{isLoading ? <Placeholder /> : getPrettyDate(profile?.last_seen)}
</div>
</div>
</Group>
<div className={styles.description}>
{is_loading ? <Placeholder /> : getPrettyDate(user?.last_seen)}
</div>
</div>
</Group>
<ProfileTabs tab={tab} is_own={!!is_own} setTab={setTab} />
{content}
</div>
);
<ProfileTabs is_own={isOwn} />
</div>
);
};
export { ProfileInfo };

View file

@ -1,6 +1,6 @@
import React, { FC } from 'react';
import styles from './styles.module.scss';
import { LoaderCircle } from '~/components/input/LoaderCircle';
import React, { FC } from "react";
import styles from "./styles.module.scss";
import { LoaderCircle } from "~/components/input/LoaderCircle";
interface IProps {}

View file

@ -2,18 +2,17 @@ import React, { FC } from 'react';
import styles from './styles.module.scss';
import { Message } from '~/components/profile/Message';
import { NodeNoComments } from '~/components/node/NodeNoComments';
import { useShallowSelect } from '~/hooks/data/useShallowSelect';
import { selectAuthProfile } from '~/redux/auth/selectors';
import { useMessages } from '~/hooks/messages/useMessages';
import { useUser } from '~/hooks/user/userUser';
import { useProfileContext } from '~/utils/providers/ProfileProvider';
const ProfileMessages: FC = () => {
const profile = useShallowSelect(selectAuthProfile);
const { profile, isLoading: isLoadingProfile } = useProfileContext();
const user = useUser();
const { messages, isLoading } = useMessages(profile.user?.username || '');
const { messages, isLoading: isLoadingMessages } = useMessages(profile?.username || '');
if (!messages.length || profile.is_loading)
return <NodeNoComments is_loading={isLoading || profile.is_loading} />;
if (!messages.length || isLoadingProfile)
return <NodeNoComments is_loading={isLoadingMessages || isLoadingProfile} />;
if (messages.length <= 0) {
return null;
@ -42,7 +41,7 @@ const ProfileMessages: FC = () => {
<Message message={message} incoming={user.id !== message.from.id} key={message.id} />
))}
{!isLoading && messages.length > 0 && (
{!isLoadingMessages && messages.length > 0 && (
<div className={styles.placeholder}>Когда-нибудь здесь будут еще сообщения</div>
)}
</div>

View file

@ -1,42 +1,40 @@
import React, { FC } from 'react';
import { IAuthState } from '~/redux/auth/types';
import { formatText } from '~/utils/dom';
import { PRESETS } from '~/constants/urls';
import { Placeholder } from '~/components/placeholders/Placeholder';
import React, { FC } from "react";
import { IUser } from "~/redux/auth/types";
import { formatText } from "~/utils/dom";
import { PRESETS } from "~/constants/urls";
import { Placeholder } from "~/components/placeholders/Placeholder";
import styles from './styles.module.scss';
import { Avatar } from '~/components/common/Avatar';
import { Markdown } from '~/components/containers/Markdown';
import styles from "./styles.module.scss";
import { Avatar } from "~/components/common/Avatar";
import { Markdown } from "~/components/containers/Markdown";
interface IProps {
profile: IAuthState['profile'];
profile: IUser;
isLoading: boolean;
username: string;
}
const ProfilePageLeft: FC<IProps> = ({ username, profile }) => {
const ProfilePageLeft: FC<IProps> = ({ username, profile, isLoading }) => {
return (
<div className={styles.wrap}>
<Avatar
username={username}
url={profile.user?.photo?.url}
url={profile?.photo?.url}
className={styles.avatar}
preset={PRESETS['600']}
/>
<div className={styles.region}>
<div className={styles.name}>
{profile.is_loading ? <Placeholder /> : profile?.user?.fullname}
</div>
<div className={styles.name}>{isLoading ? <Placeholder /> : profile?.fullname}</div>`
<div className={styles.username}>
{profile.is_loading ? <Placeholder /> : `~${profile?.user?.username}`}
{isLoading ? <Placeholder /> : `~${profile?.username}`}
</div>
</div>
{profile && profile.user && profile.user.description && (
{!!profile?.description && (
<Markdown
className={styles.description}
dangerouslySetInnerHTML={{ __html: formatText(profile.user.description) }}
dangerouslySetInnerHTML={{ __html: formatText(profile.description) }}
/>
)}
</div>

View file

@ -1,7 +1,7 @@
import React, { FC } from 'react';
import styles from './styles.module.scss';
import { StatsRow } from '~/components/common/StatsRow';
import { SubTitle } from '~/components/common/SubTitle';
import React, { FC } from "react";
import styles from "./styles.module.scss";
import { StatsRow } from "~/components/common/StatsRow";
import { SubTitle } from "~/components/common/SubTitle";
interface Props {}

View file

@ -1,15 +1,12 @@
import React, { FC } from 'react';
import styles from './styles.module.scss';
import { IAuthState } from '~/redux/auth/types';
import { Tabs } from '~/components/dialogs/Tabs';
import React, { FC } from "react";
import styles from "./styles.module.scss";
import { Tabs } from "~/components/dialogs/Tabs";
interface IProps {
tab: string;
is_own: boolean;
setTab?: (tab: IAuthState['profile']['tab']) => void;
}
const ProfileTabs: FC<IProps> = ({ tab, is_own, setTab }) => {
const ProfileTabs: FC<IProps> = ({ is_own }) => {
const items = ['Профиль', 'Сообщения', ...(is_own ? ['Настройки'] : [])];
return (