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
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
package-lock.json
/src
339 changes: 120 additions & 219 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
"eslint-plugin-import": "^2.22.1",
"eslint-plugin-jest": "^24.2.1",
"eslint-plugin-jsx-a11y": "^6.4.1",
"eslint-plugin-markdown": "^2.0.0",
"eslint-plugin-markdown": "^2.2.1",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-react": "^7.22.0",
"eslint-plugin-react-hooks": "^4.2.0",
Expand Down
Binary file removed public/favicon.ico
Binary file not shown.
1 change: 1 addition & 0 deletions public/favicon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 4 additions & 4 deletions public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,19 @@
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<link rel="icon" href="%PUBLIC_URL%/favicon.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta
name="description"
content="Web site created using create-react-app"
/>
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
<link rel="apple-touch-icon" href="%PUBLIC_URL%/favicon.svg" />
<!--
manifest.json provides metadata used when your web app is installed on a
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
-->
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<!-- <link rel="manifest" href="%PUBLIC_URL%/manifest.json" /> -->
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Expand All @@ -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`.
-->
<title>React App</title>
<title>Rick & Morty API</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
Expand Down
Binary file removed public/logo192.png
Binary file not shown.
Binary file removed public/logo512.png
Binary file not shown.
11 changes: 9 additions & 2 deletions src/App.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
import React from "react";

import Home from "./pages/Home";
import Episode from "./pages/Episode";
import Character from "./pages/Character"
import Location from "./pages/Location"

function App() {
return <Home />;
function App({ page }) {

if (page === "home") return <Home />
if (page === "episode") return <Episode />
if (page === "character") return <Character />
if (page === "location") return <Location />
}

export default App;
11 changes: 7 additions & 4 deletions src/components/CharacterCard/CharacterCard.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,19 @@ import "./CharacterCard.scss";
import * as routes from "../../constants/routes";

function CharacterCard({ id, name, image, species, status, origin, location }) {
let locationID = location.slice(41)
return (
<div className="col col-12 col-sm-6 col-xl-3 CharacterCard">
<img className="CharacterCard__img" src={image} alt="" />
<div className="col col-12 col-sm-6 col-xl-4 CharacterCard">
<Link to={`${routes.CHARACTER}/${id}`}>
<img className="CharacterCard__img" src={image} alt={`${name} image`} />
</Link>
<Link to={`${routes.CHARACTER}/${id}`}>
<h3 className="CharacterCard__name h4">{name}</h3>
</Link>
<div className="CharacterCard__meta">
<Link
className="CharacterCard__meta-item"
to={`${routes.LOCATION}/${id}`}
to={`${routes.LOCATION}/${locationID}`}
>
{origin.name}
</Link>
Expand All @@ -26,4 +29,4 @@ function CharacterCard({ id, name, image, species, status, origin, location }) {
);
}

export default CharacterCard;
export default CharacterCard;
1 change: 1 addition & 0 deletions src/images/icons/rick-sanchez.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 7 additions & 2 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from "react";
import ReactDOM from "react-dom";
import { BrowserRouter } from "react-router-dom";
import { BrowserRouter, Switch, Route } from "react-router-dom";

import "bootstrap/dist/css/bootstrap.min.css";

Expand All @@ -10,7 +10,12 @@ import reportWebVitals from "./reportWebVitals";
ReactDOM.render(
<React.StrictMode>
<BrowserRouter>
<App />
<Switch>
<Route path="/character"><App page="character" /></Route>
<Route path="/episode"><App page="episode" /></Route>
<Route path="/location"><App page="location" /></Route>
<Route path="/"><App page="home" /></Route>
</Switch>
</BrowserRouter>
</React.StrictMode>,
document.getElementById("root"),
Expand Down
111 changes: 111 additions & 0 deletions src/pages/Character/Character.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
import React, { Component } from "react";
import { Link } from "react-router-dom";
import { withRouter } from "react-router";
import axios from "axios";

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

import * as routes from "../../constants/routes";

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

this.state = {
episodes: []
}
}

componentDidMount() {
this.loadCharacter()
this.loadEpisodes()
}

async loadCharacter() {
// let characterID = window.location.pathname.slice(11)
// const res = await axios.get(`https://rickandmortyapi.com/api/character/${characterID}`)
const res = await axios.get(`https://rickandmortyapi.com/api/${this.props.location.pathname}`)

this.setState({
id: res.data.id,
name: res.data.name,
image: res.data.image,
species: res.data.species,
status: res.data.status,
location: res.data.location.name,
origin: res.data.origin.name,
origin_url: res.data.origin.url,
})
}

async loadEpisodes() {
// let characterID = window.location.pathname.slice(11)
// const res = await axios.get(`https://rickandmortyapi.com/api/character/${characterID}`)
const res = await axios.get(`https://rickandmortyapi.com/api/${this.props.location.pathname}`)

const promiseArray = res.data.episode.map(episodeURL => axios.get(episodeURL))

try {
const episodesInfo = (await axios.all(promiseArray)).map(response => response.data)
this.setState({ episodes: episodesInfo })
} catch(error) {
console.error(error)
}

}

render() {
return (
<Layout>
<section className="row">
<div className="col col-12">
<div className="d-flex justify-content-start">
<img src={this.state.image} alt={`${this.state.name} image`}/>
<div className="ml-5">
<div className="d-flex justify-content-between w-100">
<h2>{this.state.name}</h2>
<button className="col col-3 align-self-end mb-3 btn btn-primary" onClick={this.props.history.goBack}>Go back</button>
</div>
<div className="mt-4">
<h6>CHARACTER</h6>
<span className="mr-1">{this.state.species}</span>
<span className="mr-1">|</span>
<span>{this.state.status}</span>
<div className="d-flex mt-3">
<div className="mr-4">
<h6>ORIGIN</h6>
<span>{this.state.origin}</span>
</div>
<div>
<h6>LOCATION</h6>
<Link to={`${routes.LOCATION}/${this.state.id}`}>
<span>{this.state.location}</span>
</Link>
</div>
</div>

</div>
</div>
</div>
</div>
<div className="col col-12">
<h4 className="ml-3 mt-3">Episodes</h4>
<div className="col col-12 d-flex flex-wrap">
{this.state.episodes.map((episode) => (
<EpisodeCard
key={episode.id}
id={episode.id}
name={episode.name}
airDate={episode.air_date}
episode={episode.episode}
/>
))}
</div>
</div>
</section>
</Layout>
)}
}

export default withRouter(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";
85 changes: 73 additions & 12 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 { withRouter } from "react-router";
import axios from "axios";

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 = {
name: null,
episode: null,
air_date: null,
characters: [],
hasLoaded: true,
hasError: false,
errorMessage: null,
};
}

componentDidMount() {
this.loadEpisode()
this.loadCharacters()
console.log(this.props);
}

async loadEpisode() {
// let episodeId = window.location.pathname.slice(9)
// const res = await axios.get(`https://rickandmortyapi.com/api/episode/${episodeId}`)
const res = await axios.get(`https://rickandmortyapi.com/api/${this.props.location.pathname}`)

this.setState({
name: res.data.name,
episode: res.data.episode,
air_date: res.data.air_date,
})
}

// * JUST TESTING, WILL ERASE LATER
// async loadCharacters() {
// let episodeId = window.location.pathname.slice(9)
// const res = await axios.get(`https://rickandmortyapi.com/api/episode/${episodeId}`)

// let newArray = []
// await res.data.characters.forEach(urlCharacter => {
// axios.get(urlCharacter)
// .then(response => newArray.push(response.data))
// })

// setTimeout(() => {
// this.setState({characters: newArray})
// }, 50)
// }

async loadCharacters() {
// let episodeId = window.location.pathname.slice(9)
// const res = await axios.get(`https://rickandmortyapi.com/api/episode/${episodeId}`)
const res = await axios.get(`https://rickandmortyapi.com/api/${this.props.location.pathname}`)

const promiseArray = res.data.characters.map(characterURL => axios.get(characterURL))

try {
const charactersInfo = (await axios.all(promiseArray)).map(response => response.data)
this.setState({ characters: charactersInfo })
} catch(error) {
console.error(error)
}
}

render() {
return (
<Layout>
<section className="row">
<div className="col col-12">
{/* {characters.map((character) => (
<div className="d-flex justify-content-between w-75">
<div className="col col-12">
<h1 className="col col-12">{this.state.name}</h1>
<p className="col col-12">{this.state.episode} | {this.state.air_date}</p>
</div>
<button className="col col-2 align-self-end mb-3 btn btn-primary" onClick={this.props.history.goBack}>Go back</button>
</div>
<div className="col col-12 d-flex flex-wrap">
{this.state.characters.map((character) => (
<CharacterCard
key={character.id}
id={character.id}
Expand All @@ -29,14 +90,14 @@ class Episode extends Component {
species={character.species}
status={character.status}
origin={character.origin}
location={character.location}
location={character.origin.url}
/>
))} */}
))}
</div>
</section>
</Layout>
);
}
}

export default Episode;
export default withRouter(Episode);
Loading