diff --git a/README.md b/README.md
index 49093dd2..0343c7ca 100644
--- a/README.md
+++ b/README.md
@@ -1,48 +1,80 @@
# Project Cinema
-We want to create a movie search engine. To power it we will use the [Open Movie Database](http://www.omdbapi.com) API.
+> # A movie search engine powered by the [Open Movie Database](http://www.omdbapi.com) API.
+>
+> ## _”A mobile-first, responsive design that looks great at different screen widths“_
-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.
+---
-To get started, fork and clone this repo. Please submit a pull request after your first commit and push commits regularly.
+---
-You should complete as many of the following tasks as you can.
+## UX
-- [ ] Work using mobile first, that is create the mobile version first and add tablet and desktop versions after.
-- [ ] Create an HTML page which should have a `form` at the top which contains a text input and a submit button. Below it should have a placeholder element for the returned results.
-- [ ] Use JavaScript to capture the `submit` event in your search form, extract the query string from the text input and use that to make an API call to the Open Movie Database API to search for films which match the query string using `fetch`. `console.log` the results
-- [ ] Display the data returned by the API including title, year and poster picture
+- Type in your search query and hit the button.
-**Movie details**
+
-- [ ] Adjust your layout to create room for a detailed view of movie information
-- [ ] Capture clicks on your movie results items and use that information to make another request to the API for detailed movie information. Using event delegation will help you here. `console.log` the returned result
-- [ ] Display the detailed movie result in the in the details view you created earlier
-- [ ] Make your design responsive and ensure it looks great at different screen widths
+- Search results are loaded below and the screen scrolls up automatically.
-**Your own feature**
+- Load more search results by paging through. You get 10 results at a time.
-- [ ] Implement any feature you would find useful or interesting
+
-**Stretch goals**
+- Just tap on any of the films in the search results to see more information. This loads below the search results and the screen scrolls up automatically.
-- [ ] Implement pagination so that users can navigate between all movies in search results rather than just the first ten
-- [ ] Create a favourites list. It's up to you how you would add items to favourites. You could add a button or otherwise. Display a list of favourites somewhere on your page.
-- [ ] Make the favourites list sortable. Add `up` and `down` buttons to your favourites which on click will move the result in relevant direction
-- [ ] Save favourites locally using `localStorage` so that favourites persist in browser after refresh
-- [ ] Let's create a search preview. It should listen for change events on input events and submit a search request with current query string. Display the search preview results in an absolute positioned container just below the search box.
-Hint: You may want to kick of the searching after at least 3 characters have been typed.
+
-## Objectives
+- Save your favourite films - just click the button on the film detail view.
-* We want to see great looking webpages that work well at all screen widths
-* Your code should have consistent indentation and sensible naming
-* Use lots of concise, reusable functions with a clear purpose
-* Add code comments where it is not immediately obvious what your code does
-* Your code should not throw errors and handle edge cases gracefully. For example not break if server fails to return expected results
-* Use BEM methodology to style your page
-* Try to use pure functions as much as possible, but keep in mind it will not be possible to make all functions pure.
+
-## README.md
+- You can see your list of favourites by clicking the account button in the header. You can delete films from the list individually or delete them all with a single click.
-When finished, include a README.md in your repo. Someone who is not familiar with the project should be able to look at it and understand what it is and what to do with it. Explain functionality created, mention any outstanding issues and possible features you would include if you had more time. List technologies used to create the app. Include a screenshot of your app in the README.
+
+
+## Technology used
+
+- **HTML & CSS** (Flexbox, Grid)
+ - BEM methodology used in markup and CSS.
+ - Individual media queries for tablet and desktop in separate files to make the styles easier to maintain.
+- **JavaScript** (Fetch, OMDB API, localStorage)
+ - Functions are pure as much as possible – concise reusable and each with with a clear purpose.
+ - Well commented throughout.
+
+## Surprise feature
+
+- If the film you‘re looking for doesn't have a poster then look out for the ’Fill Ferrell‘ placeholder image.
+
+
+
+---
+
+## Challenges, learnings and TODOs
+
+- **localStorage**
+
+ - Favourites currently stored individually in localStorage.
+ - Working with a database that stores strings of information is challenging.
+ - TODO: Need to refactor to store a single object in localStorage. On page load this can be retrieved and parsed. Stored in an object the user favourites can then be manipulated and updated. On any interaction even the object can be stringified before re-setting in localStorage.
+ - [ ] TODO: Make the favourites list sortable. Add `up` and `down` buttons to your favourites which on click will move the result in relevant direction. Also sortable by date saved and film title.
+ - [ ] TODO: Implement a watch list feature to save films that you want to see as well as favourites.
+
+- **Search**
+
+ - [ ] TODO: Create a search preview. It should listen for change events on input events and submit a search request with current query string. Display the search preview results in an absolute positioned container just below the search box. Kick of the searching after at least 3 characters have been typed.
+
+- **Refactoring**
+
+ - [ ] TODO: Refactor code to make use of export/import to keep JS easy to navigate and maintain.
+
+---
+
+### The original brief
+
+- We want to see great looking webpages that work well at all screen widths
+- Your code should have consistent indentation and sensible naming
+- Use lots of concise, reusable functions with a clear purpose
+- Add code comments where it is not immediately obvious what your code does
+- Your code should not throw errors and handle edge cases gracefully. For example not break if server fails to return expected results
+- Use BEM methodology in your markup and CSS to style your page
+- Try to use pure functions as much as possible, but keep in mind it will not be possible to make all functions pure.
diff --git a/index.html b/index.html
new file mode 100644
index 00000000..98a03af6
--- /dev/null
+++ b/index.html
@@ -0,0 +1,46 @@
+
+
+
+
+
+
+
+ The Reel Thing - Find Your Favourite Films
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Your favourites Delete
+ all
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/bg_popcorn.jpg b/src/bg_popcorn.jpg
new file mode 100644
index 00000000..d4c4fa7c
Binary files /dev/null and b/src/bg_popcorn.jpg differ
diff --git a/src/data.json b/src/data.json
new file mode 100644
index 00000000..1cd2fc36
--- /dev/null
+++ b/src/data.json
@@ -0,0 +1,93 @@
+HTTP/1.1 200 OK
+Date: Sun, 23 Sep 2018 07:24:17 GMT
+Content-Type: application/json; charset=utf-8
+Transfer-Encoding: chunked
+Connection: keep-alive
+Cache-Control: public, max-age=86400
+Expires: Mon, 24 Sep 2018 07:24:17 GMT
+Last-Modified: Sat, 22 Sep 2018 15:18:36 GMT
+Vary: *, Accept-Encoding
+X-AspNet-Version: 4.0.30319
+X-Powered-By: ASP.NET
+Access-Control-Allow-Origin: *
+CF-Cache-Status: HIT
+Server: cloudflare
+CF-RAY: 45eb4552917f0a7e-LHR
+Content-Encoding: gzip
+
+{
+ "Search": [
+ {
+ "Title": "Titanic",
+ "Year": "1997",
+ "imdbID": "tt0120338",
+ "Type": "movie",
+ "Poster": "https://m.media-amazon.com/images/M/MV5BMDdmZGU3NDQtY2E5My00ZTliLWIzOTUtMTY4ZGI1YjdiNjk3XkEyXkFqcGdeQXVyNTA4NzY1MzY@._V1_SX300.jpg"
+ },
+ {
+ "Title": "Titanic II",
+ "Year": "2010",
+ "imdbID": "tt1640571",
+ "Type": "movie",
+ "Poster": "https://m.media-amazon.com/images/M/MV5BMTMxMjQ1MjA5Ml5BMl5BanBnXkFtZTcwNjIzNjg1Mw@@._V1_SX300.jpg"
+ },
+ {
+ "Title": "Titanic: The Legend Goes On...",
+ "Year": "2000",
+ "imdbID": "tt0330994",
+ "Type": "movie",
+ "Poster": "https://ia.media-imdb.com/images/M/MV5BMTg5MjcxODAwMV5BMl5BanBnXkFtZTcwMTk4OTMwMg@@._V1_SX300.jpg"
+ },
+ {
+ "Title": "Titanic",
+ "Year": "1953",
+ "imdbID": "tt0046435",
+ "Type": "movie",
+ "Poster": "https://m.media-amazon.com/images/M/MV5BMTU3NTUyMTc3Nl5BMl5BanBnXkFtZTgwOTA2MDE3MTE@._V1_SX300.jpg"
+ },
+ {
+ "Title": "Titanic",
+ "Year": "1996",
+ "imdbID": "tt0115392",
+ "Type": "series",
+ "Poster": "https://m.media-amazon.com/images/M/MV5BMTIyNjc0NjgyMl5BMl5BanBnXkFtZTcwMDAzMTAzMQ@@._V1_SX300.jpg"
+ },
+ {
+ "Title": "Raise the Titanic",
+ "Year": "1980",
+ "imdbID": "tt0081400",
+ "Type": "movie",
+ "Poster": "https://m.media-amazon.com/images/M/MV5BM2MyZWYzOTQtMTYzNC00OWIyLWE2NWItMzMwODA0OGQ2ZTRkXkEyXkFqcGdeQXVyMjI4MjA5MzA@._V1_SX300.jpg"
+ },
+ {
+ "Title": "The Legend of the Titanic",
+ "Year": "1999",
+ "imdbID": "tt1623780",
+ "Type": "movie",
+ "Poster": "https://images-na.ssl-images-amazon.com/images/M/MV5BMjMxNDU5MTk1MV5BMl5BanBnXkFtZTgwMDk5NDUyMTE@._V1_SX300.jpg"
+ },
+ {
+ "Title": "Titanic",
+ "Year": "2012–",
+ "imdbID": "tt1869152",
+ "Type": "series",
+ "Poster": "https://m.media-amazon.com/images/M/MV5BMTcxNzYxOTAwMF5BMl5BanBnXkFtZTcwNzU3Mjc2Nw@@._V1_SX300.jpg"
+ },
+ {
+ "Title": "Titanic: Blood and Steel",
+ "Year": "2012–",
+ "imdbID": "tt1695366",
+ "Type": "series",
+ "Poster": "https://m.media-amazon.com/images/M/MV5BMjI2MzU2NzEzN15BMl5BanBnXkFtZTcwMzI5NTU3Nw@@._V1_SX300.jpg"
+ },
+ {
+ "Title": "In Search of the Titanic",
+ "Year": "2004",
+ "imdbID": "tt1719665",
+ "Type": "movie",
+ "Poster": "https://ia.media-imdb.com/images/M/MV5BMTAzNjY0NDA2NzdeQTJeQWpwZ15BbWU4MDIwMzc1MzEx._V1_SX300.jpg"
+ }
+ ],
+ "totalResults": "190",
+ "Response": "True"
+}
\ No newline at end of file
diff --git a/src/desktop-style.css b/src/desktop-style.css
new file mode 100644
index 00000000..b111fd93
--- /dev/null
+++ b/src/desktop-style.css
@@ -0,0 +1,160 @@
+@media (min-width: 1068px) {
+ header {
+ height: 8rem;
+ }
+ #title {
+ font-size: 4rem;
+ }
+
+ .btn__account {
+ font-size: 4rem;
+ margin-right: 2rem;
+ }
+
+ #account {
+ background: skyblue;
+ position: fixed;
+ top: -50rem;
+ left: 80vw;
+ width: 20vw;
+ z-index: 5;
+ transition: top 1s;
+ box-shadow: 0px 3px 3px rgba(0, 0, 0, 0.5);
+ }
+ #account.account--active {
+ top: 8rem;
+ }
+
+ .search__input {
+ width: 50vw;
+ font-size: 3rem;
+ font-weight: 400;
+ padding: 3rem;
+ }
+
+ /* search results */
+ .search-results__page {
+ width: 85vw;
+ margin: 0 auto;
+ padding: 1rem;
+ grid-template-columns: repeat(5, 20%);
+ justify-content: space-around;
+ }
+
+ .film {
+ display: flex;
+ flex-direction: column;
+ flex: 1;
+ justify-self: center;
+ margin: 0 0.5rem;
+ width: 18vw;
+ }
+
+ .film__title {
+ width: 13vw;
+ font-size: 1.3rem;
+ }
+
+ .film__poster {
+ box-shadow: 0 2px 5px rgba(0, 0, 0, 0.6);
+ width: 13vw;
+ height: 20vw;
+ border: 6px solid white;
+ object-fit: cover;
+ transition: all 0.5s;
+ }
+
+ .film__poster:hover {
+ border-color: orangered;
+ }
+
+ #page-nav {
+ font-size: 1.5rem;
+ justify-content: center;
+ background: whitesmoke;
+ }
+
+ /*. film details */
+
+ #film-details {
+ background-image: url(/src/bg_popcorn.jpg);
+ background-size: cover;
+ padding: 5rem 0 1rem 0;
+ margin-bottom: 0;
+ }
+
+ .film-details__wrapper {
+ width: 65vw;
+ margin: 0 auto;
+ padding-top: 1rem;
+ grid-template-columns: 22vw max-content 1fr;
+ grid-template-rows: repeat(5, min-content) 1fr;
+ }
+
+ .film-details__title {
+ font-size: 2.3rem;
+ border-top: 5px solid black;
+ padding-top: 0.25rem;
+ width: 35vw;
+ }
+
+ .btn__fav {
+ margin: 0 0.5rem 0.25rem;
+ font-size: 1.2rem;
+ justify-self: end;
+ align-self: start;
+ transition: padding 0.2s;
+ }
+
+ .btn__fav:hover {
+ padding: 0.5rem 1rem;
+ }
+
+ .film-details__poster {
+ grid-column: 1 / span 1;
+ grid-row: 1 / span 8;
+ width: 20vw;
+ justify-self: stretch;
+ border: none;
+ box-shadow: 0 2px 5px rgba(0, 0, 0, 0.6);
+ }
+ .film-details__wrapper h4 {
+ grid-column: 2 / span 2;
+ margin-bottom: 0.5rem;
+ align-self: end;
+ }
+ h4.film-details__director {
+ grid-column: 2 / span 2;
+ align-self: start;
+ margin-bottom: 0.25rem;
+ }
+
+ .film-details__meta {
+ font-size: 1.2rem;
+ font-style: italic;
+ margin-top: 0.5rem;
+ grid-column: 2 / span 2;
+ }
+
+ .film-details__plot,
+ .film-details__actors {
+ grid-column: 2 / span 2;
+ width: 30vw;
+ font-family: serif;
+ margin-top: 0;
+ font-size: 1rem;
+ }
+
+ .film-details__ratings__imdb {
+ grid-column: 2 / span 2;
+ margin: 1rem 0;
+ font-size: 1.2rem;
+ }
+
+ .film-details__wrapper h4 {
+ grid-column: 2 / span 2;
+ margin: 1rem 0 0.5rem 0;
+ align-self: end;
+ font-size: 1.4rem;
+ }
+}
diff --git a/src/fill-ferrell.jpg b/src/fill-ferrell.jpg
new file mode 100644
index 00000000..cc746993
Binary files /dev/null and b/src/fill-ferrell.jpg differ
diff --git a/src/index.js b/src/index.js
new file mode 100644
index 00000000..665a1987
--- /dev/null
+++ b/src/index.js
@@ -0,0 +1,313 @@
+import * as storage from './localStorage.js';
+
+const myStorage = window.localStorage;
+
+console.log(window.innerWidth);
+
+window.scrollBy(0, -20);
+
+if (storage.storageAvailable('localStorage')) {
+ // localStorage.clear();
+ console.log(`You’re all set to save your favourite films`);
+ console.log(myStorage);
+ console.log(window.innerHeight);
+} else {
+ console.log('Please enable local storage to save your favourites.');
+}
+
+const params = {
+ base: 'http://www.omdbapi.com/?apikey=507b4100&type=movie',
+ pageNum: 1
+};
+
+const setUrl = (paramsInit, query = '', id = '') => {
+ console.log(`${paramsInit.base}&page=${params.pageNum}&s=${query}&i=${id}`);
+ return `${paramsInit.base}&page=${
+ params.pageNum
+ }&s=${query}&i=${id}&plot=full`;
+};
+
+const searchFilmBytitle = title => {
+ fetch(setUrl(params, title))
+ .then(response => response.json())
+ .then(body => displaySearchResults(body))
+ .catch(error => {
+ if (films === undefined) {
+ alert('No films match your query, please search again');
+ } else {
+ alert(error);
+ }
+ });
+};
+
+const getFilmByID = id => {
+ fetch(setUrl(params, '', id))
+ .then(response => response.json())
+ .then(body => writeFilmDetails('#film-details', body))
+ .catch(error => console.log(error));
+};
+
+/* Search resutls */
+
+const displaySearchResults = films => {
+ console.log(films);
+ const searchResults = createElement('div');
+ searchResults.classList.add('search-results__page');
+ searchResults.setAttribute('id', `page-${params.pageNum}`);
+ films.Search.forEach(film => {
+ const filmListing = createFilmSearchListing(
+ film.imdbID,
+ film.Title,
+ film.Year,
+ film.Poster
+ );
+ addElementToParent(searchResults, filmListing);
+ });
+ const searchResultsWrapper = document.querySelector('#search-results');
+ searchResultsWrapper.innerHTML = '';
+
+ addElementToParent(searchResultsWrapper, searchResults);
+ const paginationButtons = createPagination(films);
+ console.log(paginationButtons);
+ addElementToParent(searchResultsWrapper, paginationButtons);
+ addPaginationControls();
+ if (window.innerWidth > 1064) {
+ window.scrollBy({ top: window.innerHeight - 100, behaviour: 'smooth' });
+ } else if (window.innerWidth > 767) {
+ window.scrollBy({ top: window.innerHeight, behaviour: 'smooth' });
+ } else {
+ window.scrollBy({ top: window.innerHeight - 60, behaviour: 'smooth' });
+ }
+};
+
+const createFilmSearchListing = (id, title, year, poster) => {
+ const filmListing = createArticle('film');
+
+ poster === 'N/A' ? (poster = './src/fill-ferrell.jpg') : poster;
+ filmListing.innerHTML = `
+ ${title} (${year}) `;
+ filmListing.setAttribute('data-ID', id);
+
+ return filmListing;
+};
+
+const createArticle = (articleClass = '') => {
+ const article = document.createElement('article');
+ article.classList.add(articleClass);
+
+ return article;
+};
+
+const createPagination = data => {
+ const pagination = createElement('nav');
+ const numPages = Math.ceil(Number(data.totalResults) / 10);
+ // document.querySelector('.page-total').textContent = numPages;
+ pagination.innerHTML = `
+ ←
+ Page ${
+ params.pageNum
+ } of ${numPages}
+ → `;
+
+ return pagination;
+};
+
+const addPaginationControls = () => {
+ const nextPage = document.querySelector('#page-nav .next');
+ nextPage.addEventListener('click', e => {
+ const currentPageNum = document.querySelector('.page-current');
+ const totalPageNum = document.querySelector('.page-total');
+ e.preventDefault();
+ +currentPageNum.textContent < +totalPageNum.textContent // Prevent next page advancing beyond total no. of pages
+ ? params.pageNum++
+ : false;
+
+ searchFilmBytitle(params.query);
+ currentPageNum.textContent = params.pageNum;
+ document.querySelector('#film-details').innerHTML = '';
+ e.stopPropagation();
+ });
+
+ const prevPage = document.querySelector('#page-nav .prev');
+ prevPage.addEventListener('click', e => {
+ e.preventDefault();
+ params.pageNum > 1 ? params.pageNum-- : false; // Prevent previous page returning negative page number
+
+ searchFilmBytitle(params.query);
+ document.querySelector('.page-current').textContent = params.pageNum;
+ document.querySelector('#film-details').innerHTML = '';
+ e.stopPropagation();
+ });
+};
+
+/* infinite scroll */
+const infiniteScroll = () => {
+ const trigger = document.querySelector('#');
+};
+
+/* film details */
+
+const createFilmDetails = film => {
+ film.Poster === 'N/A'
+ ? (film.Poster = './src/fill-ferrell.jpg')
+ : film.Poster;
+ const rating = film.imdbRating * 10;
+ return `
+
+
${film.Title}
+
+
+
Dir. ${film.Director}
+
(Released ${film.Year}, dur. ${film.Runtime}, ${
+ film.Rated
+ })
+
+
Rating:
+
+
${film.imdbRating} out of 10
+
+
Starring
+
+ ${film.Actors}
+
Plot summary
+
${film.Plot}
+
`;
+};
+
+const writeFilmDetails = (parent, film) => {
+ document.querySelector(parent).innerHTML = createFilmDetails(film);
+
+ setFavButton(film);
+ if (window.innerWidth > 1068) {
+ window.scrollBy({ top: window.innerHeight - 100, behaviour: 'smooth' });
+ } else {
+ window.scrollBy({ top: window.innerHeight - 70, behaviour: 'smooth' });
+ }
+};
+
+/* favourites list */
+const makeFavourite = id => {
+ const favFilm = JSON.parse(myStorage[id]);
+ const favourite = document.createElement('li');
+ favourite.classList.add('favourites__list__film');
+ favourite.setAttribute('data-id', id);
+ favourite.innerHTML = `
+ ${
+ favFilm['title']
+ }
+ ${
+ favFilm['favDate']
+ }
+ Delete `;
+ return favourite;
+};
+
+const setFavButton = film => {
+ document.querySelector('#fav').addEventListener('click', e => {
+ // TODO: highlight favourited film when display details
+ e.currentTarget.classList.add('fav--active');
+ const date = new Date(Date.now())
+ .toDateString()
+ .slice(4)
+ .split(' ');
+ const favData = Object.assign(
+ {},
+ {
+ id: e.target.attributes[2].value,
+ title: film.Title,
+ isFav: true,
+ favDate: `${date[1]} ${date[0]}, ${date[2]}`
+ }
+ );
+ const id = favData.id;
+ const details = JSON.stringify(favData);
+
+ myStorage.setItem(`${myStorage.length}`, `${details}`);
+ // addToFavourites(id, e);
+ getFavourites(myStorage);
+ });
+};
+
+const getFavourites = data => {
+ const parent = document.querySelector('#favourites__list');
+ parent.innerHTML = '';
+ for (let i = 0; i < data.length; i++) {
+ // if isFav = true
+ console.log(data[i]);
+ if (data[i].includes('"isFav":true')) {
+ const favouriteFilm = makeFavourite(`${i}`);
+ parent.insertBefore(favouriteFilm, parent.firstChild);
+ }
+ }
+ // document.querySelector('#favourites__count').textContent = myStorage.length;
+};
+
+/* event listeners */
+
+/* Search */
+
+document.querySelector('#search').addEventListener('submit', e => {
+ e.preventDefault();
+ const query = e.currentTarget.query.value;
+ params.query = query;
+ searchFilmBytitle(query);
+});
+
+/* Film details */
+
+document.querySelector('#search-results').addEventListener('click', e => {
+ const id = e.target.parentNode.dataset.id;
+ getFilmByID(id);
+});
+
+/* Favourites */
+
+document.querySelector('#favourites').addEventListener('click', e => {
+ if (e.target.innerText === 'DELETE') {
+ console.log(e.target);
+ const id = e.target.parentNode.dataset.id;
+ e.target.parentNode.classList.add('hidden');
+ console.log(typeof myStorage);
+ console.log(typeof myStorage[id]);
+ // const myFilm = JSON.parse(myStorage[id]);
+ // myFilm.isFav = false;
+ // console.log(myFilm);
+ const updatedFav = myStorage[id].replace('isFav":true', 'isFav":false');
+ myStorage.setItem(id, updatedFav);
+ document.querySelector('#favourites__count').textContent = myStorage.length;
+ } else if (e.target.innerText === 'DELETE ALL') {
+ myStorage.clear();
+ getFavourites(myStorage);
+ }
+});
+
+/* Account */
+
+document.querySelector('.btn__account').addEventListener('click', e => {
+ document.querySelector('#account').classList.toggle('account--active');
+});
+
+/* utility functions */
+
+const createElement = (type, title = '') => {
+ const element = document.createElement(type);
+ element.innerHTML = title;
+
+ return element;
+};
+
+const createImageElement = url => {
+ const image = document.createElement('img');
+ image.src = url;
+
+ return image;
+};
+
+const addElementToParent = (parent, element) => {
+ return parent.appendChild(element);
+};
+
+/* init */
+getFavourites(myStorage);
diff --git a/src/localStorage.js b/src/localStorage.js
new file mode 100644
index 00000000..7ace6f88
--- /dev/null
+++ b/src/localStorage.js
@@ -0,0 +1,26 @@
+function storageAvailable(type) {
+ try {
+ var storage = window[type],
+ x = '__storage_test__';
+ storage.setItem(x, x);
+ storage.removeItem(x);
+ return true;
+ } catch (e) {
+ return (
+ e instanceof DOMException &&
+ // everything except Firefox
+ (e.code === 22 ||
+ // Firefox
+ e.code === 1014 ||
+ // test name field too, because code might not be present
+ // everything except Firefox
+ e.name === 'QuotaExceededError' ||
+ // Firefox
+ e.name === 'NS_ERROR_DOM_QUOTA_REACHED') &&
+ // acknowledge QuotaExceededError only if there's something already stored
+ storage.length !== 0
+ );
+ }
+}
+
+export { storageAvailable };
diff --git a/src/modern-normalize.css b/src/modern-normalize.css
new file mode 100644
index 00000000..3f645c85
--- /dev/null
+++ b/src/modern-normalize.css
@@ -0,0 +1,273 @@
+/*! modern-normalize | MIT License | https://github.com/sindresorhus/modern-normalize */
+
+/* Document
+ ========================================================================== */
+
+/**
+ * Use a better box model (opinionated).
+ */
+
+html {
+ box-sizing: border-box;
+}
+
+*,
+*::before,
+*::after {
+ box-sizing: inherit;
+}
+
+/**
+ * Use a more readable tab size (opinionated).
+ */
+
+:root {
+ -moz-tab-size: 4;
+ tab-size: 4;
+}
+
+/**
+ * 1. Correct the line height in all browsers.
+ * 2. Prevent adjustments of font size after orientation changes in iOS.
+ */
+
+html {
+ line-height: 1.15; /* 1 */
+ -webkit-text-size-adjust: 100%; /* 2 */
+}
+
+/* Sections
+ ========================================================================== */
+
+/**
+ * Remove the margin in all browsers.
+ */
+
+body {
+ margin: 0;
+}
+
+/**
+ * Improve consistency of default fonts in all browsers. (https://github.com/sindresorhus/modern-normalize/issues/3)
+ */
+
+body {
+ font-family:
+ -apple-system,
+ BlinkMacSystemFont,
+ 'Segoe UI',
+ Roboto,
+ Helvetica,
+ Arial,
+ sans-serif,
+ 'Apple Color Emoji',
+ 'Segoe UI Emoji',
+ 'Segoe UI Symbol';
+}
+
+/* Grouping content
+ ========================================================================== */
+
+/**
+ * Add the correct height in Firefox.
+ */
+
+hr {
+ height: 0;
+}
+
+/* Text-level semantics
+ ========================================================================== */
+
+/**
+ * Add the correct text decoration in Chrome, Edge, and Safari.
+ */
+
+abbr[title] {
+ text-decoration: underline dotted;
+}
+
+/**
+ * Add the correct font weight in Chrome, Edge, and Safari.
+ */
+
+b,
+strong {
+ font-weight: bolder;
+}
+
+/**
+ * 1. Improve consistency of default fonts in all browsers. (https://github.com/sindresorhus/modern-normalize/issues/3)
+ * 2. Correct the odd `em` font sizing in all browsers.
+ */
+
+code,
+kbd,
+samp,
+pre {
+ font-family: SFMono-Regular, Consolas, 'Liberation Mono', Menlo, Courier, monospace; /* 1 */
+ font-size: 1em; /* 2 */
+}
+
+/**
+ * Add the correct font size in all browsers.
+ */
+
+small {
+ font-size: 80%;
+}
+
+/**
+ * Prevent `sub` and `sup` elements from affecting the line height in all browsers.
+ */
+
+sub,
+sup {
+ font-size: 75%;
+ line-height: 0;
+ position: relative;
+ vertical-align: baseline;
+}
+
+sub {
+ bottom: -0.25em;
+}
+
+sup {
+ top: -0.5em;
+}
+
+/* Forms
+ ========================================================================== */
+
+/**
+ * 1. Change the font styles in all browsers.
+ * 2. Remove the margin in Firefox and Safari.
+ */
+
+button,
+input,
+optgroup,
+select,
+textarea {
+ font-family: inherit; /* 1 */
+ font-size: 100%; /* 1 */
+ line-height: 1.15; /* 1 */
+ margin: 0; /* 2 */
+}
+
+/**
+ * Remove the inheritance of text transform in Edge and Firefox.
+ * 1. Remove the inheritance of text transform in Firefox.
+ */
+
+button,
+select { /* 1 */
+ text-transform: none;
+}
+
+/**
+ * Correct the inability to style clickable types in iOS and Safari.
+ */
+
+button,
+[type='button'],
+[type='reset'],
+[type='submit'] {
+ -webkit-appearance: button;
+}
+
+/**
+ * Remove the inner border and padding in Firefox.
+ */
+
+button::-moz-focus-inner,
+[type='button']::-moz-focus-inner,
+[type='reset']::-moz-focus-inner,
+[type='submit']::-moz-focus-inner {
+ border-style: none;
+ padding: 0;
+}
+
+/**
+ * Restore the focus styles unset by the previous rule.
+ */
+
+button:-moz-focusring,
+[type='button']:-moz-focusring,
+[type='reset']:-moz-focusring,
+[type='submit']:-moz-focusring {
+ outline: 1px dotted ButtonText;
+}
+
+/**
+ * Correct the padding in Firefox.
+ */
+
+fieldset {
+ padding: 0.35em 0.75em 0.625em;
+}
+
+/**
+ * Remove the padding so developers are not caught out when they zero out `fieldset` elements in all browsers.
+ */
+
+legend {
+ padding: 0;
+}
+
+/**
+ * Add the correct vertical alignment in Chrome and Firefox.
+ */
+
+progress {
+ vertical-align: baseline;
+}
+
+/**
+ * Correct the cursor style of increment and decrement buttons in Safari.
+ */
+
+[type='number']::-webkit-inner-spin-button,
+[type='number']::-webkit-outer-spin-button {
+ height: auto;
+}
+
+/**
+ * 1. Correct the odd appearance in Chrome and Safari.
+ * 2. Correct the outline style in Safari.
+ */
+
+[type='search'] {
+ -webkit-appearance: textfield; /* 1 */
+ outline-offset: -2px; /* 2 */
+}
+
+/**
+ * Remove the inner padding in Chrome and Safari on macOS.
+ */
+
+[type='search']::-webkit-search-decoration {
+ -webkit-appearance: none;
+}
+
+/**
+ * 1. Correct the inability to style clickable types in iOS and Safari.
+ * 2. Change font properties to `inherit` in Safari.
+ */
+
+::-webkit-file-upload-button {
+ -webkit-appearance: button; /* 1 */
+ font: inherit; /* 2 */
+}
+
+/* Interactive
+ ========================================================================== */
+
+/*
+ * Add the correct display in Chrome and Safari.
+ */
+
+summary {
+ display: list-item;
+}
diff --git a/src/omdb.http b/src/omdb.http
new file mode 100644
index 00000000..8cf49116
--- /dev/null
+++ b/src/omdb.http
@@ -0,0 +1,3 @@
+
+
+http://www.omdbapi.com/?apikey=507b4100&type=movie&page=1&s=&i=tt0095016
\ No newline at end of file
diff --git a/src/style.css b/src/style.css
new file mode 100644
index 00000000..5ed768e9
--- /dev/null
+++ b/src/style.css
@@ -0,0 +1,292 @@
+:root {
+ --display-font: 'Bungee Inline', cursive;
+ --text-font: 'Dosis', sans-serif;
+}
+
+.hidden {
+ display: none;
+}
+
+div#app {
+ position: relative;
+}
+
+.btn {
+ background: none;
+ border: none;
+}
+
+.btn__account {
+ color: white;
+}
+
+.fav--active {
+ color: red;
+}
+
+body {
+ /* background: yellow; */
+ font-family: var(--text-font);
+}
+
+body {
+ display: flex;
+ flex-direction: column;
+}
+/* header */
+
+header {
+ background: black;
+ color: red;
+ display: flex;
+ height: 4rem;
+ justify-content: space-between;
+ padding-left: 1rem;
+ position: fixed;
+ width: 100vw;
+ z-index: 10;
+}
+
+#title {
+ font-size: 1.2rem;
+ font-family: var(--display-font);
+ margin-top: 1.25rem;
+}
+
+.btn__account {
+ font-size: 1.8rem;
+ margin-right: 0.25rem;
+}
+/* account */
+
+#account {
+ background: skyblue;
+ position: fixed;
+ top: -50rem;
+ left: 0vw;
+ width: 100vw;
+ z-index: 5;
+ transition: top 1s;
+ box-shadow: 0px 3px 3px rgba(0, 0, 0, 0.5);
+}
+#account.account--active {
+ top: 4rem;
+}
+
+#favourites__title {
+ margin: 1rem;
+ border-bottom: 1px solid gray;
+ padding-bottom: 0.5rem;
+}
+
+#favourites__list {
+ list-style-type: none;
+ margin-left: 1rem;
+ padding-left: 0;
+ padding-right: 1rem;
+}
+
+.favourites__list__film {
+ padding: 0.25rem 0;
+}
+
+.favourites__list__film__faved {
+ display: none;
+}
+
+.btn__favourite__remove {
+ /* font-weight:400; */
+ font-size: 0.8rem;
+ text-transform: uppercase;
+ padding: 0.1rem 0.25rem;
+ background: whitesmoke;
+ border-radius: 4px;
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.4);
+ margin-left: 0.5rem;
+ float: right;
+}
+
+/* search form */
+
+#search {
+ align-items: center;
+ background-image: url(/src/bg_popcorn.jpg);
+ background-size: cover;
+ display: flex;
+ flex-direction: column;
+ height: 100.5vh;
+}
+
+.search__label {
+ display: none;
+}
+
+.search__input {
+ background: rgba(255, 255, 255, 0.8);
+ border-width: 0 0 1px 0;
+ height: 3rem;
+ margin-bottom: 2rem;
+ margin: 37vh 0 2rem 0;
+ width: 80vw;
+ padding-left: 0.2rem;
+ font-size: 1.5rem;
+ font-weight: 600;
+ border-radius: 0;
+}
+
+.search__btn {
+ color: white;
+ display: block;
+ font-size: 2rem;
+ font-weight: 400;
+ height: 5rem;
+ width: 5rem;
+ /* background-image: linear-gradient(to bottom, rgba(0,0, 255,0.5), rgba(0,0,255,0.7) 80%); */
+ background: skyblue;
+ border-radius: 2.5rem;
+ border: none;
+ box-shadow: 0px 2px 5px rgba(0, 0, 0, 0.2);
+ text-shadow: 0 3px rgba(0, 0, 0, 0.3);
+}
+/* search results */
+
+#search-results {
+ /* height: 100vh; */
+ position: relative;
+ bottom: -1.5rem;
+}
+
+.search-results__page {
+ display: grid;
+ grid-template-columns: repeat(5, 40vw);
+ grid-template-rows: min-content min-content;
+ /* height: 100vh; */
+ overflow-y: scroll;
+ padding: 1rem;
+}
+
+.film {
+ align-self: start;
+ display: flex;
+ flex-direction: column;
+ flex: 1;
+ margin-right: 1rem;
+ /* padding: 1rem; */
+ width: 35vw;
+}
+
+.film__title {
+ font-size: 1rem;
+ order: 2;
+}
+
+.film__poster {
+ order: 1;
+ object-fit: cover;
+ width: 30vw;
+ height: 40vw;
+}
+
+.film__year {
+ font-weight: 400;
+ order: 3;
+}
+
+/* page navigation */
+
+#page-nav {
+ display: flex;
+ justify-content: space-around;
+ font-size: 0.9rem;
+}
+
+.film-details__wrapper {
+ display: grid;
+ grid-template-columns: 2fr 2fr 1fr;
+ padding: 1rem;
+ margin: 2rem 0.5rem 0 0.5rem;
+ border: 1px solid lightgray;
+ border-radius: 8px;
+ background: whitesmoke;
+ box-shadow: 0 1px 5px rgba(0, 0, 0, 0.2);
+}
+
+.film-details__title {
+ grid-column: 1 / span 2;
+ font-size: 1.5rem;
+ align-self: start;
+ margin: 0 0 1rem 0;
+}
+
+.btn__fav {
+ align-self: start;
+ justify-self: end;
+ padding: 0.25rem 0.5rem;
+ border-radius: 0.2rem;
+ display: block;
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.5);
+ margin-top: 0.25rem;
+ font-size: 0.9rem;
+}
+
+.film-details__poster {
+ display: block;
+ width: 65vw;
+ grid-column: 1 / span 3;
+ justify-self: center;
+ border: 5px solid white;
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.5);
+}
+
+.film-details__director {
+ grid-column: 1 / span 3;
+ align-self: start;
+ margin-bottom: 0.25rem;
+ font-size: 1.2rem;
+}
+
+.film-details__meta {
+ font-size: 01rem;
+ font-style: italic;
+ margin-top: 0.25rem;
+ grid-column: 1 / span 3;
+}
+
+.film-details__rating {
+ grid-column: 1 / span 3;
+ justify-self: start;
+ display: flex;
+ /* margin: auto; */
+ align-items: center;
+}
+
+.film-details__ratings__imdb {
+ flex: 1;
+}
+.film-details__rating__bar {
+ width: 30vw;
+ height: 1.5rem;
+ margin: 0 1rem;
+}
+
+.film-details__rating__score {
+ /* flex: 1; */
+}
+
+.film-details__wrapper h4 {
+ grid-column: 1 / span 3;
+ margin-bottom: 0;
+ align-self: bottom;
+}
+
+.film-details__actors {
+ grid-column: 1 / span 3;
+ margin-top: 0.25rem;
+}
+
+.film-details__plot,
+.film-details__actors {
+ grid-column: 1 / span 3;
+ font-family: serif;
+ margin: 0.25rem 0 0 0;
+}
diff --git a/src/tablet-style.css b/src/tablet-style.css
new file mode 100644
index 00000000..5a06d02f
--- /dev/null
+++ b/src/tablet-style.css
@@ -0,0 +1,173 @@
+@media (min-width: 768px) {
+ #title {
+ font-size: 2rem;
+ margin: 2rem 1rem;
+ }
+
+ header {
+ height: 6rem;
+ }
+
+ .btn__account {
+ font-size: 2.5rem;
+ margin-right: 1rem;
+ }
+
+ #account {
+ background: skyblue;
+ position: fixed;
+ top: -50rem;
+ left: 50vw;
+ width: 50vw;
+ z-index: 5;
+ transition: top 1s;
+ box-shadow: 0px 3px 3px rgba(0, 0, 0, 0.5);
+ }
+ #account.account--active {
+ top: 6rem;
+ }
+
+ .search__label {
+ display: block;
+ margin: 37vh 0 0 0;
+ font-size: 3rem;
+ font-weight: 600;
+ text-shadow: 0px 1px 2px rgba(0, 0, 0, 0.2);
+ }
+
+ .search__input {
+ margin-top: 2rem;
+ padding-left: 1rem;
+ }
+
+ .search-results__page {
+ padding-top: 5rem;
+ grid-template-columns: repeat(4, 25vw);
+ overflow-y: none;
+ }
+
+ .film {
+ justify-self: center;
+ display: flex;
+ flex-direction: column;
+ flex: 1;
+ margin-right: 1rem;
+ width: 22vw;
+ }
+
+ .film__title {
+ width: 20vw;
+ }
+
+ .film__poster {
+ width: 20vw;
+ height: 32vw;
+ /* border: 1px solid rgba(0,0,0,0.1); */
+ object-fit: cover;
+ }
+
+ /*. film details */
+
+ .film-details__wrapper {
+ width: 85vw;
+ display: grid;
+ grid-template-columns: 32vw max-content 1fr;
+ grid-template-rows: repeat(6, min-content);
+ padding: 1rem;
+ margin: 2rem auto 0 auto;
+ border: 1px solid lightgray;
+ border-radius: 8px;
+ background: whitesmoke;
+ box-shadow: 0 1px 5px rgba(0, 0, 0, 0.2);
+ }
+
+ .film-details__title {
+ grid-column: 2 / span 1;
+ grid-row: 1 / span 1;
+ font-size: 1.5rem;
+ align-self: end;
+ margin: 0;
+ }
+
+ .btn__fav {
+ grid-column: 3 / span 1;
+ grid-row: 1 / span 1;
+ align-self: end;
+ justify-self: start;
+ padding: 0.25rem 0.5rem;
+ border-radius: 0.2rem;
+ display: block;
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.5);
+ margin: 0 0 0.1rem 1rem;
+ font-size: 0.9rem;
+ }
+
+ .film-details__poster {
+ grid-column: 1 / span 1;
+ grid-row: 1 / span 7;
+ width: 30vw;
+ justify-self: stretch;
+ border: 5px solid white;
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
+ }
+ .film-details__wrapper h4 {
+ grid-column: 2 / span 2;
+ margin: 0 0 0.5rem 0;
+ align-self: start;
+ line-height: 1;
+ }
+ h4.film-details__director {
+ grid-column: 2 / span 2;
+ /* grid-row: 2 / span 1; */
+ align-self: start;
+ margin-bottom: 0.25rem;
+ }
+
+ .film-details__meta {
+ font-size: 0.85rem;
+ font-style: italic;
+ margin-top: 0;
+ grid-column: 2 / span 2;
+ line-height: 0.5;
+ }
+
+ .film-details__plot,
+ .film-details__actors {
+ grid-column: 2 / span 2;
+ font-family: serif;
+ margin-top: 0;
+ }
+
+ .film-details__rating {
+ grid-column: 2 / span 2;
+ justify-self: start;
+ display: flex;
+ /* margin: auto; */
+ align-items: center;
+ }
+
+ .film-details__ratings__imdb {
+ flex: 1;
+ }
+ .film-details__rating__bar {
+ width: 30vw;
+ height: 1.5rem;
+ margin: 0 1rem;
+ }
+
+ .film-details__rating__score {
+ /* flex: 1; */
+ }
+
+ /* .film-details__ratings__imdb {
+ grid-column: 2 / span 2;
+ margin: 0;
+ line-height: 0.5;
+ } */
+
+ .film-details__wrapper h4 {
+ grid-column: 2 / span 2;
+ margin-bottom: 0.5rem;
+ align-self: end;
+ }
+}