Created
July 14, 2018 08:37
-
-
Save redmandarin/55803153eeec9a5fb4834e227f58fe1f to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { configureChannel } from './channel'; | |
export const ADD_ACTIONS = 'ADD_ACTIONS'; | |
export const ADD_OFFERS = 'ADD_OFFERS'; | |
export const ADD_DATA = 'ADD_DATA'; | |
export const FILTER_OFFERS_BY_TYPE = 'FILTER_OFFERS_BY_TYPE'; | |
export const UPDATE_OFFERS = 'UPDATE_OFFERS'; | |
export const SHOW_ACTIVE_OFFERS_ACTION = 'SHOW_ACTIVE_OFFERS_ACTION'; | |
export const CHANGE_ONLY_ACTIVE_OFFERS_STATE = | |
'CHANGE_ONLY_ACTIVE_OFFERS_STATE'; | |
export const CHANGE_FILTER_OFFER_TYPE = 'CHANGE_FILTER_OFFER_TYPE'; | |
export const HANDLE_PAGINATION_CLICK = 'HANDLE_PAGINATION_CLICK'; | |
export const CHANGE_PAGE_STATE = 'CHANGE_PAGE_STATE'; | |
export const UPDATE_PAGES_COUNT = 'UPDATE_PAGES_COUNT'; | |
export const BEGIN_LOADING = 'BEGIN_LOADING'; | |
export const END_LOADING = 'END_LOADING'; | |
let socket = configureChannel(); | |
let channel = socket.channel('terminal', { token: window.userToken }); | |
export function addActions(actions) { | |
return { type: ADD_ACTIONS, actions }; | |
} | |
export function addOffers(offers) { | |
return { type: ADD_OFFERS, offers }; | |
} | |
export function addData(graphData, statisticData) { | |
return { type: ADD_DATA, graphData, statisticData }; | |
} | |
const changeFilterOfferType = type => { | |
return { type: CHANGE_FILTER_OFFER_TYPE, offerType: type }; | |
}; | |
export const handlePaginationClick = (page, event) => { | |
return (dispatch, getState) => { | |
const { offerType, onlyActiveOffers } = getState(); | |
Promise.all([ | |
dispatch({ type: CHANGE_PAGE_STATE, page: page }), | |
dispatch(getOffersAction(offerType, onlyActiveOffers, page)) | |
]); | |
}; | |
}; | |
export const filterOffersByType = offerType => { | |
return (dispatch, getState) => { | |
const { onlyActiveOffers } = getState(); | |
Promise.all([ | |
dispatch({ type: BEGIN_LOADING }), | |
dispatch(changeFilterOfferType(offerType)), | |
dispatch(getOffersAction(offerType, onlyActiveOffers)) | |
]); | |
}; | |
}; | |
const changeonlyActiveOffersState = () => { | |
return { type: CHANGE_ONLY_ACTIVE_OFFERS_STATE }; | |
}; | |
export const onlyActiveOffersAction = () => { | |
return (dispatch, getState) => { | |
const { onlyActiveOffers, offerType } = getState(); | |
Promise.all([ | |
dispatch(changeonlyActiveOffersState()), | |
dispatch(getOffersAction(offerType, !onlyActiveOffers)) | |
]); | |
}; | |
}; | |
const getOffersAction = (offerType, onlyActiveOffers, page = 1) => { | |
let headers = new Headers({ | |
'Content-Type': 'application/json' | |
}); | |
return (dispatch, getState) => { | |
const { itemsOnPage } = getState(); | |
const offset = (page - 1) * itemsOnPage; | |
const url = `/api/v1/terminal/offers?offer_type=${offerType}&only_active_offers=${onlyActiveOffers}&offset=${offset}`; | |
return fetch(url, { | |
method: 'GET', | |
headers: headers, | |
credentials: 'same-origin' | |
}) | |
.then(res => res.json()) | |
.then(res => { | |
Promise.all([ | |
dispatch({ | |
type: UPDATE_OFFERS, | |
offers: res.offers | |
}), | |
dispatch(updatePagesCount(res.total_count, page)), | |
dispatch({ type: END_LOADING }) | |
]); | |
}); | |
}; | |
}; | |
const updatePagesCount = (totalCount, page) => { | |
return (dispatch, getState) => { | |
const { itemsOnPage } = getState(); | |
let pagesCount = Math.ceil(totalCount / itemsOnPage); | |
dispatch({ | |
type: UPDATE_PAGES_COUNT, | |
totalCount: totalCount, | |
pagesCount: pagesCount, | |
page: page | |
}); | |
}; | |
}; | |
export function fetchData() { | |
return dispatch => { | |
channel | |
.join() | |
.receive('ok', response => { | |
dispatch(addActions(response.actions)); | |
dispatch(addOffers(response.offers.companies)); | |
dispatch( | |
addData(response.offers.graph_data, response.offers.statistic) | |
); | |
}) | |
.receive('error', reason => { | |
console.log('failed join', reason); | |
}); | |
channel.on('new:action', msg => { | |
dispatch(addActions([msg])); | |
}); | |
}; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { combineReducers } from 'redux'; | |
import { | |
ADD_OFFERS, | |
ADD_ACTIONS, | |
ADD_DATA, | |
UPDATE_OFFERS, | |
CHANGE_FILTER_OFFER_TYPE, | |
CHANGE_ONLY_ACTIVE_OFFERS_STATE, | |
SAVE_FILTER_TO_LOCAL_STORAGE, | |
CHANGE_PAGE_STATE, | |
UPDATE_PAGES_COUNT, | |
BEGIN_LOADING, | |
END_LOADING | |
} from './actions'; | |
function actions(state = [], action) { | |
switch (action.type) { | |
// case ADD_ACTIONS: | |
// return { ...state, actions: [...state.actions, ...action.actions] }; | |
case ADD_OFFERS: | |
return { ...state, offers: [...state.offers, ...action.offers] }; | |
case ADD_DATA: | |
return { | |
...state, | |
graphData: action.graphData, | |
statistic: action.statisticData | |
}; | |
case UPDATE_OFFERS: | |
return { ...state, offers: action.offers }; | |
case CHANGE_ONLY_ACTIVE_OFFERS_STATE: | |
return { ...state, onlyActiveOffers: !state.onlyActiveOffers }; | |
case CHANGE_FILTER_OFFER_TYPE: | |
return { ...state, offerType: action.offerType }; | |
case CHANGE_PAGE_STATE: | |
return { ...state, page: action.page }; | |
case BEGIN_LOADING: | |
return { ...state, loading: true }; | |
case END_LOADING: | |
return { ...state, loading: false }; | |
case UPDATE_PAGES_COUNT: | |
return { | |
...state, | |
totalCount: action.totalCount, | |
pagesCount: action.pagesCount, | |
page: action.page | |
}; | |
default: | |
return state; | |
} | |
} | |
export default actions; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { createStore, applyMiddleware } from 'redux'; | |
import reducers from './reducers'; | |
import thunkMiddleware from 'redux-thunk'; | |
import { composeWithDevTools } from 'redux-devtools-extension'; | |
const initialState = offers => { | |
const settings = offers.terminal_settings; | |
const itemsOnPage = 9; | |
console.log(offers); | |
return { | |
actions: [], | |
offers: offers.companies, | |
statistic: offers.statistic, | |
graphData: offers.graph_data, | |
onlyActiveOffers: settings.only_active_offers, | |
offerType: settings.offer_type, | |
totalCount: offers.total_count, | |
pagesCount: Math.ceil(offers.total_count / itemsOnPage), | |
itemsOnPage: itemsOnPage, | |
loading: false, | |
page: 1 | |
}; | |
}; | |
export const store = offers => { | |
const store = createStore( | |
reducers, | |
initialState(offers), | |
composeWithDevTools(applyMiddleware(thunkMiddleware)) | |
); | |
return store; | |
}; | |
export default store; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, { Component, PropTypes } from 'react'; | |
import { connect } from 'react-redux'; | |
import { fetchData } from './actions'; | |
import ActionList from './components/ActionList'; | |
import OfferList from './components/OfferList'; | |
import Pagination from './components/Pagination'; | |
import Graph from './components/Graph'; | |
import { store } from './store'; | |
import * as actionCreators from './actions'; | |
import { bindActionCreators } from 'redux'; | |
class Terminal extends React.Component { | |
render() { | |
return ( | |
<div className="terminal__inner"> | |
<div className="terminal__content"> | |
<Graph data={this.props.graphData} statistic={this.props.statistic} /> | |
<OfferList | |
offers={this.props.offers} | |
filterOffersByType={this.props.filterOffersByType} | |
loading={this.props.loading} | |
offerType={this.props.offerType} | |
onlyActiveOffersAction={this.props.onlyActiveOffersAction} | |
onlyActiveOffers={this.props.onlyActiveOffers} | |
/> | |
<Pagination | |
pagesCount={this.props.pagesCount} | |
handleClick={this.props.handlePaginationClick} | |
currentPage={this.props.page} | |
/> | |
</div> | |
<div className="terminal__sidebar"> | |
<ActionList actions={this.props.actions} /> | |
</div> | |
</div> | |
); | |
} | |
} | |
const mapStateToProps = store => { | |
return { | |
actions: store.actions, | |
offers: store.offers, | |
graphData: store.graphData, | |
statistic: store.statistic, | |
onlyActiveOffers: store.onlyActiveOffers, | |
offerType: store.offerType, | |
pagesCount: store.pagesCount, | |
page: store.page, | |
total_count: store.totalCount, | |
loading: store.loading | |
}; | |
}; | |
const mapDispatchToProps = dispatch => { | |
return bindActionCreators( | |
{ | |
...actionCreators | |
}, | |
dispatch | |
); | |
}; | |
export default connect(mapStateToProps, mapDispatchToProps)(Terminal); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment