Skip to content
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,4 @@ dist-ssr
*.njsproj
*.sln
*.sw?
.env
20 changes: 17 additions & 3 deletions src/App.css
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,25 @@
.App-header {
background-color: #282c34;
display: flex;
flex-direction: row;
flex-direction: column;
align-items: center;
justify-content: space-evenly;
justify-content: center;
color: white;
padding: 20px;

}

.title {
display: flex;
align-items: center;
height: 100px;
}

.title h1 {
font-size: 50px;
}

.title img {
height: 60px;
}

@media (max-width: 600px) {
Expand Down
14 changes: 12 additions & 2 deletions src/App.jsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,20 @@
import { useState } from 'react'
import './App.css'
import MovieList from "./MovieList"
import "../public/movie.png"

const App = () => {
return (
<div className="App">

<header className='App-header'>
<div className='title'>
<h1>Flixster</h1>
<img src="../public/movie.png" alt="" />
</div>

</header>
<MovieList />
</div>
);
}

export default App
45 changes: 45 additions & 0 deletions src/MovieCard.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
.card {
display: flex;
flex-direction: column;
width: 200px;
height: 375px;
border: solid black;
background-color: white;
margin: 10px;
box-shadow: 12px 12px 2px 1px rgba(0, 0, 0, 0.582);
position: relative;
top: 0;
transition: top ease 0.5s;
}
.card:hover {
top: -15px;
cursor: pointer;
}

.img-container {
width: 100%;
height: 80%;
background-color: #ccc;
overflow: contain;
}

.img-container img {
width: 100%;
height: 100%;
object-fit: contain;
}

.txt-container {
text-align: center;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
height: 20%;

}

.txt-container h2, .txt-container p {
font-size: 15px;
margin: 0%;
}
16 changes: 16 additions & 0 deletions src/MovieCard.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import "./MovieCard.css";
const MovieCard = ({key, poster, title, rating}) => {

return(//using info from MovieList to create element
<div className="card">
<div className="img-container">
<img src={poster} alt="Movie Poster" />
</div>
<div className="txt-container">
<h2>{title}</h2>
<p>{rating}</p>
</div>
</div>
);
}
export default MovieCard;
16 changes: 16 additions & 0 deletions src/MovieList.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
.movie-row {
display: flex;
flex-wrap: wrap;
justify-content: space-between; /* Center cards horizontally */
padding: 20px;
width: 75%;
margin: 0 auto;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minor: use format to eliminate empty lines.


}

.load-btn {
width: 100%;
float: left;
margin-top: 30px;
}
97 changes: 97 additions & 0 deletions src/MovieList.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import { useState, useEffect } from "react";
import MovieCard from "./MovieCard";
import "./MovieList.css";

// Purpose: Create card elements from API info
const MovieList = () => {
const [data, setData] = useState([]);
const [page, updatePage] = useState(1);
const [searchText, updateSearchText] = useState("");

const searchMovies = () => {
updatePage(1);
setData([]);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might not need this as data is being set in the fetchData function anyway

fetchData();
};

const resetPage = () => {
console.log("resetPage");

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove console

updatePage(
// make sure that fetch data runs after updating prevPage
(prevPage) => prevPage + 1,
() => {
fetchData();
}
);
};

const options = {
method: "GET",
headers: {
accept: "application/json",
Authorization: `Bearer ${import.meta.env.VITE_TOKEN}`, //private token used to access api
},
};

const fetchData = async () => {
if (searchText === "") {
const resp = await fetch(
`https://api.themoviedb.org/3/movie/now_playing?language=en-US&page=${page}`,
options
); //fills link
const Data = await resp.json();

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

name it data or moviesList instead?

if (page === 1) {
setData([...Data.results]);
} else {
setData((prevData) => [...prevData, ...Data.results]); //appends results to end
}
console.log("prev", Data.results);
} else {
const resp = await fetch(
`https://api.themoviedb.org/3/search/movie?query=${searchText}&include_adult=false&language=en-US&page=${page}`,
options
);
const Data = await resp.json();
if (page === 1) {
setData([...Data.results]);
} else {
setData((prevData) => [...prevData, ...Data.results]); //appends results to end
}
}
};
useEffect(() => {
fetchData();
}, [page]); //adds to update for every new page

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can probably remove page from this dependency array, as we are calling API once page is changed.


return (
//creates movie card element
<>
<div>
<input
type="text"
onChange={(e) => updateSearchText(e.target.value)}
value={searchText}
/>
<button onClick={searchMovies}>Search</button>
</div>
<div className="movie-row">
{data.length > 0 ? (
data.map((movie) => (
<MovieCard
key={movie.id}
title={movie.title}
poster={`https://image.tmdb.org/t/p/original${movie.poster_path}`}
rating={Math.round(movie.vote_average * 100) / 100} //get two decimal points
/>
))
) : (
<p>Loading movies...</p> //error handle if data length == 0

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can probably say "No Movies found instead"

)}
<button className="load-btn" onClick={resetPage}>
Show More
</button>
</div>
</>
);
};
export default MovieList;
2 changes: 1 addition & 1 deletion src/index.css
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
body {
margin: 0;
font-family: Arial, sans-serif;
background-color: #f4f4f4;
background-color: white;
}

button {
Expand Down