diff --git a/README.md b/README.md index a12177342..0bc70d2ad 100644 --- a/README.md +++ b/README.md @@ -1,44 +1,39 @@ -# WEB102 Prework - *Name of App Here* +# WEB102 Prework - *Sea Monster Crowdfunding Web App* -Submitted by: **Your Name Here** +Submitted by: **Jaydon Bingham** -**Name of your app** is a website for the company Sea Monster Crowdfunding that displays information about the games they have funded. +**Sea Monster Crowdfunding Web App** is a website for the company Sea Monster Crowdfunding that displays information about the games they have funded. -Time spent: **X** hours spent in total +Time spent: **6** hours spent in total ## Required Features The following **required** functionality is completed: -* [ ] The introduction section explains the background of the company and how many games remain unfunded. -* [ ] The Stats section includes information about the total contributions and dollars raised as well as the top two most funded games. -* [ ] The Our Games section initially displays all games funded by Sea Monster Crowdfunding -* [ ] The Our Games section has three buttons that allow the user to display only unfunded games, only funded games, or all games. +* [x] The introduction section explains the background of the company and how many games remain unfunded. +* [x] The Stats section includes information about the total contributions and dollars raised as well as the top two most funded games. +* [x] The Our Games section initially displays all games funded by Sea Monster Crowdfunding +* [x] The Our Games section has three buttons that allow the user to display only unfunded games, only funded games, or all games. The following **optional** features are implemented: -* [ ] List anything else that you can get done to improve the app functionality! +* [x] Custom message below each gamecard displaying all relevant information, which changes depending on whether funding has been completed. +* [x] Checkbox button which changes the information display from gamecards to a table (information displayed is based on last button clicked) ## Video Walkthrough Here's a walkthrough of implemented features: -Video Walkthrough - - -GIF created with ... - +
CodePath Website Demo
+GIF created with ScreenToGif ## Notes -Describe any challenges encountered while building the app. +I wasn't incredibly challenged while building the app, but there were a couple concepts I was unfamiliar with, such as the ternary operator and destructuring. I did a bit of research, got much more familiar with these concepts, and finished up development. I was relatively familiar with other parts of the application because of previous experience, and didn't see too much difficulty. Creating a custom improvement was also a bit harder compared to the rest (as it wasn't as guided) but I was able to brainstorm and implement my custom feature after spending a bit of time on it. ## License - Copyright [yyyy] [name of copyright owner] + Copyright [2023] [Jaydon Bingham] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/index.html b/index.html index ba8123340..420d0aa70 100644 --- a/index.html +++ b/index.html @@ -54,6 +54,10 @@

Our Games

+
diff --git a/index.js b/index.js index 86fe7d438..53854fe26 100644 --- a/index.js +++ b/index.js @@ -29,27 +29,61 @@ const gamesContainer = document.getElementById("games-container"); function addGamesToPage(games) { // loop over each item in the data + for (let game of games){ + + // Set-up + let gameCard = document.createElement("div"); + gameCard.classList.add("game-card"); + + // Customization: Custom message depending on goal being met or not, made more sense than a single type of message + let goalsMet = ` +

The $${game["goal"].toLocaleString('en-US')} goal ${game["pledged"] >= game["goal"] ? "has been met!": "has not been met."} + For this game, ${game["backers"].toLocaleString('en-US')} backers have pledged $${game["pledged"].toLocaleString()} total.

+ `; + + // Adding info to page + const gameInfo = ` + ${game[ +

${game["name"]}

+

${game["description"]}

+ ${goalsMet} + `; + gameCard.innerHTML = gameInfo; + document.getElementById("games-container").appendChild(gameCard); + } +} +// Customization: function adds games to an html table when called +function addGamesToTable(games) { + + // Set-up + let gameTable = document.createElement("table"); + let tableInfo = ` + Name + Description + Pledged + Goal + Backers + ` + + // Loops through each game and sets up the info as expected + for (let game of games){ + tableInfo += ` + + + + + + ` + } - // create a new div element, which will become the game card - - - // add the class game-card to the list - - - // set the inner HTML using a template literal to display some info - // about each game - // TIP: if your images are not displaying, make sure there is space - // between the end of the src attribute and the end of the tag ("/>") - - - // append the game to the games-container - + // Adding info to page + gameTable.innerHTML = tableInfo; + document.getElementById("games-container").appendChild(gameTable); } -// call the function we just defined using the correct variable -// later, we'll call this function using a different list of games - +// Function Call -> Moved to 248 +// addGamesToPage(GAMES_JSON); /************************************************************************************* * Challenge 4: Create the summary statistics at the top of the page displaying the @@ -61,19 +95,22 @@ function addGamesToPage(games) { const contributionsCard = document.getElementById("num-contributions"); // use reduce() to count the number of total contributions by summing the backers - +const contributions = GAMES_JSON.reduce( (accum, game) => {return accum + game["backers"];}, 0); // set the inner HTML using a template literal and toLocaleString to get a number with commas - +contributionsCard.innerHTML = `

${contributions.toLocaleString()}

`; // grab the amount raised card, then use reduce() to find the total amount raised const raisedCard = document.getElementById("total-raised"); +const raised = GAMES_JSON.reduce( (accum, game) => {return accum + game["pledged"];}, 0); // set inner HTML using template literal - +raisedCard.innerHTML = `

$${raised.toLocaleString()}

`; // grab number of games card and set its inner HTML const gamesCard = document.getElementById("num-games"); +const games = GAMES_JSON.length; +gamesCard.innerHTML = `

${games.toLocaleString()}

`; /************************************************************************************* @@ -82,43 +119,81 @@ const gamesCard = document.getElementById("num-games"); * Skills used: functions, filter */ +// Customization: record last click to ensure switching to table format works on current button +let lastClick = "all"; + // show only games that do not yet have enough funding function filterUnfundedOnly() { + + // Setup deleteChildElements(gamesContainer); + lastClick = "unfunded"; + let tableBtn = document.getElementById("table-btn"); // use filter() to get a list of games that have not yet met their goal + let unfundedGames = GAMES_JSON.filter(game => { return game["pledged"] < game["goal"];}); - - // use the function we previously created to add the unfunded games to the DOM - + // use the function we previously created to add the unfunded games to the DOM, depending on specificied format + tableBtn.checked ? addGamesToTable(unfundedGames) : addGamesToPage(unfundedGames); } // show only games that are fully funded function filterFundedOnly() { + + // Setup deleteChildElements(gamesContainer); + lastClick = "funded"; + let tableBtn = document.getElementById("table-btn"); - // use filter() to get a list of games that have met or exceeded their goal - - - // use the function we previously created to add unfunded games to the DOM + // use filter() to get a list of g\ames that have met or exceeded their goal + let fundedGames = GAMES_JSON.filter(game => { return game["pledged"] >= game["goal"];}); + // use the function we previously created to add the unfunded games to the DOM, depending on specificied format + tableBtn.checked ? addGamesToTable(fundedGames) : addGamesToPage(fundedGames); } // show all games function showAllGames() { - deleteChildElements(gamesContainer); - // add all games from the JSON data to the DOM + // Setup + deleteChildElements(gamesContainer); + lastClick = "all" + let tableBtn = document.getElementById("table-btn"); + // add all games from the JSON data to the DOM, depending on specificied format + tableBtn.checked ? addGamesToTable(GAMES_JSON) : addGamesToPage(GAMES_JSON); } +// Customization: Sets up the Table depending on the last button clicked +function setTable() { + switch (lastClick) { + case "funded": + filterFundedOnly(); + break; + + case "unfunded": + filterUnfundedOnly(); + break; + + default: + showAllGames(); + break; + } +} // select each button in the "Our Games" section const unfundedBtn = document.getElementById("unfunded-btn"); const fundedBtn = document.getElementById("funded-btn"); const allBtn = document.getElementById("all-btn"); +const tableBtn = document.getElementById("table-btn"); // add event listeners with the correct functions to each button +unfundedBtn.addEventListener("click", filterUnfundedOnly); +fundedBtn.addEventListener("click", filterFundedOnly); +allBtn.addEventListener("click", showAllGames); +// Customization: Event listener for new button +tableBtn.addEventListener("change", () => tableBtn.checked != "checked" ? tableBtn.checked = "checked" : tableBtn.checked = null); +tableBtn.addEventListener("change", setTable); /************************************************************************************* * Challenge 6: Add more information at the top of the page about the company. @@ -129,13 +204,20 @@ const allBtn = document.getElementById("all-btn"); const descriptionContainer = document.getElementById("description-container"); // use filter or reduce to count the number of unfunded games - +let unfundedGames = GAMES_JSON.filter(game => { return game["pledged"] < game["goal"];}).length; // create a string that explains the number of unfunded games using the ternary operator - +let unfundedStr = `A total of $${GAMES_JSON.reduce( (accum, game) => {return accum + game["pledged"];}, 0).toLocaleString()} has been raised for ${GAMES_JSON.length} games. +Currently, ${unfundedGames} ${unfundedGames > 1 ? "games remain" : "game remains"} unfunded. +We need your help to fund ${unfundedGames > 1 ? "these amazing games" : "this amazing game"}!`; // create a new DOM element containing the template string and append it to the description container +const description = document.createElement("p"); +const descriptionText = document.createTextNode(unfundedStr); +description.appendChild(descriptionText); + +descriptionContainer.appendChild(description); /************************************************************************************ * Challenge 7: Select & display the top 2 games * Skills used: spread operator, destructuring, template literals, sort @@ -149,7 +231,19 @@ const sortedGames = GAMES_JSON.sort( (item1, item2) => { }); // use destructuring and the spread operator to grab the first and second games +let [firstGame, secondGame, ...otherGames] = sortedGames; // create a new element to hold the name of the top pledge game, then append it to the correct element - -// do the same for the runner up item \ No newline at end of file +const firstGameElement = document.createElement("p"); +const firstGameName = document.createTextNode(`${firstGame["name"]}`); +firstGameElement.appendChild(firstGameName); +firstGameContainer.appendChild(firstGameElement); + +// do the same for the runner up item +const secondGameElement = document.createElement("p"); +const secondGameName = document.createTextNode(`${secondGame["name"]}`); +secondGameElement.appendChild(secondGameName); +secondGameContainer.appendChild(secondGameElement); + +// Late function call ensures list of games is sorted by pledged +addGamesToPage(GAMES_JSON); \ No newline at end of file diff --git a/style.css b/style.css index 11303c2a7..d339c6beb 100644 --- a/style.css +++ b/style.css @@ -21,6 +21,9 @@ body { .stats-container { display: flex; + align-items: center; + cursor: pointer; + box-shadow: 0 0 30px lightblue; } .stats-card { @@ -72,4 +75,21 @@ button { padding: 1%; margin: 1%; border-radius: 7px; -} \ No newline at end of file +} + +/* Custom cs for table and tale elements */ +table { + border-collapse: collapse; + box-shadow: 0 0 30px lightblue; + border: 3px solid ; + width: 90%; +} + +th, td { + border-collapse: collapse; + background-color: #a8b0bc; + padding: 10px; + border: 2 px solid lightblue; + box-shadow: 0 0 30px lightblue; + box-sizing: border-box; + } \ No newline at end of file
${game["name"]} ${game["description"]} $${game["pledged"].toLocaleString()} $${game["goal"].toLocaleString()} ${game["backers"].toLocaleString()}