├── README.md
├── public
├── favicon.ico
├── manifest.json
└── index.html
├── src
├── index.js
├── App.css
├── components
│ ├── Navigation.js
│ ├── Navigation.css
│ ├── Movie.css
│ └── Movie.js
├── routes
│ ├── About.js
│ ├── Detail.js
│ ├── About.css
│ ├── Home.css
│ └── Home.js
└── App.js
├── .gitignore
└── package.json
/README.md:
--------------------------------------------------------------------------------
1 | # Movie App 2019
2 |
3 | React JS Fundamentals Course (2019 Update!)
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nomadcoders/movie_app_2019/HEAD/public/favicon.ico
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import ReactDOM from "react-dom";
3 | import App from "./App";
4 |
5 | ReactDOM.render(, document.getElementById("potato"));
6 |
--------------------------------------------------------------------------------
/src/App.css:
--------------------------------------------------------------------------------
1 | * {
2 | box-sizing: border-box;
3 | }
4 |
5 | body {
6 | margin: 0;
7 | padding: 0;
8 | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen,
9 | Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif;
10 | background-color: #eff3f7;
11 | height: 100%;
12 | }
13 |
--------------------------------------------------------------------------------
/src/components/Navigation.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { Link } from "react-router-dom";
3 | import "./Navigation.css";
4 |
5 | function Navigation() {
6 | return (
7 |
8 | Home
9 | About
10 |
11 | );
12 | }
13 |
14 | export default Navigation;
15 |
--------------------------------------------------------------------------------
/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | }
10 | ],
11 | "start_url": ".",
12 | "display": "standalone",
13 | "theme_color": "#000000",
14 | "background_color": "#ffffff"
15 | }
16 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # production
12 | /build
13 |
14 | # misc
15 | .DS_Store
16 | .env.local
17 | .env.development.local
18 | .env.test.local
19 | .env.production.local
20 |
21 | npm-debug.log*
22 | yarn-debug.log*
23 | yarn-error.log*
24 |
--------------------------------------------------------------------------------
/src/routes/About.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import "./About.css";
3 |
4 | function About(props) {
5 | console.log(props);
6 | return (
7 |
8 |
9 | “Freedom is the freedom to say that two plus two make four. If that is
10 | granted, all else follows.”
11 |
12 | − George Orwell, 1984
13 |
14 | );
15 | }
16 |
17 | export default About;
18 |
--------------------------------------------------------------------------------
/src/routes/Detail.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | class Detail extends React.Component {
4 | componentDidMount() {
5 | const { location, history } = this.props;
6 | if (location.state === undefined) {
7 | history.push("/");
8 | }
9 | }
10 | render() {
11 | const { location } = this.props;
12 | if (location.state) {
13 | return {location.state.title};
14 | } else {
15 | return null;
16 | }
17 | }
18 | }
19 | export default Detail;
20 |
--------------------------------------------------------------------------------
/src/routes/About.css:
--------------------------------------------------------------------------------
1 | .about__container {
2 | box-shadow: 0 13px 27px -5px rgba(50, 50, 93, 0.25),
3 | 0 8px 16px -8px rgba(0, 0, 0, 0.3), 0 -6px 16px -6px rgba(0, 0, 0, 0.025);
4 | padding: 20px;
5 | border-radius: 5px;
6 | background-color: white;
7 | margin: 0 auto;
8 | margin-top: 100px;
9 | width: 100%;
10 | max-width: 400px;
11 | font-weight: 300;
12 | }
13 |
14 | .about__container span:first-child {
15 | font-size: 20px;
16 | }
17 |
18 | .about__container span:last-child {
19 | display: block;
20 | margin-top: 10px;
21 | }
22 |
--------------------------------------------------------------------------------
/src/App.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { HashRouter, Route } from "react-router-dom";
3 | import Home from "./routes/Home";
4 | import About from "./routes/About";
5 | import Detail from "./routes/Detail";
6 | import Navigation from "./components/Navigation";
7 | import "./App.css";
8 |
9 | function App() {
10 | return (
11 |
12 |
13 |
14 |
15 |
16 |
17 | );
18 | }
19 |
20 | export default App;
21 |
--------------------------------------------------------------------------------
/src/routes/Home.css:
--------------------------------------------------------------------------------
1 | .container {
2 | height: 100%;
3 | display: flex;
4 | justify-content: center;
5 | }
6 |
7 | .loader {
8 | width: 100%;
9 | height: 100vh;
10 | display: flex;
11 | justify-content: center;
12 | align-items: center;
13 | font-weight: 300;
14 | }
15 |
16 | .movies {
17 | display: grid;
18 | grid-template-columns: repeat(2, minmax(400px, 1fr));
19 | grid-gap: 100px;
20 | padding: 50px;
21 | width: 80%;
22 | padding-top: 70px;
23 | }
24 |
25 | @media screen and (max-width: 1090px) {
26 | .movies {
27 | grid-template-columns: 1fr;
28 | width: 100%;
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/components/Navigation.css:
--------------------------------------------------------------------------------
1 | .nav {
2 | z-index: 1;
3 | position: fixed;
4 | top: 50px;
5 | left: 10px;
6 | display: flex;
7 | flex-direction: column;
8 | background-color: white;
9 | padding: 10px 20px;
10 | box-shadow: 0 13px 27px -5px rgba(50, 50, 93, 0.25),
11 | 0 8px 16px -8px rgba(0, 0, 0, 0.3), 0 -6px 16px -6px rgba(0, 0, 0, 0.025);
12 | border-radius: 5px;
13 | }
14 |
15 | @media screen and (max-width: 1090px) {
16 | .nav {
17 | left: initial;
18 | top: initial;
19 | bottom: 0px;
20 | width: 100%;
21 | }
22 | }
23 |
24 | .nav a {
25 | text-decoration: none;
26 | color: #0008fc;
27 | text-transform: uppercase;
28 | font-size: 12px;
29 | text-align: center;
30 | font-weight: 600;
31 | }
32 |
33 | .nav a:not(:last-child) {
34 | margin-bottom: 20px;
35 | }
36 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "movie_app_2019",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "axios": "^0.19.0",
7 | "gh-pages": "^2.0.1",
8 | "prop-types": "^15.7.2",
9 | "react": "^16.8.6",
10 | "react-dom": "^16.8.6",
11 | "react-router-dom": "^5.1.2",
12 | "react-scripts": "3.0.1"
13 | },
14 | "scripts": {
15 | "start": "react-scripts start",
16 | "build": "react-scripts build",
17 | "deploy": "gh-pages -d build",
18 | "predeploy": "npm run build"
19 | },
20 | "eslintConfig": {
21 | "extends": "react-app"
22 | },
23 | "browserslist": {
24 | "production": [
25 | ">0.2%",
26 | "not dead",
27 | "not op_mini all"
28 | ],
29 | "development": [
30 | "last 1 chrome version",
31 | "last 1 firefox version",
32 | "last 1 safari version"
33 | ]
34 | },
35 | "homepage": "https://nomadcoders.github.io/movie_app_2019/"
36 | }
37 |
--------------------------------------------------------------------------------
/src/components/Movie.css:
--------------------------------------------------------------------------------
1 | .movies .movie {
2 | background-color: white;
3 | margin-bottom: 70px;
4 | font-weight: 300;
5 | padding: 20px;
6 | border-radius: 5px;
7 | color: #adaeb9;
8 | box-shadow: 0 13px 27px -5px rgba(50, 50, 93, 0.25),
9 | 0 8px 16px -8px rgba(0, 0, 0, 0.3), 0 -6px 16px -6px rgba(0, 0, 0, 0.025);
10 | }
11 |
12 | .movies .movie a {
13 | display: grid;
14 | grid-template-columns: minmax(150px, 1fr) 2fr;
15 | grid-gap: 20px;
16 | text-decoration: none;
17 | color: inherit;
18 | }
19 |
20 | .movie img {
21 | position: relative;
22 | top: -50px;
23 | max-width: 150px;
24 | width: 100%;
25 | margin-right: 30px;
26 | box-shadow: 0 30px 60px -12px rgba(50, 50, 93, 0.25),
27 | 0 18px 36px -18px rgba(0, 0, 0, 0.3), 0 -12px 36px -8px rgba(0, 0, 0, 0.025);
28 | }
29 |
30 | .movie .movie__title,
31 | .movie .movie__year {
32 | margin: 0;
33 | font-weight: 300;
34 | }
35 |
36 | .movie .movie__title {
37 | margin-bottom: 5px;
38 | font-size: 24px;
39 | color: #2c2c2c;
40 | }
41 |
42 | .movie .movie__genres {
43 | list-style: none;
44 | padding: 0;
45 | margin: 0;
46 | display: flex;
47 | flex-wrap: wrap;
48 | margin: 5px 0px;
49 | }
50 |
51 | .movie__genres li,
52 | .movie .movie__year {
53 | margin-right: 10px;
54 | font-size: 14px;
55 | }
56 |
--------------------------------------------------------------------------------
/src/routes/Home.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import axios from "axios";
3 | import Movie from "../components/Movie";
4 | import "./Home.css";
5 |
6 | class Home extends React.Component {
7 | state = {
8 | isLoading: true,
9 | movies: []
10 | };
11 | getMovies = async () => {
12 | const {
13 | data: {
14 | data: { movies }
15 | }
16 | } = await axios.get(
17 | "https://yts-proxy.now.sh/list_movies.json?sort_by=rating"
18 | );
19 | this.setState({ movies, isLoading: false });
20 | };
21 | componentDidMount() {
22 | this.getMovies();
23 | }
24 | render() {
25 | const { isLoading, movies } = this.state;
26 | return (
27 |
28 | {isLoading ? (
29 |
30 | Loading...
31 |
32 | ) : (
33 |
34 | {movies.map(movie => (
35 |
44 | ))}
45 |
46 | )}
47 |
48 | );
49 | }
50 | }
51 |
52 | export default Home;
53 |
--------------------------------------------------------------------------------
/src/components/Movie.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { Link } from "react-router-dom";
3 | import PropTypes from "prop-types";
4 | import "./Movie.css";
5 |
6 | function Movie({ id, year, title, summary, poster, genres }) {
7 | return (
8 |
9 |
21 |

22 |
23 |
{title}
24 |
{year}
25 |
26 | {genres.map((genre, index) => (
27 | -
28 | {genre}
29 |
30 | ))}
31 |
32 |
{summary.slice(0, 180)}...
33 |
34 |
35 |
36 | );
37 | }
38 |
39 | Movie.propTypes = {
40 | id: PropTypes.number.isRequired,
41 | year: PropTypes.number.isRequired,
42 | title: PropTypes.string.isRequired,
43 | summary: PropTypes.string.isRequired,
44 | poster: PropTypes.string.isRequired,
45 | genres: PropTypes.arrayOf(PropTypes.string).isRequired
46 | };
47 |
48 | export default Movie;
49 |
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
12 |
13 |
22 | Movie App
23 |
24 |
25 |
26 |
27 |
37 |
38 |
39 |
--------------------------------------------------------------------------------