diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 00000000..8e452fbc Binary files /dev/null and b/.DS_Store differ diff --git a/README.md b/README.md index 49093dd2..4409a02d 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -# Project Cinema +# Project Cinema by Mariusz Sygnowski -We want to create a movie search engine. To power it we will use the [Open Movie Database](http://www.omdbapi.com) API. +[Click here](https://mariuszsygnowski.github.io/project-cinema/) to see live version. To start using the OMDB API you will first need to sign up with them to receive and API key. The key issued to you will allow you 1000 requests per day and you will need to include this key as part of every request. diff --git a/images/noPoster.jpg b/images/noPoster.jpg new file mode 100644 index 00000000..f4be8721 Binary files /dev/null and b/images/noPoster.jpg differ diff --git a/index.html b/index.html new file mode 100644 index 00000000..05996646 --- /dev/null +++ b/index.html @@ -0,0 +1,36 @@ + + + + + + + + Project Cinema by Mariusz Sygnowski + + + +
+
+ +
+ +
+ +

+
+ +
+

+ +
+ +
+ + + + + \ No newline at end of file diff --git a/js/app.js b/js/app.js new file mode 100644 index 00000000..aa104fc0 --- /dev/null +++ b/js/app.js @@ -0,0 +1,125 @@ +const form = document.querySelector('#control__search'), + searchInput = document.querySelector('.control__search__input'), + results = document.querySelector('.results'), + buttonsClass = document.querySelector('.buttons'), + currentPageClasses = document.querySelectorAll('.currentPage'), + nextBtn = document.querySelector('.buttons__button-next'), + prevBtn = document.querySelector('.buttons__button-prev'); + +let params = { + inputValue: searchInput.value, + pageNumber: 2, + totalPages: 0, + imdbID: '', + apiKey: 'f899a3c1' +}; + +form.addEventListener('submit', (e) => { + e.preventDefault(); + buttonsClass.style.display = 'none'; + results.innerHTML = ''; + params.pageNumber = 1; + params.totalPages = 0; + params.inputValue = searchInput.value; + runFetch(); +}); + +nextBtn.addEventListener('click', (e) => { + e.preventDefault(); + results.innerHTML = ''; + buttonsClass.style.display = 'none'; + if (params.pageNumber === params.totalPages) { + params.pageNumber = 1; + } else { + params.pageNumber++; + } + + runFetch(); +}); + +prevBtn.addEventListener('click', (e) => { + e.preventDefault(); + results.innerHTML = ''; + buttonsClass.style.display = 'none'; + if (params.pageNumber === 1) { + params.pageNumber = params.totalPages; + } else { + params.pageNumber--; + } + runFetch(); + +}); + +function setUrlWithTypedSearch() { + return `https://www.omdbapi.com/?&plot=full&apikey=${params.apiKey}&s=${params.inputValue}&page=${params.pageNumber}`; +} + +function setUrlForEachMovieWithImdbIDNumber() { //I need imdbID to get full details of every found movie + return `https://www.omdbapi.com/?i=${params.imdbID}&plot=full&apikey=${params.apiKey}&page=${params.pageNumber}`; +} + +function runFetch() { + fetch(setUrlWithTypedSearch()) + .then((response) => { + return response.json(); + }) + .then((body) => { + params.totalPages = body.totalResults / 10; //divide by as as there is 10 results per page + params.totalPages = Math.ceil(params.totalPages); //round up as I want to have all possible number of pages + currentPageClasses.forEach((currentPageClass) => { + currentPageClass.textContent = `page ${params.pageNumber} / ${params.totalPages}`; + }); + body.Search.forEach(e => { + params.imdbID = e.imdbID; + fetch(setUrlForEachMovieWithImdbIDNumber()) + .then((response) => { + return response.json(); + }) + .then((body) => { + // console.log(body); + buttonsClass.style.display = 'block'; + let movieParams = { + description: body.Plot, + poster: body.Poster, + title: body.Title, + year: body.Year, + actors: body.Actors + }; + + let searchResult = document.createElement('div'); + searchResult.className = 'results__searchResult'; + + if (movieParams.poster === 'N/A') { //if there is no poster then I use default image + movieParams.poster = 'images/noPoster.jpg'; + } + if (movieParams.description === 'N/A') { //if there is no description I set + movieParams.description = ''; + } + + searchResult.innerHTML = ` +

${movieParams.title}

+ +

(${movieParams.year})

+

Actors: ${movieParams.actors}

+

${movieParams.description}

+ `; + const posterImg = searchResult.querySelector('.results__searchResult__poster'); + const description = searchResult.querySelector('.results__searchResult__description'); + const year = searchResult.querySelector('.results__searchResult__year'); + const actors = searchResult.querySelector('.results__searchResult__actors'); + searchResult.addEventListener('click', () => { + // console.log(posterImg); + description.classList.toggle('hide'); + year.classList.toggle('hide'); + posterImg.classList.toggle('hide'); + actors.classList.toggle('hide'); + }); + results.append(searchResult); + }) + }); + }) + .catch((error) => { + console.log('Server failed to return data: ' + error); + }); +} + diff --git a/style.css b/style.css new file mode 100644 index 00000000..ec943828 --- /dev/null +++ b/style.css @@ -0,0 +1,268 @@ +*, +*:before, +*:after { + box-sizing: inherit; +} + +html { + box-sizing: border-box; +} + +body { + font-family: 'FF Meta VF', Helvetica, Arial, sans-serif; + background-color: #232f3e; + padding: 0; + margin: 0; +} + +.container { + display: grid; + grid-auto-rows: min-content 1fr; + width: 100vw; + margin: 0 auto; + padding: 0 0.7rem; +} + +.control { + font-family: 'Open Sans', sans-serif; +} + +/* search box*/ + +#control__search { + background: #e1e1e1; /* Fallback color for non-css3 browsers */ + width: 100%; + margin: 3rem 0 0 0; + display: grid; + grid-template-columns: 1fr min-content; + + /* Gradients */ + background: -webkit-gradient(linear, left top, left bottom, color-stop(0, rgb(243, 243, 243)), color-stop(1, rgb(225, 225, 225))); + background: -moz-linear-gradient(center top, rgb(243, 243, 243) 0%, rgb(225, 225, 225) 100%); + + /* Rounded Corners */ + border-radius: 17px; + -webkit-border-radius: 17px; + -moz-border-radius: 17px; + + /* Shadows */ + box-shadow: 1px 1px 2px rgba(0, 0, 0, .3), 0 0 2px rgba(0, 0, 0, .3); + -webkit-box-shadow: 1px 1px 2px rgba(0, 0, 0, .3), 0 0 2px rgba(0, 0, 0, .3); + -moz-box-shadow: 1px 1px 2px rgba(0, 0, 0, .3), 0 0 2px rgba(0, 0, 0, .3); +} + +/*** TEXT BOX ***/ +.control__search__input { + background: #fafafa; /* Fallback color for non-css3 browsers */ + + /* Gradients */ + background: -webkit-gradient(linear, left bottom, left top, color-stop(0, rgb(250, 250, 250)), color-stop(1, rgb(230, 230, 230))); + background: -moz-linear-gradient(center top, rgb(250, 250, 250) 0%, rgb(230, 230, 230) 100%); + border: 0; + border-bottom: 1px solid #fff; + border-right: 1px solid rgba(255, 255, 255, .8); + font-size: 1rem; + margin: 0.2rem; + padding-left: 1rem; + + /* Rounded Corners */ + border-radius: 17px; + -webkit-border-radius: 17px; + -moz-border-radius: 17px; + + /* Shadows */ + box-shadow: -1px -1px 2px rgba(0, 0, 0, .3), 0 0 1px rgba(0, 0, 0, .2); + -webkit-box-shadow: -1px -1px 2px rgba(0, 0, 0, .3), 0 0 1px rgba(0, 0, 0, .2); + -moz-box-shadow: -1px -1px 2px rgba(0, 0, 0, .3), 0 0 1px rgba(0, 0, 0, .2); +} + +/*** USER IS FOCUSED ON TEXT BOX ***/ +.control__search__input:focus { + outline: none; + background: #fff; /* Fallback color for non-css3 browsers */ + + /* Gradients */ + background: -webkit-gradient(linear, left bottom, left top, color-stop(0, rgb(255, 255, 255)), color-stop(1, rgb(235, 235, 235))); + background: -moz-linear-gradient(center top, rgb(255, 255, 255) 0%, rgb(235, 235, 235) 100%); +} + +/*** SEARCH BUTTON ***/ +.control__search__submit { + background: #44921f; /* Fallback color for non-css3 browsers */ + /* Gradients */ + background: -webkit-gradient(linear, left top, left bottom, color-stop(0, rgb(79, 188, 32)), color-stop(0.15, rgb(73, 157, 34)), color-stop(0.88, rgb(62, 135, 28)), color-stop(1, rgb(49, 114, 21))); + background: -moz-linear-gradient(center top, rgb(79, 188, 32) 0%, rgb(73, 157, 34) 15%, rgb(62, 135, 28) 88%, rgb(49, 114, 21) 100%); + border: 0; + color: #eee; + cursor: pointer; + float: right; + font: 16px 'Raleway', sans-serif; + font-weight: bold; + height: 30px; + margin: 4px; + text-shadow: 0 -1px 0 rgba(0, 0, 0, .3); + outline: none; + + /* Rounded Corners */ + border-radius: 30px; + -webkit-border-radius: 30px; + -moz-border-radius: 30px; + + /* Shadows */ + box-shadow: -1px -1px 1px rgba(255, 255, 255, .5), 1px 1px 0 rgba(0, 0, 0, .4); + -moz-box-shadow: -1px -1px 1px rgba(255, 255, 255, .5), 1px 1px 0 rgba(0, 0, 0, .2); + -webkit-box-shadow: -1px -1px 1px rgba(255, 255, 255, .5), 1px 1px 0 rgba(0, 0, 0, .4); +} + +/*** SEARCH BUTTON HOVER ***/ +.control__search__submit:hover { + background: #4ea923; /* Fallback color for non-css3 browsers */ + + /* Gradients */ + background: -webkit-gradient(linear, left top, left bottom, color-stop(0, rgb(89, 222, 27)), color-stop(0.15, rgb(83, 179, 38)), color-stop(0.8, rgb(66, 143, 27)), color-stop(1, rgb(54, 120, 22))); + background: -moz-linear-gradient(center top, rgb(89, 222, 27) 0%, rgb(83, 179, 38) 15%, rgb(66, 143, 27) 80%, rgb(54, 120, 22) 100%); +} + +.control__search__submit:active { + background: #4ea923; /* Fallback color for non-css3 browsers */ + + /* Gradients */ + background: -webkit-gradient(linear, left bottom, left top, color-stop(0, rgb(89, 222, 27)), color-stop(0.15, rgb(83, 179, 38)), color-stop(0.8, rgb(66, 143, 27)), color-stop(1, rgb(54, 120, 22))); + background: -moz-linear-gradient(center bottom, rgb(89, 222, 27) 0%, rgb(83, 179, 38) 15%, rgb(66, 143, 27) 80%, rgb(54, 120, 22) 100%); +} + +.buttons { + display: none; + color: white; + text-align: center; +} + +.buttons__button-next { + position: fixed; + right: calc(50% - 1.7rem); + bottom: calc(0% + 0.2rem); + font-size: 1.3rem; + border: none; + color: black; + opacity: 0.6; + text-align: center; + text-shadow: 0 1px 1px rgba(0, 0, 0, 0.35); + border-radius: 50%; + white-space: nowrap; + display: inline-block; + cursor: pointer; + outline: none; +} + +.buttons__button-prev { + position: fixed; + top: calc(0% + 0.2rem); + right: calc(50% - 1.7rem); + font-size: 1.3rem; + color: black; + opacity: 0.6; + text-align: center; + text-shadow: 0 1px 1px rgba(0, 0, 0, 0.35); + border-radius: 50%; + white-space: nowrap; + display: inline-block; + cursor: pointer; + outline: none; +} + +.currentPage:last-of-type { + margin-bottom: 2.4rem; +} + +.results { + display: grid; + grid-gap: 1rem; +} + +.results__searchResult { + display: grid; + grid-template-rows: repeat(5, min-content); + grid-gap: 0.5rem; +} + +.results__searchResult span:first-child { + margin-top: 0.5rem; +} + +.results__searchResult span { + padding: 0 0.5rem; + margin: 0; + grid-gap: 0.5rem; +} + +.emptyBox { + margin: 0; + padding: 0; +} + +.results__searchResult:nth-child(odd) { + background-color: #3d516b; +} + +.results__searchResult:nth-child(even) { + background-color: #4a6282; +} + +.results__searchResult__poster { + width: 100%; + align-self: flex-end; +} + +.hide { + display: none; + height: 0; +} + +.results__searchResult__title { + font-weight: 600; + font-size: 1.2rem; +} + +.results__searchResult__description:first-line{ + font-weight: bold; +} + +@media (min-width: 500px) { + .control { + display: grid; + justify-content: center; + } + + #control__search { + width: 30rem; + } + + .results { + grid-template-columns: 1fr 1fr; + } +} + +@media (min-width: 768px) { + + .results { + grid-template-columns: 1fr 1fr 1fr; + } +} + +@media (min-width: 1024px) { + .results { + grid-template-columns: 1fr 1fr 1fr 1fr; + } +} + +@media (min-width: 1248px) { + .results { + grid-template-columns: 1fr 1fr 1fr 1fr 1fr; + } +} + +@media (min-width: 1800px) { + .results { + grid-template-columns: 1fr 1fr 1fr 1fr 1fr; + } +} \ No newline at end of file