diff --git a/client/src/constants/enums.js b/client/src/constants/enums.js
new file mode 100644
index 0000000..a6da2d0
--- /dev/null
+++ b/client/src/constants/enums.js
@@ -0,0 +1,17 @@
+
+export const UNLOCKED_INCIDENT = 2;
+export const UNSCHEDULED_INCIDENT = 3;
+
+export const incidentDescriptions = {};
+incidentDescriptions[UNLOCKED_INCIDENT] = 'User left door unlocked';
+incidentDescriptions[UNSCHEDULED_INCIDENT] = 'Unscheduled use';
+
+export const incidentLevelDescriptions = {
+ UNLOCKED_0: 'First month',
+ UNLOCKED_1: 'Second month',
+ UNLOCKED_2: 'Third month',
+ UNLOCKED_3: 'Fourth month',
+ UNLOCKED_4: 'Fifth month',
+ UNLOCKED_5: 'Sixth month',
+
+};
diff --git a/client/src/constants/menuItems.js b/client/src/constants/menuItems.js
index cd4f3d2..8a910e3 100644
--- a/client/src/constants/menuItems.js
+++ b/client/src/constants/menuItems.js
@@ -1,5 +1,6 @@
-import UploadDLockData from "../scenes/UploadDLockData";
-import Home from "../scenes/Home";
+import UploadDLockData from '../scenes/UploadDLockData';
+import Home from '../scenes/Home';
+import IncidentsReport from '../scenes/IncidentsReport';
export const mainMenuItems = [
{
@@ -8,6 +9,12 @@ export const mainMenuItems = [
url: '/',
component: Home,
},
+ {
+ id: 'report',
+ title: 'Incidents Report',
+ url: '/incidents-report',
+ component: IncidentsReport,
+ },
{
id: 'uploadDLockData',
title: 'DLock',
@@ -15,3 +22,14 @@ export const mainMenuItems = [
component: UploadDLockData,
},
];
+
+export const incidentsReportHeaderTitles = {
+ officeName: 'Office',
+ resourceName: 'Room',
+ bookingStart: 'Reservation Start',
+ bookingEnd: 'Reservation End',
+ memberName: 'Member Name',
+ incidentType: 'Incident Type',
+ feeDescription: 'Fee description',
+ totalChargeFee: 'Total Fee',
+};
diff --git a/client/src/scenes/IncidentsReport/index.js b/client/src/scenes/IncidentsReport/index.js
new file mode 100644
index 0000000..defc361
--- /dev/null
+++ b/client/src/scenes/IncidentsReport/index.js
@@ -0,0 +1,100 @@
+import React, { Component } from 'react';
+import { connect } from 'react-redux';
+import { Container, Loader } from 'semantic-ui-react';
+import ReactTable from 'react-table';
+import 'react-table/react-table.css';
+
+import MainMenu from '../../components/MainMenu';
+import { fetchIncidents } from '../../store/actions';
+import { incidentsReportHeaderTitles } from '../../constants/menuItems';
+import { incidentDescriptions, incidentLevelDescriptions, UNSCHEDULED_INCIDENT, UNLOCKED_INCIDENT } from '../../constants/enums';
+
+class IncidentsReport extends Component {
+
+ componentDidMount() {
+ const { fetchIncidents } = this.props;
+ fetchIncidents();
+ }
+
+ render () {
+ const { pendingIncidents, incidents } = this.props;
+
+ const columns = [];
+ if (incidents && incidents.length > 0){
+ const incidentHeaders = Object.keys(incidentsReportHeaderTitles);
+
+ incidentHeaders.forEach((header) => {
+ const columnTitle = incidentsReportHeaderTitles[header];
+
+ if (columnTitle){
+ columns.push({
+ Header: incidentsReportHeaderTitles[header],
+ accessor: header,
+ Cell: props => {
+ let cellValue;
+
+ switch (props.column.id) {
+ case 'incidentType':
+ cellValue = incidentDescriptions[props.value];
+ break;
+ case 'incidentLevel':
+ cellValue = incidentLevelDescriptions[props.value];
+ break;
+
+ case 'feeDescription':
+ const { incidentType, incidentLevel, timeIntervalsToCharge } = props.row['_original'];
+ switch (incidentType) {
+ case UNLOCKED_INCIDENT:
+ cellValue = `${incidentLevelDescriptions[incidentLevel]}`;
+ break;
+ case UNSCHEDULED_INCIDENT:
+ cellValue = `${timeIntervalsToCharge} x 5 min`;
+ break;
+ }
+ break;
+
+ case 'totalChargeFee':
+ const totalFee = props.value ? props.value : props.row['_original'].incidentPrice;
+ cellValue = `$ ${totalFee}`;
+ break;
+
+ default:
+ cellValue = props.value;
+ }
+
+ return {cellValue}
+ }
+ });
+ }
+ });
+ }
+
+ return (
+
+
+ Incidents Report
+
+
+ {
+ !pendingIncidents && incidents &&
+
+ }
+
+ );
+ }
+}
+
+const mapStateToProps = (state) => ({
+ pendingIncidents: state.incidentsReport.pending,
+ incidents: state.incidentsReport.result,
+});
+
+const mapDispatchToProps = (dispatch) => ({
+ fetchIncidents: () => fetchIncidents(dispatch),
+});
+
+export default connect(mapStateToProps, mapDispatchToProps)(IncidentsReport);
diff --git a/client/src/store/actions/integrationActions.js b/client/src/store/actions/integrationActions.js
index b61b58b..599573f 100644
--- a/client/src/store/actions/integrationActions.js
+++ b/client/src/store/actions/integrationActions.js
@@ -5,7 +5,10 @@ import {
ADD_NEW_MAPPING_PENDING,
ADD_NEW_MAPPING_SUCCESS,
ADD_NEW_MAPPING_FAILED,
-} from "../constants";
+ FETCH_INCIDENTS_PENDING,
+ FETCH_INCIDENTS_SUCCESS,
+ FETCH_INCIDENTS_FAILED,
+} from '../constants';
import API from '../../utilities/api';
@@ -32,3 +35,14 @@ export const addNewMapping = (dispatch, mapping) => {
dispatch({type: ADD_NEW_MAPPING_FAILED, payload: error.response});
});
};
+
+export const fetchIncidents = (dispatch) => {
+ dispatch({type: FETCH_INCIDENTS_PENDING});
+ API.get('integration/report/allIncidents')
+ .then(response => {
+ dispatch({type: FETCH_INCIDENTS_SUCCESS, payload: response.data});
+ })
+ .catch(error => {
+ dispatch({type: FETCH_INCIDENTS_FAILED, payload: error.response});
+ });
+};
diff --git a/client/src/store/constants.js b/client/src/store/constants.js
index aecc675..9b20bbc 100644
--- a/client/src/store/constants.js
+++ b/client/src/store/constants.js
@@ -9,3 +9,7 @@ export const FETCH_MAPPINGS_FAILED = 'FETCH_MAPPINGS_FAILED';
export const ADD_NEW_MAPPING_PENDING = 'ADD_NEW_MAPPING_PENDING';
export const ADD_NEW_MAPPING_SUCCESS = 'ADD_NEW_MAPPING_SUCCESS';
export const ADD_NEW_MAPPING_FAILED = 'ADD_NEW_MAPPING_FAILED';
+
+export const FETCH_INCIDENTS_PENDING = 'FETCH_INCIDENTS_PENDING';
+export const FETCH_INCIDENTS_SUCCESS = 'FETCH_INCIDENTS_SUCCESS';
+export const FETCH_INCIDENTS_FAILED = 'FETCH_INCIDENTS_FAILED';
diff --git a/client/src/store/reducers/incidentsReportReducer.js b/client/src/store/reducers/incidentsReportReducer.js
new file mode 100644
index 0000000..85ca58d
--- /dev/null
+++ b/client/src/store/reducers/incidentsReportReducer.js
@@ -0,0 +1,38 @@
+import {
+ FETCH_INCIDENTS_PENDING,
+ FETCH_INCIDENTS_SUCCESS,
+ FETCH_INCIDENTS_FAILED,
+} from '../constants';
+
+const initialState = {
+ pending: false,
+ result: null,
+ error: null,
+};
+
+export const incidentsReport = (state, action) => {
+ state = state || initialState;
+ action = action || {};
+
+ switch(action.type){
+ case FETCH_INCIDENTS_PENDING:
+ return Object.assign({}, state, {
+ pending: true,
+ error: null,
+ });
+ case FETCH_INCIDENTS_SUCCESS:
+ return Object.assign({}, state, {
+ pending: false,
+ result: action.payload,
+ error: null,
+ });
+ case FETCH_INCIDENTS_FAILED:
+ return Object.assign({}, state, {
+ pending: false,
+ result: {},
+ error: action.payload,
+ });
+ default:
+ return state;
+ }
+};
diff --git a/client/src/store/reducers/index.js b/client/src/store/reducers/index.js
index ed2a547..3c060be 100644
--- a/client/src/store/reducers/index.js
+++ b/client/src/store/reducers/index.js
@@ -1,12 +1,14 @@
-import { combineReducers } from "redux";
+import { combineReducers } from 'redux';
-import { doorLockData} from "./doorLockReducers";
-import { mappingsData } from "./mappingsReducer";
+import { doorLockData} from './doorLockReducers';
+import { mappingsData } from './mappingsReducer';
import { addMapping } from './addMappingReducer';
+import { incidentsReport } from './incidentsReportReducer';
export const rootReducer = combineReducers({
doorLockData,
mappingsData,
addMapping,
+ incidentsReport,
});