mirror of
https://github.com/sergeyyarkov/educt-client.git
synced 2026-10-11 10:19:22 +03:00
feat: added typing for user result fetch & logout
This commit is contained in:
parent
e7e98dd7ac
commit
d4703b97d3
23
src/App.tsx
23
src/App.tsx
@ -13,22 +13,19 @@ import MessagesPage from './pages/messages';
|
||||
import ProfilePage from './pages/profile';
|
||||
import AuthPage from './pages/auth';
|
||||
import NotFoundPage from './pages/404';
|
||||
import { ErrorBoundary } from 'react-error-boundary';
|
||||
|
||||
const App = () => {
|
||||
return (
|
||||
<ErrorBoundary FallbackComponent={ErrorFallback}>
|
||||
<Router>
|
||||
<Switch>
|
||||
<PrivateRoute exact path='/' component={MainPage} title='Main' />
|
||||
<PrivateRoute path='/courses' component={CoursesPage} title='Courses' />
|
||||
<PrivateRoute path='/messages' component={MessagesPage} title='Messages' />
|
||||
<PrivateRoute path='/profile' component={ProfilePage} title='Profile' />
|
||||
<Route path='/auth' component={AuthPage} />
|
||||
<Route component={NotFoundPage} />
|
||||
</Switch>
|
||||
</Router>
|
||||
</ErrorBoundary>
|
||||
<Router>
|
||||
<Switch>
|
||||
<PrivateRoute exact path='/' component={MainPage} title='Main' />
|
||||
<PrivateRoute path='/courses' component={CoursesPage} title='Courses' />
|
||||
<PrivateRoute path='/messages' component={MessagesPage} title='Messages' />
|
||||
<PrivateRoute path='/profile' component={ProfilePage} title='Profile' />
|
||||
<Route path='/auth' component={AuthPage} />
|
||||
<Route component={NotFoundPage} />
|
||||
</Switch>
|
||||
</Router>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@ -11,14 +11,13 @@ import {
|
||||
Box,
|
||||
Avatar,
|
||||
Text,
|
||||
Link,
|
||||
useToast,
|
||||
Skeleton,
|
||||
} from '@chakra-ui/react';
|
||||
import { MdSettings, MdExitToApp } from 'react-icons/md';
|
||||
import { observer } from 'mobx-react';
|
||||
import { useRootStore } from '../../../hooks/useRootStore';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
import { useHistory, Link } from 'react-router-dom';
|
||||
|
||||
const UserInfo: React.FC = () => {
|
||||
const { authStore, userStore } = useRootStore();
|
||||
|
||||
@ -12,15 +12,13 @@ import { useErrorHandler } from 'react-error-boundary';
|
||||
* Сomponent for rendering the current page.
|
||||
*/
|
||||
const Layout: React.FC = ({ children }) => {
|
||||
const { authStore } = useRootStore();
|
||||
const { authStore, userStore } = useRootStore();
|
||||
const handleError = useErrorHandler();
|
||||
|
||||
React.useEffect(() => {
|
||||
if (authStore.isLoggedIn) {
|
||||
authStore.root.userStore.loadCurrentUserData().catch(error => {
|
||||
if (error.response && error.response.status === 401) {
|
||||
handleError(error);
|
||||
}
|
||||
userStore.loadCurrentUserData().catch(error => {
|
||||
handleError(error);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
@ -5,6 +5,8 @@ import { Route, Redirect } from 'react-router-dom';
|
||||
import { IPrivateRouteProps } from '../../interfaces';
|
||||
import { useRootStore } from '../../hooks/useRootStore';
|
||||
import { observer } from 'mobx-react';
|
||||
import { ErrorBoundary } from 'react-error-boundary';
|
||||
import ErrorFallback from '../ErrorFallback';
|
||||
|
||||
/**
|
||||
* Checks if the user is loggedIn by reactive variable and if not,
|
||||
@ -18,12 +20,14 @@ const PrivateRoute: React.FC<IPrivateRouteProps> = ({ children, component: Compo
|
||||
{...options}
|
||||
render={props =>
|
||||
authStore.isLoggedIn ? (
|
||||
<Layout>
|
||||
<Helmet>
|
||||
<title>{title} • App </title>
|
||||
</Helmet>
|
||||
<Component {...props} title={title} />
|
||||
</Layout>
|
||||
<ErrorBoundary FallbackComponent={ErrorFallback}>
|
||||
<Layout>
|
||||
<Helmet>
|
||||
<title>{title} • App </title>
|
||||
</Helmet>
|
||||
<Component {...props} title={title} />
|
||||
</Layout>
|
||||
</ErrorBoundary>
|
||||
) : (
|
||||
<Redirect to={{ pathname: '/auth', state: { from: props.location } }} />
|
||||
)
|
||||
|
||||
@ -12,12 +12,36 @@ export interface IAppConfig {
|
||||
links: LinkType[];
|
||||
}
|
||||
|
||||
export interface IUserRole {
|
||||
id: number;
|
||||
name: string;
|
||||
slug: string;
|
||||
}
|
||||
|
||||
export interface IDataResult {
|
||||
data: any;
|
||||
message: string;
|
||||
status: number;
|
||||
}
|
||||
|
||||
export interface ILoginResult extends IDataResult {
|
||||
data: {
|
||||
token: string;
|
||||
type: string;
|
||||
expires_at: string;
|
||||
};
|
||||
}
|
||||
|
||||
export interface IUserResult extends IDataResult {
|
||||
data: {
|
||||
id: string;
|
||||
first_name: string;
|
||||
last_name: string;
|
||||
email: string;
|
||||
roles: IUserRole[];
|
||||
};
|
||||
}
|
||||
|
||||
export interface IPageProps extends RouteComponentProps {
|
||||
title?: string;
|
||||
}
|
||||
|
||||
@ -1,13 +1,5 @@
|
||||
import { IDataResult } from '../interfaces';
|
||||
import { AxiosInstance } from 'axios';
|
||||
|
||||
export interface ILoginResult extends IDataResult {
|
||||
data: {
|
||||
token: string;
|
||||
type: string;
|
||||
expires_at: string;
|
||||
};
|
||||
}
|
||||
import { IDataResult, ILoginResult } from '../interfaces';
|
||||
import { AxiosInstance, AxiosResponse } from 'axios';
|
||||
|
||||
export default class AuthService {
|
||||
public api: AxiosInstance;
|
||||
@ -24,22 +16,20 @@ export default class AuthService {
|
||||
* @returns Login result
|
||||
*/
|
||||
public async requestLogin(login: string, password: string): Promise<ILoginResult> {
|
||||
const result = await this.api.post('v1/auth/login', {
|
||||
const result: AxiosResponse<any> = await this.api.post('v1/auth/login', {
|
||||
login,
|
||||
password,
|
||||
});
|
||||
|
||||
return result.data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Revoke token
|
||||
*
|
||||
* @returns Logout result
|
||||
* @returns Data result
|
||||
*/
|
||||
public async requestLogout(): Promise<any> {
|
||||
const result = await this.api.post('v1/auth/logout');
|
||||
|
||||
public async requestLogout(): Promise<IDataResult> {
|
||||
const result: AxiosResponse<any> = await this.api.post('v1/auth/logout');
|
||||
return result.data;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import { AxiosInstance } from 'axios';
|
||||
import { IUserResult } from '../interfaces';
|
||||
|
||||
export default class UserService {
|
||||
public api: AxiosInstance;
|
||||
@ -12,7 +13,7 @@ export default class UserService {
|
||||
*
|
||||
* @returns User data
|
||||
*/
|
||||
public async fetchMe(): Promise<any> {
|
||||
public async fetchMe(): Promise<IUserResult> {
|
||||
const result = await this.api.get('v1/me');
|
||||
return result.data;
|
||||
}
|
||||
|
||||
@ -3,6 +3,7 @@ import Cookies from 'js-cookie';
|
||||
import RootStore from './RootStore';
|
||||
import AuthService from '../services/AuthService';
|
||||
import { AxiosInstance } from 'axios';
|
||||
import { IDataResult, ILoginResult } from '../interfaces';
|
||||
|
||||
export default class AuthStore {
|
||||
public root: RootStore;
|
||||
@ -27,7 +28,7 @@ export default class AuthStore {
|
||||
this.loading = value;
|
||||
}
|
||||
|
||||
public async login(login: string, password: string) {
|
||||
public async login(login: string, password: string): Promise<ILoginResult> {
|
||||
try {
|
||||
this.setLoading(true);
|
||||
const result = await this.authService.requestLogin(login, password);
|
||||
@ -43,7 +44,7 @@ export default class AuthStore {
|
||||
}
|
||||
}
|
||||
|
||||
public async logout() {
|
||||
public async logout(): Promise<IDataResult> {
|
||||
try {
|
||||
this.setLoading(true);
|
||||
const result = await this.authService.requestLogout();
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import { AxiosInstance } from 'axios';
|
||||
import { autorun, makeAutoObservable } from 'mobx';
|
||||
import { IUserResult } from '../interfaces';
|
||||
import UserService from '../services/UserService';
|
||||
import RootStore from './RootStore';
|
||||
|
||||
@ -25,13 +26,17 @@ export default class UserStore {
|
||||
makeAutoObservable(this);
|
||||
}
|
||||
|
||||
public async loadCurrentUserData(): Promise<any> {
|
||||
const result = await this.userService.fetchMe();
|
||||
public async loadCurrentUserData(): Promise<IUserResult> {
|
||||
try {
|
||||
const result = await this.userService.fetchMe();
|
||||
|
||||
autorun(() => {
|
||||
this.me = result.data;
|
||||
});
|
||||
autorun(() => {
|
||||
this.me = result.data;
|
||||
});
|
||||
|
||||
return result;
|
||||
return result;
|
||||
} catch (error) {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user