summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKamran Ahmed <kamranahmed.se@gmail.com>2018-08-28 15:47:02 +0500
committerKamran Ahmed <kamranahmed.se@gmail.com>2018-08-28 15:47:02 +0500
commitf441166a3bf27c145a48ae2350cd8cd0931504e9 (patch)
treecad4e80d88d6910cda192ec3f1f0d4d80f71f331
parentAlert for token (diff)
downloadgithunt-f441166a3bf27c145a48ae2350cd8cd0931504e9.tar.gz
Refactor and add error handling
-rw-r--r--src/components/alert/index.js13
-rw-r--r--src/containers/feed/index.js89
-rw-r--r--src/containers/feed/styles.css17
-rw-r--r--src/containers/options/index.js5
-rw-r--r--src/redux/github/actions.js25
-rw-r--r--src/redux/github/reducer.js8
-rw-r--r--src/redux/github/types.js1
7 files changed, 105 insertions, 53 deletions
diff --git a/src/components/alert/index.js b/src/components/alert/index.js
new file mode 100644
index 0000000..7d04355
--- /dev/null
+++ b/src/components/alert/index.js
@@ -0,0 +1,13 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import classnames from 'classnames';
+
+const Alert = (props) => (
+ <div className={ classnames('alert', `alert-${props.type}`) }>{ props.children }</div>
+);
+
+Alert.propTypes = {
+ type: PropTypes.string.isRequired
+};
+
+export default Alert;
diff --git a/src/containers/feed/index.js b/src/containers/feed/index.js
index 6cff00f..b33e192 100644
--- a/src/containers/feed/index.js
+++ b/src/containers/feed/index.js
@@ -12,10 +12,12 @@ import RepositoryGrid from '../../components/repository-grid';
import RepositoryList from '../../components/repository-list';
import { updateDateJump, updateLanguage, updateViewType } from '../../redux/preference/actions';
import GroupHeading from '../../components/group-heading';
+import Alert from '../../components/alert';
class FeedContainer extends React.Component {
componentDidMount() {
const existingRepositories = this.props.github.repositories || [];
+
// If there are no loaded repositories before, fetch them
if (existingRepositories.length === 0) {
this.fetchNextRepositories();
@@ -27,7 +29,7 @@ class FeedContainer extends React.Component {
this.props.fetchTrending(filters);
}
- componentDidUpdate(prevProps, prevState, snapshot) {
+ componentDidUpdate(prevProps) {
const currPreferences = this.props.preference;
const prevPreferences = prevProps.preference;
@@ -43,7 +45,6 @@ class FeedContainer extends React.Component {
const filters = {};
filters.dateRange = this.getNextDateRange();
-
if (this.props.preference.language) {
filters.language = this.props.preference.language;
}
@@ -73,6 +74,60 @@ class FeedContainer extends React.Component {
return dateRange;
}
+ renderTokenWarning() {
+ return !this.props.preference.options.token && (
+ <Alert type='warning'>
+ Although not required but make sure to
+ <strong className='ml-1 mr-1'>
+ <Link to='/options'>add a token</Link>
+ </strong>
+ to avoid hitting the rate limit
+ </Alert>
+ );
+ }
+
+ renderErrors() {
+ return this.props.github.error && (
+ <Alert type='danger'>
+ { this.props.github.error }
+ </Alert>
+ );
+ }
+
+ renderAlerts() {
+ const tokenWarning = this.renderTokenWarning();
+ const error = this.renderErrors();
+
+ if (tokenWarning || error) {
+ return (
+ <div className="alert-group">
+ { tokenWarning }
+ { error }
+ </div>
+ );
+ }
+
+ return null;
+ }
+
+ renderRepositoriesList() {
+ if (this.props.preference.viewType === 'grid') {
+ return <RepositoryGrid
+ repositories={ this.props.github.repositories || [] }
+ dateJump={ this.props.preference.dateJump }
+ />;
+ }
+
+ return <RepositoryList
+ repositories={ this.props.github.repositories || [] }
+ dateJump={ this.props.preference.dateJump }
+ />;
+ }
+
+ hasRepositories() {
+ return this.props.github.repositories && this.props.github.repositories.length !== 0;
+ }
+
render() {
return (
<div className="page-wrap">
@@ -81,24 +136,12 @@ class FeedContainer extends React.Component {
selectedDateJump={ this.props.preference.dateJump }
/>
- {
- !this.props.preference.options.token && (
- <p className="alert alert-warning">
- Although not required but make sure to
- <strong className='ml-1 mr-1'>
- <Link to='/options'>add a token</Link>
- </strong>
- to avoid hitting the rate limit
- </p>
- )
- }
+ { this.renderAlerts() }
<div className="container mb-5 pb-4">
<div className="header-row clearfix">
{
- this.props.github.repositories &&
- this.props.github.repositories[0] &&
- <GroupHeading
+ this.hasRepositories() && <GroupHeading
start={ this.props.github.repositories[0].start }
end={ this.props.github.repositories[0].end }
dateJump={ this.props.preference.dateJump }
@@ -106,9 +149,7 @@ class FeedContainer extends React.Component {
}
<div className="group-filters">
{
- this.props.github.repositories &&
- this.props.github.repositories[0] &&
- <Filters
+ this.hasRepositories() && <Filters
selectedLanguage={ this.props.preference.language }
selectedViewType={ this.props.preference.viewType }
updateLanguage={ this.props.updateLanguage }
@@ -118,16 +159,14 @@ class FeedContainer extends React.Component {
</div>
</div>
<div className="body-row">
- {
- this.props.preference.viewType === 'grid'
- ? <RepositoryGrid repositories={ this.props.github.repositories || [] } dateJump={ this.props.preference.dateJump }/>
- : <RepositoryList repositories={ this.props.github.repositories || [] } dateJump={ this.props.preference.dateJump }/>
- }
+ { this.renderRepositoriesList() }
{ this.props.github.processing && <Loader/> }
{
- !this.props.github.processing && (
+ !this.props.github.processing &&
+ this.hasRepositories() &&
+ (
<button className="btn btn-primary shadow load-next-date"
onClick={ () => this.fetchNextRepositories() }>
<i className="fa fa-refresh mr-2"></i>
diff --git a/src/containers/feed/styles.css b/src/containers/feed/styles.css
index 95d47bc..d2c5806 100644
--- a/src/containers/feed/styles.css
+++ b/src/containers/feed/styles.css
@@ -36,10 +36,21 @@
margin: 25px auto auto;
}
-.alert-warning {
+.alert-group {
margin-top: -35px;
- background: #ffa;
- border-top: none;
margin-bottom: 25px;
text-align: center;
}
+
+.alert-group .alert:not(:last-child) {
+ border-bottom: none;
+}
+
+.alert-group .alert {
+ border-top: none;
+ margin-bottom: 0;
+}
+
+.alert-warning {
+ background: #ffa;
+}
diff --git a/src/containers/options/index.js b/src/containers/options/index.js
index 172bd61..16ddd2a 100644
--- a/src/containers/options/index.js
+++ b/src/containers/options/index.js
@@ -1,9 +1,12 @@
import React from 'react';
+import Logo from '../../components/icons/logo';
class OptionsContainer extends React.Component {
render() {
return (
- <h1>Hello from the options</h1>
+ <div className="container">
+ <Logo/>
+ </div>
);
}
}
diff --git a/src/redux/github/actions.js b/src/redux/github/actions.js
index 5474144..73dba10 100644
--- a/src/redux/github/actions.js
+++ b/src/redux/github/actions.js
@@ -5,7 +5,6 @@ import {
FETCH_TRENDING_FAILED,
FETCH_TRENDING_SUCCESS,
PROCESS_FETCH_TRENDING,
- UPDATE_FILTERS
} from './types';
const API_URL = 'https://api.github.com/search/repositories';
@@ -49,24 +48,18 @@ export const fetchTrending = function (filters) {
}
});
}).catch(error => {
+ let message = error.response &&
+ error.response.data &&
+ error.response.data.message;
+
+ if (!message) {
+ message = error.message;
+ }
+
dispatch({
type: FETCH_TRENDING_FAILED,
- payload: error
+ payload: message
});
});
};
};
-
-/**
- * Updates the filters used in queries
- * @param filters
- * @return {Function}
- */
-export const updateFilters = function (filters) {
- return dispatch => {
- dispatch({
- type: UPDATE_FILTERS,
- payload: filters
- });
- };
-};
diff --git a/src/redux/github/reducer.js b/src/redux/github/reducer.js
index 79543b8..0d443f6 100644
--- a/src/redux/github/reducer.js
+++ b/src/redux/github/reducer.js
@@ -1,4 +1,4 @@
-import { FETCH_TRENDING_FAILED, FETCH_TRENDING_SUCCESS, PROCESS_FETCH_TRENDING, UPDATE_FILTERS } from './types';
+import { FETCH_TRENDING_FAILED, FETCH_TRENDING_SUCCESS, PROCESS_FETCH_TRENDING } from './types';
import { UPDATE_DATE_TYPE, UPDATE_LANGUAGE } from '../preference/types';
export const initialState = {
@@ -9,7 +9,6 @@ export const initialState = {
// { start: '', end: '', data: [] }
// ]
repositories: [],
- filters: {},
error: null,
};
@@ -44,11 +43,6 @@ export default function reducer(state = initialState, action) {
processing: false,
error: action.payload
};
- case UPDATE_FILTERS:
- return {
- ...state,
- filters: action.payload
- };
default:
return state;
}
diff --git a/src/redux/github/types.js b/src/redux/github/types.js
index c5be4bc..a345496 100644
--- a/src/redux/github/types.js
+++ b/src/redux/github/types.js
@@ -1,4 +1,3 @@
export const PROCESS_FETCH_TRENDING = 'PROCESS_FETCH_TRENDING';
export const FETCH_TRENDING_SUCCESS = 'FETCH_TRENDING_SUCCESS';
export const FETCH_TRENDING_FAILED = 'FETCH_TRENDING_FAILED';
-export const UPDATE_FILTERS = 'UPDATE_FILTERS';