Skip to content

Commit

Permalink
Merge 3f0c653 into be6db4f
Browse files Browse the repository at this point in the history
  • Loading branch information
Easybuoy committed Nov 9, 2019
2 parents be6db4f + 3f0c653 commit 7ec1151
Show file tree
Hide file tree
Showing 15 changed files with 334 additions and 157 deletions.
21 changes: 21 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2019 Ekunola Ezekiel

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
58 changes: 58 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,64 @@
[![Coverage Status](https://coveralls.io/repos/github/Easybuoy/pstk-swapi-challenge/badge.svg?branch=develop)](https://coveralls.io/github/Easybuoy/pstk-swapi-challenge?branch=master)
## Pstk Swapi Challenge

<br>
<img src="src/assets/images/landing.png" />

Link to Pivotal Tracker: https://www.pivotaltracker.com/n/projects/2415802

Link to application: https://pstk-swapi-challenge.netlify.com/

## Built With
<ul>
<li><a href="https://reactjs.org">React</a></li>
<li><a href="https://redux.js.org/">Redux</a></li>
<li><a href="https://www.styled-components.com/">Styled-Components</a></li>
<li><a href="https://swapi.co/api/">Swapi API</a></li>
</ul>



## Testing Tools
<ul>
<li><a href="https://jestjs.io/">Jest</a></li>
<li><a href="https://airbnb.io/enzyme/">Enzyme</a></li>
</ul>


## Getting Started

<h3>Prerequisites</h3>
You need Nodejs Installed to be able to run this project on your machine.

<h3>Installing<h3>
<ul><li>Clone Repository</li></ul>
<pre><code>git clone https://github.com/Easybuoy/pstk-swapi-challenge</code> </pre>
<br>
<br>

<ul><li>Change directory to Swapi Challenge</li></ul>
<pre><code>cd pstk-swapi-challenge</code></pre>
<br>
<br>

<ul><li>Install Dependencies</li></ul>
<pre><code>npm install</code></pre>
<br>
<br>

<ul><li>Start Application</li></ul>
<pre><code>npm start</code></pre>
<br>
<br>

<ul><li>Run Test</li></ul>
<pre><code>npm test</code></pre>
<br>
<br>

<ul><li>Run Coverage Report</li></ul>
<pre><code>npm run coveralls</code></pre>
<br>

## License
<h4>This project makes use of the MIT License which can be found <a href="https://github.com/Easybuoy/pstk-swapi-challenge/master/LICENSE">here</a></h4>
6 changes: 4 additions & 2 deletions src/App.jsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import React from 'react';
import MovieListDropdown from './components/Common/MovieListDropdown';
import CharacterList from './components/Characters/CharacterList';
import Navigation from './components/Common/Navigation';

const App = () => {
return (
<div>
<>
<Navigation />
<MovieListDropdown />
<CharacterList />
</div>
</>
);
};

Expand Down
34 changes: 25 additions & 9 deletions src/actions/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import axios from 'axios';
import { toast } from 'react-toastify';

import {
LOADING,
Expand All @@ -9,21 +8,22 @@ import {
SET_MOVIE,
SET_CHARACTERS
} from './types';
import { toast } from 'react-toastify';

export const getMovies = () => dispatch => {
dispatch({ type: LOADING });
axios
.get('https://cors-anywhere.herokuapp.com/https://swapi.co/api/films')
.then(res => dispatch({ type: SET_MOVIES, payload: res.data.results }))
.catch(err => {
if (typeof err.message == 'string') {
dispatch({ type: ERROR, payload: err.message });
toast.error(err.message)
if (err.response) {
dispatch({ type: ERROR, payload: err.response.data.detail });
toast.error(err.response.data.detail);
} else {
dispatch({ type: ERROR, payload: err.response.data });
dispatch({ type: ERROR, payload: err.message });
toast.error(err.message);
}
})

.finally(() => dispatch({ type: LOADING }));
};

Expand All @@ -35,7 +35,15 @@ export const getMovie = movie_url => dispatch => {
dispatch({ type: SET_MOVIE, payload: res.data });
dispatch(getCharacter(res.data.characters));
})
.catch(err => dispatch({ type: ERROR, payload: err.response.data }))
.catch(err => {
if (err.response) {
dispatch({ type: ERROR, payload: err.response.data.detail });
toast.error(err.response.data.detail);
} else {
dispatch({ type: ERROR, payload: err.message });
toast.error(err.message);
}
})
.finally(() => dispatch({ type: LOADING }));
};

Expand All @@ -49,7 +57,15 @@ export const getCharacter = character_urls => dispatch => {
)
)
.then(res => dispatch(setCharacters(res)))
.catch(err => dispatch({ type: ERROR, payload: err.response.data }))
.catch(err => {
if (err.response) {
dispatch({ type: ERROR, payload: err.response.data.detail });
toast.error(err.response.data.detail);
} else {
dispatch({ type: ERROR, payload: err.message });
toast.error(err.message);
}
})
.finally(() => dispatch({ type: LOADING }));
};

Expand All @@ -59,4 +75,4 @@ export const selectMovie = movie => {

export const setCharacters = characters => {
return { type: SET_CHARACTERS, payload: characters };
};
};
Binary file added src/assets/images/landing.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
39 changes: 36 additions & 3 deletions src/components/Characters/Character.jsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useState } from 'react';
import React, { useState, useEffect } from 'react';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';

Expand All @@ -12,7 +12,8 @@ import {
sortHeight,
sortName,
calculateFeet,
calculateInches
calculateInches,
sortGender
} from '../../utils';
import PreLoader from '../Common/PreLoader';

Expand All @@ -30,6 +31,19 @@ export const sortArrow = order => {
const Character = ({ movie, characters, setCharacters }) => {
const [heightOrder, setHeightOrder] = useState(undefined);
const [nameOrder, setNameOrder] = useState(undefined);
const [genderValue] = useState('Select Gender');
const [stateCharacters, setStateCharacters] = useState([]);

useEffect(() => {
const timer = setTimeout(() => {
if (characters.length > 0) {
setStateCharacters(characters);
}
}, 3000);
return () => clearTimeout(timer);
// setStateCharacters(characters);
// eslint-disable-next-line react-hooks/exhaustive-deps
});

const sortNameField = array => {
let sorted = [];
Expand Down Expand Up @@ -61,6 +75,11 @@ const Character = ({ movie, characters, setCharacters }) => {
setCharacters(sorted);
};

const sortGenderField = (array, letter) => {
const sorted = sortGender(array, letter);
setCharacters(sorted);
};

if (characters.length > 0) {
const totalHeight = calculateHeights(characters);
return (
Expand All @@ -76,7 +95,21 @@ const Character = ({ movie, characters, setCharacters }) => {
>
Name {sortArrow(nameOrder)}
</th>
<th>Gender</th>
<th className="toggle-gender">
Gender
<select
value={genderValue}
onChange={e =>
sortGenderField(stateCharacters, e.target.value)
}
>
<option defaultValue="Select Gender" disabled>
Select Gender
</option>
<option value="M">M</option>
<option value="F">F</option>
</select>
</th>
<th
onDoubleClick={() => sortHeightField(characters)}
className="toggle"
Expand Down
20 changes: 13 additions & 7 deletions src/components/Common/MovieListDropdown.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,12 @@ import React, { useEffect, useState } from 'react';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';

import PreLoader from '../Common/PreLoader';
import { getMovies, selectMovie, getMovie } from '../../actions';
import { MovieListDropdown as StyledMovieListDropdown } from '../../styles';
import {
MovieListDropdown as StyledMovieListDropdown,
Select
} from '../../styles';

const MovieListDropdown = ({ movies, selectMovie, getMovies, getMovie }) => {
const [movieValue, setMovieValue] = useState('');
Expand All @@ -25,7 +29,7 @@ const MovieListDropdown = ({ movies, selectMovie, getMovies, getMovie }) => {

if (movies.length > 0) {
dropDownItems = (
<select value={movieValue} onChange={handleChange}>
<Select value={movieValue} onChange={handleChange}>
<option value="Select Movie" disabled>
Select Star Wars Movie
</option>
Expand All @@ -37,8 +41,10 @@ const MovieListDropdown = ({ movies, selectMovie, getMovies, getMovie }) => {
{movie.title}
</option>
))}
</select>
</Select>
);
} else {
dropDownItems = <PreLoader />;
}

return (
Expand All @@ -51,14 +57,14 @@ const MovieListDropdown = ({ movies, selectMovie, getMovies, getMovie }) => {
};

MovieListDropdown.propTypes = {
loading: PropTypes.object.isRequired,
error: PropTypes.object.isRequired,
loading: PropTypes.bool.isRequired,
error: PropTypes.string.isRequired,
getMovies: PropTypes.func.isRequired
};

const mapStateToProps = state => ({
loading: state.loading,
error: state.error,
loading: state.loading.loading,
error: state.error.error,
movies: state.swapi.movies,
movie: state.swapi.movie,
selectedMovie: state.swapi.selectedMovie
Expand Down
14 changes: 14 additions & 0 deletions src/components/Common/Navigation.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import React from 'react'

import { Navigation as StyledNavigation } from '../../styles';
import logo from '../../assets/images/star-wars.png'

function Navigation() {
return (
<StyledNavigation>
<img src={logo} alt="star wars" />
</StyledNavigation>
)
}

export default Navigation
Loading

0 comments on commit 7ec1151

Please sign in to comment.