Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added data error modal. Fix store not saving error #426

Merged
merged 1 commit into from
Mar 14, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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';