- { map(data.days, (day, key) => (
+ { !isEmpty(data) && map(data.days, (day, key) => (
{ map(day.blocks, (block, blockKey) => {
if (block.section) {
diff --git a/src/modules/reservation/components/Reservation/index.jsx b/src/modules/reservation/components/Reservation/index.jsx
index 29c8462..b6e145d 100644
--- a/src/modules/reservation/components/Reservation/index.jsx
+++ b/src/modules/reservation/components/Reservation/index.jsx
@@ -1,5 +1,6 @@
import React, { Component, PropTypes } from 'react';
import map from 'lodash/map';
+import isEmpty from 'lodash/isEmpty';
import Tabs from '../../../main/components/Tabs';
import Rooms from '../Rooms';
@@ -15,13 +16,16 @@ class Reservation extends Component {
render() {
const { infrastructure, blocks, days, data } = this.props;
const { selected } = this.state;
+ const rooms = !isEmpty(infrastructure) ? infrastructure[selected].rooms : {};
return (
({ key, name: item.name, icon: item.icon }))}
+ list={infrastructure ? map(infrastructure, (item, key) => ({ key, name: item.name, icon: item.icon })) : []}
selected={selected}
>
-
-
+
+
+
+
);
}
diff --git a/src/modules/reservation/container.jsx b/src/modules/reservation/container.jsx
index 636bd50..ba2bd4b 100644
--- a/src/modules/reservation/container.jsx
+++ b/src/modules/reservation/container.jsx
@@ -1,16 +1,45 @@
+import React, { Component, PropTypes } from 'react';
+import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
+import isEmpty from 'lodash/isEmpty';
import Reservation from './components/Reservation';
+import reservationActions from './api';
+
+class Container extends Component {
+ componentWillMount() {
+ this.props.base();
+ }
+ componentWillReceiveProps(nextProps) {
+ if (!isEmpty(nextProps.infrastructure)) {
+ this.props.getCalendarByRoom(nextProps.selected.room);
+ }
+ }
+ render() {
+ return
;
+ }
+}
+
+Container.propTypes = {
+ base: PropTypes.func.isRequired,
+ getCalendarByRoom: PropTypes.func.isRequired,
+};
+
const mapStateToProps = (state) => {
const { reservation } = state;
return {
- infrastructure: reservation.base.infrastructure,
- blocks: reservation.blocks,
- days: reservation.days,
+ infrastructure: reservation.base.response ? reservation.base.response.infrastructures : {},
+ blocks: reservation.base.response ? reservation.base.response.blocks : {},
+ days: reservation.base.response ? reservation.base.response.days : {},
data: reservation.data,
- timetables: reservation.timetables,
+ selected: reservation.selected,
};
};
-export default connect(mapStateToProps)(Reservation);
+const mapDispatchToProps = dispatch => bindActionCreators({
+ base: reservationActions.base,
+ getCalendarByRoom: reservationActions.getCalendarByRoom,
+}, dispatch);
+
+export default connect(mapStateToProps, mapDispatchToProps)(Container);
diff --git a/src/modules/reservation/reducer.jsx b/src/modules/reservation/reducer.jsx
index 96415e6..77757fa 100644
--- a/src/modules/reservation/reducer.jsx
+++ b/src/modules/reservation/reducer.jsx
@@ -1,29 +1,34 @@
import { combineReducers } from 'redux';
-const initialState = {
- 1: {
- name: 'Laboratorios',
- icon: '',
- rooms: {
- 1: {
- name: 'C01',
- characteristics: [
- {
- name: 'Infraestructura',
- icon: '',
- characteristics: [
- {
- name: 'Aire Acondicionado',
- icon: '',
- value: 'Si',
- },
- ],
- },
- ],
- },
- },
- },
-};
+import { init } from './api';
+
+import { RESERVATION_SET_INITIAL_IDS } from './actionTypes';
+
+// const initialState = {
+// 1: {
+// name: 'Laboratorios',
+// icon: '',
+// rooms: {
+// 1: {
+// name: 'C01',
+// characteristics: [
+// {
+// name: 'Infraestructura',
+// icon: '',
+// characteristics: [
+// {
+// name: 'Aire Acondicionado',
+// icon: '',
+// value: 'Si',
+// },
+// ],
+// },
+// ],
+// },
+// },
+// },
+// };
+
// const rooms = (state = {}, action = {}) => {
// switch (action.type) {
@@ -33,46 +38,21 @@ const initialState = {
// }
// };
-const infrastructure = (state = initialState, action = {}) => {
+const selected = (state = {}, action = {}) => {
switch (action.type) {
+ case RESERVATION_SET_INITIAL_IDS:
+ return Object.assign({}, state, {
+ infrastructure: action.payload[0],
+ room: action.payload[1],
+ });
default:
return state;
}
};
-const base = combineReducers({
- infrastructure,
-});
-
export default combineReducers({
- blocks: () => ({
- 1: '7:00',
- 2: '8:00',
- 3: '9:00',
- 4: '10:00',
- 5: '11:00',
- 6: '12:00',
- 7: '13:00',
- 8: '14:00',
- 9: '15:00',
- 10: '16:00',
- 11: '17:00',
- 12: '18:00',
- 13: '19:00',
- 14: '20:00',
- 15: '21:00',
- 16: '22:00',
- }),
- days: () => ({
- 0: 'Lunes',
- 1: 'Martes',
- 2: 'Miércoles',
- 3: 'Jueves',
- 4: 'Vernes',
- 5: 'Sábado',
- 6: 'Domingo',
- }),
- base,
+ base: init.actions.base.reducer,
+ selected,
data: () => ({
days: {
0: {
@@ -145,3 +125,105 @@ export default combineReducers({
],
}),
});
+
+// export default combineReducers({
+// blocks: () => ({
+// 1: '7:00',
+// 2: '8:00',
+// 3: '9:00',
+// 4: '10:00',
+// 5: '11:00',
+// 6: '12:00',
+// 7: '13:00',
+// 8: '14:00',
+// 9: '15:00',
+// 10: '16:00',
+// 11: '17:00',
+// 12: '18:00',
+// 13: '19:00',
+// 14: '20:00',
+// 15: '21:00',
+// 16: '22:00',
+// }),
+// days: () => ({
+// 0: 'Lunes',
+// 1: 'Martes',
+// 2: 'Miércoles',
+// 3: 'Jueves',
+// 4: 'Vernes',
+// 5: 'Sábado',
+// 6: 'Domingo',
+// }),
+// base,
+// data: () => ({
+// days: {
+// 0: {
+// blocks: {
+// 1: {
+// section: {
+// code: 'm1',
+// subject: 'Multimedia',
+// subject_code: '123',
+// color: '#e2c376',
+// },
+// },
+// 2: {
+// section: {
+// code: 'm1',
+// subject: 'Multimedia',
+// subject_code: '123',
+// color: '#e2c376',
+// },
+// },
+// },
+// },
+// 1: {
+// blocks: {},
+// },
+// 2: {
+// blocks: {},
+// },
+// 3: {
+// blocks: {
+// 1: {},
+// 2: {},
+// 3: {},
+// 4: {
+// section: {
+// code: 'm1',
+// subject: 'Computación I',
+// subject_code: '123',
+// color: '#e2c376',
+// },
+// },
+// },
+// },
+// 4: {
+// blocks: {},
+// },
+// 5: {
+// blocks: {},
+// },
+// 6: {
+// blocks: {},
+// },
+// },
+// }),
+// timetables: () => ({
+// rows: [
+// {
+// section: {
+// code: 'm1',
+// subject: 'Multimedia',
+// subject_code: '123',
+// color: '#e2c376',
+// },
+// day: 0,
+// blocks: [
+// 1,
+// 2,
+// ],
+// },
+// ],
+// }),
+// });
diff --git a/src/modules/utils/APIModule.js b/src/modules/utils/APIModule.js
new file mode 100644
index 0000000..86137e1
--- /dev/null
+++ b/src/modules/utils/APIModule.js
@@ -0,0 +1,106 @@
+import { API } from '../../env';
+
+const headers = new Headers();
+headers.append('Content-Type', 'application/json');
+
+export class ActionType {
+ constructor(moduleName, name) {
+ this.keys = {};
+ ['REQUEST', 'SUCCESS', 'FAILURE'].forEach((result) => {
+ const value = `${moduleName}/${name.toUpperCase()}@${result.toUpperCase()}`;
+ this.keys[result] = `${moduleName}_${name}_${result}`.toUpperCase();
+ this[this.keys[result]] = value;
+ });
+ }
+ getConstant(result) {
+ return this[this.keys[result]];
+ }
+}
+
+export class Action {
+ constructor(self, moduleName, initialState) {
+ this.initialState = Object.assign({
+ requested: false,
+ }, initialState);
+ this.method = this._method(self);
+ this.url = this._url(self);
+ this.actionsType = new ActionType(moduleName, self.name);
+ this.reducer = this._reducer.bind(this);
+ this.request = this._request.bind(this);
+ this.afterSuccess = self.afterSuccess;
+ this.errorHandling = self.errorHandling;
+ }
+ _method(self) {
+ if (self.method) {
+ return self.method;
+ } else if (self.body) {
+ return 'POST';
+ }
+ return 'GET';
+ }
+ _url(self) {
+ if (self.url) {
+ return `${API}/${self.url}`;
+ }
+ return `${API}/`;
+ }
+ _reducer(state = this.initialState, action = {}) {
+ switch (action.type) {
+ case this.actionsType.getConstant('REQUEST'):
+ return Object.assign({}, state, {
+ requested: true,
+ });
+ case this.actionsType.getConstant('SUCCESS'):
+ return Object.assign({}, state, {
+ completed: true,
+ requested: false,
+ response: action.args,
+ });
+ case this.actionsType.getConstant('FAILURE'):
+ return Object.assign({}, state, {
+ requested: false,
+ error: action.args,
+ });
+ default:
+ return state;
+ }
+ }
+ _request(body = null) {
+ return (dispatch) => {
+ const data = {
+ method: this.method,
+ body,
+ };
+ fetch(this.url, data)
+ .then(json => this._check(json))
+ .then((json) => { dispatch(this.getState('REQUEST')); return json; })
+ .then((json) => { dispatch(this.getState('SUCCESS', json)); this.afterSuccess(dispatch, json); return json; })
+ .catch(error => dispatch(this.getState('FAILURE', error)));
+ };
+ }
+ _check(response) { // warning here
+ let res = response && response.statusText !== 'No Content' ? response.json() : {};
+ if (!response.ok) {
+ res = res.then((err) => {
+ throw new Error(err.message);
+ });
+ }
+ return res;
+ }
+ getState(result, args = {}) {
+ return {
+ type: this.actionsType.getConstant(result),
+ args,
+ };
+ }
+}
+
+export class Module {
+ constructor(name, actions, initialState = {}) {
+ this.name = name;
+ this.actions = {};
+ actions.forEach((action) => {
+ this.actions[action.name] = new Action(action, name, initialState);
+ });
+ }
+}
diff --git a/src/modules/utils/store.jsx b/src/modules/utils/store.jsx
index 3271394..4bbddec 100644
--- a/src/modules/utils/store.jsx
+++ b/src/modules/utils/store.jsx
@@ -1,16 +1,18 @@
-import { createStore } from 'redux';
-
+import { createStore, applyMiddleware } from 'redux';
+import thunk from 'redux-thunk';
// import Middleware, {
// LOGGER_MIDDLEWARE,
// THUNK_MIDDLEWARE
// } from './middlewares/factory';
-// const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
+const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
export default (initialState, reducers) => (
createStore(
reducers,
initialState,
- window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__(),
+ composeEnhancers(
+ applyMiddleware(thunk)
+ ),
)
);