Unverified Commit 9fb1ace1 authored by andreswebs's avatar andreswebs
Browse files

restructure redux

parent 6f048534
......@@ -2,12 +2,12 @@ REACT_APP_CLIENT_ID="54_5yhfa1hjaps00s8o0ogssc8oc80ks4so8cg4soko0ok48gwk4w"
REACT_APP_CLIENT_SECRET="4hqd4dzsrvcw8osgkkwsgks8gsgw4kg0c0k4wskow800g8scs0"
REACT_APP_BACKEND_URL="https://api.bankofthecommons.coop"
REACT_APP_LOGIN_PATH="oauth/v3/token"
REACT_APP_WALLET_PATH="company/v1/wallet"
REACT_APP_COMPANY_WALLET_PATH="company/v1/wallet"
REACT_APP_USER_WALLET_PATH="user/v1/wallet"
REACT_APP_USER_ACCOUNT_PATH="user/v1/account"
REACT_APP_WALLET_ACTIONS_PATH="user/v1/methods"
REACT_APP_TRANSACTIONS_PATH="user/v1/last"
REACT_APP_MONTH_EARNINGS_PATH="user/v1/wallet/monthearnings"
REACT_APP_LAST_TRANSACTIONS_PATH="user/v1/last"
REACT_APP_TRANSACTIONS_PATH="user/v1/wallet/transactions"
REACT_APP_MONTH_EARNINGS_PATH="user/v1/wallet/monthearnings"
REACT_APP_EARNINGS_PATH="user/v1/wallet/earnings"
REACT_APP_CURRENCIES_VALUE_PATH="exchange/v1/ticker/eur"
\ No newline at end of file
REACT_APP_CURRENCY_VALUES_PATH="exchange/v1/ticker/eur"
\ No newline at end of file
......@@ -9,7 +9,9 @@ REACT_APP_CLIENT_SECRET="<< client secret here >>"
# src/widgets/WalletActions/CashIn/methods/actions.js
# src/utils.js
REACT_APP_BACKEND_URL="<< api base url here >>"
REACT_APP_WALLET_PATH="<< wallet api path here >>"
# src/widgets/WalletActions/CashIn/methods/actions.js
REACT_APP_COMPANY_WALLET_PATH="<< wallet api path here >>"
# src/pages/login/actions.js
REACT_APP_LOGIN_PATH="<< login api path here >>"
......@@ -27,7 +29,7 @@ REACT_APP_LAST_TRANSACTIONS_PATH="<< last transactions api path here >>"
REACT_APP_EARNINGS_PATH="<< earnings api path here >>"
# src/widgets/CurrenciesValue/actions.js
REACT_APP_CURRENCIES_VALUE_PATH="<< currencies value api path here >>"
REACT_APP_CURRENCY_VALUES_PATH="<< currencies value api path here >>"
# src/widgets/WalletActions/actions.js
REACT_APP_WALLET_ACTIONS_PATH="<< wallet actions api path here >>"
......
{
"short_name": "React App",
"name": "Create React App Sample",
"short_name": "BotC Wallet",
"name": "Bank of the Commons Wallet",
"icons": [
{
"src": "favicon.ico",
......@@ -12,4 +12,4 @@
"display": "standalone",
"theme_color": "#000000",
"background_color": "#ffffff"
}
}
\ No newline at end of file
import React from 'react';
import { Provider } from 'react-redux';
import store from 'store';
import Router from 'routes';
import MainRoutes from 'routes/MainRoutes';
import 'App.css';
const App = () => (
<Provider store={store}>
<Router />
<MainRoutes />
</Provider>
);
......
......@@ -101,7 +101,7 @@ class Sidebar extends React.Component {
rtlActive,
user
} = this.props;
const { company_image = avatar } = user.group_data;
const { company_image = avatar } = user.group_data || {};
const itemText = `${classes.itemText} ${cx({
[classes.itemTextMini]: this.props.miniActive && this.state.miniActive,
[classes.itemTextMiniRTL]:
......
import React from 'react';
import cx from 'classnames';
import { connect } from 'react-redux';
import { isLoggedIn } from 'utils';
import { Switch, Route, Redirect } from 'react-router-dom';
......@@ -10,15 +9,15 @@ import withStyles from '@material-ui/core/styles/withStyles';
// core components
import Header from 'components/Header/Header';
import Sidebar from 'components/Sidebar/Sidebar';
import Sidebar from 'components/Sidebar';
import dashboardRoutes from 'routes/dashboard';
import dashboardRoutes from 'routes/dashboard-routes';
import appStyle from 'assets/jss/material-dashboard-react/layouts/dashboardStyle';
import image from 'assets/img/sidebar-2.jpg';
import logo from 'logo.jpg';
import actions from './actions';
import * as actions from './actions';
const switchRoutes = (
<Switch>
......@@ -38,14 +37,13 @@ const switchRoutes = (
</Switch>
);
class Dashboard extends React.Component {
class DashboardLayout extends React.Component {
constructor(props) {
super(props);
this.state = {
mobileOpen: false,
miniActive: false,
loading: true
miniActive: false
};
this.mainPanelRef = React.createRef();
......@@ -56,23 +54,18 @@ class Dashboard extends React.Component {
this.resizeFunction = this.resizeFunction.bind(this);
}
// TODO: fix me
UNSAFE_componentWillMount() {
if (!isLoggedIn()) {
this.props.history.push('/login');
}
componentDidMount() {
this.props.getMe();
}
// TODO: fix me
UNSAFE_componentWillReceiveProps(nextProps) {
if (nextProps.status === 'success') {
this.setState({ loading: false });
} else if (nextProps.status === 'error') {
if (nextProps.status === 'error') {
this.props.history.push('/login');
}
}
// TODO: check this - what is it for?
getRoute = () => {
return this.props.location.pathname !== '/maps/full-screen-maps';
};
......@@ -92,10 +85,9 @@ class Dashboard extends React.Component {
};
render() {
const { classes, user, ...rest } = this.props;
const { loading } = this.state;
if (loading) {
return 'Loading';
const { classes, user, status, walletStatus, ...rest } = this.props;
if (status === 'pending' && walletStatus === 'pending') {
return <div>Loading</div>;
}
const mainPanel = `${classes.mainPanel} ${cx({
[classes.mainPanelSidebarMini]: this.state.miniActive,
......@@ -135,12 +127,12 @@ class Dashboard extends React.Component {
}
const mapStateToProps = state => ({
user: state.user.data,
user: state.user.user,
status: state.user.status,
wallet_status: state.wallet.status
walletStatus: state.wallet.status
});
export default connect(
mapStateToProps,
actions
)(withStyles(appStyle)(Dashboard));
)(withStyles(appStyle)(DashboardLayout));
import { createAction } from 'redux-actions';
import { fetchApi, logOut } from 'utils';
import { USER, WALLET } from './constants';
const USER_WALLET_PATH = process.env.REACT_APP_USER_WALLET_PATH;
const USER_ACCOUNT_PATH = process.env.REACT_APP_USER_ACCOUNT_PATH;
const reset = createAction(USER, () => ({
status: 'initial'
}));
function reset() {
return {
type: USER,
payload: {
status: 'initial'
}
};
}
const begin = createAction(USER, () => ({
status: 'pending'
}));
function begin() {
return {
type: USER,
payload: {
status: 'pending'
}
};
}
const fail = createAction(USER, error => ({
error,
status: 'error'
}));
function failure(error) {
return {
type: USER,
payload: {
status: 'error',
error
},
error: true
};
}
const success = createAction(USER, user => ({
user,
status: 'success'
}));
function success(user) {
return {
type: USER,
payload: {
status: 'success',
user
}
};
}
const resetWallet = createAction(WALLET, () => ({
status: 'initial'
}));
function resetWallet() {
return {
type: WALLET,
payload: {
status: 'initial'
}
};
}
const beginWallet = createAction(WALLET, () => ({
status: 'pending'
}));
function beginWallet() {
return {
type: WALLET,
payload: {
status: 'pending'
}
};
}
const failWallet = createAction(WALLET, error => ({
error,
status: 'error'
}));
function failureWallet(error) {
return {
type: WALLET,
payload: {
status: 'error',
error
},
error: true
};
}
const successWallet = createAction(WALLET, wallet => ({
wallet,
status: 'success'
}));
function successWallet(wallet) {
return {
type: WALLET,
payload: {
status: 'success',
wallet
}
};
}
const getMe = () => dispatch => {
dispatch(begin());
......@@ -56,21 +97,19 @@ const getMe = () => dispatch => {
})
.catch(error => {
logOut();
dispatch(fail(error));
dispatch(failWallet(error));
dispatch(failure(error));
dispatch(failureWallet(error));
});
};
const actions = {
export {
reset,
begin,
success,
fail,
failure,
resetWallet,
beginWallet,
successWallet,
failWallet,
failureWallet,
getMe
};
export default actions;
import DashboardLayout from './DashboardLayout';
export default DashboardLayout;
import { USER, WALLET } from './constants';
function userReducer(
state = { status: 'initial', user: {}, error: null },
action
) {
if (action.type === USER) {
const { status, user, error } = action.payload;
return {
status,
user: user || state.user,
error: error || state.error
};
}
return state;
}
function walletReducer(
state = { status: 'initial', wallet: [], error: null },
action
) {
if (action.type === WALLET) {
const { status, wallet, error } = action.payload;
return {
status,
wallet: wallet || state.wallet,
error: error || state.error
};
}
return state;
}
export { userReducer, walletReducer };
......@@ -27,11 +27,11 @@ import IconButton from '@material-ui/core/IconButton';
import CloseIcon from '@material-ui/icons/Close';
import loginPageStyle from 'assets/jss/material-dashboard-react/views/loginPageStyle';
import { isLoggedIn } from '../../utils';
import { isLoggedIn } from 'utils';
import actions from './actions';
import * as actions from 'store/login/actions';
class LoginPage extends React.Component {
class LoginLayout extends React.Component {
constructor(props) {
super(props);
// we use this to make the card to appear after the page has been rendered
......@@ -63,14 +63,10 @@ class LoginPage extends React.Component {
};
}
// TODO: FIX ME
UNSAFE_componentWillMount() {
componentDidMount() {
if (isLoggedIn()) {
this.props.history.push('/dashboard');
}
}
componentDidMount() {
// we add a hidden class to the card and after 700 ms we delete it and the transition appears
this.timeOutFunction = setTimeout(
function makeTransition() {
......@@ -224,7 +220,7 @@ class LoginPage extends React.Component {
}
}
LoginPage.propTypes = {
LoginLayout.propTypes = {
classes: PropTypes.object.isRequired
};
......@@ -237,4 +233,4 @@ const mapStateToProps = state => ({
export default connect(
mapStateToProps,
actions
)(withStyles(loginPageStyle)(LoginPage));
)(withStyles(loginPageStyle)(LoginLayout));
import { USER, WALLET } from './constants';
export function user(state = { status: 'initial' }, action) {
switch (action.type) {
case USER: {
const {
user = state.data,
error = state.error,
status = state.status
} = action.payload;
return {
data: user,
error,
status
};
}
default:
return state;
}
}
export function wallet(state = { status: 'initial', data: [] }, action) {
switch (action.type) {
case WALLET: {
const {
wallet = state.data,
error = state.error,
status = state.status
} = action.payload;
return {
data: wallet,
error,
status
};
}
default:
return state;
}
}
......@@ -4,16 +4,18 @@ import React from 'react';
import withStyles from '@material-ui/core/styles/withStyles';
import dashboardStyle from 'assets/jss/material-dashboard-react/views/dashboardStyle';
import CurrenciesValue from 'widgets/CurrenciesValue';
import GridContainer from 'components/Grid/GridContainer';
import GridItem from 'components/Grid/GridItem';
// widgets
import CurrencyValues from 'widgets/CurrencyValues';
import Earnings from 'widgets/Earnings';
import MonthEarnings from 'widgets/MonthEarnings';
import LastTransactions from 'widgets/LastTransactions';
import GridContainer from 'components/Grid/GridContainer';
import GridItem from 'components/Grid/GridItem';
const Dashboard = () => (
<div>
<CurrenciesValue />
<CurrencyValues />
<MonthEarnings />
<GridContainer
direction="row"
......
import { createAction } from 'redux-actions';
import { fetchApi, tokenName } from 'utils';
import { LOGIN, CLIENT_ID, CLIENT_SECRET } from './constants';
const LOGIN_PATH = process.env.REACT_APP_LOGIN_PATH;
const reset = createAction(LOGIN, () => ({
status: 'initial'
}));
const begin = createAction(LOGIN, () => ({
status: 'pending'
}));
const success = createAction(LOGIN, token => {
window.localStorage[tokenName] = token;
return {
token,
status: 'success'
};
});
const fail = createAction(LOGIN, error => ({
error,
status: 'error'
}));
const login = (username, password, code) => dispatch => {
dispatch(begin());
const body = {
client_id: CLIENT_ID,
client_secret: CLIENT_SECRET,
pin: code,
grant_type: 'password',
scope: 'panel',
username,
password
};
fetchApi({
body,
path: LOGIN_PATH,
method: 'post'
})
.then(response => {
const user = response;
dispatch(success(user.access_token));
})
.catch(error => {
dispatch(fail(error));
});
};
const actions = {
reset,
begin,
success,
fail,
login
};
export default actions;
export const LOGIN = 'LOGIN';
export const CLIENT_ID = process.env.REACT_APP_CLIENT_ID;
export const CLIENT_SECRET = process.env.REACT_APP_CLIENT_SECRET;
import { LOGIN } from './constants';
export function login(state = { status: 'initial' }, action) {
switch (action.type) {
case LOGIN: {
const {
token = state.token,
error = state.error,
status = state.status
} = action.payload;
return {
token,
error,
status
};
}
default:
return state;
}
}