diff --git a/.DS_Store b/.DS_Store index f3d46a1..c517da4 100644 Binary files a/.DS_Store and b/.DS_Store differ diff --git a/public/assets/css/style.css b/public/assets/css/style.css index 930823b..ae459c9 100644 --- a/public/assets/css/style.css +++ b/public/assets/css/style.css @@ -15,6 +15,66 @@ body { justify-content: flex-start; } +.header { + grid-area: header; + display: flex; + flex-direction: row; + height: 100px; + align-items: center; + justify-content: space-between; +} + +.header-left { + display: flex; + flex-direction: row; + align-items: center; + justify-content: flex-start; + gap: 20px; +} + +.header-right { + display: flex; + flex-direction: row; + align-items: center; + justify-content: flex-end; +} + +.nw { + grid-area: nw; +} + +.ne { + grid-area: ne; +} + +.se { + grid-area: se; +} + +.sw { + grid-area: sw; +} + +.box { + border: 2px solid white; + margin: 2px; + padding: 4px; + display: flex; + flex-direction: column; + justify-content: flex-start; + text-justify: center; +} + +.grid-container { + display: grid; + grid-template-columns: 50px, 50px; + grid-template-rows: auto; + grid-template-areas: + "header header" + "nw ne" + "sw se"; +} + .center { display: flex; flex-direction: column; @@ -40,7 +100,6 @@ a { color: white; padding-left: 5px; padding-right: 5px; - margin-top: 4px; text-decoration: none; text-align: center; align-items: center; @@ -53,9 +112,7 @@ a { button { background-color: transparent; border: 2px solid #606060; - margin-left: 10px; - margin-top: 10px; - margin-bottom: 10px; + margin: 10px; width: 75px; border-radius: 5px; padding: 5px; @@ -203,15 +260,12 @@ h2 { color: #ffffff; font: 32px "Verdana"; margin: 0; - margin-top: 32px; - margin-bottom: 10px; } h3 { color: #CCCCCC; font: 24px "Verdana"; margin: 0; - margin-bottom: 30px; } p { diff --git a/public/home.html b/public/home.html index 541df76..44e692a 100644 --- a/public/home.html +++ b/public/home.html @@ -5,20 +5,49 @@ -
-

Home

-

Welcome, %

- Search Players -
- Personal Information -
- -
- +
+
+
+

Paydirt

+ Search Players +
+
+
+ Welcome, % + + +
- - - +
+
+

Favorites

+ + + + + +
+
+
+

Highest contracts

+ + + + + +
+
+
+

Highest paydirt score

+
+
+

Highest offense score

+
+ + + + + diff --git a/public/home.js b/public/home.js new file mode 100644 index 0000000..84f8b51 --- /dev/null +++ b/public/home.js @@ -0,0 +1,87 @@ +import { postData, verifyLogin } from "./client.js"; +import { formatSalary } from "./utils.js"; + +const token = window.localStorage.getItem("token"); + +const highest = document.querySelector("#highest"); + +updateHighest(); +updateFavorites(); + +async function updateHighest() { + if (!verifyLogin()) return; + + const tableHeader = document.querySelector("#highest thead"); + const tableBody = document.querySelector("#highest tbody"); + + let resultObject = await postData("/getHighest", { amount: 10 }, token); + console.log(resultObject); + + if (resultObject.matches.length === 0) { + alert("Error loading highest"); + return; + } + + tableHeader.innerHTML = ""; + const headerRow = document.createElement("tr"); + //Object.keys(resultObject.matches[0]).forEach(attribute => { + // headerRow.innerHTML += `${attribute}`; + //}); + headerRow.innerHTML = ` + Name + Contract + Team + Position + `; + tableHeader.appendChild(headerRow); + + tableBody.innerHTML = ""; + resultObject.matches.forEach(player => { + const row = document.createElement("tr"); + + //for (attribute in player) { + // row.innerHTML += `${player}l`; + //} + row.innerHTML = ` + ${player.PlayerName} + ${formatSalary(player.TotalValue)} + ${player.Team} + ${player.Position} + `; + tableBody.appendChild(row); + }); +}; + +async function updateFavorites() { + if (!verifyLogin()) return; + + const tableHeader = document.querySelector("#favorites thead"); + const tableBody = document.querySelector("#favorites tbody"); + + let resultObject = await postData("/getWatchlist", {}, token); + + tableHeader.innerHTML = ""; + const headerRow = document.createElement("tr"); + //Object.keys(resultObject.matches[0]).forEach(attribute => { + // headerRow.innerHTML += `${attribute}`; + //}); + headerRow.innerHTML = ` + Name + Team + Position + `; + tableHeader.appendChild(headerRow); + + tableBody.innerHTML = ""; + console.log(resultObject.watchlist); + resultObject.watchlist.forEach(player => { + const row = document.createElement("tr"); + + row.innerHTML = ` + ${player.PlayerName} + ${player.Team} + ${player.Position} + `; + tableBody.appendChild(row); + }); +}; diff --git a/public/player.html b/public/player.html index e8f0738..48e0e82 100644 --- a/public/player.html +++ b/public/player.html @@ -7,7 +7,7 @@
-

[Player Name]

+

[Player Name]

@@ -21,17 +21,19 @@ - - - - - + + + + +
[Name][ID][Salary][Team][Position][Name][ID][Salary][Team][Position]
+ +
Return to Player Search diff --git a/public/player.js b/public/player.js index ad41ad0..4d3f678 100644 --- a/public/player.js +++ b/public/player.js @@ -10,7 +10,28 @@ const tableBody = document.getElementById("results"); const table = document.getElementById("table"); const nomatch = document.getElementById("nomatch"); +const watchButton = document.querySelector("#watch"); + +//const watchlist = await postData("/getWatchlist", {}, token); + populatePlayerData(); +updateIsWatched(); + +watchButton.onclick = async e => { + e.preventDefault(); + + const [, , id] = window.location.pathname.split("/"); + const resultObject = await postData("/toggleWatched", { id: id }, token); + alert(resultObject.message); + updateIsWatched(); +} + +async function updateIsWatched() { + const [, , id] = window.location.pathname.split("/"); + const resultObject = await postData("/isWatched", {id: id}, token); + const isWatched = resultObject.isWatched; + watchButton.innerHTML = isWatched ? "Stop Watching Player" : "Watch Player"; +} async function populatePlayerData() { const [, , id] = window.location.pathname.split("/"); diff --git a/public/search.js b/public/search.js index 73a575d..8c3312b 100644 --- a/public/search.js +++ b/public/search.js @@ -29,24 +29,32 @@ if (searchForm)searchForm.onsubmit = async e => { table.style.display = ""; tableHeader.innerHTML = ""; const headerRow = document.createElement("tr") - Object.keys(resultObject.matches[0]).forEach(attribute => { - headerRow.innerHTML += `${attribute}`; - }) + //Object.keys(resultObject.matches[0]).forEach(attribute => { + // headerRow.innerHTML += `${attribute}`; + //}); + headerRow.innerHTML += ` + ID + Name + Contract + Team + Position + `; tableHeader.appendChild(headerRow); tableBody.innerHTML = ""; resultObject.matches.forEach(player => { const row = document.createElement("tr"); + console.log(player); //for (attribute in player) { // row.innerHTML += `${player}l`; //} row.innerHTML = ` - ${player.player_id} - ${player.player_name} - ${formatSalary(player.salary)} - ${player.team_name} - ${player.position} + ${player.PlayerID} + ${player.PlayerName} + ${formatSalary(player.TotalValue)} + ${player.Team} + ${player.Position} `; tableBody.appendChild(row); }); diff --git a/server.js b/server.js index 2dbb861..11b480c 100644 --- a/server.js +++ b/server.js @@ -32,7 +32,7 @@ dbConfig = { user: "server", password: "TorusField1*", server: "mssql.rochesterx.dev", - database: "ProjectTest", + database: "Project", options: { trustServerCertificate: true } }; @@ -105,22 +105,91 @@ app.post("/login", async (req, res) => { } }); +app.post("/getWatchlist", authenticate, async (req, res) => { + const { id } = req.body; + + const watchlist = await pool.request() + .input("userID", sql.Int, req.user.Id) + .input("id", sql.Int, id) + .query(`SELECT Player.PlayerName, Player.Team, Player.Position, Player.PlayerID FROM Watch JOIN Player ON Watch.PlayerID = Player.PlayerID WHERE UserID = @userID`); + + res.status(200).json({ watchlist: watchlist.recordset }); +}); + +app.post("/isWatched", authenticate, async (req, res) => { + const { id } = req.body; + + const watchlist = await pool.request() + .input("userID", sql.Int, req.user.Id) + .input("id", sql.Int, id) + .query(`SELECT PlayerID FROM Watch WHERE UserID = @userID`); + + const isWatched = watchlist.recordset.some(row => row.PlayerID === parseInt(id)); + + res.status(200).json({ isWatched: isWatched }); +}); + +app.post("/toggleWatched", authenticate, async (req, res) => { + const { id } = req.body; + + const watchlist = await pool.request() + .input("userID", sql.Int, req.user.Id) + .input("id", sql.Int, id) + .query(`SELECT PlayerID FROM Watch WHERE UserID = @userID`); + console.log(watchlist.recordset); + + const isWatched = watchlist.recordset.some(row => row.PlayerID === parseInt(id)); + console.log(isWatched); + + if (isWatched) { + const result = await pool.request() + .input("userID", sql.Int, req.user.Id) + .input("id", sql.Int, id) + .query(`DELETE FROM Watch WHERE UserID = @userID AND PlayerID = @id`); + + res.status(200).json({ message: "No longer watching player" }); + return; + } + + // Otherwise, watch the player + const result = await pool.request() + .input("userID", sql.Int, req.user.Id) + .input("id", sql.Int, id) + .query(`INSERT INTO Watch (UserID, PlayerID) VALUES (@userID, @id)`); + + res.status(200).json({ message: "Watching Player" }); +}); + app.post("/getPlayers", authenticate, async (req, res) => { const { player } = req.body; const result = await pool.request() .input("query", sql.VarChar, player) - .query(`SELECT * FROM Player WHERE player_name LIKE '%' + @query + '%'`); + .query(`SELECT p.PlayerID, p.PlayerName, c.TotalValue, p.Team, p.Position FROM Player AS p JOIN Contract AS c ON p.PlayerID = c.PlayerID WHERE p.PlayerName LIKE '%' + @query + '%'`); res.status(200).json({ query: player, matches: result.recordset }); }); +app.post("/getHighest", authenticate, async (req, res) => { + const { amount } = req.body; + + const result = await pool.request() + .input("amount", sql.Int, amount) + .query(` + SELECT TOP (@amount) p.PlayerID, p.PlayerName, p.[Position], p.Team, TotalValue + FROM Player AS p JOIN Contract AS c ON p.PlayerID = c.PlayerID + ORDER BY TotalValue DESC; + `); + + res.status(200).json({ matches: result.recordset }); +}); + app.post("/getPlayer", authenticate, async (req, res) => { const { id } = req.body; const result = await pool.request() .input("query", sql.VarChar, id) - .query(`SELECT * FROM Player WHERE player_id = @query`); + .query(`SELECT p.PlayerName, p.PlayerID, c.TotalValue, p.Team, p.Position FROM Player AS p JOIN Contract AS c ON p.PlayerID = c.PlayerID WHERE p.PlayerID = @query`); if (result.recordset.length !== 1) { res.status(400).json({ success: false })