Browse Source

finished authorization

unknown 2 years ago
parent
commit
5fc05111e2

File diff suppressed because it is too large
+ 1 - 1
.eslintcache


+ 9 - 9
src/App.tsx

@@ -1,18 +1,16 @@
-import { lazy, Suspense } from 'react';
+import { lazy, Suspense , useEffect } from 'react';
 import { BrowserRouter, Switch } from 'react-router-dom';
 import { ToastContainer } from 'react-toastify';
-import { useEffect } from 'react';
 import { useSelector, useDispatch } from 'react-redux';
 
 import s from './App.module.css';
 import { getToken } from './redux/authorization/selector'
-import {asyncLogout} from './redux/authorization/operations'
+import { asyncLogout, asyncCurrentUser } from './redux/authorization/operations'
+import { setToken } from './api-data'
 import PrivateRoute from './components/Routes/PrivateRoute/PrivateRoute';
 import PublicRoute from './components/Routes/PublicRoute/PublicRoute';
 import Loader from './components/Loader/Loader';
 
-
-
 const AuthPage = lazy(
   () =>
     import(
@@ -20,8 +18,6 @@ const AuthPage = lazy(
     ),
 );
 
-
-
 function App() {
   const token = useSelector(getToken)
   const dispatch = useDispatch()
@@ -31,6 +27,10 @@ function App() {
   }, [])
 
   useEffect(() => {
+    if (token) {
+      setToken.set(token)
+      dispatch(asyncCurrentUser())
+    }
     const handleKeepIn = () => {
      if (localStorage.isChecked === 'false') dispatch(asyncLogout())
     }
@@ -51,11 +51,11 @@ function App() {
               </PublicRoute>
           </Switch>
         </BrowserRouter>
+        <Loader/>
       </Suspense>
-      
       <ToastContainer
         position="top-right"
-        autoClose={3000}
+        autoClose={5000}
         hideProgressBar={false}
         newestOnTop={false}
         closeOnClick

+ 14 - 3
src/api-data/index.ts

@@ -53,7 +53,7 @@ const loginUser = async <T>(number:string,code:string):Promise<T | undefined> =>
   }
 };
 
-const updateCredentials = async (name: string,lastName: string):Promise<any> => {
+const updateCredentials = async <T>(name: string,lastName: string):Promise<T | undefined> => {
   try {
     const { data : {data} } = await axios.patch('/users/current', { name, lastName });
     success(`CREDENTIALS UPDATED`);
@@ -63,7 +63,7 @@ const updateCredentials = async (name: string,lastName: string):Promise<any> =>
   }
 };
 
-const updateUserAvatar = async (formData: any): Promise<any> => {
+const updateUserAvatar = async <T>(formData: object): Promise<T | undefined> => {
   try {
     const { data : {data} } = await axios.patch('/users/avatars', formData);
     success(`AVATAR UPDATED`);
@@ -73,6 +73,16 @@ const updateUserAvatar = async (formData: any): Promise<any> => {
   } 
 };
 
+const currentUser = async <T>(): Promise<T | undefined> => {
+  try {
+    const { data : {data} } = await axios.get('/users/current');
+    success(`LOGIN`);
+    return data
+  } catch (e) {
+    error('BAD REQUEST');
+  } 
+};
+
 
 
 export {
@@ -80,5 +90,6 @@ export {
   authorizeUser,
   loginUser,
   updateCredentials,
-  updateUserAvatar
+  updateUserAvatar,
+  currentUser
 };

+ 6 - 0
src/components/AuthPage/index.tsx

@@ -7,6 +7,7 @@ import SMSCode from './SMSCode'
 import Registration from './Registration'
 import { authorizeUser } from '../../api-data'
 import { asyncLogin } from '../../redux/authorization/operations'
+import { actionIsLoading } from '../../redux/loading/action'
 
 const AuthPage = () => {
   const [isQR, setIsQR] = useState<boolean>(false)
@@ -28,8 +29,13 @@ const AuthPage = () => {
   const handleIsQR = (): void => setIsQR(!isQR)
 
   const handleSendCode = async (): Promise<void> => {
+    try {
+      dispatch(actionIsLoading(true))
       const res = await authorizeUser(format(number), country)
       res&&setIsCode(res)
+    }  finally {
+      dispatch(actionIsLoading(false))
+    }
   }
 
   const handleIsValidCode = async (e: React.ChangeEvent<HTMLInputElement>):Promise<void> => {

+ 5 - 2
src/components/Loader/Loader.jsx

@@ -1,10 +1,13 @@
 import 'react-loader-spinner/dist/loader/css/react-spinner-loader.css';
 import Loader from 'react-loader-spinner';
+import { useSelector } from 'react-redux';
 
+import {getLoad} from '../../redux/loading/selector'
 import s from './Loader.module.css';
 
 const Load = () => {
-  return (
+  const isLoading = useSelector(getLoad)
+  return isLoading?(
     <Loader
       className={s.loader}
       type="Puff"
@@ -13,6 +16,6 @@ const Load = () => {
       width={100}
       timeout={300000}
     />
-  );
+  ):null
 };
 export default Load;

+ 1 - 2
src/index.tsx

@@ -7,12 +7,11 @@ import 'react-toastify/dist/ReactToastify.css';
 import 'modern-normalize/modern-normalize.css';
 import './index.css';
 import App from './App';
-import Loader from './components/Loader/Loader';
 import { store, persistor } from './redux/store';
 
 ReactDOM.render(
   <React.StrictMode>
-    <PersistGate loading={<Loader/>} persistor={persistor}>
+    <PersistGate loading={null} persistor={persistor}>
       <Provider store={store}>
         <App />
       </Provider>

+ 11 - 0
src/redux/authorization/action/index.ts

@@ -1,4 +1,5 @@
 import { createAction } from '@reduxjs/toolkit';
+import {IAuthorizationState} from '../../../typescript/redux/authorization/interfaces'
 
 const actionLogInSuccess = createAction('login/success', (value:string) => ({
   payload: value,
@@ -16,9 +17,19 @@ const actionLogOutReject = createAction('logout/reject', () => ({
   payload: null,
 }));
 
+const actionCurrentSuccess = createAction('current/success', (value:IAuthorizationState) => ({
+  payload: value,
+}));
+
+const actionCurrentReject = createAction('current/reject', () => ({
+  payload: null,
+}));
+
 export {
   actionLogInSuccess,
   actionLogInReject,
   actionLogOutSuccess,
   actionLogOutReject,
+  actionCurrentSuccess,
+  actionCurrentReject
 };

+ 25 - 12
src/redux/authorization/operations/index.ts

@@ -1,41 +1,43 @@
 import { actionIsLoading } from '../../loading/action';
-
 import {
   actionLogInSuccess,
   actionLogInReject,
   actionLogOutSuccess,
   actionLogOutReject,
+  actionCurrentSuccess,
+  actionCurrentReject
 } from '../action';
+import { setToken, loginUser, updateCredentials, updateUserAvatar, currentUser } from '../../../api-data';
+import { IAuthorizationState } from '../../../typescript/redux/authorization/interfaces'
+import { TResPromiseAll } from '../../../typescript/redux/authorization/types'
 
-import { setToken, loginUser,updateCredentials,updateUserAvatar } from '../../../api-data';
-
-const asyncCreateUser = (name:string, lastName: string,file:any) => async (dispatch:any) => {
+const asyncCreateUser = (name:string, lastName: string,file:object) => async (dispatch:any) => {
   try {
     dispatch(actionIsLoading(true));
     const reader: any = new FileReader()
     const formData:any = new FormData()
       reader.onload = async () => {
         formData.append("avatar", file);
-        const data = await Promise.all([updateUserAvatar(formData), updateCredentials(name, lastName)])
-        const res = data.find(el => el.token)
-        res?.token&&dispatch(actionLogInSuccess(res.token))
+        const data = await Promise.all<TResPromiseAll>(
+          [updateUserAvatar(formData), updateCredentials(name, lastName)])
+        const token = data.find(el => el?.token)?.token
+        token&&dispatch(actionLogInSuccess(token))
       }
      await reader.readAsArrayBuffer(file)
   } catch (e) {
-    console.log(e)
+    dispatch(actionLogInReject())
   } finally {
     dispatch(actionIsLoading(false));
   }
 };
 
-
-
 const asyncLogin = (number:string, code: string,cb:() => void ) => async (dispatch:any) => {
   try {
     dispatch(actionIsLoading(true));
     const data = await loginUser<{ token: string, registered: boolean }>(number, code);
     const token = data?.token
     const registered = data?.registered
+    console.log(token,registered)
     if (!token) return
     setToken.set(token)
     if (!registered) return cb()
@@ -60,6 +62,17 @@ const asyncLogout = () => async (dispatch:any) => {
   }
 };
 
+const asyncCurrentUser = () => async (dispatch:any) => {
+  try {
+    dispatch(actionIsLoading(true));
+    const data = await currentUser<IAuthorizationState>()
+    data && dispatch(actionCurrentSuccess(data));
+    if(!data?.token) throw new Error('old token')
+  } catch (e) {
+    dispatch(actionCurrentReject());
+  } finally {
+    dispatch(actionIsLoading(false));
+  }
+};
 
-
-export { asyncCreateUser, asyncLogin, asyncLogout };
+export { asyncCreateUser, asyncLogin, asyncLogout, asyncCurrentUser };

+ 9 - 1
src/redux/authorization/reducer/index.ts

@@ -1,11 +1,13 @@
 import { createReducer } from '@reduxjs/toolkit';
-import { IAuthorizationState } from '../../../typescript/redux/authorization/interfaces';
+import { IAuthorizationState , IAuthorizationPayload} from '../../../typescript/redux/authorization/interfaces';
 
 import {
   actionLogInSuccess,
   actionLogInReject,
   actionLogOutSuccess,
   actionLogOutReject,
+  actionCurrentSuccess,
+  actionCurrentReject
 } from '../action';
 
 const initialState:IAuthorizationState = {
@@ -31,6 +33,12 @@ const reducerAuthorization = createReducer(initialState, {
   [actionLogOutReject.type]: (state, _) => {
     return state;
   },
+  [actionCurrentSuccess.type]: (_state, { payload}:IAuthorizationPayload) => {
+    return payload
+  },
+  [actionCurrentReject.type]: (_state, _) => {
+    return initialState;
+  },
 });
 
 export default reducerAuthorization;

+ 6 - 0
src/typescript/redux/authorization/interfaces.ts

@@ -1,3 +1,5 @@
+import { string } from "prop-types";
+
 export interface IAuthorizationState  {
         token: string,
         number: string ,
@@ -11,3 +13,7 @@ export interface IAuthorizationPayload  {
   payload: IAuthorizationState
 }
 
+export interface IResToken  {
+  token?: string | null
+}
+

+ 3 - 0
src/typescript/redux/authorization/types.ts

@@ -0,0 +1,3 @@
+import { IResToken } from './interfaces'
+
+export type TResPromiseAll = IResToken | undefined