Skip to content

Commit

Permalink
Merge pull request #426 from hackforla/264_error_handling
Browse files Browse the repository at this point in the history
Added data error modal. Fix store not saving error
  • Loading branch information
brodly authored Mar 14, 2020
2 parents 555ea08 + 555b596 commit 5b4168d
Show file tree
Hide file tree
Showing 8 changed files with 151 additions and 100 deletions.
25 changes: 23 additions & 2 deletions src/components/main/body/Body.jsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,40 @@
import React from 'react';
import { connect } from 'react-redux';
import PropTypes from 'proptypes';

import Visualizations from '@components/Visualizations';
import Loader from '@components/common/Loader';
import Modal from '@components/common/Modal';
import Menu from '../menu/Menu';
import PinMap from '../../PinMap/PinMap';
import DataRequestError from './DataRequestError';

const Body = () => (
const Body = ({
openErrorModal,
error,
}) => (
<div id="body-container" className="body is-relative">
<Menu />
<main id="body-wrap">
<PinMap />
<Visualizations />
<Loader />
<Modal
open={openErrorModal}
content={<DataRequestError error={error} />}
/>
</main>
</div>
);

export default Body;
Body.propTypes = {
error: PropTypes.shape({}).isRequired,
openErrorModal: PropTypes.bool.isRequired,
};

const mapStateToProps = state => ({
error: state.data.error,
openErrorModal: state.ui.error.isOpen,
});

export default connect(mapStateToProps, null)(Body);
48 changes: 48 additions & 0 deletions src/components/main/body/DataRequestError.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import React from 'react';
import { connect } from 'react-redux';
import propTypes from 'proptypes';

import { setErrorModal } from '@reducers/ui';

import Icon from '@components/common/Icon';
import Button from '@components/common/Button';

const DataRequestError = ({ closeModal }) => (
<div className="data-request-error">
<div className="has-text-centered">
<Icon
id="data-request-error-icon"
icon="exclamation-triangle"
color="warning"
size="large"
iconSize="3x"
/>
</div>
<br />
<p className="has-text-centered has-text-weight-bold is-size-4">
Something went wrong
</p>
<br />
<p className="has-text-centered">
We failed to retrieve data for this request; please try again.
</p>
<br />
<div className="has-text-centered">
<Button
label="Back"
color="danger"
handleClick={closeModal}
/>
</div>
</div>
);

DataRequestError.propTypes = {
closeModal: propTypes.func.isRequired,
};

const mapDispatchToProps = dispatch => ({
closeModal: () => dispatch(setErrorModal(false)),
});

export default connect(null, mapDispatchToProps)(DataRequestError);
119 changes: 38 additions & 81 deletions src/components/main/header/Header.jsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
import React from 'react';
import propTypes from 'proptypes';
import { connect } from 'react-redux';

import COLORS from '../../../styles/COLORS';

const Header = ({
data,
}) => {
const Header = () => {
const cta2Style = {
color: COLORS.BRAND.CTA2,
fontWeight: 'bold',
Expand All @@ -22,86 +19,46 @@ const Header = ({
};

return (
<>
<header
className="navbar"
role="navigation"
aria-label="main navigation"
style={{
background: COLORS.BRAND.MAIN,
height: '60px',
boxShadow: '0 2px 4px rgba(0, 0, 0, 0.5)',
// Really high z-index here to ensure Header is on top of modal
zIndex: '20000',
}}
>
<div className="navbar-brand">
<div className="navbar-item">
<p style={cta1Style}>311</p>
<p style={cta2Style}>Data</p>
</div>
<header
className="navbar"
role="navigation"
aria-label="main navigation"
style={{
background: COLORS.BRAND.MAIN,
height: '60px',
boxShadow: '0 2px 4px rgba(0, 0, 0, 0.5)',
// Really high z-index here to ensure Header is on top of modal
zIndex: '20000',
}}
>
<div className="navbar-brand">
<div className="navbar-item">
<p style={cta1Style}>311</p>
<p style={cta2Style}>Data</p>
</div>
</div>

<div id="navbar" className="navbar-menu">
<div className="navbar-end">
<div className="navbar-item">
<a href="/" style={cta2Style}>
CSV Reporter
</a>
</div>
<div className="navbar-item">
<a href="/" style={backgroundStyle}>
About 311 Data
</a>
</div>
<div className="navbar-item">
<a href="/" style={backgroundStyle}>
Contact Us
</a>
</div>
<div id="navbar" className="navbar-menu">
<div className="navbar-end">
<div className="navbar-item">
<a href="/" style={cta2Style}>
CSV Reporter
</a>
</div>
</div>
</header>
{/* Errors */}
{data.error && (
<article
className="message is-danger"
style={{ margin: '0' }}
>
<div className="message-body">
<div className="level">
<div className="level-right">
{data.error.message}
</div>
<div className="level-left">
<button
type="button"
className="delete"
aria-label="delete"
/>
</div>
</div>
<div className="navbar-item">
<a href="/" style={backgroundStyle}>
About 311 Data
</a>
</div>
<div className="navbar-item">
<a href="/" style={backgroundStyle}>
Contact Us
</a>
</div>
</article>
)}
</>
</div>
</div>
</header>
);
};

const mapStateToProps = state => ({
data: state.data,
});

Header.propTypes = {
data: propTypes.shape({
error: propTypes.shape({
message: propTypes.string,
}),
}),
};

Header.defaultProps = {
data: undefined,
};

export default connect(mapStateToProps, null)(Header);
export default Header;
29 changes: 12 additions & 17 deletions src/redux/reducers/data.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,31 +35,26 @@ export default (state = initialState, action) => {
...state,
isLoading: true,
};
case types.GET_DATA_SUCCESS: {
const {
lastUpdated,
pins,
counts,
frequency,
timeToClose,
} = action.payload;

case types.GET_DATA_SUCCESS:
return {
...state,
error: null,
isLoading: false,
lastUpdated,
pins,
counts,
frequency,
timeToClose,
...action.payload,
};
}
case types.GET_DATA_FAILURE: {
const { error } = action.payload;
const {
response: { status },
message,
} = action.payload;

return {
...state,
error,
error: {
code: status,
message,
error: action.payload,
},
isLoading: false,
};
}
Expand Down
17 changes: 17 additions & 0 deletions src/redux/reducers/ui.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { MENU_TABS } from '@components/common/CONSTANTS';
const types = {
TOGGLE_MENU: 'TOGGLE_MENU',
SET_MENU_TAB: 'SET_MENU_TAB',
SET_ERROR_MODAL: 'SET_ERROR_MODAL',
};

export const toggleMenu = () => ({
Expand All @@ -14,11 +15,19 @@ export const setMenuTab = tab => ({
payload: tab,
});

export const setErrorModal = isOpen => ({
type: types.SET_ERROR_MODAL,
payload: isOpen,
});

const initialState = {
menu: {
isOpen: true,
activeTab: MENU_TABS.MAP,
},
error: {
isOpen: false,
},
};

export default (state = initialState, action) => {
Expand All @@ -31,6 +40,14 @@ export default (state = initialState, action) => {
isOpen: !state.menu.isOpen,
},
};
case types.SET_ERROR_MODAL:
return {
...state,
error: {
...state.error,
isOpen: action.payload,
},
};
case types.SET_MENU_TAB:
return {
...state,
Expand Down
6 changes: 6 additions & 0 deletions src/redux/rootSaga.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,17 @@ import {
select,
all,
} from 'redux-saga/effects';

import {
types,
getDataSuccess,
getDataFailure,
} from './reducers/data';

import {
setErrorModal,
} from './reducers/ui';

/* /////////// INDIVIDUAL API CALLS /////////// */

const BASE_URL = process.env.DB_URL;
Expand Down Expand Up @@ -102,6 +107,7 @@ function* getData() {
yield put(getDataSuccess(data));
} catch (e) {
yield put(getDataFailure(e));
yield put(setErrorModal(true));
}
}

Expand Down
6 changes: 6 additions & 0 deletions src/styles/main/_body.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
.data-request-error {
border-radius: 5px;
background: rgba(153, 153, 153, 0.7);
padding: 10px 35px;
margin: 0 10em;
}
1 change: 1 addition & 0 deletions src/styles/styles.scss
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@
@import './main/tooltip';
@import './main/visualizations';
@import './main/loader';
@import './main/body';

0 comments on commit 5b4168d

Please sign in to comment.