mirror of
https://github.com/mgerb/classic-wow-forums
synced 2026-01-10 17:12:48 +00:00
client - use mobx as state container
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import axios, { AxiosInstance, AxiosResponse } from 'axios';
|
||||
import userStore from '../stores/user-store';
|
||||
|
||||
// create our own instance of axios so we can set request headers
|
||||
const ax: AxiosInstance = axios.create();
|
||||
@@ -9,11 +10,10 @@ ax.interceptors.response.use(
|
||||
return config;
|
||||
},
|
||||
(error: any) => {
|
||||
// TODO: log the user out if they get a 401
|
||||
// if code is unauthorized (401) then logout if already logged in
|
||||
// if (error.response.status === 401 && store.getState().user.loggedIn) {
|
||||
// store.dispatch(userActions.logout());
|
||||
// }
|
||||
if (error.response.status === 401 && userStore.user) {
|
||||
userStore.resetUser();
|
||||
}
|
||||
|
||||
return Promise.reject(error);
|
||||
},
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
import React from 'react';
|
||||
import { inject, observer } from 'mobx-react';
|
||||
import { UserStore } from '../../stores/user-store';
|
||||
|
||||
interface Props {
|
||||
className?: string;
|
||||
userStore?: UserStore;
|
||||
}
|
||||
|
||||
interface State {}
|
||||
@@ -12,14 +15,17 @@ const oauthUrl: string =
|
||||
? ''
|
||||
: 'https://us.battle.net/oauth/authorize?redirect_uri=https://localhost/oauth&scope=wow.profile&client_id=2pfsnmd57svcpr5c93k7zb5zrug29xvp&response_type=code';
|
||||
|
||||
@inject('userStore')
|
||||
@observer
|
||||
export class LoginButton extends React.Component<Props, State> {
|
||||
|
||||
login() {
|
||||
window.open(oauthUrl, '_blank', 'resizeable=yes, height=900, width=1200');
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div {...this.props}>
|
||||
<div className={this.props.className}>
|
||||
<img src={require('../../assets/login-bot-left.gif')} />
|
||||
<img src={require('../../assets/login-bot-login.gif')} style={{ cursor: 'pointer' }} onClick={this.login.bind(this)} />
|
||||
<img src={require('../../assets/login-bot-right.gif')} />
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
export interface UserModel {
|
||||
|
||||
access_token: string;
|
||||
battle_net_id: number;
|
||||
battletag: string;
|
||||
id: number;
|
||||
permissions: string;
|
||||
token: string;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import React from 'react';
|
||||
import { RouteComponentProps } from 'react-router-dom';
|
||||
import { ContentContainer } from '../../components';
|
||||
import { UserService } from '../../services';
|
||||
|
||||
interface Props extends RouteComponentProps<any> {}
|
||||
|
||||
@@ -9,9 +8,7 @@ interface State {}
|
||||
|
||||
export class UserAccount extends React.Component<Props, State> {
|
||||
|
||||
componentDidMount() {
|
||||
console.log(UserService.getUser());
|
||||
}
|
||||
componentDidMount() {}
|
||||
|
||||
render() {
|
||||
return (
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import React from 'react';
|
||||
import { BrowserRouter, Route, Switch } from 'react-router-dom';
|
||||
import { Provider } from 'mobx-react';
|
||||
import { Footer, Header } from './components';
|
||||
import { Forum, Home, NotFound, Oauth, Realms, UserAccount } from './pages';
|
||||
import { stores } from './stores/stores';
|
||||
|
||||
// styling
|
||||
import './scss/index.scss';
|
||||
@@ -14,20 +16,22 @@ export class Routes extends React.Component<Props, State> {
|
||||
|
||||
public render() {
|
||||
return (
|
||||
<BrowserRouter>
|
||||
<div>
|
||||
<Header />
|
||||
<Switch>
|
||||
<Route exact path="/" component={Home} />
|
||||
<Route exact path="/realms" component={Realms} />
|
||||
<Route exact path="/f/:id" component={Forum} />
|
||||
<Route exact path="/oauth" component={Oauth} />
|
||||
<Route exact path="/user-account" component={UserAccount} />
|
||||
<Route component={NotFound} />
|
||||
</Switch>
|
||||
<Footer />
|
||||
</div>
|
||||
</BrowserRouter>
|
||||
<Provider {...stores}>
|
||||
<BrowserRouter>
|
||||
<div>
|
||||
<Header />
|
||||
<Switch>
|
||||
<Route exact path="/" component={Home} />
|
||||
<Route exact path="/realms" component={Realms} />
|
||||
<Route exact path="/f/:id" component={Forum} />
|
||||
<Route exact path="/oauth" component={Oauth} />
|
||||
<Route exact path="/user-account" component={UserAccount} />
|
||||
<Route component={NotFound} />
|
||||
</Switch>
|
||||
<Footer />
|
||||
</div>
|
||||
</BrowserRouter>
|
||||
</Provider>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ const getCategories = async () => {
|
||||
const res = await axios.get('/api/category');
|
||||
categoryCache = cloneDeep(res.data.data);
|
||||
return res.data.data;
|
||||
}
|
||||
};
|
||||
|
||||
export const CategoryService = {
|
||||
getCategories,
|
||||
|
||||
@@ -1,27 +1,16 @@
|
||||
import axios from '../axios/axios';
|
||||
import { UserModel } from '../model';
|
||||
|
||||
const storeUser = (user: UserModel): void => {
|
||||
localStorage.setItem('user', JSON.stringify(user));
|
||||
}
|
||||
|
||||
const getUser = (): UserModel => {
|
||||
const u = localStorage.getItem('user');
|
||||
return u ? JSON.parse(u) : null;
|
||||
}
|
||||
import userStore from '../stores/user-store';
|
||||
|
||||
// fetch user and store in local storage
|
||||
const authorize = async (code: string): Promise<void> => {
|
||||
try {
|
||||
const res = await axios.post('/api/battlenet/authorize', { code });
|
||||
UserService.storeUser(res.data.data);
|
||||
userStore.setUser(res.data.data);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export const UserService = {
|
||||
storeUser,
|
||||
getUser,
|
||||
authorize,
|
||||
}
|
||||
};
|
||||
|
||||
5
client/app/stores/stores.ts
Normal file
5
client/app/stores/stores.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import userStore from './user-store';
|
||||
|
||||
export const stores = {
|
||||
userStore,
|
||||
};
|
||||
38
client/app/stores/user-store.ts
Normal file
38
client/app/stores/user-store.ts
Normal file
@@ -0,0 +1,38 @@
|
||||
import { action, observable } from 'mobx';
|
||||
import { UserModel } from '../model';
|
||||
import { resetAuthorizationHeader, setAuthorizationHeader } from '../axios/axios';
|
||||
|
||||
export class UserStore {
|
||||
|
||||
@observable user?: UserModel;
|
||||
|
||||
constructor() {
|
||||
// use timeout or axios won't be defined
|
||||
setTimeout(() => {
|
||||
this.getUserFromStorage();
|
||||
});
|
||||
}
|
||||
|
||||
@action setUser(user: UserModel) {
|
||||
localStorage.setItem('user', JSON.stringify(user));
|
||||
this.getUserFromStorage();
|
||||
}
|
||||
|
||||
@action private getUserFromStorage(): void {
|
||||
const u = localStorage.getItem('user');
|
||||
if (u) {
|
||||
this.user = JSON.parse(u);
|
||||
setAuthorizationHeader(this.user!.token);
|
||||
}
|
||||
}
|
||||
|
||||
// when the user logs out
|
||||
@action resetUser() {
|
||||
this.user = undefined;
|
||||
resetAuthorizationHeader();
|
||||
localStorage.removeItem('user');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default new UserStore();
|
||||
Reference in New Issue
Block a user