diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000..813f375 Binary files /dev/null and b/.DS_Store differ diff --git a/README.md b/README.md index 7d38b84..46440c2 100644 --- a/README.md +++ b/README.md @@ -1 +1,7 @@ -# project-library \ No newline at end of file +# project-library +The project was to build a digital library, using an array of books, recipes, or a data collection of your choice. + +Applying concepts like DOM manipulation, event handling, function definitions, conditional statements, variable assignment, and object and array manipulation. + +## Netlify link +https://readcloud.netlify.app/ \ No newline at end of file diff --git a/books-images/header-booklibrary.png b/books-images/header-booklibrary.png new file mode 100644 index 0000000..da4bd91 Binary files /dev/null and b/books-images/header-booklibrary.png differ diff --git a/index.html b/index.html index cf5c31a..c384c10 100644 --- a/index.html +++ b/index.html @@ -1,13 +1,65 @@ + + + + + + + + Project Library + -

Project Library

+ +
+

ReadCloud

+
+ +
+ +
+ + + + + + + +
+ +
+
+
+ + + +
+ + + \ No newline at end of file diff --git a/pull_request_template.md b/pull_request_template.md index d92c89b..0355a16 100644 --- a/pull_request_template.md +++ b/pull_request_template.md @@ -1,7 +1,9 @@ ## Netlify link -Add your Netlify link here. -PS. Don't forget to add it in your readme as well. +https://readcloud.netlify.app/ ## Collaborators -Add your collaborators here. Write their GitHub usernames in square brackets. If there's more than one, separate them with a comma, like this: -[github-username-1, github-username-2] +Emelie Nyberg Kedert +Jonas Hellström +Jenny Andersén + +[EmelieNyberg, Jonash189, jempa182] diff --git a/script.js b/script.js index 6a61c06..cf72bba 100644 --- a/script.js +++ b/script.js @@ -1,7 +1,4 @@ -/*Here we have created two different arrays that you can work with if you want. -If you choose to create your own arrays with elements, just make sure that some -of the properties make sense to filter on, and some to sort on.*/ - +// The book array const books = [ { title: 'The Great Gatsby', @@ -71,7 +68,7 @@ const books = [ rating: 4.7, description: 'The first book in the beloved Harry Potter series, it introduces readers to the magical world of Hogwarts and the young wizard Harry Potter.', - image: "./books-images/harry-potter-and-the-sorcerer'.jpg" + image: "./books-images/harry-potter-and-the-sorcerer.jpg" }, { title: 'Moby-Dick', @@ -185,222 +182,106 @@ const books = [ } ] -const recipes = [ - { - name: 'Individual vegetarian lasagnes', - cuisineType: ['italian'], - ingredients: [ - '1.2 kg cherry tomatoes', - '5 sprigs of fresh thyme', - 'extra virgin olive oil', - '2 shallots', - '2 cloves of garlic', - '500 g baby spinach', - '8-12 fresh or dried lasagne sheets', - '350 g ricotta cheese', - 'WHITE SAUCE', - '600 ml milk', - '25 g unsalted butter', - '2 heaped tablespoons flour', - '150 g vegetarian sharp, mature cheese', - '100 g mozzarella' - ], - source: 'Jamie Oliver', - totalTime: 130, - url: 'http://www.jamieoliver.com/recipes/vegetables-recipes/individual-vegetarian-lasagnes/', - image: './recipe-images/individual-vegetarian-lasagnes.jpg' - }, - { - name: 'Vegetarian Stir-Fried Garlic Scape', - cuisineType: ['Balanced'], - ingredients: [ - '8 oz. garlic scapes', - '3 oz. baby corn', - '3 oz. carrots', - '1 oz. dried shiitake mushrooms', - '1 clove of garlic sliced thinly', - '3 slices of fresh ginger root', - '2 tablespoons vegetable oil', - '1/4 cup shaoxing cooking wine', - '1/4 vegetarian stock or water', - '1 tablespoon light soy sauce', - '1 teaspoon sugar', - '1 teaspoon cornstarch', - '1/4 teaspoon ground white pepper' - ], - source: 'Red Cook', - totalTime: null, - url: 'http://redcook.net/2010/06/16/garlic-scape-an-off-menu-treat/', - image: './recipe-images/vegetarian-stir-fried-garlic-s.jpg' - }, - { - name: 'Cheat’s cheesy focaccia', - cuisineType: ['Italian'], - ingredients: [ - '500g pack bread mix', - '2 tbsp olive oil , plus a little extra for drizzling', - '25g parmesan (or vegetarian alternative), grated', - '75g dolcelatte cheese (or vegetarian alternative)' - ], - source: 'BBC Good Food', - totalTime: 40, - url: 'https://www.bbcgoodfood.com/recipes/cheats-cheesy-focaccia', - image: './recipe-images/cheat’s-cheesy-focaccia.jpg' - }, - { - name: "Vegetarian Shepherd's Pie", - cuisineType: ['Balanced', 'High-Fiber'], - ingredients: [ - '2 tablespoons extra-virgin olive oil', - '1 large onion, finely diced', - '2 carrots, peeled and thinly sliced', - '2 celery stalks, thinly sliced', - '10 ounces cremini mushrooms, trimmed and sliced', - '1 tablespoon tomato paste', - "1 tablespoon vegetarian Worcestershire sauce, such as Annie's Naturals", - '1 dried bay leaf', - '1 cup French green lentils, picked over', - 'Kosher salt and freshly ground pepper', - '1 cup frozen peas', - '2 pounds Yukon Gold potatoes, scrubbed and cut into 1 1/2-inch pieces', - '4 cloves garlic', - '4 tablespoons unsalted butter', - '1/2 cup whole milk, warmed' - ], - source: 'Martha Stewart', - totalTime: 120, - url: 'https://www.marthastewart.com/1535235/vegetarian-shepherds-pie', - image: "./recipe-images/vegetarian-shepherd's-pie.jpg" - }, - { - name: 'Chicken Paprikash', - cuisineType: ['Low-Carb'], - ingredients: [ - '640 grams chicken - drumsticks and thighs ( 3 whole chicken legs cut apart)', - '1/2 teaspoon salt', - '1/4 teaspoon black pepper', - '1 tablespoon butter – cultured unsalted (or olive oil)', - '240 grams onion sliced thin (1 large onion)', - '70 grams Anaheim pepper chopped (1 large pepper)', - '25 grams paprika (about 1/4 cup)', - '1 cup chicken stock', - '1/2 teaspoon salt', - '1/2 cup sour cream', - '1 tablespoon flour – all-purpose' - ], - source: 'No Recipes', - totalTime: 80, - url: 'http://norecipes.com/recipe/chicken-paprikash/', - image: './recipe-images/chicken-paprikash.jpg' - }, - { - name: 'Baked Chicken', - cuisineType: ['american'], - ingredients: [ - '6 bone-in chicken breast halves, or 6 chicken thighs and wings, skin-on', - '1/2 teaspoon coarse salt', - '1/2 teaspoon Mrs. Dash seasoning', - '1/4 teaspoon freshly ground black pepper' - ], - source: 'Martha Stewart', - totalTime: 90, - url: 'http://www.marthastewart.com/318981/baked-chicken', - image: './recipe-images/baked-chicken.jpg' - }, - { - name: 'Deep Fried Fish Bones', - cuisineType: ['south east asian'], - ingredients: ['8 small whiting fish or smelt', '4 cups vegetable oil'], - source: 'Serious Eats', - totalTime: 31, - url: 'http://www.seriouseats.com/recipes/2011/03/deep-fried-fish-bones-recipe.html', - image: './recipe-images/deep-fried-fish-bones.jpg' - }, - { - name: 'Burnt-Scallion Fish', - cuisineType: ['chinese'], - ingredients: [ - '2 bunches scallions', - '8 tbsp. butter', - '2 8-oz. fish filets' - ], - source: 'Saveur', - totalTime: 70, - url: 'http://www.saveur.com/article/Recipes/Burnt-Scallion-Fish', - image: './recipe-images/fish-dish.jpg' - }, - { - name: 'Curry-Crusted Fish', - cuisineType: ['south east asian'], - ingredients: [ - '3 slices bread , about 85g/3oz in total', - '1 lime', - '1.0 tbsp Korma curry paste', - '4 thick white fish fillets' - ], - source: 'BBC Good Food', - totalTime: 80, - url: 'http://www.bbcgoodfood.com/recipes/4717/', - image: './recipe-images/fish-dish.jpg' - }, - { - name: 'Meat Stock', - cuisineType: 'american', - ingredients: [ - '2.5 pounds beef marrow bones', - '1 large onion, quartered', - '2 carrots, sliced', - '1 leek, cleaned and sliced', - '2 celery stalks, sliced', - '2.5 pounds organic beef stew meat, cubed', - '2 tablespoons tomato paste', - '5 cloves garlic', - '2 bay leaves', - '3 sprigs thyme', - '3 sprigs Italian parsley', - '1/2 teaspoon black peppercorns' - ], - source: 'Food52', - totalTime: 60, - url: 'https://food52.com/recipes/3712-meat-stock', - image: './recipe-images/meat.jpg' - }, - { - name: 'Homemade Meat Broth', - cuisineType: 'american', - ingredients: [ - '1 teaspoon salt', - '1 carrot, peeled', - '1 medium onion, peeled', - '2 or 3 celery stalks', - '¼ red or yellow bell pepper, stripped of all its seeds', - '1 small boiling potato, peeled', - '1 ripe, fresh tomato, or 1 canned Italian plum tomato, drained of juice', - '5 pounds assorted pieces of meat and bones (see meat suggestions above), of which no less than 1½ pounds is all meat' - ], - source: 'Cookstr', - totalTime: 60, - url: 'http://www.cookstr.com/recipes/il-brodo-homemade-meat-broth', - image: './recipe-images/meat.jpg' - }, - { - name: 'Spice-Rubbed Grilled Flap Meat (Sirloin Tip) Recipe', - cuisineType: 'south-american', - ingredients: [ - '1 tablespoon whole black peppercorns, toasted', - '1 teaspoon coriander seed, toasted', - '1 teaspoon fennel seed, toasted', - '1 teaspoon cumin pods, toasted', - '1 teaspoon red pepper flakes', - '1/2 teaspoon dried oregano', - '2 medium cloves garlic, minced (about 2 teaspoons)', - '2 tablespoons vegetable or canola oil', - '1 whole flap meat steak, 2 to 2 1/2 pounds', - 'Kosher salt' - ], - source: 'Serious Eats', - totalTime: 240, - url: 'http://www.seriouseats.com/recipes/2012/05/spice-rubbed-grilled-flap-meat-sirloin-tip-recipe.html', - image: './recipe-images/grilled.jpg' +// DOM +const buttonShuffle = document.getElementById('buttonShuffle'); +const bookContainer = document.getElementById('bookContainer'); +const genreFilter = document.getElementById('genreFilter'); +const buttonPopular = document.getElementById('buttonPopular'); +const buttonLatest = document.getElementById('buttonLatest'); +const buttons = document.querySelectorAll('button'); + +// Show all books from array +const displayBooks = (bookArray) => { + bookContainer.innerHTML = ''; + bookArray.forEach(book => { + bookContainer.innerHTML += ` +
+ ${book.title} +

${book.title}

+

${book.author}

+

Year: ${book.year}

+

${book.genre}

+

⭐️ ${book.rating}

+

${book.description}

+
+ `; + }); +}; + +// Random book button +const getRandomBook = () => { + const randomIndex = Math.floor(Math.random() * books.length); + const book = books[randomIndex]; + + bookContainer.innerHTML = ` +
+ ${book.title} +

${book.title}

+

${book.author}

+

Year: ${book.year}

+

${book.genre}

+

⭐️ ${book.rating}

+

${book.description}

+
+ `; +}; + +// Filter by genre +const filterGenre = () => { + const value = genreFilter.value; + if (value === 'all') { + // Show all books + displayBooks(books); + } else { + // filter the books + const filteredList = books.filter(book => book.genre.toLowerCase() === value.toLowerCase()); + displayBooks(filteredList); } -] +} + +// Filter most poular books +const filterPopular = () => { + const sortedRating = books.sort((a, b) => b.rating - a.rating); + displayBooks(sortedRating); +} + +// Filter latest books +const filterLatest = () => { + const sortedYear = books.sort((a, b) => b.year - a.year); + displayBooks(sortedYear); +} + +// Button colored if active/clicked +const handleButtonClick = (event) => { + buttons.forEach(button => button.classList.remove('active')); + event.target.classList.add('active'); +}; + +// Adding eventlisteners for all buttons +buttons.forEach(button => { + button.addEventListener('click', handleButtonClick); +}); + +// Drop-down colored if active/selected +const handleDropdownSelection = () => { + const selectedValue = genreFilter.value; + + // If value is chosen the dropdown is active + if (selectedValue) { + genreFilter.classList.add('active'); + } else { + genreFilter.classList.remove('active'); + } +}; + +//Eventlistener +buttonShuffle.addEventListener("click", getRandomBook); +genreFilter.addEventListener("change", filterGenre); +buttonPopular.addEventListener("click", filterPopular); +buttonLatest.addEventListener("click", filterLatest); +genreFilter.addEventListener('change', handleDropdownSelection); + +// Invoking displayBooks function +displayBooks(books); + + diff --git a/style.css b/style.css index e69de29..7166ebe 100644 --- a/style.css +++ b/style.css @@ -0,0 +1,187 @@ +body { + margin: 0; + background-color: D9D9D9; + font-family: "Roboto Serif", serif; + font-optical-sizing: auto; + font-weight: 300; + font-style: normal; + font-variation-settings: + "wdth" 100, + "GRAD" 0; +} + +/* .wrapper { + background-color: #2f2e47; + margin: auto; + max-width: 1100px; +} */ +/* +.roboto-serif { + +} */ + + +header { + background-image: url("/books-images/header-booklibrary.png"); + background-size: cover; + background-repeat: no-repeat; + min-height: 500px; + position: relative; + /* Behövs för att positionera överlägget */ +} + +header::before { + content: ""; + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-color: rgba(0, 0, 0, 0.1); + /* Mörkare överlägg (50% opacitet) */ + z-index: 1; + /* Gör att överlägget hamnar över bakgrunden */ +} + +header h1, +header p { + position: relative; + z-index: 2; + /* Gör att texten hamnar över överlägget */ +} + +h1 { + margin: 0; + padding: 30px; + color: white; + font-family: "Playfair Display SC", serif; + font-weight: 500; + font-style: normal; + font-size: 270%; +} + +.button-container { + max-width: 1200px; + margin: auto; + padding: 0.5% 0 0.5% 0; +} + +/* Style for inactive buttons/drop-down menu */ +select, +button { + padding: 12px; + margin: 5px; + background-color: white; + color: #2f2e47; + border: 2px solid #2f2e47; + border-radius: 5px; + cursor: pointer; + transition: all 0.3s ease; + text-align: center; + font-family: "Roboto Serif", serif; +} + +/* Style for active buttons */ +button.active { + background-color: #2f2e47; + color: white; + +} + +/* Button hover-effekt */ +button:hover { + background-color: #2f2e47; + color: white; +} + +.book-wrapper { + background-color: #2f2e47; +} + +/* Container with all cards */ +.book-container { + display: grid; + grid-template-columns: repeat(4, 1fr); + gap: 1rem; + max-width: 1200px; + margin: auto; + padding: 2% 0; +} + +/* Syling on cards */ +.card { + background-color: white; + border: 1px solid #ddd; + padding: 10px; + margin: 10px; + border-radius: 8px; +} + +/* Styling */ +.card img { + width: 100%; + height: 200px; + object-fit: cover; +} + +select:focus { + border-color: #2f2e47; + outline: #2f2e47; +} + +select.active { + background-color: #2f2e47; + color: white; + border: 1px solid #2f2e47; +} + +/* Dropdown hover-effekt */ +select:hover { + background-color: #2f2e47; + color: white; +} + +footer { + display: flex; + flex-direction: row-reverse; + margin: 1% 3%; +} + +h4 { + font-weight: 50; +} + +/* Tablet */ +@media (min-width: 668px) and (max-width: 1024px) { + .book-container { + grid-template-columns: repeat(2, 1fr); + } +} + +/* Mobil */ +@media (max-width: 667px) { + + header { + min-height: 300px; + display: flex; + justify-content: center; + align-items: center; + } + + .book-container { + grid-template-columns: repeat(1, 1fr); + } + + .button-container { + display: flex; + justify-content: space-evenly; + } + + select, + button { + width: 85px; + font-size: 10px; + padding: 6px; + } + +} \ No newline at end of file