From 8883eacd2a5e2f3f5637a6b71123dfcb2a64c3d5 Mon Sep 17 00:00:00 2001 From: Indrajith K L Date: Thu, 12 Dec 2019 19:31:50 +0530 Subject: :fire: :zap: Major Update * Adds Actions, Redicers and Middlewares * Adds Http Service * Adds Cancel option for Http Service * Adds HOC's for API Loader, Sidebar and Headers * Adds Random key generator for Routes --- src/actions/login.action.js | 16 +++++ src/core/app.routes.js | 6 ++ src/core/custom.router.js | 4 +- src/core/permission.router.js | 17 ++++- src/core/routes.js | 43 ++++++------ src/index.css | 15 +++++ src/index.js | 4 ++ src/master/master.component.js | 36 +++++++++++ src/middlewares/login.middleware.js | 29 +++++++++ src/middlewares/root.middleware.js | 3 +- src/modules/admin/admin.container.js | 33 +++++++--- src/modules/dashboard/dashboard.container.js | 30 +++++++-- src/modules/login/login.container.js | 50 ++++++++++++-- src/modules/login/login.service.js | 9 +++ src/modules/superadmin/superadmin.container.js | 57 ++++++++++++++-- src/reducers/error.reducer.js | 18 ++++++ src/reducers/loading.reducer.js | 12 ++++ src/reducers/login.reducer.js | 21 ++++++ src/reducers/root.reducer.js | 6 ++ src/services/http.service.js | 90 ++++++++++++++++++++++++++ src/services/selectors.js | 10 +++ src/services/storage.service.js | 3 +- src/shared/footer.css | 13 ++++ src/shared/footer.hoc.js | 35 ++++++++++ src/shared/header.hoc.js | 0 src/shared/header_footer.hoc.js | 39 +++++++++++ src/shared/loader.css | 48 ++++++++++++++ src/shared/loader.hoc.js | 16 +++++ src/shared/sidebar.css | 6 ++ src/shared/sidebar.hoc.js | 36 +++++++++++ src/utils/constants.js | 5 ++ src/utils/random.key.js | 3 + src/utils/utls.js | 0 33 files changed, 662 insertions(+), 51 deletions(-) create mode 100644 src/actions/login.action.js create mode 100644 src/master/master.component.js create mode 100644 src/middlewares/login.middleware.js create mode 100644 src/modules/login/login.service.js create mode 100644 src/reducers/error.reducer.js create mode 100644 src/reducers/loading.reducer.js create mode 100644 src/reducers/login.reducer.js create mode 100644 src/services/selectors.js create mode 100644 src/shared/footer.css create mode 100644 src/shared/footer.hoc.js delete mode 100644 src/shared/header.hoc.js create mode 100644 src/shared/header_footer.hoc.js create mode 100644 src/shared/loader.css create mode 100644 src/shared/loader.hoc.js create mode 100644 src/shared/sidebar.css create mode 100644 src/shared/sidebar.hoc.js create mode 100644 src/utils/constants.js create mode 100644 src/utils/random.key.js create mode 100644 src/utils/utls.js diff --git a/src/actions/login.action.js b/src/actions/login.action.js new file mode 100644 index 0000000..3468e4e --- /dev/null +++ b/src/actions/login.action.js @@ -0,0 +1,16 @@ +import { LOGIN_REQUEST, LOGIN_SUCCESS } from "../utils/constants"; + + +export const loginRequest = (payload)=>{ + return { + type: LOGIN_REQUEST, + ...payload + }; +} + +export const loginSuccess = (payload)=>{ + return { + type: LOGIN_SUCCESS, + ...payload + }; +} \ No newline at end of file diff --git a/src/core/app.routes.js b/src/core/app.routes.js index 5d06e63..b581d2e 100644 --- a/src/core/app.routes.js +++ b/src/core/app.routes.js @@ -1,5 +1,6 @@ import AdminContainer from "../modules/admin/admin.container"; import SuperAdminContainer from "../modules/superadmin/superadmin.container"; +import DashBoardContainer from "../modules/dashboard/dashboard.container"; export const AppRoutes = [ { @@ -11,5 +12,10 @@ export const AppRoutes = [ path: '/superadmin', component: SuperAdminContainer, permission: ['admin', 'superadmin', 'user'] + }, + { + path: '/dashboard', + component: DashBoardContainer, + permission: ['user'] } ]; diff --git a/src/core/custom.router.js b/src/core/custom.router.js index c6b2859..9fcd4f6 100644 --- a/src/core/custom.router.js +++ b/src/core/custom.router.js @@ -1,6 +1,8 @@ import React from "react"; import { Route, Redirect } from "react-router-dom"; import Storage from "../services/storage.service"; +import Permissions from "./permission.router"; +import { RandomKey } from "../utils/random.key"; export const CustomRouter = ({ xComponent: Component, ...xProps }) => { return ( @@ -19,7 +21,7 @@ export const CustomRouter = ({ xComponent: Component, ...xProps }) => { return ; } - return ; + return ; }} /> ); diff --git a/src/core/permission.router.js b/src/core/permission.router.js index 4047b75..d698917 100644 --- a/src/core/permission.router.js +++ b/src/core/permission.router.js @@ -1,4 +1,19 @@ import React from "react"; import { Route, Redirect } from "react-router-dom"; -// export const Permi \ No newline at end of file +export const Permissions = ({Component: Component, ..._props})=>{ + + return ( + { + let returnProps = {..._props, ...props}; + // let token = Storage.get("token"); + let pathName = props.match.path; + console.log(returnProps); + return ; + }} + /> + ); +} + +export default Permissions; \ No newline at end of file diff --git a/src/core/routes.js b/src/core/routes.js index 764e793..9c2d222 100644 --- a/src/core/routes.js +++ b/src/core/routes.js @@ -1,33 +1,36 @@ import React, { Suspense } from "react"; -import { Provider } from "react-redux"; +import { Provider, connect } from "react-redux"; import { ConnectedRouter } from "connected-react-router"; -import { Switch, Redirect, Route } from "react-router-dom"; +import { Switch, Redirect, Route, withRouter } from "react-router-dom"; import { CustomRouter } from "./custom.router"; import LoginContainer from "../modules/login/login.container"; import DashBoardContainer from "../modules/dashboard/dashboard.container"; import { AppRoutes } from "./app.routes"; +import MasterComponent from "../master/master.component"; const Routes = ({ store, history }) => { return ( - - Loading ...} - > - - - - {AppRoutes.map(_routes => - )} - - - - + + + Loading ...} + > + + + + {AppRoutes.map(_routes => + )} + + + + + ); }; diff --git a/src/index.css b/src/index.css index 1532074..0d4c466 100644 --- a/src/index.css +++ b/src/index.css @@ -6,3 +6,18 @@ body { -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } + + +html, body { + margin:0; + padding:0; + height:100%; +} + +.container-fluid{ + height: 100%; +} + +.content{ + margin-left: 92px; +} \ No newline at end of file diff --git a/src/index.js b/src/index.js index a3b342f..787b0c1 100644 --- a/src/index.js +++ b/src/index.js @@ -11,6 +11,7 @@ import { Route } from "react-router-dom"; import Routes from './core/routes'; +import HttpService from './services/http.service'; require("es6-promise").polyfill(); @@ -18,6 +19,9 @@ require("es6-promise").polyfill(); const store = configureStore(); store.runSaga(rootMiddleware); +HttpService.reduxStore = store; +HttpService.httpInterceptor(); +// console.log(HttpService.httpInterceptor) const XRouter = () => { return ( diff --git a/src/master/master.component.js b/src/master/master.component.js new file mode 100644 index 0000000..703badf --- /dev/null +++ b/src/master/master.component.js @@ -0,0 +1,36 @@ +import React from 'react'; +import { createLoadingSelector, createNotificationSelector } from '../services/selectors'; +import WithLoader from '../shared/loader.hoc'; +import { connect } from "react-redux"; + +let loadingSelector = createLoadingSelector([ + 'LOGIN', + 'COMMON' +]); + +let errorSelector = createNotificationSelector([ + 'LOGIN', + 'COMMON' +]); + +const MasterComponent = (props) => { + + return ( + <> + {props.children} + + ); +} + + +const mapStateToProps = state => { + return { + isLoading: loadingSelector(state), + error: errorSelector(state) + }; +}; + +export default connect(mapStateToProps)( + WithLoader(MasterComponent) +); + diff --git a/src/middlewares/login.middleware.js b/src/middlewares/login.middleware.js new file mode 100644 index 0000000..c4dbc5b --- /dev/null +++ b/src/middlewares/login.middleware.js @@ -0,0 +1,29 @@ +import { put, call, fork, takeEvery } from "redux-saga/effects"; +import { LOGIN_REQUEST, LOGIN_SUCCESS } from "../utils/constants"; +import { loginMock } from "../modules/login/login.service"; +import { history } from '../core/store'; +function* loginWatcher() { + yield takeEvery(LOGIN_REQUEST, loginWorker); +} + +function* loginWorker(action) { + let { email, password } = action; + let res = yield call(loginApi, { email, password }); + if (res && res.data) { + let { token } = res.data; + yield put({ + type: LOGIN_SUCCESS, + payload: { + token + } + }); + history.push('/dashboard'); + } + console.log(res); +} + +function loginApi(params) { + return loginMock(params); +} + +export const LoginSaga = [fork(loginWatcher)]; \ No newline at end of file diff --git a/src/middlewares/root.middleware.js b/src/middlewares/root.middleware.js index 2e90582..065a572 100644 --- a/src/middlewares/root.middleware.js +++ b/src/middlewares/root.middleware.js @@ -1,7 +1,8 @@ import { all } from "redux-saga/effects"; +import { LoginSaga } from "./login.middleware"; export default function* rootMiddleware() { yield all([ - //...LoginSaga, + ...LoginSaga, ]); } \ No newline at end of file diff --git a/src/modules/admin/admin.container.js b/src/modules/admin/admin.container.js index bd6e1dc..91b0d1c 100644 --- a/src/modules/admin/admin.container.js +++ b/src/modules/admin/admin.container.js @@ -1,16 +1,33 @@ -import React, {Component} from 'react'; - -class AdminContainer extends Component{ - constructor(props){ +import React, { Component } from 'react'; +import { connect } from "react-redux"; +import WithHeaderFooter from '../../shared/header_footer.hoc'; +import WithSidebar from '../../shared/sidebar.hoc'; +class AdminContainer extends Component { + constructor(props) { console.log(props); super(props); } - render(){ - return( -
Admin Container
+ render() { + return ( +
+
+
+ Admin Container +
+
+
); } } -export default AdminContainer; \ No newline at end of file +const mapStateToProps = state => { + return { + + }; +}; + + +export default connect(mapStateToProps)( + WithSidebar(WithHeaderFooter(AdminContainer)) +); \ No newline at end of file diff --git a/src/modules/dashboard/dashboard.container.js b/src/modules/dashboard/dashboard.container.js index 595aa9f..f792c20 100644 --- a/src/modules/dashboard/dashboard.container.js +++ b/src/modules/dashboard/dashboard.container.js @@ -1,12 +1,28 @@ -import React, {Component} from 'react'; +import React, { Component } from 'react'; +import { connect } from "react-redux"; +import WithHeaderFooter from '../../shared/header_footer.hoc'; +import WithSidebar from '../../shared/sidebar.hoc'; +class DashBoardContainer extends Component { -class DashBoardContainer extends Component{ - - render(){ - return( -
Dashboard
+ render() { + return ( +
+
+
+ Dashboard +
+
+
); } } -export default DashBoardContainer; \ No newline at end of file +const mapStateToProps = state => { + return { + + }; +}; + +export default connect(mapStateToProps)( + WithSidebar(WithHeaderFooter(DashBoardContainer)) +); \ No newline at end of file diff --git a/src/modules/login/login.container.js b/src/modules/login/login.container.js index 705284e..2bf05b1 100644 --- a/src/modules/login/login.container.js +++ b/src/modules/login/login.container.js @@ -1,12 +1,50 @@ -import React,{Component} from 'react'; +import React, { Component } from 'react'; +import { connect } from "react-redux"; +import WithFooter from '../../shared/footer.hoc'; +import { loginMock } from './login.service'; +import { loginRequest } from '../../actions/login.action'; +import HttpService from '../../services/http.service'; +class LoginContainer extends Component { -class LoginContainer extends Component{ + state = { - render(){ - return( -
Login
+ }; + + onLogin = ()=>{ + let params = { + email: "eve.holt@reqres.in", + password: "cityslicka" + }; + + // loginMock(params).then(res=>{ + // console.log(res); + // }) + this.props.dispatch(loginRequest(params)); + // HttpService.cancelRequest(); + } + + render() { + return ( +
+
+
+ Login +
+
+ +
+
+
); } } -export default LoginContainer; \ No newline at end of file +const mapStateToProps = state => { + return { + + }; +}; + +export default connect(mapStateToProps)( + WithFooter(LoginContainer) +); \ No newline at end of file diff --git a/src/modules/login/login.service.js b/src/modules/login/login.service.js new file mode 100644 index 0000000..15fc3cc --- /dev/null +++ b/src/modules/login/login.service.js @@ -0,0 +1,9 @@ +import HttpService from '../../services/http.service'; + +export const loginMock = (params)=>{ + return HttpService.fetch({ + url: 'https://reqres.in/api/login', + method: 'post', + data: params + }); +} \ No newline at end of file diff --git a/src/modules/superadmin/superadmin.container.js b/src/modules/superadmin/superadmin.container.js index a82608d..ef83a52 100644 --- a/src/modules/superadmin/superadmin.container.js +++ b/src/modules/superadmin/superadmin.container.js @@ -1,12 +1,57 @@ -import React, {Component} from 'react'; +import React, { Component } from 'react'; +import { connect } from "react-redux"; +import WithHeaderFooter from '../../shared/header_footer.hoc'; +import WithSidebar from '../../shared/sidebar.hoc'; +import { COMMON_REQUEST, COMMON_CANCEL } from '../../utils/constants'; +import HttpService from '../../services/http.service'; +class SuperAdminContainer extends Component { -class SuperAdminContainer extends Component{ + componentDidMount() { - render(){ - return( -
SuperAdminContainer
+ } + + startRequest = () => { + this.props.dispatch({ + type: COMMON_REQUEST + }); + let params = { + url: 'https://reqres.in/api/users?page=2' + } + HttpService.fetch(params).then(res=>{ + console.log(res); + }) + } + + stopRequest = () => { + // this.props.dispatch({ + // type: COMMON_CANCEL + // }) + HttpService.cancelRequest(); + } + + render() { + return ( +
+
+
+ SuperAdminContainer +
+
+
+
+
+
+
); } } -export default SuperAdminContainer; \ No newline at end of file +const mapStateToProps = state => { + return { + + }; +}; + +export default connect(mapStateToProps)( + WithSidebar(WithHeaderFooter(SuperAdminContainer)) +); \ No newline at end of file diff --git a/src/reducers/error.reducer.js b/src/reducers/error.reducer.js new file mode 100644 index 0000000..83d1128 --- /dev/null +++ b/src/reducers/error.reducer.js @@ -0,0 +1,18 @@ +export default function ErrorReducer(state = {}, action) { + const { type, error } = action; + const matches = /(.*)_(REQUEST|FAILED|ERROR)/.exec( + type + ); + if (!matches) return state; + const [, requestName, requestState] = matches; + return { + errorMessage: + requestState === "FAILED" || requestState === "ERROR" + ? error + ? error + : "" + : "", + [requestName]: requestState === "FAILED" || requestState === "ERROR" ? true: false + }; + } + \ No newline at end of file diff --git a/src/reducers/loading.reducer.js b/src/reducers/loading.reducer.js new file mode 100644 index 0000000..5ff7651 --- /dev/null +++ b/src/reducers/loading.reducer.js @@ -0,0 +1,12 @@ +export default function LoadingReducer(state = {}, action) { + console.log("Reducer",action) + const { type } = action; + const matches = /(.*)_(REQUEST|SUCCESS|FAILED|ERROR|SUBMIT|CANCEL)/.exec(type); + if (!matches) return state; + const [, requestName, requestState] = matches; + return { + ...state, + [requestName]: (requestState === 'REQUEST' || requestState === 'SUBMIT') + }; + +} \ No newline at end of file diff --git a/src/reducers/login.reducer.js b/src/reducers/login.reducer.js new file mode 100644 index 0000000..3229e35 --- /dev/null +++ b/src/reducers/login.reducer.js @@ -0,0 +1,21 @@ +import { LOGIN_REQUEST, LOGIN_SUCCESS } from "../utils/constants"; +import Storage from "../services/storage.service"; + + +let initialState = { + token: "" +}; + +export const LoginReducer = (state=initialState, action)=>{ + switch (action.type) { + case LOGIN_REQUEST: return state; + case LOGIN_SUCCESS: + + Storage.set('token', action.payload.token); + return { + ...state, + token: action.payload.token + }; + default: return state; + } +} \ No newline at end of file diff --git a/src/reducers/root.reducer.js b/src/reducers/root.reducer.js index de1a3b8..c5796ea 100644 --- a/src/reducers/root.reducer.js +++ b/src/reducers/root.reducer.js @@ -1,9 +1,15 @@ import { combineReducers } from "redux"; import { connectRouter } from "connected-react-router"; +import LoadingReducer from "./loading.reducer"; +import ErrorReducer from "./error.reducer"; +import { LoginReducer } from "./login.reducer"; const createRootReducer = history => combineReducers({ router: connectRouter(history), + loading: LoadingReducer, + error: ErrorReducer, + login: LoginReducer }); export default createRootReducer; diff --git a/src/services/http.service.js b/src/services/http.service.js index e69de29..c3914f6 100644 --- a/src/services/http.service.js +++ b/src/services/http.service.js @@ -0,0 +1,90 @@ +import axios from 'axios'; +import Storage from './storage.service'; +import { COMMON_REQUEST, COMMON_SUCCESS, COMMON_CANCEL } from '../utils/constants'; + +class HttpServiceSingleton { + constructor() { + axios.defaults.headers.post["Content-Type"] = "application/json"; + axios.defaults.headers.put["Accept"] = "application/json"; + this.count = 0; // This will store API requests + this.complete = 0; // This will store API Success/errors + } + + set reduxStore(store) { + this.store = store; + } + + fetch(payload, noAuth) { + const cancelToken = axios.CancelToken; + this.cancelSource = cancelToken.source(); + let config = {}; + if (!noAuth) { + let token = Storage.get("token"); + config.headers = { + 'Authirization': `Bearer ${token}` + }; + } + + config.method = payload.method ? payload.method : 'get'; + config.url = payload.url ? payload.url : ''; + config.cancelToken = this.cancelSource.token; + if (payload.data) config.data = JSON.stringify(payload.data); + + return axios(config).catch((thrown) => { + if (axios.isCancel(thrown)) { + this.count = 0; + this.complete = 0; + this.store.dispatch({ + type: COMMON_CANCEL + }); + console.log('Request canceled', thrown.message); + } else { + // handle error + } + }); + } + + httpInterceptor() { + axios.interceptors.request.use((config) => { + this.count++; + this.checkApiComplete(this.store); + return config; + }, (error) => { + this.complete++; + this.checkApiComplete(this.store); + return Promise.reject(error); + }); + + axios.interceptors.response.use((response) => { + this.complete++; + this.checkApiComplete(this.store); + return response; + }, (error) => { + this.complete++; + this.checkApiComplete(this.store); + return Promise.reject(error); + }); + } + + cancelRequest() { + this.cancelSource.cancel(); + } + + //Fallback to cancel all API loaders in case of multiple API call occuts + checkApiComplete(store) { + if (this.count == this.complete) { // Cancel API loader when all requests are completed + store.dispatch({ + type: COMMON_SUCCESS + }); + } else { + store.dispatch({ + type: COMMON_REQUEST + }); + } + } +} + +const HttpService = new HttpServiceSingleton(); +// Object.freeze(HttpService); // Singleton Http Service + +export default HttpService; \ No newline at end of file diff --git a/src/services/selectors.js b/src/services/selectors.js new file mode 100644 index 0000000..f9942d4 --- /dev/null +++ b/src/services/selectors.js @@ -0,0 +1,10 @@ +import _ from "lodash"; + +export const createLoadingSelector = actions => state => { + return _(actions).some(action => _.get(state, `loading.${action}`)); +}; + +export const createNotificationSelector = actions => state => { + return _(actions) + .some(action => _.get(state, `error.${action}`)); +}; diff --git a/src/services/storage.service.js b/src/services/storage.service.js index c41d552..d29a1e5 100644 --- a/src/services/storage.service.js +++ b/src/services/storage.service.js @@ -9,7 +9,8 @@ class Storage{ if(!key||!value){ throw("Storag.set expects a 'key' and a 'value' - 'value' & 'key' can't be null"); } - localStorage.setItem(key, JSON.stringify(value)); + value = (typeof value=="string") ? value : JSON.stringify(value); + localStorage.setItem(key, value); } } diff --git a/src/shared/footer.css b/src/shared/footer.css new file mode 100644 index 0000000..048b0c6 --- /dev/null +++ b/src/shared/footer.css @@ -0,0 +1,13 @@ +.footer { + position: absolute; + bottom: 0; + width: 95%; + height: 60px; + line-height: 60px; + background-color: #f5f5f5; +} + +.footer>.container { + padding-right: 15px; + padding-left: 15px; +} \ No newline at end of file diff --git a/src/shared/footer.hoc.js b/src/shared/footer.hoc.js new file mode 100644 index 0000000..535a52d --- /dev/null +++ b/src/shared/footer.hoc.js @@ -0,0 +1,35 @@ +import React, { Component } from "react"; +import { Link } from 'react-router-dom'; +import { connect } from "react-redux"; +import { compose } from "redux"; +import './footer.css'; + +const Footer = (HocComponent) => { + return class FooterComponent extends Component { + + render() { + return ( + + +
+
Footer
+
+ +
+ ); + } + } +} + + +const mapStateToProps = state => { + return { + + }; +}; + +const WithFooter = compose( + connect(mapStateToProps, null), + Footer +) +export default WithFooter; \ No newline at end of file diff --git a/src/shared/header.hoc.js b/src/shared/header.hoc.js deleted file mode 100644 index e69de29..0000000 diff --git a/src/shared/header_footer.hoc.js b/src/shared/header_footer.hoc.js new file mode 100644 index 0000000..0c093a6 --- /dev/null +++ b/src/shared/header_footer.hoc.js @@ -0,0 +1,39 @@ +import React, { Component } from "react"; +import { Link } from 'react-router-dom'; +import { connect } from "react-redux"; +import { compose } from "redux"; + +const HeaderFooter = (HocComponent) => { + return class HeaderFooterComponent extends Component { + + render() { + return ( + + + +
+
Footer
+
+
+ ); + } + } +} + + +const mapStateToProps = state => { + return { + + }; +}; + +const WithHeaderFooter = compose( + connect(mapStateToProps, null), + HeaderFooter +) +export default WithHeaderFooter; \ No newline at end of file diff --git a/src/shared/loader.css b/src/shared/loader.css new file mode 100644 index 0000000..2ee47a2 --- /dev/null +++ b/src/shared/loader.css @@ -0,0 +1,48 @@ +.loader { + position: absolute; + z-index: 6; + top: 0px; + left: 0; + height: 4px; + width: 100%; + overflow: hidden; + background-color: #ddd; + } + + .loader:before { + display: block; + position: absolute; + content: ""; + left: -200px; + width: 200px; + height: 4px; + background-color: #ff8373; + animation: loading 2s linear infinite; + } + + @keyframes loading { + from { + left: -200px; + width: 30%; + } + + 50% { + width: 30%; + } + + 70% { + width: 70%; + } + + 80% { + left: 50%; + } + + 95% { + left: 120%; + } + + to { + left: 100%; + } + } \ No newline at end of file diff --git a/src/shared/loader.hoc.js b/src/shared/loader.hoc.js new file mode 100644 index 0000000..c60089e --- /dev/null +++ b/src/shared/loader.hoc.js @@ -0,0 +1,16 @@ +import React from 'react'; +import "./loader.css"; +const WithLoader = HocComponent => { + return function ({ ...props }) { + return ( +
+ {props.isLoading && ( +
+ )} + +
+ ); + }; +}; + +export default WithLoader; \ No newline at end of file diff --git a/src/shared/sidebar.css b/src/shared/sidebar.css new file mode 100644 index 0000000..cfb3e02 --- /dev/null +++ b/src/shared/sidebar.css @@ -0,0 +1,6 @@ +.sidebar{ + background: #cccc; + width: 92px; + height: calc(100vh); + position: absolute; +} \ No newline at end of file diff --git a/src/shared/sidebar.hoc.js b/src/shared/sidebar.hoc.js new file mode 100644 index 0000000..30a18a3 --- /dev/null +++ b/src/shared/sidebar.hoc.js @@ -0,0 +1,36 @@ +import React, { Component } from "react"; +import { Link } from 'react-router-dom'; +import { connect } from "react-redux"; +import { compose } from "redux"; +import './sidebar.css'; + +const Sidebar = (HocComponent) => { + return class SidebarComponent extends Component { + + render() { + return ( + +
+ Sidebar +
+
+ +
+
+ ); + } + } +} + + +const mapStateToProps = state => { + return { + + }; +}; + +const WithSidebar = compose( + connect(mapStateToProps, null), + Sidebar +) +export default WithSidebar; \ No newline at end of file diff --git a/src/utils/constants.js b/src/utils/constants.js new file mode 100644 index 0000000..a7ae6de --- /dev/null +++ b/src/utils/constants.js @@ -0,0 +1,5 @@ +export const LOGIN_REQUEST = "LOGIN_REQUEST"; +export const LOGIN_SUCCESS = "LOGIN_SUCCESS"; +export const COMMON_REQUEST = "COMMON_REQUEST"; +export const COMMON_SUCCESS = "COMMON_SUCCESS"; +export const COMMON_CANCEL = "COMMON_CANCEL"; \ No newline at end of file diff --git a/src/utils/random.key.js b/src/utils/random.key.js new file mode 100644 index 0000000..50e5293 --- /dev/null +++ b/src/utils/random.key.js @@ -0,0 +1,3 @@ +export const RandomKey = { + generate : ()=> parseInt(Math.random()*Math.pow(10,12),10) +}; \ No newline at end of file diff --git a/src/utils/utls.js b/src/utils/utls.js new file mode 100644 index 0000000..e69de29 -- cgit v1.2.3