Skip to content
Open
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
19,609 changes: 19,585 additions & 24 deletions package-lock.json

Large diffs are not rendered by default.

24 changes: 23 additions & 1 deletion src/App.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,31 @@
import React from "react";
import { Switch, Route } from "react-router-dom"

import { EPISODE, HOME, CHARACTER, LOCATION } from "./constants/routes"
import Home from "./pages/Home";
import Episode from "./pages/Episode";
import Character from "./pages/Character";
import Location from "./pages/Location";

function App() {
return <Home />;
return <Switch>
<Route
path={`${EPISODE}/:episodeId`}
render={(routeProps) => <Episode {...routeProps} />}
/>
<Route
path={`${CHARACTER}/:characterId`}
render={(routeProps) => <Character {...routeProps} />}
/>
<Route
path={`${LOCATION}/:locationId`}
render={(routeProps) => <Location {...routeProps} />}
/>
<Route
path={HOME}
render={(routeProps) => <Home {...routeProps} />}
/>
</Switch>;
}

export default App;
33 changes: 33 additions & 0 deletions src/api/api.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import axios from "axios";

// Creating default base calling for our API
export function makeApi() {
return axios.create({
baseURL: "https://rickandmortyapi.com/api/",
});
}

export function getEpisodes(page = 1, api = makeApi()) {
return api.get(`/episode?page=${page}`);
}

export function getEpisode(episodeId, api = makeApi()) {
return api.get(`/episode/${episodeId}`);
}

export function getCharacter(characterId, api = makeApi()) {
return api.get(`/character/${characterId}`);
}

export function getLocation(locationId, api = makeApi()) {
return api.get(`/location/${locationId}`);
}

export function getUrl(url, api = makeApi()) {
return api.get(url);
}

export function makePromises (urls = []) {
return urls.map((url) => getUrl(url));
}

1 change: 1 addition & 0 deletions src/api/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./api";
130 changes: 130 additions & 0 deletions src/pages/Character/Character.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
import React, { Component } from "react";

import Layout from "../../components/Layout";
import EpisodeCard from "../../components/EpisodeCard";

import { getCharacter, makePromises } from "../../api";

class Character extends Component {
constructor(props) {
super(props);

this.state = {
character: null,
episodes: [],
hasLoaded: false,
hasError: false,
errorMessage: null,
}

this.loadCharacter = this.loadCharacter.bind(this);
}

componentDidMount() {
const { match } = this.props;
const { characterId } = match.params;

this.loadCharacter(characterId);
}

async loadCharacter(characterId) {
try {
const { data } = await getCharacter(characterId);
const episodeResponse = await Promise.all(makePromises(data.episode));
const episodes = episodeResponse.map((episode) => episode.data);
// console.log({ data });
// console.log({ episodeResponse });
// console.log({ episodes });

this.setState({
character: data,
episodes: episodes,
hasLoaded: true,
hasError: false,
});

} catch (error) {
this.setState({
hasLoaded: true,
hasError: true,
errorMessage: error.message
});
}
}

render() {
const {
character,
episodes,
hasLoaded,
hasError,
errorMessage } = this.state;
return (
<Layout>
<section className="row">
{!hasLoaded && (
<div className="col col-12">
<p>Character loading...</p>
</div>
)}
{hasLoaded && (
<div className="col col-12">
<p>Character loaded!</p>
</div>
)}
{hasError && (
<div className="col col-12">
<p>Character error...</p>
<p>{errorMessage}</p>
</div>
)}
<div className="col col-12">
<hr />
</div>
{!hasError && hasLoaded && (
<div className="col col-4 col-sm-4 col-xl-3">
<img className="CharacterCard__img" src={character.image} alt="" />
</div>
)}
{!hasError && hasLoaded && (
<div className="col">
<h1>{character.name}</h1>
<hr />
<h5>CHARACTER</h5>
<p>{character.species} | {character.status}</p>
<h5>ORIGIN</h5>
<p>{character.origin.name}</p>
<h5>LOCATION</h5>
<p>{character.location.name}</p>
</div>
)}
<div className="col col-12">
<hr />
</div>
<div className="col col-12">
<h3>Episodes</h3>
</div>
<div className="col col-12">
<hr />
</div>

{episodes.length > 0 &&
episodes.map((episode) => (
<EpisodeCard
key={episode.id}
id={episode.id}
name={episode.name}
airDate={episode.air_date}
episode={episode.episode}
/>
))}
<div className="col col-12">
<hr />
</div>
</section>
</Layout>
);
}
}

export default Character;
1 change: 1 addition & 0 deletions src/pages/Character/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from "./Character";
82 changes: 71 additions & 11 deletions src/pages/Episode/Episode.js
Original file line number Diff line number Diff line change
@@ -1,26 +1,87 @@
import React, { Component } from "react";

import Layout from "../../components/Layout";
// import CharacterCard from "../../components/CharacterCard";
import CharacterCard from "../../components/CharacterCard";

import {getEpisode, makePromises} from "../../api";

class Episode extends Component {
constructor(props) {
super(props);

this.state = {};
// episode: null,
// characters: [],
// hasLoaded: false,
// hasError: false,
// errorMessage: null,
this.state = {
episode: null,
characters: [],
hasLoaded: false,
hasError: false,
errorMessage: null,
};

this.loadEpisode = this.loadEpisode.bind(this);
}

componentDidMount() {
// If the check previus console.log we will see that on match property we have the ID information for the episode
const { match } = this.props;
const { episodeId } = match.params;

this.loadEpisode(episodeId);
}

async loadEpisode(episodeId) {
try {
// data is the information of the hole episode
const { data } = await getEpisode(episodeId);
// charactersResponse is an array with all characters
const charactersResponse = await Promise.all(makePromises(data.characters));
// Because of the structure of the charactersResponse:
const characters = charactersResponse.map((character) => character.data);

this.setState ({
hasLoaded: true,
hasError: false,
episode: data,
characters: characters,
});
} catch (error) {
this.setState({
hasLoaded: true,
hasError: true,
errorMessage: error.message
});
}
}

render() {
const {
episode,
characters,
hasLoaded,
hasError,
errorMessage
} = this.state;
return (
<Layout>
<section className="row">
<div className="col col-12">
{/* {characters.map((character) => (
{!hasLoaded && (
<div className="col col-12">
<p>Episode loading...</p>
</div>
)}
{hasLoaded && (
<div className="col col-12">
<p>Episode loaded!</p>
</div>
)}
{hasError && (
<div className="col col-12">
<p>Episode error...</p>
<p>{errorMessage}</p>
</div>
)}
<hr />
{characters.length > 0 &&
characters.map((character) => (
<CharacterCard
key={character.id}
id={character.id}
Expand All @@ -31,8 +92,7 @@ class Episode extends Component {
origin={character.origin}
location={character.location}
/>
))} */}
</div>
))}
</section>
</Layout>
);
Expand Down
Loading