diff options
| author | Kamran Ahmed <kamranahmed.se@gmail.com> | 2018-08-28 15:47:02 +0500 |
|---|---|---|
| committer | Kamran Ahmed <kamranahmed.se@gmail.com> | 2018-08-28 15:47:02 +0500 |
| commit | f441166a3bf27c145a48ae2350cd8cd0931504e9 (patch) | |
| tree | cad4e80d88d6910cda192ec3f1f0d4d80f71f331 | |
| parent | Alert for token (diff) | |
| download | githunt-f441166a3bf27c145a48ae2350cd8cd0931504e9.tar.gz | |
Refactor and add error handling
| -rw-r--r-- | src/components/alert/index.js | 13 | ||||
| -rw-r--r-- | src/containers/feed/index.js | 89 | ||||
| -rw-r--r-- | src/containers/feed/styles.css | 17 | ||||
| -rw-r--r-- | src/containers/options/index.js | 5 | ||||
| -rw-r--r-- | src/redux/github/actions.js | 25 | ||||
| -rw-r--r-- | src/redux/github/reducer.js | 8 | ||||
| -rw-r--r-- | src/redux/github/types.js | 1 |
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'; |
