1
0
mirror of https://github.com/mgerb/classic-wow-forums synced 2026-01-10 09:02:50 +00:00

client - use mobx as state container

This commit is contained in:
2018-01-09 20:24:09 -06:00
parent 8a39f687a8
commit 2d6ff0875f
13 changed files with 100 additions and 42 deletions

View File

@@ -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);
},

View File

@@ -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')} />

View File

@@ -1,3 +1,8 @@
export interface UserModel {
access_token: string;
battle_net_id: number;
battletag: string;
id: number;
permissions: string;
token: string;
}

View File

@@ -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 (

View File

@@ -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,6 +16,7 @@ export class Routes extends React.Component<Props, State> {
public render() {
return (
<Provider {...stores}>
<BrowserRouter>
<div>
<Header />
@@ -28,6 +31,7 @@ export class Routes extends React.Component<Props, State> {
<Footer />
</div>
</BrowserRouter>
</Provider>
);
}
}

View File

@@ -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,

View File

@@ -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,
}
};

View File

@@ -0,0 +1,5 @@
import userStore from './user-store';
export const stores = {
userStore,
};

View 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();

View File

@@ -34,6 +34,8 @@
"font-awesome": "^4.7.0",
"html-webpack-plugin": "^2.30.1",
"lodash": "^4.17.4",
"mobx": "^3.4.1",
"mobx-react": "^4.3.5",
"node-sass": "^4.7.2",
"normalize.css": "^7.0.0",
"postcss-loader": "^2.0.9",

View File

@@ -1,5 +1,6 @@
{
"compilerOptions": {
"experimentalDecorators": true,
"target": "es2015",
"module": "es2015",
"moduleResolution": "node",

View File

@@ -3,6 +3,7 @@
"rules": {
"import-name": false,
"max-line-length": [true, 140],
"no-unused-variable": [true]
"no-unused-variable": [true],
"variable-name": [false]
}
}

View File

@@ -2830,7 +2830,7 @@ hoek@4.x.x:
version "4.2.0"
resolved "https://registry.yarnpkg.com/hoek/-/hoek-4.2.0.tgz#72d9d0754f7fe25ca2d01ad8f8f9a9449a89526d"
hoist-non-react-statics@^2.3.0:
hoist-non-react-statics@^2.3.0, hoist-non-react-statics@^2.3.1:
version "2.3.1"
resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-2.3.1.tgz#343db84c6018c650778898240135a1420ee22ce0"
@@ -3833,6 +3833,16 @@ mkdirp@0.5.1, mkdirp@0.5.x, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdi
dependencies:
minimist "0.0.8"
mobx-react@^4.3.5:
version "4.3.5"
resolved "https://registry.yarnpkg.com/mobx-react/-/mobx-react-4.3.5.tgz#76853f2f2ef4a6f960c374bcd9f01e875929c04c"
dependencies:
hoist-non-react-statics "^2.3.1"
mobx@^3.4.1:
version "3.4.1"
resolved "https://registry.yarnpkg.com/mobx/-/mobx-3.4.1.tgz#37abe5ee882d401828d9f26c6c1a2f47614bbbef"
ms@0.7.1:
version "0.7.1"
resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.1.tgz#9cd13c03adbff25b65effde7ce864ee952017098"