diff --git a/package-lock.json b/package-lock.json index 993b456..b909d62 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2830,11 +2830,18 @@ "integrity": "sha512-vwPpH4Aj4122EW38mxO/fxhGKtwWTMLDIJfZ1He0Edbtjcfna/R3YB67yVhezUMzqc3Jr3+Ii50KRntlENL4xQ==" }, "axios": { - "version": "0.21.1", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz", - "integrity": "sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==", + "version": "0.21.4", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", + "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", "requires": { - "follow-redirects": "^1.10.0" + "follow-redirects": "^1.14.0" + }, + "dependencies": { + "follow-redirects": { + "version": "1.14.4", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.4.tgz", + "integrity": "sha512-zwGkiSXC1MUJG/qmeIFH2HBJx9u0V46QGUe3YR1fXG8bXQxq7fLj0RjLZQ5nubr9qNJUZrH+xUcwXEoXNpfS+g==" + } } }, "axobject-query": { diff --git a/package.json b/package.json index a154f9e..a2acbf6 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "@testing-library/jest-dom": "^5.11.4", "@testing-library/react": "^11.1.0", "@testing-library/user-event": "^12.1.10", - "axios": "^0.21.1", + "axios": "^0.21.4", "bootstrap": "^4.6.0", "clsx": "^1.1.1", "prop-types": "^15.7.2", diff --git a/public/index.html b/public/index.html index aa069f2..9ba798a 100644 --- a/public/index.html +++ b/public/index.html @@ -24,7 +24,7 @@ work correctly both with client-side routing and a non-root public URL. Learn how to configure a non-root public URL by running `npm run build`. --> - React App + Rick y Morty React App diff --git a/src/App.js b/src/App.js index 3a49c0e..db31b16 100644 --- a/src/App.js +++ b/src/App.js @@ -1,9 +1,23 @@ import React from "react"; +import { BrowserRouter as Router, Switch, Route } from "react-router-dom"; import Home from "./pages/Home"; +import Episode from "./pages/Episode"; +import Character from "./pages/Character"; +import Location from "./pages/Location"; function App() { - return ; + return ( + + + {/* add routes here */} + + + + + + + ); } export default App; diff --git a/src/components/CharacterCard/CharacterCard.js b/src/components/CharacterCard/CharacterCard.js index 9e7e4ab..d6c33d9 100644 --- a/src/components/CharacterCard/CharacterCard.js +++ b/src/components/CharacterCard/CharacterCard.js @@ -5,9 +5,11 @@ import "./CharacterCard.scss"; import * as routes from "../../constants/routes"; -function CharacterCard({ id, name, image, species, status, origin, location }) { +function CharacterCard({ id, name, image, species, status, origin }) { + const locationUrlArray = origin.url.split("/"); + const locationId = locationUrlArray[locationUrlArray.length - 1]; return ( -
+

{name}

@@ -15,12 +17,12 @@ function CharacterCard({ id, name, image, species, status, origin, location }) {
{origin.name} -

|

-

{status}

+

{species} |

+

{status}

); diff --git a/src/components/EpisodeCard/EpisodeCard.js b/src/components/EpisodeCard/EpisodeCard.js index 13cb5cf..79fe7cc 100644 --- a/src/components/EpisodeCard/EpisodeCard.js +++ b/src/components/EpisodeCard/EpisodeCard.js @@ -8,7 +8,12 @@ import * as routes from "../../constants/routes"; function EpisodeCard({ id, name, airDate, episode }) { return (
- +

{name}

diff --git a/src/pages/Character/Character.js b/src/pages/Character/Character.js new file mode 100644 index 0000000..2380be7 --- /dev/null +++ b/src/pages/Character/Character.js @@ -0,0 +1,102 @@ +/* eslint-disable no-console */ + +import axios from "axios"; +import React, { Component } from "react"; + +import Layout from "../../components/Layout"; +import CharacterCard from "../../components/CharacterCard"; +import EpisodeCard from "../../components/EpisodeCard"; + +class Character extends Component { + constructor(props) { + super(props); + + this.state = { + character: null, + episodes: [], + hasLoaded: false, + hasError: false, + errorMessage: null, + }; + } + + async componentDidMount() { + this.loadCharacter(); + } + + async loadCharacter() { + console.log(this); + // eslint-disable-next-line react/destructuring-assignment + const id = this.props.match.params.id; + const baseURL = `https://rickandmortyapi.com/api/character/ ${id}`; + try { + const APIcall = await axios.get(baseURL); + + const episodeArray = APIcall.data.episode; + const episodes = await axios.all( + episodeArray.map((episodeURL) => axios.get(episodeURL)), + ); + + this.setState({ + character: APIcall.data, + episodes: episodes, + hasLoaded: true, + }); + } catch (err) { + this.setState({ + hasError: false, + errorMessage: "Character not found!!", + }); + } + } + + render() { + const { + hasLoaded, + hasError, + errorMessage, + character, + episodes, + } = this.state; + + return ( + +
+
+ {hasLoaded && !hasError ? ( + + ) : ( +

{errorMessage}

+ )} +
+
+
+
+ {episodes.map((episode) => ( + + ))} +
+
+
+
+
+ ); + } +} + +export default Character; diff --git a/src/pages/Character/index.js b/src/pages/Character/index.js new file mode 100644 index 0000000..f267ceb --- /dev/null +++ b/src/pages/Character/index.js @@ -0,0 +1 @@ +export { default } from "./Character"; diff --git a/src/pages/Episode/Episode.js b/src/pages/Episode/Episode.js index 8255df5..92b23a0 100644 --- a/src/pages/Episode/Episode.js +++ b/src/pages/Episode/Episode.js @@ -1,37 +1,102 @@ +/* eslint-disable no-console */ +import axios from "axios"; import React, { Component } from "react"; import Layout from "../../components/Layout"; -// import CharacterCard from "../../components/CharacterCard"; +import CharacterCard from "../../components/CharacterCard"; class Episode extends Component { constructor(props) { super(props); - this.state = {}; - // episode: null, - // characters: [], - // hasLoaded: false, - // hasError: false, - // errorMessage: null, + this.state = { + episode: null, + name: "", + airDate: "", + characters: [], + hasLoaded: false, + hasError: false, + errorMessage: null, + }; + } + + async componentDidMount() { + this.loadEpisode(); + } + + async loadEpisode() { + console.log(this); + // eslint-disable-next-line react/destructuring-assignment + const id = this.props.match.params.id; + const baseURL = `https://rickandmortyapi.com/api/episode/ ${id}`; + try { + const APIcall = await axios.get(baseURL); + const charArray = APIcall.data.characters; + const chars = await axios.all( + charArray.map((charURL) => axios.get(charURL)), + ); + + this.setState({ + episode: APIcall.data.episode, + characters: chars, + name: APIcall.data.name, + airDate: APIcall.data.air_date, + hasLoaded: true, + }); + } catch (err) { + this.setState({ + hasError: false, + errorMessage: "Episode not found!!", + }); + } } render() { + const { + hasLoaded, + hasError, + errorMessage, + characters, + name, + airDate, + episode, + } = this.state; + return (
- {/* {characters.map((character) => ( - - ))} */} + {hasLoaded && !hasError ? ( + <> +

{name}

+
+

{airDate}

+

|

+

{episode}

+
+ + ) : ( +

{errorMessage}

+ )} +
+
+
+
+ + {characters.map((character) => ( + + ))} + +
+
diff --git a/src/pages/Home/Home.js b/src/pages/Home/Home.js index f86e93c..0e568cd 100644 --- a/src/pages/Home/Home.js +++ b/src/pages/Home/Home.js @@ -1,50 +1,131 @@ +/* eslint-disable no-console */ +import axios from "axios"; import React, { Component } from "react"; import Layout from "../../components/Layout"; -// import EpisodeCard from "../../components/EpisodeCard"; +import EpisodeCard from "../../components/EpisodeCard"; class Home extends Component { constructor(props) { super(props); - this.state = {}; - // page: 1, - // paginationInfo: null, - // episodes: [], - // hasLoaded: false, - // hasError: false, - // errorMessage: null, + this.state = { + baseURL: "https://rickandmortyapi.com/api/episode?page=1", + episodes: [], + hasLoaded: false, + hasError: false, + errorMessage: null, + page: 1, + next: null, + prev: null, + }; } async componentDidMount() { - // this.loadEpisodes(); + this.loadEpisodes(); + } + + async nextHandler() { + const { next } = this.state; + await this.setState({ + baseURL: next, + }); + this.loadEpisodes(); + } + + async prevHandler() { + const { prev } = this.state; + await this.setState({ + baseURL: prev, + }); + this.loadEpisodes(); } async loadEpisodes() { console.log(this); + + const { baseURL } = this.state; + const currentPage = baseURL.slice(-1); + + try { + const APIcall = await axios.get(baseURL); + console.log(APIcall); + this.setState({ + episodes: APIcall.data.results, + page: currentPage, + next: APIcall.data.info.next, + prev: APIcall.data.info.prev, + hasLoaded: true, + }); + } catch (err) { + this.setState({ + hasError: false, + errorMessage: "Episodes not found!!", + }); + } } render() { + const { + episodes, + hasLoaded, + hasError, + errorMessage, + prev, + next, + page, + } = this.state; + return (
- {/* {hasLoaded && !hasError && ( -
+
+ {hasLoaded && !hasError ? (

Episodes loaded!

+ ) : ( +

{errorMessage}

+ )} +
+
+
+ {prev && ( + + )} + +

{page}

+ {next && ( + + )}
- )} */} +

- {/* {episodes.map((episode) => ( - - ))} */} + {episodes.map((episode) => ( + + ))}

diff --git a/src/pages/Location/Location.js b/src/pages/Location/Location.js new file mode 100644 index 0000000..91cbada --- /dev/null +++ b/src/pages/Location/Location.js @@ -0,0 +1,110 @@ +/* eslint-disable no-console */ +import axios from "axios"; +import React, { Component } from "react"; + +import Layout from "../../components/Layout"; +import CharacterCard from "../../components/CharacterCard"; + +class Location extends Component { + constructor(props) { + super(props); + + this.state = { + residents: [], + dimension: "", + name: "", + type: "", + hasLoaded: false, + hasError: false, + errorMessage: null, + }; + } + + async componentDidMount() { + this.loadLocation(); + } + + async loadLocation() { + console.log(this.props); + // eslint-disable-next-line react/destructuring-assignment + const id = this.props.match.params.locationId; + + const baseURL = `https://rickandmortyapi.com/api/location/${id}`; + + try { + const APIcall = await axios.get(baseURL); + console.log(APIcall); + const residentsArray = APIcall.data.residents; + const res = await axios.all( + residentsArray.map((resURL) => axios.get(resURL)), + ); + + this.setState({ + dimension: APIcall.data.dimension, + residents: res, + name: APIcall.data.name, + type: APIcall.data.type, + hasLoaded: true, + }); + } catch (err) { + this.setState({ + hasError: false, + errorMessage: "Location not found!!", + }); + } + } + + render() { + const { + hasLoaded, + hasError, + errorMessage, + residents, + name, + dimension, + type, + } = this.state; + + return ( + +
+
+ {hasLoaded && !hasError ? ( + <> +

{name}

+
+

{dimension}

+

|

+

{type}

+
+ + ) : ( +

{errorMessage}

+ )} +
+
+
+
+ + {residents.map((character) => ( + + ))} + +
+
+
+
+
+ ); + } +} +export default Location; diff --git a/src/pages/Location/index.js b/src/pages/Location/index.js new file mode 100644 index 0000000..7625c87 --- /dev/null +++ b/src/pages/Location/index.js @@ -0,0 +1 @@ +export { default } from "./Location";