-
Notifications
You must be signed in to change notification settings - Fork 417
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Project Movies by Michelle Wegler & Maja Zimnoch #313
base: master
Are you sure you want to change the base?
Changes from 27 commits
7572657
38ca598
0af8cc2
f077bd5
2ec8b7a
e2dd00a
8024514
718bd8a
cada76c
b5ec085
2632a92
040eb20
ca3fd15
d2e5a63
eb07e54
6add743
61d90c3
6dd0ea8
6612982
c52e1bc
24b9bb5
5e37d99
a8537ef
1e35507
d795c49
99f7d03
ad6404a
d527e42
0658772
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,15 @@ | ||
# Project Movies | ||
|
||
Replace this readme with your own information about your project. | ||
This is a multi-page React application designed to showcase the use of APIs in React. The project utilizes useState and useEffect hooks to display information about upcoming movie releases. It was developed through pair programming. | ||
|
||
Start by briefly describing the assignment in a sentence or two. Keep it short and to the point. | ||
|
||
## The problem | ||
|
||
Describe how you approached to problem, and what tools and techniques you used to solve it. How did you plan? What technologies did you use? If you had more time, what would be next? | ||
- working with an API and having it in an external folder 'utils' and then exporting it for the use of the project | ||
- first time working with React Router | ||
- using new React hooks | ||
|
||
## View it live | ||
|
||
Every project should be deployed somewhere. Be sure to include the link to the deployed project so that the viewer can click around and see what it's all about. | ||
https://michelle-maja-movies.netlify.app/ | ||
|
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,52 @@ | ||
import React from 'react'; | ||
import React, { useState, useEffect } from 'react'; | ||
import { BrowserRouter, Routes, Route, Navigate } from 'react-router-dom'; | ||
import NotFound from 'components/NotFound'; | ||
import Details from 'components/Details'; | ||
import ListMovies from 'components/ListMovies'; | ||
import { LIST_URL } from 'utils/urls.js'; | ||
|
||
export const App = () => { | ||
const [listMovies, setListMovies] = useState([]); | ||
const [loading, setLoading] = useState(false); | ||
|
||
// this is borrowed from the example project | ||
useEffect(() => { | ||
setLoading(true); | ||
fetch(LIST_URL) | ||
.then((response) => response.json()) | ||
.then((data) => { | ||
setListMovies(data.results) | ||
}) | ||
.catch((e) => { | ||
console.error(e) | ||
}) | ||
.finally(() => { | ||
setLoading(false); | ||
}) | ||
}, []); | ||
|
||
if (loading) { | ||
return ( | ||
<p>Loading...</p> | ||
); | ||
} | ||
console.log(listMovies) | ||
|
||
return ( | ||
<div> | ||
Find me in src/app.js! | ||
</div> | ||
// this is the main wrapper for the whole app | ||
<BrowserRouter> | ||
<section className="outer-container"> | ||
<div className="inner-container"> | ||
<Routes> | ||
{/* path to a single component */} | ||
<Route path="/" element={<ListMovies listMovies={listMovies} />} /> | ||
<Route path="/details/:id" element={<Details />} /> | ||
<Route path="/404" element={<NotFound />} /> | ||
<Route path="*" element={<Navigate to="/404" />} /> | ||
</Routes> | ||
</div> | ||
{/* wrapper for every component that need to be linked to */} | ||
</section> | ||
</BrowserRouter> | ||
); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
/* eslint-disable react/jsx-max-props-per-line */ | ||
/* eslint-disable react/jsx-indent-props */ | ||
/* eslint-disable react/jsx-first-prop-new-line */ | ||
/* eslint-disable react/jsx-closing-tag-location */ | ||
/* eslint-disable max-len */ | ||
import React, { useEffect, useState } from 'react'; | ||
import { useParams } from 'react-router-dom'; | ||
import '../details.css'; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good job with making separate css-files! |
||
|
||
// Define the Details component | ||
const Details = () => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We noticed that when refreshing your details page, we get the Netlify error page. We have the same problem and do not know why this happens. If you find the problem, please let us know. |
||
// Get the id parameter from the URL using the useParams hook | ||
const { id } = useParams(); | ||
// Define state for the movie details, initialized as an empty object | ||
const [movieDetail, setMovieDetail] = useState({}); | ||
|
||
useEffect(() => { | ||
fetch(`https://api.themoviedb.org/3/movie/${id}?api_key=39168ef639d8a2d49b6d7a9893ad1b8c&language=en-US`) | ||
.then((data) => data.json()) | ||
.then((configuredData) => setMovieDetail(configuredData)) | ||
}, [id]); | ||
|
||
return ( | ||
<div className="backdrop-overlay"> | ||
{/* The ternary operator checks if the image paths property of the movieDetail object is truthy (i.e., not undefined, null, 0, false, etc.). If it is truthy, it | ||
sets the src attribute of the imgtag to the URL of the image file. If it is falsy, it sets the src` attribute to an empty string. */} | ||
<img className="backdrop" src={movieDetail.backdrop_path ? `https://image.tmdb.org/t/p/w1280${movieDetail.backdrop_path}` : ''} alt={`Movie backdrop for"${movieDetail.title}`} /> | ||
<a className="goBackBtn" href="/"><svg className="goback-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 30 30"><path d="M27 14.5C27 7.596441 21.4035594 2 14.5 2S2 7.596441 2 14.5 7.5964406 27 14.5 27 27 21.403559 27 14.5zm-19.3388348-.353553l7.4852814-7.485282c.1952622-.195262.5118446-.195262.7071068 0l2.1213203 2.121321c.1952622.195262.1952622.511844 0 .707106L12.9644661 14.5l5.0104076 5.010408c.1952622.195262.1952622.511844 0 .707106l-2.1213203 2.121321c-.1952622.195262-.5118446.195262-.7071068 0l-7.4852814-7.485282c-.19799-.19799-.197989-.509117 0-.707106z" fill="#fff" fillRule="evenodd" /></svg><span className="backBtnName">Movies</span></a> | ||
<div className="movie-details-container"> | ||
<div className="poster-rating-container"> | ||
<img className="poster" src={movieDetail.poster_path ? `https://image.tmdb.org/t/p/w342/${movieDetail.poster_path}` : ''} alt={`Movie poster for" ${movieDetail.title}`} /> | ||
<div className="title-rating-text"> | ||
<h1 className="title-rating-container"> | ||
<span className="title-details title-details-margin">{movieDetail.title}</span> | ||
<span className="rating">⭐{Math.round(movieDetail.vote_average * 10) / 10}</span> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If you would have wanted to have the rating as out of 10, you could add the text /10 after the last curly bracket and before the closing bracket. |
||
</h1> | ||
<p className="movie-description">{movieDetail.overview}</p> | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
); | ||
}; | ||
|
||
export default Details; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import React from 'react'; | ||
import { NavLink } from 'react-router-dom'; | ||
import GitIcon from '../assets/github.png'; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Another way of solving this if you would like more social media icons is to import Font Awesome icons (like we did but we put it in the footer). We wanted to post code but for some reason it does not display in the comment? To make the icons show one also has to import them in the top of the component. If you would like to know more then we can discuss it on the Monday session! |
||
import MovieIcon from '../assets/movie.png'; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Super cute icon! We're stealing the idea! |
||
import '../header.css'; | ||
|
||
const Header = () => { | ||
return ( | ||
<header className="header"> | ||
<nav className="header-items-container"> | ||
<div className="welcome"> | ||
<h2 className="text-welcome"> <NavLink to="/">Welcome to the Movies Page!</NavLink></h2> | ||
<a href="https://pngtree.com/element/down?id=NTc2Njc2OQ==&type=1&time=1680214203&token=Y2E0NGQ2NmI1MjNjOTAxN2ZjYTU5N2Q4ZDkyMTQwMzA="><img src={MovieIcon} className="icon-popcorn" alt="Popcorn icon" /></a> | ||
</div> | ||
<div className="authors"> | ||
<h2 className="text-welcome">Authors:</h2> | ||
<ul> | ||
<li><a href="https://github.com/smirrebinx"><img src={GitIcon} className="icon-contact" alt="Github icon" /></a> </li> | ||
<li><a href="https://github.com/majazimnoch"><img src={GitIcon} className="icon-contact" alt="Github icon" /></a></li> | ||
</ul> | ||
</div> | ||
</nav> | ||
</header>) | ||
} | ||
|
||
export default Header; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import React from 'react'; | ||
import { Link } from 'react-router-dom'; | ||
import moment from 'moment'; | ||
import '../listmovies.css'; | ||
import Header from './Header'; | ||
|
||
const ListMovies = ({ listMovies }) => { | ||
return ( | ||
<> | ||
<Header /> | ||
<div className="movies-list"> | ||
{listMovies.map((movie) => { | ||
return ( | ||
<Link | ||
key={movie.id} | ||
to={`/details/${movie.id}`} | ||
className="single-movie"> | ||
<img className="cover-image" src={movie.poster_path ? `https://image.tmdb.org/t/p/w342${movie.poster_path}` : ''} alt="poster" /> | ||
<div className="hover-container"> | ||
<h1 className="text-hover">{movie.original_title}</h1> | ||
<p className="text-hover">Released: {moment(movie.release_date).format('D MMMM YYYY')}</p> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nice way of showing the release date! |
||
</div> | ||
</Link> | ||
) | ||
})} | ||
</div> | ||
</> | ||
) | ||
} | ||
|
||
export default ListMovies; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import React from 'react'; | ||
import { useNavigate } from 'react-router-dom'; | ||
|
||
const NotFound = () => { | ||
const navigate = useNavigate(); | ||
const onGoToHomeButtonClick = () => { | ||
navigate('/'); | ||
} | ||
|
||
const onGoBackButtonClick = () => { | ||
navigate(-1); | ||
} | ||
return ( | ||
<div> | ||
<h2> Sorry, nothing here :( </h2> | ||
<button type="button" onClick={onGoToHomeButtonClick}>Go to Home</button> | ||
<button type="button" onClick={onGoBackButtonClick}>Go back</button> | ||
</div>) | ||
} | ||
|
||
export default NotFound; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice way of solving the url!