mirror of
https://github.com/muerwre/vault-frontend.git
synced 2025-04-25 12:56:41 +07:00
added account list and ability to drop them
This commit is contained in:
parent
2388a7e20e
commit
5396cf7611
11 changed files with 282 additions and 47 deletions
|
@ -1,17 +1,16 @@
|
||||||
import React, { FC, useState, useEffect, useCallback } from 'react';
|
import React, { FC, useCallback, useEffect, useState } from 'react';
|
||||||
import styles from './styles.scss';
|
import styles from './styles.scss';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import classNames from 'classnames';
|
import { selectAuthProfile, selectAuthUser } from '~/redux/auth/selectors';
|
||||||
import { selectAuthUser, selectAuthProfile } from '~/redux/auth/selectors';
|
|
||||||
import { Textarea } from '~/components/input/Textarea';
|
import { Textarea } from '~/components/input/Textarea';
|
||||||
import { Button } from '~/components/input/Button';
|
import { Button } from '~/components/input/Button';
|
||||||
import { Group } from '~/components/containers/Group';
|
import { Group } from '~/components/containers/Group';
|
||||||
import { Filler } from '~/components/containers/Filler';
|
import { Filler } from '~/components/containers/Filler';
|
||||||
import { TextInput } from '~/components/input/TextInput';
|
|
||||||
import { InputText } from '~/components/input/InputText';
|
import { InputText } from '~/components/input/InputText';
|
||||||
import reject from 'ramda/es/reject';
|
import reject from 'ramda/es/reject';
|
||||||
import * as AUTH_ACTIONS from '~/redux/auth/actions';
|
import * as AUTH_ACTIONS from '~/redux/auth/actions';
|
||||||
import { ERROR_LITERAL } from '~/constants/errors';
|
import { ERROR_LITERAL } from '~/constants/errors';
|
||||||
|
import { ProfileSettingsSocials } from '~/components/profile/ProfileSettingsSocials';
|
||||||
|
|
||||||
const mapStateToProps = state => ({
|
const mapStateToProps = state => ({
|
||||||
user: selectAuthUser(state),
|
user: selectAuthUser(state),
|
||||||
|
@ -21,15 +20,19 @@ const mapStateToProps = state => ({
|
||||||
const mapDispatchToProps = {
|
const mapDispatchToProps = {
|
||||||
authPatchUser: AUTH_ACTIONS.authPatchUser,
|
authPatchUser: AUTH_ACTIONS.authPatchUser,
|
||||||
authSetProfile: AUTH_ACTIONS.authSetProfile,
|
authSetProfile: AUTH_ACTIONS.authSetProfile,
|
||||||
|
authGetSocials: AUTH_ACTIONS.authGetSocials,
|
||||||
|
authDropSocial: AUTH_ACTIONS.authDropSocial,
|
||||||
};
|
};
|
||||||
|
|
||||||
type IProps = ReturnType<typeof mapStateToProps> & typeof mapDispatchToProps & {};
|
type IProps = ReturnType<typeof mapStateToProps> & typeof mapDispatchToProps & {};
|
||||||
|
|
||||||
const ProfileSettingsUnconnected: FC<IProps> = ({
|
const ProfileSettingsUnconnected: FC<IProps> = ({
|
||||||
user,
|
user,
|
||||||
profile: { patch_errors },
|
profile: { patch_errors, socials },
|
||||||
authPatchUser,
|
authPatchUser,
|
||||||
authSetProfile,
|
authSetProfile,
|
||||||
|
authGetSocials,
|
||||||
|
authDropSocial,
|
||||||
}) => {
|
}) => {
|
||||||
const [password, setPassword] = useState('');
|
const [password, setPassword] = useState('');
|
||||||
const [new_password, setNewPassword] = useState('');
|
const [new_password, setNewPassword] = useState('');
|
||||||
|
@ -40,11 +43,8 @@ const ProfileSettingsUnconnected: FC<IProps> = ({
|
||||||
data,
|
data,
|
||||||
setData,
|
setData,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const setEmail = useCallback(email => setData({ ...data, email }), [data, setData]);
|
const setEmail = useCallback(email => setData({ ...data, email }), [data, setData]);
|
||||||
|
|
||||||
const setUsername = useCallback(username => setData({ ...data, username }), [data, setData]);
|
const setUsername = useCallback(username => setData({ ...data, username }), [data, setData]);
|
||||||
|
|
||||||
const setFullname = useCallback(fullname => setData({ ...data, fullname }), [data, setData]);
|
const setFullname = useCallback(fullname => setData({ ...data, fullname }), [data, setData]);
|
||||||
|
|
||||||
const onSubmit = useCallback(
|
const onSubmit = useCallback(
|
||||||
|
@ -88,6 +88,13 @@ const ProfileSettingsUnconnected: FC<IProps> = ({
|
||||||
комментариях.
|
комментариях.
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<ProfileSettingsSocials
|
||||||
|
accounts={socials.accounts}
|
||||||
|
is_loading={socials.is_loading}
|
||||||
|
authGetSocials={authGetSocials}
|
||||||
|
authDropSocial={authDropSocial}
|
||||||
|
/>
|
||||||
|
|
||||||
<Group className={styles.pad}>
|
<Group className={styles.pad}>
|
||||||
<InputText
|
<InputText
|
||||||
value={data.username}
|
value={data.username}
|
||||||
|
@ -135,9 +142,6 @@ const ProfileSettingsUnconnected: FC<IProps> = ({
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const ProfileSettings = connect(
|
const ProfileSettings = connect(mapStateToProps, mapDispatchToProps)(ProfileSettingsUnconnected);
|
||||||
mapStateToProps,
|
|
||||||
mapDispatchToProps
|
|
||||||
)(ProfileSettingsUnconnected);
|
|
||||||
|
|
||||||
export { ProfileSettings };
|
export { ProfileSettings };
|
||||||
|
|
63
src/components/profile/ProfileSettingsSocials/index.tsx
Normal file
63
src/components/profile/ProfileSettingsSocials/index.tsx
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
import React, { FC, useEffect, Fragment } from 'react';
|
||||||
|
import * as AUTH_ACTIONS from '~/redux/auth/actions';
|
||||||
|
import { IAuthState, ISocialProvider } from '~/redux/auth/types';
|
||||||
|
import styles from './styles.scss';
|
||||||
|
import { Placeholder } from '~/components/placeholders/Placeholder';
|
||||||
|
import { Icon } from '~/components/input/Icon';
|
||||||
|
|
||||||
|
interface IProps {
|
||||||
|
accounts: IAuthState['profile']['socials']['accounts'];
|
||||||
|
is_loading: boolean;
|
||||||
|
authGetSocials: typeof AUTH_ACTIONS.authGetSocials;
|
||||||
|
authDropSocial: typeof AUTH_ACTIONS.authDropSocial;
|
||||||
|
}
|
||||||
|
|
||||||
|
const SOCIAL_ICONS: Record<ISocialProvider, string> = {
|
||||||
|
vkontakte: 'vk',
|
||||||
|
google: 'google',
|
||||||
|
};
|
||||||
|
|
||||||
|
const ProfileSettingsSocials: FC<IProps> = ({
|
||||||
|
authGetSocials,
|
||||||
|
authDropSocial,
|
||||||
|
accounts,
|
||||||
|
is_loading,
|
||||||
|
}) => {
|
||||||
|
useEffect(() => {
|
||||||
|
authGetSocials();
|
||||||
|
}, [authGetSocials]);
|
||||||
|
|
||||||
|
if (!accounts.length) return null;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={styles.wrap}>
|
||||||
|
{is_loading && (
|
||||||
|
<div className={styles.loader}>
|
||||||
|
{[...new Array(accounts.length || 1)].map((_, i) => (
|
||||||
|
<Fragment key={i}>
|
||||||
|
<Placeholder width="50%" />
|
||||||
|
<Placeholder width="auto" />
|
||||||
|
</Fragment>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{!is_loading &&
|
||||||
|
accounts.map(it => (
|
||||||
|
<div className={styles.account}>
|
||||||
|
<div className={styles.account__provider}>
|
||||||
|
<Icon icon={SOCIAL_ICONS[it.provider]} />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className={styles.account__name}>{it.name}</div>
|
||||||
|
|
||||||
|
<div className={styles.account__drop}>
|
||||||
|
<Icon icon="close" size={22} onClick={() => authDropSocial(it.provider, it.id)} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export { ProfileSettingsSocials };
|
36
src/components/profile/ProfileSettingsSocials/styles.scss
Normal file
36
src/components/profile/ProfileSettingsSocials/styles.scss
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
.wrap {
|
||||||
|
padding: $gap,
|
||||||
|
}
|
||||||
|
|
||||||
|
.loader {
|
||||||
|
display: grid;
|
||||||
|
grid-row-gap: $gap;
|
||||||
|
grid-column-gap: $gap * 4;
|
||||||
|
grid-template-columns: 1fr 32px;
|
||||||
|
|
||||||
|
& > div {
|
||||||
|
height: 22px;
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.account {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 20px auto 20px;
|
||||||
|
grid-column-gap: $gap;
|
||||||
|
|
||||||
|
&__name {
|
||||||
|
font: $font_16_semibold;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__drop {
|
||||||
|
cursor: pointer;
|
||||||
|
opacity: 0.5;
|
||||||
|
transition: opacity 0.25s;
|
||||||
|
fill: $red;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -12,6 +12,8 @@ export const API = {
|
||||||
GET_UPDATES: '/user/updates',
|
GET_UPDATES: '/user/updates',
|
||||||
REQUEST_CODE: (code?: string) => `/user/restore/${code || ''}`,
|
REQUEST_CODE: (code?: string) => `/user/restore/${code || ''}`,
|
||||||
UPLOAD: (target, type) => `/upload/${target}/${type}`,
|
UPLOAD: (target, type) => `/upload/${target}/${type}`,
|
||||||
|
GET_SOCIALS: '/oauth/',
|
||||||
|
DROP_SOCIAL: (provider, id) => `/oauth/${provider}/${id}`,
|
||||||
},
|
},
|
||||||
NODE: {
|
NODE: {
|
||||||
SAVE: '/node/',
|
SAVE: '/node/',
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { AUTH_USER_ACTIONS } from '~/redux/auth/constants';
|
import { AUTH_USER_ACTIONS } from '~/redux/auth/constants';
|
||||||
import { IAuthState, IUser } from '~/redux/auth/types';
|
import { IAuthState, ISocialProvider, IUser } from '~/redux/auth/types';
|
||||||
import { IMessage } from '../types';
|
import { IMessage } from '../types';
|
||||||
|
|
||||||
export const userSendLoginRequest = ({
|
export const userSendLoginRequest = ({
|
||||||
|
@ -101,3 +101,23 @@ export const authRestorePassword = (password: string) => ({
|
||||||
type: AUTH_USER_ACTIONS.RESTORE_PASSWORD,
|
type: AUTH_USER_ACTIONS.RESTORE_PASSWORD,
|
||||||
password,
|
password,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const authGetSocials = () => ({
|
||||||
|
type: AUTH_USER_ACTIONS.GET_SOCIALS,
|
||||||
|
});
|
||||||
|
|
||||||
|
export const authAddSocial = (provider: ISocialProvider) => ({
|
||||||
|
type: AUTH_USER_ACTIONS.ADD_SOCIAL,
|
||||||
|
provider,
|
||||||
|
});
|
||||||
|
|
||||||
|
export const authDropSocial = (provider: string, id: string) => ({
|
||||||
|
type: AUTH_USER_ACTIONS.DROP_SOCIAL,
|
||||||
|
provider,
|
||||||
|
id,
|
||||||
|
});
|
||||||
|
|
||||||
|
export const authSetSocials = (socials: Partial<IAuthState['profile']['socials']>) => ({
|
||||||
|
type: AUTH_USER_ACTIONS.SET_SOCIALS,
|
||||||
|
socials,
|
||||||
|
});
|
||||||
|
|
|
@ -2,7 +2,7 @@ import { api, errorMiddleware, resultMiddleware, configWithToken } from '~/utils
|
||||||
import { API } from '~/constants/api';
|
import { API } from '~/constants/api';
|
||||||
import { IResultWithStatus, IMessage, INotification } from '~/redux/types';
|
import { IResultWithStatus, IMessage, INotification } from '~/redux/types';
|
||||||
import { userLoginTransform } from '~/redux/auth/transforms';
|
import { userLoginTransform } from '~/redux/auth/transforms';
|
||||||
import { IUser } from './types';
|
import { ISocialAccount, IUser } from './types';
|
||||||
|
|
||||||
export const apiUserLogin = ({
|
export const apiUserLogin = ({
|
||||||
username,
|
username,
|
||||||
|
@ -55,9 +55,10 @@ export const apiAuthGetUpdates = ({
|
||||||
access,
|
access,
|
||||||
exclude_dialogs,
|
exclude_dialogs,
|
||||||
last,
|
last,
|
||||||
}): Promise<
|
}): Promise<IResultWithStatus<{
|
||||||
IResultWithStatus<{ notifications: INotification[]; boris: { commented_at: string } }>
|
notifications: INotification[];
|
||||||
> =>
|
boris: { commented_at: string };
|
||||||
|
}>> =>
|
||||||
api
|
api
|
||||||
.get(API.USER.GET_UPDATES, configWithToken(access, { params: { exclude_dialogs, last } }))
|
.get(API.USER.GET_UPDATES, configWithToken(access, { params: { exclude_dialogs, last } }))
|
||||||
.then(resultMiddleware)
|
.then(resultMiddleware)
|
||||||
|
@ -86,3 +87,31 @@ export const apiRestoreCode = ({ code, password }): Promise<IResultWithStatus<{}
|
||||||
.post(API.USER.REQUEST_CODE(code), { password })
|
.post(API.USER.REQUEST_CODE(code), { password })
|
||||||
.then(resultMiddleware)
|
.then(resultMiddleware)
|
||||||
.catch(errorMiddleware);
|
.catch(errorMiddleware);
|
||||||
|
|
||||||
|
export const apiGetSocials = ({
|
||||||
|
access,
|
||||||
|
}: {
|
||||||
|
access: string;
|
||||||
|
}): Promise<IResultWithStatus<{
|
||||||
|
accounts: ISocialAccount[];
|
||||||
|
}>> =>
|
||||||
|
api
|
||||||
|
.get(API.USER.GET_SOCIALS, configWithToken(access))
|
||||||
|
.then(resultMiddleware)
|
||||||
|
.catch(errorMiddleware);
|
||||||
|
|
||||||
|
export const apiDropSocial = ({
|
||||||
|
access,
|
||||||
|
id,
|
||||||
|
provider,
|
||||||
|
}: {
|
||||||
|
access: string;
|
||||||
|
id: string;
|
||||||
|
provider: string;
|
||||||
|
}): Promise<IResultWithStatus<{
|
||||||
|
accounts: ISocialAccount[];
|
||||||
|
}>> =>
|
||||||
|
api
|
||||||
|
.delete(API.USER.DROP_SOCIAL(provider, id), configWithToken(access))
|
||||||
|
.then(resultMiddleware)
|
||||||
|
.catch(errorMiddleware);
|
||||||
|
|
|
@ -24,6 +24,11 @@ export const AUTH_USER_ACTIONS = {
|
||||||
REQUEST_RESTORE_CODE: 'REQUEST_RESTORE_CODE',
|
REQUEST_RESTORE_CODE: 'REQUEST_RESTORE_CODE',
|
||||||
SHOW_RESTORE_MODAL: 'SHOW_RESTORE_MODAL',
|
SHOW_RESTORE_MODAL: 'SHOW_RESTORE_MODAL',
|
||||||
RESTORE_PASSWORD: 'RESTORE_PASSWORD',
|
RESTORE_PASSWORD: 'RESTORE_PASSWORD',
|
||||||
|
|
||||||
|
GET_SOCIALS: 'GET_SOCIALS',
|
||||||
|
DROP_SOCIAL: 'DROP_SOCIAL',
|
||||||
|
ADD_SOCIAL: 'ADD_SOCIAL',
|
||||||
|
SET_SOCIALS: 'SET_SOCIALS',
|
||||||
};
|
};
|
||||||
|
|
||||||
export const USER_ERRORS = {
|
export const USER_ERRORS = {
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import { AUTH_USER_ACTIONS } from '~/redux/auth/constants';
|
import { AUTH_USER_ACTIONS } from '~/redux/auth/constants';
|
||||||
import * as ActionCreators from '~/redux/auth/actions';
|
import * as ActionCreators from '~/redux/auth/actions';
|
||||||
import { IAuthState } from '~/redux/auth/types';
|
import { IAuthState } from '~/redux/auth/types';
|
||||||
import { Action } from 'history';
|
|
||||||
|
|
||||||
interface ActionHandler<T> {
|
interface ActionHandler<T> {
|
||||||
(state: IAuthState, payload: T extends (...args: any[]) => infer R ? R : any): IAuthState;
|
(state: IAuthState, payload: T extends (...args: any[]) => infer R ? R : any): IAuthState;
|
||||||
|
@ -65,6 +64,16 @@ const setRestore: ActionHandler<typeof ActionCreators.authSetRestore> = (state,
|
||||||
...restore,
|
...restore,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
const setSocials: ActionHandler<typeof ActionCreators.authSetSocials> = (state, { socials }) => ({
|
||||||
|
...state,
|
||||||
|
profile: {
|
||||||
|
...state.profile,
|
||||||
|
socials: {
|
||||||
|
...state.profile.socials,
|
||||||
|
...socials,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
export const AUTH_USER_HANDLERS = {
|
export const AUTH_USER_HANDLERS = {
|
||||||
[AUTH_USER_ACTIONS.SET_LOGIN_ERROR]: setLoginError,
|
[AUTH_USER_ACTIONS.SET_LOGIN_ERROR]: setLoginError,
|
||||||
|
@ -74,4 +83,5 @@ export const AUTH_USER_HANDLERS = {
|
||||||
[AUTH_USER_ACTIONS.SET_UPDATES]: setUpdates,
|
[AUTH_USER_ACTIONS.SET_UPDATES]: setUpdates,
|
||||||
[AUTH_USER_ACTIONS.SET_LAST_SEEN_MESSAGES]: setLastSeenMessages,
|
[AUTH_USER_ACTIONS.SET_LAST_SEEN_MESSAGES]: setLastSeenMessages,
|
||||||
[AUTH_USER_ACTIONS.SET_RESTORE]: setRestore,
|
[AUTH_USER_ACTIONS.SET_RESTORE]: setRestore,
|
||||||
|
[AUTH_USER_ACTIONS.SET_SOCIALS]: setSocials,
|
||||||
};
|
};
|
||||||
|
|
|
@ -31,6 +31,12 @@ const INITIAL_STATE: IAuthState = {
|
||||||
messages: [],
|
messages: [],
|
||||||
messages_error: null,
|
messages_error: null,
|
||||||
patch_errors: {},
|
patch_errors: {},
|
||||||
|
|
||||||
|
socials: {
|
||||||
|
accounts: [],
|
||||||
|
error: '',
|
||||||
|
is_loading: false,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
restore: {
|
restore: {
|
||||||
|
|
|
@ -1,48 +1,53 @@
|
||||||
import { call, put, takeEvery, takeLatest, select, delay } from 'redux-saga/effects';
|
import { call, delay, put, select, takeEvery, takeLatest } from 'redux-saga/effects';
|
||||||
import { AUTH_USER_ACTIONS, EMPTY_USER, USER_ERRORS, USER_ROLES } from '~/redux/auth/constants';
|
import { AUTH_USER_ACTIONS, EMPTY_USER, USER_ERRORS, USER_ROLES } from '~/redux/auth/constants';
|
||||||
import {
|
import {
|
||||||
authSetToken,
|
authDropSocial,
|
||||||
userSetLoginError,
|
|
||||||
authSetUser,
|
|
||||||
userSendLoginRequest,
|
|
||||||
gotAuthPostMessage,
|
|
||||||
authOpenProfile,
|
|
||||||
authSetProfile,
|
|
||||||
authGetMessages,
|
authGetMessages,
|
||||||
authSendMessage,
|
authGetSocials,
|
||||||
authSetUpdates,
|
authLoadProfile,
|
||||||
authLoggedIn,
|
authLoggedIn,
|
||||||
authSetLastSeenMessages,
|
authOpenProfile,
|
||||||
authPatchUser,
|
authPatchUser,
|
||||||
authShowRestoreModal,
|
|
||||||
authSetRestore,
|
|
||||||
authRequestRestoreCode,
|
authRequestRestoreCode,
|
||||||
authRestorePassword,
|
authRestorePassword,
|
||||||
authLoadProfile,
|
authSendMessage,
|
||||||
|
authSetLastSeenMessages,
|
||||||
|
authSetProfile,
|
||||||
|
authSetRestore,
|
||||||
|
authSetSocials,
|
||||||
|
authSetToken,
|
||||||
|
authSetUpdates,
|
||||||
|
authSetUser,
|
||||||
|
authShowRestoreModal,
|
||||||
|
gotAuthPostMessage,
|
||||||
|
userSendLoginRequest,
|
||||||
|
userSetLoginError,
|
||||||
} from '~/redux/auth/actions';
|
} from '~/redux/auth/actions';
|
||||||
import {
|
import {
|
||||||
apiUserLogin,
|
|
||||||
apiAuthGetUser,
|
|
||||||
apiAuthGetUserProfile,
|
|
||||||
apiAuthGetUserMessages,
|
|
||||||
apiAuthSendMessage,
|
|
||||||
apiAuthGetUpdates,
|
apiAuthGetUpdates,
|
||||||
apiUpdateUser,
|
apiAuthGetUser,
|
||||||
apiRequestRestoreCode,
|
apiAuthGetUserMessages,
|
||||||
|
apiAuthGetUserProfile,
|
||||||
|
apiAuthSendMessage,
|
||||||
apiCheckRestoreCode,
|
apiCheckRestoreCode,
|
||||||
|
apiDropSocial,
|
||||||
|
apiGetSocials,
|
||||||
|
apiRequestRestoreCode,
|
||||||
apiRestoreCode,
|
apiRestoreCode,
|
||||||
|
apiUpdateUser,
|
||||||
|
apiUserLogin,
|
||||||
} from '~/redux/auth/api';
|
} from '~/redux/auth/api';
|
||||||
import { modalSetShown, modalShowDialog } from '~/redux/modal/actions';
|
import { modalSetShown, modalShowDialog } from '~/redux/modal/actions';
|
||||||
import {
|
import {
|
||||||
selectToken,
|
|
||||||
selectAuthProfile,
|
|
||||||
selectAuthUser,
|
|
||||||
selectAuthUpdates,
|
|
||||||
selectAuthRestore,
|
|
||||||
selectAuth,
|
selectAuth,
|
||||||
|
selectAuthProfile,
|
||||||
|
selectAuthRestore,
|
||||||
|
selectAuthUpdates,
|
||||||
|
selectAuthUser,
|
||||||
|
selectToken,
|
||||||
} from './selectors';
|
} from './selectors';
|
||||||
import { IResultWithStatus, INotification, IMessageNotification, Unwrap } from '../types';
|
import { IMessageNotification, IResultWithStatus, Unwrap } from '../types';
|
||||||
import { IUser, IAuthState } from './types';
|
import { IAuthState, IUser } from './types';
|
||||||
import { REHYDRATE, RehydrateAction } from 'redux-persist';
|
import { REHYDRATE, RehydrateAction } from 'redux-persist';
|
||||||
import { selectModal } from '~/redux/modal/selectors';
|
import { selectModal } from '~/redux/modal/selectors';
|
||||||
import { IModalState } from '~/redux/modal/reducer';
|
import { IModalState } from '~/redux/modal/reducer';
|
||||||
|
@ -372,6 +377,45 @@ function* restorePassword({ password }: ReturnType<typeof authRestorePassword>)
|
||||||
yield call(refreshUser);
|
yield call(refreshUser);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function* getSocials() {
|
||||||
|
yield put(authSetSocials({ is_loading: true, error: '' }));
|
||||||
|
|
||||||
|
try {
|
||||||
|
const { data, error }: Unwrap<ReturnType<typeof apiGetSocials>> = yield call(
|
||||||
|
reqWrapper,
|
||||||
|
apiGetSocials,
|
||||||
|
{}
|
||||||
|
);
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
throw new Error(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
yield put(authSetSocials({ is_loading: false, accounts: data.accounts, error: '' }));
|
||||||
|
} catch (e) {
|
||||||
|
yield put(authSetSocials({ is_loading: false, error: e.toString() }));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function* dropSocial({ provider, id }: ReturnType<typeof authDropSocial>) {
|
||||||
|
try {
|
||||||
|
yield put(authSetSocials({ error: '' }));
|
||||||
|
const { error }: Unwrap<ReturnType<typeof apiDropSocial>> = yield call(
|
||||||
|
reqWrapper,
|
||||||
|
apiDropSocial,
|
||||||
|
{ id, provider }
|
||||||
|
);
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
throw new Error(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
yield call(getSocials);
|
||||||
|
} catch (e) {
|
||||||
|
yield put(authSetSocials({ error: e.toString() }));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function* authSaga() {
|
function* authSaga() {
|
||||||
yield takeEvery(REHYDRATE, checkUserSaga);
|
yield takeEvery(REHYDRATE, checkUserSaga);
|
||||||
yield takeLatest([REHYDRATE, AUTH_USER_ACTIONS.LOGGED_IN], startPollingSaga);
|
yield takeLatest([REHYDRATE, AUTH_USER_ACTIONS.LOGGED_IN], startPollingSaga);
|
||||||
|
@ -388,6 +432,8 @@ function* authSaga() {
|
||||||
yield takeLatest(AUTH_USER_ACTIONS.REQUEST_RESTORE_CODE, requestRestoreCode);
|
yield takeLatest(AUTH_USER_ACTIONS.REQUEST_RESTORE_CODE, requestRestoreCode);
|
||||||
yield takeLatest(AUTH_USER_ACTIONS.SHOW_RESTORE_MODAL, showRestoreModal);
|
yield takeLatest(AUTH_USER_ACTIONS.SHOW_RESTORE_MODAL, showRestoreModal);
|
||||||
yield takeLatest(AUTH_USER_ACTIONS.RESTORE_PASSWORD, restorePassword);
|
yield takeLatest(AUTH_USER_ACTIONS.RESTORE_PASSWORD, restorePassword);
|
||||||
|
yield takeLatest(AUTH_USER_ACTIONS.GET_SOCIALS, getSocials);
|
||||||
|
yield takeLatest(AUTH_USER_ACTIONS.DROP_SOCIAL, dropSocial);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default authSaga;
|
export default authSaga;
|
||||||
|
|
|
@ -24,6 +24,15 @@ export interface IUser {
|
||||||
is_user: boolean;
|
is_user: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type ISocialProvider = 'vkontakte' | 'google';
|
||||||
|
|
||||||
|
export interface ISocialAccount {
|
||||||
|
provider: ISocialProvider;
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
photo: string;
|
||||||
|
}
|
||||||
|
|
||||||
export type IAuthState = Readonly<{
|
export type IAuthState = Readonly<{
|
||||||
user: IUser;
|
user: IUser;
|
||||||
token: string;
|
token: string;
|
||||||
|
@ -48,8 +57,13 @@ export type IAuthState = Readonly<{
|
||||||
user: IUser;
|
user: IUser;
|
||||||
messages: IMessage[];
|
messages: IMessage[];
|
||||||
messages_error: string;
|
messages_error: string;
|
||||||
|
|
||||||
patch_errors: Record<string, string>;
|
patch_errors: Record<string, string>;
|
||||||
|
|
||||||
|
socials: {
|
||||||
|
accounts: ISocialAccount[];
|
||||||
|
error: string;
|
||||||
|
is_loading: boolean;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
restore: {
|
restore: {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue