Skip to content

Commit cd68ed7

Browse files
Merge pull request #3 from jorgecortesdev/Task-3.4
it fetch movies from API and add propTypes
2 parents f17ba21 + bcd48aa commit cd68ed7

File tree

5 files changed

+137
-57
lines changed

5 files changed

+137
-57
lines changed

package-lock.json

Lines changed: 24 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@
1010
"license": "ISC",
1111
"dependencies": {
1212
"react": "^18.2.0",
13-
"react-dom": "^18.2.0"
13+
"react-dom": "^18.2.0",
14+
"prop-types": "^15.8.1"
1415
},
1516
"devDependencies": {
1617
"@parcel/transformer-sass": "^2.12.0",

src/components/main-view/main-view.jsx

Lines changed: 51 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,60 +1,61 @@
1-
import { useState } from "react";
1+
import { useState, useEffect } from "react";
22
import { MovieCard } from "../movie-card/movie-card";
33
import { MovieView } from "../movie-view/movie-view";
44

55
export const MainView = () => {
6-
const [movies, setMovies] = useState([
7-
{
8-
id: 1,
9-
title: "Fight Club",
10-
description: "An insomniac office worker and a devil-may-care soap maker form an underground fight club that evolves...",
11-
genre: { name: "Drama" },
12-
director: { name: "David Fincher" },
13-
image:
14-
"https://upload.wikimedia.org/wikipedia/en/f/fc/Fight_Club_poster.jpg",
15-
},
16-
{
17-
id: 2,
18-
title: "Schindler's List",
19-
description: "In German-occupied Poland during World War II, industrialist Oskar Schindler gradually becomes concerned...",
20-
genre: { name: "Biography" },
21-
director: { name: "Steven Spielberg" },
22-
image:
23-
"https://upload.wikimedia.org/wikipedia/en/3/38/Schindler%27s_List_movie.jpg",
24-
},
25-
{
26-
id: 3,
27-
title: "The Shawshank Redemption",
28-
description: "Two imprisoned men bond over a number of years, finding solace and eventual redemption through acts of common...",
29-
genre: { name: "Drama" },
30-
director: { name: "Frank Darabont" },
31-
image:
32-
"https://upload.wikimedia.org/wikipedia/en/8/81/ShawshankRedemptionMoviePoster.jpg",
33-
},
34-
{
35-
id: 4,
36-
title: "The Dark Knight",
37-
description: "When the menace known as the Joker wreaks havoc and chaos on the people of Gotham, Batman must accept...",
38-
genre: { name: "Action" },
39-
director: { name: "Christopher Nolan" },
40-
image:
41-
"https://upload.wikimedia.org/wikipedia/en/1/1c/The_Dark_Knight_%282008_film%29.jpg",
42-
},
43-
{
44-
id: 5,
45-
title: "The Matrix",
46-
description: "A computer hacker learns from mysterious rebels about the true nature of his reality and his role in the war...",
47-
genre: { name: "Sci-Fi" },
48-
director: { name: "Lana Wachowski" },
49-
image:
50-
"https://upload.wikimedia.org/wikipedia/en/c/c1/The_Matrix_Poster.jpg",
51-
}
52-
]);
53-
6+
const [movies, setMovies] = useState([]);
547
const [selectedMovie, setSelectedMovie] = useState(null);
558

9+
useEffect(() => {
10+
fetch("https://cf-2-movie-api.onrender.com/movies")
11+
.then((response) => response.json())
12+
.then(({ data }) => {
13+
// Please review the response format of the API here
14+
// https://cf-2-movie-api.onrender.com/docs/#/Movie/get_movies
15+
const moviesFromApi = data.map(movie => {
16+
return {
17+
id: movie._id,
18+
Title: movie.Title,
19+
Description: movie.Description,
20+
ImagePath: movie.ImagePath,
21+
Featured: movie.Featured,
22+
ReleaseYear: movie.ReleaseYear,
23+
MPA: movie.MPA,
24+
IMDb: movie.IMDb,
25+
Genre: movie.Genre,
26+
Director: movie.Director,
27+
Actors: movie.Actors,
28+
}
29+
});
30+
31+
setMovies(moviesFromApi);
32+
});
33+
}, []);
34+
5635
if (selectedMovie) {
57-
return <MovieView movie={selectedMovie} onBackClick={() => setSelectedMovie(null)} />
36+
// Bonus Task 2: Similar Movies
37+
const similarMovies = movies.filter(movie => {
38+
const isSimilarMovie = movie.Genre.Name === selectedMovie.Genre.Name;
39+
const isNotTheSelectedMovie = movie.id !== selectedMovie.id;
40+
return isNotTheSelectedMovie && isSimilarMovie;
41+
});
42+
43+
return (
44+
<>
45+
<MovieView movie={selectedMovie} onBackClick={() => setSelectedMovie(null)} />
46+
<hr />
47+
<h2>Similar Movies</h2>
48+
{similarMovies.map(movie => (
49+
<MovieCard
50+
key={movie.id}
51+
movie={movie}
52+
onMovieClick={(newSelectedMovie) => {
53+
setSelectedMovie(newSelectedMovie);
54+
}}
55+
/>
56+
))}
57+
</>
58+
);
5859
}
5960

6061
if (movies.length === 0) {
Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,20 @@
1+
import PropTypes from "prop-types";
2+
13
export const MovieCard = ({ movie, onMovieClick }) => {
24
return (
35
<div
46
onClick={() => {
57
onMovieClick(movie);
68
}}
79
>
8-
{movie.title}
10+
{movie.Title}
911
</div>
1012
);
1113
};
14+
15+
MovieCard.propTypes = {
16+
movie: PropTypes.shape({
17+
Title: PropTypes.string
18+
}).isRequired,
19+
onMovieClick: PropTypes.func.isRequired
20+
};
Lines changed: 50 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,71 @@
1+
import PropTypes from "prop-types";
2+
13
export const MovieView = ({ movie, onBackClick }) => {
24
return (
35
<div>
46
<div>
5-
<img src={movie.image} />
7+
<img src={movie.ImagePath} />
68
</div>
79
<div>
810
<span>Title: </span>
9-
<span>{movie.title}</span>
11+
<span>{movie.Title}</span>
1012
</div>
1113
<div>
1214
<span>Description: </span>
13-
<span>{movie.description}</span>
15+
<span>{movie.Description}</span>
1416
</div>
1517
<div>
1618
<span>Genre: </span>
17-
<span>{movie.genre.name}</span>
19+
<span>{movie.Genre.Name}</span>
1820
</div>
1921
<div>
2022
<span>Director: </span>
21-
<span>{movie.director.name}</span>
23+
<span>{movie.Director.Name}</span>
24+
</div>
25+
<div>
26+
<span>Release Year: </span>
27+
<span>{movie.ReleaseYear}</span>
28+
</div>
29+
<div>
30+
<span>MPA: </span>
31+
<span>{movie.MPA}</span>&nbsp;
32+
<small>(Motion Picture Association rating)</small>
33+
</div>
34+
<div>
35+
<span>Rating: </span>
36+
<span>{movie.IMDb}</span>&nbsp;
37+
<small>(IMDb rating)</small>
2238
</div>
2339
<button onClick={onBackClick}>Back</button>
2440
</div>
2541
);
2642
};
43+
44+
MovieView.propTypes = {
45+
movie: PropTypes.shape({
46+
id: PropTypes.string.isRequired,
47+
Title: PropTypes.string.isRequired,
48+
Description: PropTypes.string.isRequired,
49+
ImagePath: PropTypes.string.isRequired,
50+
ReleaseYear: PropTypes.number,
51+
MPA: PropTypes.string,
52+
IMDb: PropTypes.number,
53+
Genre: PropTypes.shape({
54+
Name: PropTypes.string.isRequired,
55+
Description: PropTypes.string.isRequired
56+
}).isRequired,
57+
Director: PropTypes.shape({
58+
Name: PropTypes.string.isRequired,
59+
Bio: PropTypes.string.isRequired,
60+
Birth: PropTypes.string,
61+
Death: PropTypes.string,
62+
}),
63+
Actors: PropTypes.arrayOf(PropTypes.shape({
64+
Name: PropTypes.string.isRequired,
65+
Bio: PropTypes.string.isRequired,
66+
Birthday: PropTypes.string,
67+
ImagePath: PropTypes.string.isRequired
68+
}))
69+
}).isRequired,
70+
onBackClick: PropTypes.func.isRequired
71+
};

0 commit comments

Comments
 (0)