fetch and display door lock incidents on frontend
This commit is contained in:
17
client/src/constants/enums.js
Normal file
17
client/src/constants/enums.js
Normal file
@@ -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',
|
||||||
|
|
||||||
|
};
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
import UploadDLockData from "../scenes/UploadDLockData";
|
import UploadDLockData from '../scenes/UploadDLockData';
|
||||||
import Home from "../scenes/Home";
|
import Home from '../scenes/Home';
|
||||||
|
import IncidentsReport from '../scenes/IncidentsReport';
|
||||||
|
|
||||||
export const mainMenuItems = [
|
export const mainMenuItems = [
|
||||||
{
|
{
|
||||||
@@ -8,6 +9,12 @@ export const mainMenuItems = [
|
|||||||
url: '/',
|
url: '/',
|
||||||
component: Home,
|
component: Home,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
id: 'report',
|
||||||
|
title: 'Incidents Report',
|
||||||
|
url: '/incidents-report',
|
||||||
|
component: IncidentsReport,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
id: 'uploadDLockData',
|
id: 'uploadDLockData',
|
||||||
title: 'DLock',
|
title: 'DLock',
|
||||||
@@ -15,3 +22,14 @@ export const mainMenuItems = [
|
|||||||
component: UploadDLockData,
|
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',
|
||||||
|
};
|
||||||
|
|||||||
100
client/src/scenes/IncidentsReport/index.js
Normal file
100
client/src/scenes/IncidentsReport/index.js
Normal file
@@ -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 <span>{cellValue}</span>
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Container>
|
||||||
|
<MainMenu/>
|
||||||
|
<h3>Incidents Report</h3>
|
||||||
|
<hr/>
|
||||||
|
<Loader active={pendingIncidents} />
|
||||||
|
{
|
||||||
|
!pendingIncidents && incidents &&
|
||||||
|
<ReactTable
|
||||||
|
data={incidents}
|
||||||
|
multiSort={false}
|
||||||
|
columns={columns}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
</Container>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const mapStateToProps = (state) => ({
|
||||||
|
pendingIncidents: state.incidentsReport.pending,
|
||||||
|
incidents: state.incidentsReport.result,
|
||||||
|
});
|
||||||
|
|
||||||
|
const mapDispatchToProps = (dispatch) => ({
|
||||||
|
fetchIncidents: () => fetchIncidents(dispatch),
|
||||||
|
});
|
||||||
|
|
||||||
|
export default connect(mapStateToProps, mapDispatchToProps)(IncidentsReport);
|
||||||
@@ -5,7 +5,10 @@ import {
|
|||||||
ADD_NEW_MAPPING_PENDING,
|
ADD_NEW_MAPPING_PENDING,
|
||||||
ADD_NEW_MAPPING_SUCCESS,
|
ADD_NEW_MAPPING_SUCCESS,
|
||||||
ADD_NEW_MAPPING_FAILED,
|
ADD_NEW_MAPPING_FAILED,
|
||||||
} from "../constants";
|
FETCH_INCIDENTS_PENDING,
|
||||||
|
FETCH_INCIDENTS_SUCCESS,
|
||||||
|
FETCH_INCIDENTS_FAILED,
|
||||||
|
} from '../constants';
|
||||||
|
|
||||||
import API from '../../utilities/api';
|
import API from '../../utilities/api';
|
||||||
|
|
||||||
@@ -32,3 +35,14 @@ export const addNewMapping = (dispatch, mapping) => {
|
|||||||
dispatch({type: ADD_NEW_MAPPING_FAILED, payload: error.response});
|
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});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|||||||
@@ -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_PENDING = 'ADD_NEW_MAPPING_PENDING';
|
||||||
export const ADD_NEW_MAPPING_SUCCESS = 'ADD_NEW_MAPPING_SUCCESS';
|
export const ADD_NEW_MAPPING_SUCCESS = 'ADD_NEW_MAPPING_SUCCESS';
|
||||||
export const ADD_NEW_MAPPING_FAILED = 'ADD_NEW_MAPPING_FAILED';
|
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';
|
||||||
|
|||||||
38
client/src/store/reducers/incidentsReportReducer.js
Normal file
38
client/src/store/reducers/incidentsReportReducer.js
Normal file
@@ -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;
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -1,12 +1,14 @@
|
|||||||
import { combineReducers } from "redux";
|
import { combineReducers } from 'redux';
|
||||||
|
|
||||||
import { doorLockData} from "./doorLockReducers";
|
import { doorLockData} from './doorLockReducers';
|
||||||
import { mappingsData } from "./mappingsReducer";
|
import { mappingsData } from './mappingsReducer';
|
||||||
import { addMapping } from './addMappingReducer';
|
import { addMapping } from './addMappingReducer';
|
||||||
|
import { incidentsReport } from './incidentsReportReducer';
|
||||||
|
|
||||||
export const rootReducer = combineReducers({
|
export const rootReducer = combineReducers({
|
||||||
doorLockData,
|
doorLockData,
|
||||||
mappingsData,
|
mappingsData,
|
||||||
addMapping,
|
addMapping,
|
||||||
|
incidentsReport,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user