diff --git a/movie-project/oop-movie/.vscode/settings.json b/movie-project/oop-movie/.vscode/settings.json
new file mode 100644
index 0000000..1b6b18f
--- /dev/null
+++ b/movie-project/oop-movie/.vscode/settings.json
@@ -0,0 +1,4 @@
+{
+ "liveServer.settings.port": 5501,
+ "liveshare.autoShareTerminals": false
+}
\ No newline at end of file
diff --git a/movie-project/oop-movie/README.md b/movie-project/oop-movie/README.md
new file mode 100644
index 0000000..1b254dd
--- /dev/null
+++ b/movie-project/oop-movie/README.md
@@ -0,0 +1,115 @@
+# Movie Project
+This is a movie database project, where it shows movies, their casts, ratings, trailers, related movies, genres, and so on.
+
+This project uses The Movie DB API: `https://api.themoviedb.org/`. It is up to
+you to use your Google and Postman skills to explore the API and understand the
+data.
+
+Documentation : 'https://developers.themoviedb.org/3/getting-started/introduction'
+
+# Already built for you
+- A home page that shows popular movies
+- When you click one of the movies, you'll see the Single Movie page, which includes:
+ - Movie poster
+ - Movie title
+ - Movie release date
+ - Movie runtime
+ - Movie description
+ - An empty cast section
+
+# What you and your partner will build
+
+## Homepage
+
+### Navbar
+Add a universal navbar (it appears on every page) to the home page that includes
+buttons that go to the following pages:
+
+
+- DONE Home button, takes you to the home page
+- DONE Movies button that has a dropdown list to show different movie genres. For
+ example: Action (28), Sci-Fi (878), Comedy (35), Drama (18), Horror (27), Animation (16)...etc, When you click one of them it should
+ load the movies for that genre.
+ (Implement API to get all genres if you have time for it. Genre List: https://api.themoviedb.org/3/genre/movie/list?api_key=ecfdd3d5230c96c392fc9421937894a9&language=en-US
+ Pass the genre id to the discover API
+ Get movies by genre https://developers.themoviedb.org/3/discover/movie-discover, with_genres)
+- DONE Actor list page
+- DONE About page that has a description of the website
+- DONE Search box where you can type the movie or actor name and display the
+related results. ( https://api.themoviedb.org/3/search/movie?api_key=ecfdd3d5230c96c392fc9421937894a9&query=fight&include_adult=false, https://api.themoviedb.org/3/search/person?api_key=ecfdd3d5230c96c392fc9421937894a9&query=edward&include_adult=false, use the input with movie and actor search, NOT MULTI SEARCH!)
+- DONE A filter dropdown to filter the displayed movies in the home page, based
+on (popular, top rated, now playing and up coming) (https://developers.themoviedb.org/3/movies/get-movie-details,
+https://api.themoviedb.org/3/movie/popular?api_key=ecfdd3d5230c96c392fc9421937894a9,
+https://api.themoviedb.org/3/movie/top_rated?api_key=ecfdd3d5230c96c392fc9421937894a9,
+https://api.themoviedb.org/3/movie/now_playing?api_key=ecfdd3d5230c96c392fc9421937894a9,
+https://api.themoviedb.org/3/movie/upcoming?api_key=ecfdd3d5230c96c392fc9421937894a9)
+
+### Footer
+Add a universal footer that includes:
+
+- DONE Credit to you and your partner for building the website,
+- DONE You and your partner's github link inside an icon and optionally, your social
+ media links
+
+### DONE Styling
+
+- DONE Make it so that hovering over the movie makes the mouse pointer icon seem
+ clickable. Right now, if you are about to click a movie, it's not obvious that
+ it's clickable.
+
+## Movies List Page
+
+### DONE Styling
+
+- DONE Using CSS and Bootstrap, display the page as a grid with 3 columns (3 movies
+ in the same row)
+- DONE Make it responsive where it displays 2 columns for tablets and 1 column for
+ phones
+- Style the rest of the page however you like.
+- DONE Add the rating and genres to the movies in the home page and a description
+ when you hover over one of them (https://api.themoviedb.org/3/movie/550?api_key=ecfdd3d5230c96c392fc9421937894a9, genres, overview)
+
+## STYLE IT Single Movie Page
+We build part of the single movie page for you, but the information isn't
+totally complete, a few more features are needed:
+
+- DONE The main 5 actors of the movies in the credit section (https://developers.themoviedb.org/3/movies/get-movie-credits, cast[0-4].name)
+- DONE The movie language (spoken_languages in API, loop through them like genres)
+- DONE A related movies section which includes at least five related movies (https://developers.themoviedb.org/3/movies/get-movie-recommendations)
+- DONE A trailer section that has the movie trailer from youtube (https://api.themoviedb.org/3/movie/550/videos?api_key=ecfdd3d5230c96c392fc9421937894a9)
+- DONE The movie production company name and logo (https://api.themoviedb.org/3/movie/550?api_key=ecfdd3d5230c96c392fc9421937894a9 ,production companies)
+- DONE The director name (https://developers.themoviedb.org/3/movies/get-movie-credits, crew[i].job == "director", return crew[i].name)
+- DONE The movie rating and how many votes has it received (https://api.themoviedb.org/3/movie/550?api_key=ecfdd3d5230c96c392fc9421937894a9 voteAverage,voteCount)
+
+### DONE Functionality
+- DONE Clicking an actor in the main actors should go to the single actor page. (Eventlisteners for actors just like eventlisteners for movies in homepage)
+
+### DONE Other requirements
+- DONE There's an issue with duplication (undefined in the movie page) in the movie page that has to be fixed (and
+ you need to open the site and read the code to fix it)
+- Style the page however you like
+
+## STYLE IT Actor List Page
+-DONE Displays a list of actors styles in the same way as the movies list page, but
+with the actor photo and the actor name. Clicking any actor should go to the
+Single Actor Page. CSS should most certainly be reused here! (https://developers.themoviedb.org/3/people/get-popular-people, can check for known_for_department "Acting" to be sure to get only actors later on)
+
+## STYLE IT Single Actor Page
+This page can be reached by clicking on an actor in the actors list page or the
+credits in the single movie page.
+
+### DONE Data Display
+- DONE The actor name (https://api.themoviedb.org/3/person/819?api_key=ecfdd3d5230c96c392fc9421937894a9&language=en-US)
+- DONE The actor gender (gender, 1:Female, 2:Male)
+- DONE A picture of the actor (profile_path)
+- DONE The actor popularity (popularity)
+- DONE The birthday of the actor and (if available) death day (birthday and if(deathday != null) deathday)
+- DONE A biography about the actor (biography)
+- DONE A list of movies the actor participated in (https://api.themoviedb.org/3/person/819/movie_credits?api_key=ecfdd3d5230c96c392fc9421937894a9&language=en-US, first 6 for cast and crew roles)
+
+## Bonus
+If you finish early you can work on the same functionalities, but for TV shows.
+Your code should be completely reusable (e.g., don't just copy paste a second
+copy of the files).
+
+## Testing
diff --git a/movie-project/oop-movie/index.html b/movie-project/oop-movie/index.html
new file mode 100644
index 0000000..d2da049
--- /dev/null
+++ b/movie-project/oop-movie/index.html
@@ -0,0 +1,131 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Movie
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/movie-project/oop-movie/logos/600px-GitHub_logo_2013.svg.png b/movie-project/oop-movie/logos/600px-GitHub_logo_2013.svg.png
new file mode 100644
index 0000000..947168e
Binary files /dev/null and b/movie-project/oop-movie/logos/600px-GitHub_logo_2013.svg.png differ
diff --git a/movie-project/oop-movie/logos/linkedin.svg b/movie-project/oop-movie/logos/linkedin.svg
new file mode 100644
index 0000000..4013ac6
--- /dev/null
+++ b/movie-project/oop-movie/logos/linkedin.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/movie-project/oop-movie/oop-script.js b/movie-project/oop-movie/oop-script.js
new file mode 100644
index 0000000..c119e21
--- /dev/null
+++ b/movie-project/oop-movie/oop-script.js
@@ -0,0 +1,565 @@
+//the API documentation site https://developers.themoviedb.org/3/
+const container = document.getElementById('container');
+
+class App {
+ static async run(input) {
+ //At initialization, fetches now playing movies *else statement* and displays them in the homepage, also gets movies by filter or genres from the navbar to display in the homepage
+ let movies
+ if (typeof input === "number") { movies = await APIService.fetchMoviesByGenre(input) }
+ else { movies = await APIService.fetchMovies(input) }
+ HomePage.renderMovies(movies);
+ };
+};
+
+class APIService {
+ static TMDB_BASE_URL = 'https://api.themoviedb.org/3';
+ //Creates the url to look up
+ static _constructUrl(path) {
+ return `${this.TMDB_BASE_URL}/${path}?api_key=${atob('NTQyMDAzOTE4NzY5ZGY1MDA4M2ExM2M0MTViYmM2MDI=')}`;
+ };
+
+ //returns movie objects (now playing, popular, top rated, upcoming )
+ static async fetchMovies(property) {
+ const url = APIService._constructUrl(`movie/${property}`)
+ const data = await (await fetch(url)).json()
+ //results is the array that has the movies as objects inside
+ return data.results.map(movie => new Movie(movie))
+ };
+
+ //returns single movie object
+ static async fetchMovie(movieId) {
+ const url = APIService._constructUrl(`movie/${movieId}`)
+ const data = await (await fetch(url)).json()
+ return new Movie(data)
+ };
+
+ //returns actor objects for any given movie id
+ static async fetchActors(movieId) {
+ const url = APIService._constructUrl(`movie/${movieId}/credits`);
+ const data = await (await fetch(url)).json();
+ return new CastCrew(data);
+ };
+
+ //returns related (recommended) movie objects for any given movie id
+ static async fetchRelatedMovie(movieId) {
+ const url = APIService._constructUrl(`movie/${movieId}/recommendations`);
+ const data = await (await fetch(url)).json();
+ return new RelatedMovies(data);
+ };
+
+ //returns trailer object for any given movie id
+ static async fetchTrailer(movieId) {
+ const url = APIService._constructUrl(`movie/${movieId}/videos`);
+ const data = await (await fetch(url)).json();
+ return new Trailer(data);
+ };
+
+ //returns actor details for single actor page for any actor id
+ static async fetchSingleActor(personId) {
+ const url = APIService._constructUrl(`person/${personId}`);
+ const data = await (await fetch(url)).json();
+ return new SingleActor(data);
+ }
+
+ //returns the movie credits for a person id
+ static async fetchMovieCreditsForActor(personId) {
+ const url = APIService._constructUrl(`person/${personId}/movie_credits`);
+ const data = await (await fetch(url)).json();
+ return new MovieCredits(data);
+ }
+
+ //returns movies for any genre id
+ static async fetchMoviesByGenre(genreId) {
+ const data = await (await fetch(`https://api.themoviedb.org/3/discover/movie?api_key=ecfdd3d5230c96c392fc9421937894a9&include_adult=false&with_genres=${genreId}`)).json();
+ //results is the array that has the movies as objects inside
+ return data.results.map(movie => new Movie(movie))
+ }
+
+ //returns popular actors to display on the actor list page
+ static async fetchPopularActors() {
+ const data = await (await fetch(`https://api.themoviedb.org/3/person/popular?api_key=ecfdd3d5230c96c392fc9421937894a9&language=en-US&page=1`)).json();
+ //results is the array that has the people as objects inside
+ return data.results.map(person => new SingleActor(person))
+ }
+
+ //returns actor results for search
+ static async fetchActorSearchResults (search) {
+ const personSearchResults = await (await fetch(`https://api.themoviedb.org/3/search/person?api_key=ecfdd3d5230c96c392fc9421937894a9&query=${search}&include_adult=false`)).json()
+ //results is the array that has the people as objects inside
+ return personSearchResults.results.map(person => new SingleActor(person))
+ }
+
+ //returns movie results for search
+ static async fetchMovieSearchResults (search) {
+ const movieSearchResults = await (await fetch(`https://api.themoviedb.org/3/search/movie?api_key=ecfdd3d5230c96c392fc9421937894a9&query=${search}&include_adult=false`)).json()
+ //results is the array that has the movies as objects inside
+ return movieSearchResults.results.map(movie => new Movie(movie))
+ }
+
+ static async fetchCompanies (companyId) {
+ const url = APIService._constructUrl(`/company/${companyId}`);
+ const data = await (await fetch(url)).json();
+ return new Company(data);
+ }
+};
+
+class HomePage {
+ //displays returned movie objects in the home page
+ static renderMovies(movies) {
+
+ //Empty the container div if it has something in it
+ if (container.innerText !== "") {
+ container.innerText = "";
+ }
+
+ const div = document.createElement("div");
+ div.setAttribute("class", "homePageMovies row g-3 p-3");
+ // div.setAttribute("style", "font-family: Poppins;");
+
+ const moviesContainer = container.appendChild(div);
+
+ movies.forEach(movie => {
+ //creates single movie divisions for the home page for each movie
+ const movieDiv = document.createElement("div");
+ movieDiv.setAttribute("class", "col-md-4 col-sm-6")
+ const movieImage = document.createElement("img");
+ movieImage.setAttribute("class", "img-fluid homePageMovieImg");
+ movieImage.setAttribute("title", `${movie.overview}`)
+ movieImage.src = `${movie.backdropUrl}`;
+
+ const movieTitle = document.createElement("h3");
+ movieTitle.textContent = `${movie.title.toUpperCase()}`;
+ movieTitle.setAttribute("class", "movie-title text-center");
+
+ movieImage.addEventListener("click", function () {
+ Movies.run(movie); //calls Movies.run with the movie parameter from movies.forEach(movie)
+ });
+
+ movieDiv.appendChild(movieImage);
+ movieDiv.appendChild(movieTitle);
+ moviesContainer.appendChild(movieDiv);
+ })
+ }
+}
+
+class Movies {
+ static async runFromID (movieId) {
+ const movie = await APIService.fetchMovie(movieId)
+ Movies.run(movie)
+ }
+
+ static async run(movie) {
+ //gets the movie info from "Movies.run(movie)" and passes it into fetch to get that movie's info
+ const movieData = await APIService.fetchMovie(movie.id)
+ const castCrew = await APIService.fetchActors(movie.id)
+ const relatedMovies = await APIService.fetchRelatedMovie(movie.id)
+ const trailer = await APIService.fetchTrailer(movie.id)
+
+ MoviePage.renderMovieSection(movieData, castCrew, relatedMovies, trailer);
+ };
+};
+
+//Classes for pages start here
+class MoviePage {
+ static renderMovieSection(movie, castCrew, relatedMovies, trailer) {
+ MovieSection.renderMovie(movie);
+ MovieSection.renderCastCrew(castCrew);
+ MovieSection.renderRelatedMovies(relatedMovies);
+ MovieSection.renderTrailer(trailer);
+ };
+};
+
+class MovieSection {
+ static renderMovie(movie) {
+
+ //Loop through genres and create a html string to display
+ const genres = movie.genres.map(genre => genre.name).join(", ")
+
+ //Loop through languages and create a html string to display
+ const languages = movie.spokenLanguages.map(language => language.name).join(", ")
+
+ //Loop through production companies and create a html string to display
+ const production = movie.productionCompanies.map(company => `
+
`
+ }
+
+ static renderCastCrew(castCrew) {
+ const castCrewDiv = document.querySelector('#castCrew-wrapper')
+ castCrew.director.name = castCrew.director.name + ", Director"
+ castCrew.actors.unshift(castCrew.director)
+
+ //Loop through director and actors and create a html string including their names and photos, onclick image, call renderActorPage with the actor's id
+ const directorAndActors = castCrew.actors.map(actor => `
+
+
+
${actor.name}
+
`).join(" ")
+
+ castCrewDiv.innerHTML = `
+
Director and Actors:
+
+ ${directorAndActors}
+
`
+ }
+
+ static renderRelatedMovies(relatedMovies) {
+ const relatedMoviesDiv = document.querySelector('#related-movies')
+
+ //Loop through related movies and create a html string to display
+ const recommendations = relatedMovies.movies.map(movie => `
+
+
+
${movie.title}
+
`).join(" ")
+ relatedMoviesDiv.innerHTML = recommendations
+ }
+
+ //Displays the trailer from youtube in the trailer section of single movie page, takes trailer class instance as a parameter
+ static renderTrailer(trailer) {
+ const trailerDiv = document.querySelector('.trailerDiv');
+ trailerDiv.innerHTML = `
+
Trailer
+
+
+
+ `
+ }
+};
+
+class ActorListPage {
+ static async run() {
+
+ //Empty the container div if it has something in it
+ if (container.innerText !== "") {
+ container.innerText = "";
+ }
+
+ //gets popular actors from API and returns an array of actor objects
+ const actorData = await APIService.fetchPopularActors()
+ ActorListPage.renderActors(actorData)
+ }
+ static renderActors(actors) {
+ const div = document.createElement("div");
+ div.setAttribute("class", "actorListPageActors row p-4");
+ const actorsContainer = container.appendChild(div);
+
+ actors.forEach(actor => {
+ //creates single movie divisions for the home page for each movie
+ const actorDiv = document.createElement("div");
+ actorDiv.setAttribute("class", "actorListPageActor col-lg-2 col-md-3 col-sm-4 col-6")
+ const actorImage = document.createElement("img");
+ actorImage.setAttribute("class", "img-fluid actorListPageImg");
+ actorImage.src = `${actor.actorsProfileUrl()}`;
+
+ const actorTitle = document.createElement("h3");
+ actorTitle.textContent = `${actor.name.toUpperCase()}`;
+ actorTitle.setAttribute("class", "actor-name text-center");
+
+ actorImage.addEventListener("click", function () {
+ ActorPage.run(actor.id); //calls ActorPage.run with the id parameter from actor.forEach(actor)
+ });
+
+ actorDiv.appendChild(actorImage);
+ actorDiv.appendChild(actorTitle);
+ actorsContainer.appendChild(actorDiv);
+ })
+ }
+}
+
+class ActorPage {
+ static async run(personId) {
+ const actorData = await APIService.fetchSingleActor(personId)
+ const movieCredits = await APIService.fetchMovieCreditsForActor(personId)
+
+ ActorPage.renderActorPage(actorData, movieCredits)
+ }
+ static renderActorPage(actorData, movieCredits) {
+ //A function to create the string of the birthday and deathday if the actor is deceased, otherwise only birthday, none if no info
+ const birthAndDeathday = actorData => {
+ if (actorData.birthday != null) {
+ if (actorData.deathday != null) { return `Birthday: ${actorData.birthday} Deathday: ${actorData.deathday}` }
+ else { return `Birthday: ${actorData.birthday}` }
+ }
+ else return ``
+ }
+
+ //A function to create the string for the gender of the actor
+ const gender = actorData => actorData.gender == 1 ? "Female" : "Male";
+
+ //Loop through movies played in and create a html string to display
+ const moviesCast = movieCredits.moviesInCast.map(movie => `
+
+
+
${movie.title} as ${movie.character}
+
`).join(" ")
+
+ //Loop through movies worked in and create a html string to display
+ const moviesCrew = movieCredits.moviesInCrew.map(movie => `
+
+
+
${movie.title} as ${movie.job}
+
`).join(" ")
+
+ container.innerHTML = `
+
+
+
+
+
+
${actorData.name}
+
Gender: ${gender(actorData)}
+
Popularity: ${actorData.popularity}
+
${birthAndDeathday(actorData)}
+
Biography:
+
${actorData.biography}
+
}
+
+
+
Movies In Cast
+
+ ${moviesCast}
+
+
+
+
Movies In Crew
+
+ ${moviesCrew}
+
+
`
+ };
+};
+
+class SearchPage {
+ static async renderSearchResults(search) {
+ const movieSearchResults = await APIService.fetchMovieSearchResults(search)
+ const personSearchResults = await APIService.fetchActorSearchResults(search)
+
+ let movies, people
+ if (movieSearchResults.length === 0) { movies = "
Unfortunately, no such movies found.
" }
+
+ //Loop through movie search results and create a html string to display
+ else {movies = movieSearchResults.map(movie => `
+
+
+
${movie.title}
+
`).join(" ");}
+
+ if (personSearchResults.length === 0) { people = "
Unfortunately, no such people found.
"}
+
+ //Loop through person search results and create a html string to display
+ else {people = personSearchResults.map(person => `
+