diff --git a/database/scores/games.js b/database/scores/games.js index 96463ec..9af0b89 100644 --- a/database/scores/games.js +++ b/database/scores/games.js @@ -1,5 +1,4 @@ const database = require('./../database'); -const moment = require('moment'); @@ -51,8 +50,9 @@ async function retrieveByTeamDivisionAndSeason(teamID, divisionID, seasonID) { teamScore = opponentIsTeam2 ? row[6] : row[7]; opponentScore = opponentIsTeam2 ? row[7] : row[6]; - gamesList.push(new Game(row[0], moment(row[3]), teamID, opponentID, teamScore, opponentScore)); + gamesList.push(new Game(row[0], row[3].toISOString().slice(0,10), teamID, opponentID, teamScore, opponentScore)); }); + console.log(gamesList); return gamesList; } diff --git a/database/scores/teams.js b/database/scores/teams.js index 89f2c4c..893cc34 100644 --- a/database/scores/teams.js +++ b/database/scores/teams.js @@ -51,6 +51,14 @@ async function retrieveBySport(sportID) { return teamsList; } +async function getFromID(id) { + const query = `SELECT team_name + FROM scores.teams + WHERE team_id = $1;`; + const name = (await database.executeQuery(query, [id]))[0][0]; + return new Team(id, name); +} + @@ -58,4 +66,5 @@ async function retrieveBySport(sportID) { exports.add = add; exports.rename = rename; exports.remove = remove; -exports.retrieveBySport = retrieveBySport; \ No newline at end of file +exports.retrieveBySport = retrieveBySport; +exports.getFromID = getFromID; \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 821a54c..225db7b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,7 +14,6 @@ "dotenv": "^10.0.0", "express": "~4.16.0", "http-errors": "~1.6.2", - "moment": "^2.29.1", "morgan": "~1.9.0", "nodemailer": "^6.6.5", "passport": "^0.5.0", @@ -910,14 +909,6 @@ "ms": "2.0.0" } }, - "node_modules/moment": { - "version": "2.29.1", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz", - "integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==", - "engines": { - "node": "*" - } - }, "node_modules/morgan": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.9.0.tgz", @@ -2409,11 +2400,6 @@ } } }, - "moment": { - "version": "2.29.1", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz", - "integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==" - }, "morgan": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.9.0.tgz", diff --git a/package.json b/package.json index 2e3323a..c94c979 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,6 @@ "dotenv": "^10.0.0", "express": "~4.16.0", "http-errors": "~1.6.2", - "moment": "^2.29.1", "morgan": "~1.9.0", "nodemailer": "^6.6.5", "passport": "^0.5.0", diff --git a/public/scripts/data.js b/public/scripts/data.js index 7e21436..61f3923 100644 --- a/public/scripts/data.js +++ b/public/scripts/data.js @@ -26,4 +26,16 @@ export async function getTeams(sportID) { const response = await fetch(`/data/teams?sport=${+sportID}`); const teamsList = await response.json(); return teamsList; +} + +export async function getTeamName(teamID) { + const response = await fetch(`/data/team?team=${+teamID}`); + const team = await response.json(); + return team.name; +} + +export async function getGames(teamID, divisionID, seasonID) { + const response = await fetch(`/data/games?team=${+teamID}&division=${+divisionID}&season=${+seasonID}`); + const gamesList = await response.json(); + return gamesList; } \ No newline at end of file diff --git a/public/scripts/index.js b/public/scripts/index.js new file mode 100644 index 0000000..4a4721c --- /dev/null +++ b/public/scripts/index.js @@ -0,0 +1,176 @@ +import * as Data from "./data.js"; + +const sportDropdown = document.getElementById('sport-dropdown'); +const seasonDropdown = document.getElementById('year-dropdown'); +const genderDropdown = document.getElementById('gender-dropdown'); +const divisionDropdown = document.getElementById('division-dropdown'); +const teamDropdown = document.getElementById('team-dropdown'); +const gamesTable = document.getElementById('games-table'); +const gamesTableHeader = document.getElementById('games-table-header'); +const noScoresMessage = document.getElementById('no-scores-message'); + + + + + +async function listSeasons() { + seasonDropdown.innerHTML = ""; + + const seasonsList = await Data.getSeasons(); + + seasonsList.forEach(season => { + const option = document.createElement('option'); + option.text = season.year - 1 + "-" + season.year; + option.value = season.id; + seasonDropdown.appendChild(option); + }); +} +listSeasons(); + +async function listSports() { + sportDropdown.innerHTML = ""; + + const sportsList = await Data.getSports(); + + sportsList.forEach(sport => { + const option = document.createElement('option'); + option.text = sport.name; + option.value = sport.id; + sportDropdown.appendChild(option); + }); + + listGenders(); +} +listSports(); + +async function listGenders() { + genderDropdown.innerHTML = ""; + + const selectedSportID = sportDropdown.value; + const gendersList = await Data.getGenders(selectedSportID); + + if(selectedSportID) { + gendersList.forEach(gender => { + const option = document.createElement('option'); + option.text = (gender.name == "female") ? "Female" : (gender.name == "male") ? "Male" : ""; + option.value = gender.name; + genderDropdown.appendChild(option); + }); + } + + listDivisions(); +} + +async function listDivisions() { + divisionDropdown.innerHTML = ""; + + const selectedSportID = sportDropdown.value; + const selectedGender = genderDropdown.value; + + if(selectedGender) { + const divisionsList = await Data.getDivisions(selectedSportID, selectedGender); + + divisionsList.forEach(division => { + const option = document.createElement('option'); + option.text = division.name; + option.value = division.id; + divisionDropdown.appendChild(option); + }); + } + listTeams(); +} + +async function listTeams() { + teamDropdown.innerHTML = ""; + + const selectedSportID = sportDropdown.value; + + if(selectedSportID) { + const teamsList = await Data.getTeams(selectedSportID); + + teamsList.forEach(team => { + const option = document.createElement('option'); + option.text = team.name; + option.value = team.id; + teamDropdown.appendChild(option); + }); + } + + listGames(); +} + +async function listGames() { + gamesTable.innerHTML = ""; + gamesTableHeader.textContent = ""; + noScoresMessage.textContent = ""; + + const selectedTeamID = teamDropdown.value; + const selectedDivisionID = divisionDropdown.value; + const selectedSeasonID = seasonDropdown.value; + + if(selectedTeamID && selectedDivisionID) { + gamesTableHeader.textContent = `Scores for ${teamDropdown.options[teamDropdown.selectedIndex].text}`; + + const gamesList = await Data.getGames(selectedTeamID, selectedDivisionID, selectedSeasonID); + if(gamesList.length > 0) { + await setupGamesTableHeaders(); + + gamesList.forEach((game) => { + const row = document.createElement('tr'); + + const scoreCell = document.createElement('td'); + const winLossLine = document.createElement('span'); + winLossLine.textContent = (game.team1Score > game.team2Score) ? "Win" : (game.team1Score < game.team2Score) ? "Loss" : "Tie"; + scoreCell.appendChild(winLossLine); + const scoreLine = document.createElement('span'); + scoreLine.textContent = game.team1Score + "-" + game.team2Score; + scoreCell.appendChild(scoreLine); + row.appendChild(scoreCell); + + const opponentCell = document.createElement('td'); + Data.getTeamName(game.team2ID) + .then(data => opponentCell.textContent = data); + row.appendChild(opponentCell); + + const dateCell = document.createElement('td'); + dateCell.textContent = game.date; + row.appendChild(dateCell); + + gamesTable.appendChild(row); + }); + } + else { + noScoresMessage.textContent = "No scores available"; + } + } +} +async function setupGamesTableHeaders() { + + const row = document.createElement('tr'); + + const scoresHeader = document.createElement('th'); + scoresHeader.textContent = "Score" + row.appendChild(scoresHeader); + + const opponentHeader = document.createElement('th'); + opponentHeader.textContent = "Opponent"; + row.appendChild(opponentHeader); + + const dateHeader = document.createElement('th'); + dateHeader.textContent = "Date"; + row.appendChild(dateHeader); + + gamesTable.appendChild(row); +} + + + + + +sportDropdown.onchange = (() => { + listGenders(); + listTeams(); +}); +genderDropdown.onchange = listDivisions; +teamDropdown.onchange = listGames; +seasonDropdown.onchange = listGames; \ No newline at end of file diff --git a/public/stylesheets/form.css b/public/stylesheets/form.css new file mode 100644 index 0000000..85b34bc --- /dev/null +++ b/public/stylesheets/form.css @@ -0,0 +1,34 @@ +form { + display: flex; + flex-direction: column; + } + + span { + display: flex; + flex-direction: column; + } + + + .form-main-dropdown { + width: 100%; + } + + .form-section { + margin-bottom: 0.75em; + } + + .form-section-input { + flex-direction: row; + } + + input { + width: 100%; + } + + .form-score-input{ + width: 35%; + } + + #submit-button { + margin-top: 1.5em; + } \ No newline at end of file diff --git a/public/stylesheets/index.css b/public/stylesheets/index.css new file mode 100644 index 0000000..2f8f252 --- /dev/null +++ b/public/stylesheets/index.css @@ -0,0 +1,21 @@ +h1 { + text-align: left; +} + +th { + text-align: left; +} + +#score-column { + width: 20%; +} +#opponent-column{ + width: 60%; +} +#date-column { + width: 20%; +} + +tr { + height: 3em; +} \ No newline at end of file diff --git a/public/stylesheets/style.css b/public/stylesheets/style.css index 6a727df..b6a5c49 100644 --- a/public/stylesheets/style.css +++ b/public/stylesheets/style.css @@ -7,3 +7,11 @@ a { color: #00B7FF; } +#mobile-view { + max-width: 20em; + margin-left: auto; + margin-right: auto; + display: flex; + flex-direction: column; +} + diff --git a/public/stylesheets/submit.css b/public/stylesheets/submit.css index 80a8146..af4e239 100644 --- a/public/stylesheets/submit.css +++ b/public/stylesheets/submit.css @@ -1,41 +1,3 @@ h1 { text-align: center; -} - -form { - display: flex; - flex-direction: column; - max-width: 20em; - margin-left: auto; - margin-right: auto; -} - -span { - display: flex; - flex-direction: column; -} - - -.main-dropdown { - width: 100%; -} - -.form-section { - margin-bottom: 0.75em; -} - -.form-section-input { - flex-direction: row; -} - -input { - width: 100%; -} - -.score-input{ - width: 35%; -} - -button { - margin-top: 1.5em; } \ No newline at end of file diff --git a/routes/data.js b/routes/data.js index fc6c947..4344d2d 100644 --- a/routes/data.js +++ b/routes/data.js @@ -5,6 +5,7 @@ var seasons = require('../database/scores/seasons'); var genders = require('../database/scores/genders'); var divisions = require('../database/scores/divisions'); var teams = require('../database/scores/teams'); +var games = require('../database/scores/games'); router.get('/sports', function(req, res, next) { @@ -23,7 +24,7 @@ router.get('/genders', function(req, res, next) { }) router.get('/divisions', function(req, res, next) { - const gender = req.body.gender == 'female' ? genders.FEMALE : genders.MALE; + const gender = req.query.gender == 'female' ? genders.FEMALE : genders.MALE; divisions.retrieveBySportAndGender(req.query.sport, gender) .then(data => res.json(data)); @@ -34,4 +35,14 @@ router.get('/teams', function(req, res, next) { .then(data => res.json(data)); }) +router.get('/team', function(req, res, next) { + teams.getFromID(req.query.team) + .then(data => res.json(data)); +}) + +router.get('/games', function(req, res, next) { + games.retrieveByTeamDivisionAndSeason(req.query.team, req.query.division, req.query.season) + .then(data => res.json(data)); +}) + module.exports = router; \ No newline at end of file diff --git a/routes/index.js b/routes/index.js index c806b1c..4cb7f20 100644 --- a/routes/index.js +++ b/routes/index.js @@ -4,7 +4,7 @@ var database = require('../database/database'); /* GET home page. */ router.get('/', function(req, res, next) { - res.render('index', { title: 'Submit Score' }); + res.render('index', { title: 'View Scores' }); }); module.exports = router; diff --git a/routes/submit.js b/routes/submit.js index 8510303..fcd660b 100644 --- a/routes/submit.js +++ b/routes/submit.js @@ -2,11 +2,10 @@ var express = require('express'); var router = express.Router(); var genders = require('../database/scores/genders'); var games = require('../database/scores/games'); -var moment = require('moment'); /* GET submit page. */ router.get('/', function(req, res, next) { - res.render('submit', { title: 'Submit Score', date: moment().format('YYYY-MM-DD') }); + res.render('submit', { title: 'Submit Score' }); }); /* POST submit page. */ diff --git a/views/index.pug b/views/index.pug index e69de29..1d3ffb2 100644 --- a/views/index.pug +++ b/views/index.pug @@ -0,0 +1,38 @@ +extends layout + +block stylesheets + link(rel='stylesheet', href='/stylesheets/index.css') + link(rel='stylesheet', href='/stylesheets/form.css') + +block content + div#mobile-view + h1 Score Tracker + div + span(class='form-section') + label Year + span(class='form-section-input') + select#year-dropdown(name="year" class="form-main-dropdown") + span(class='form-section') + label Sport + span(class='form-section-input') + select#sport-dropdown(name="sport" class="form-main-dropdown") + select#gender-dropdown(name="gender") + select#division-dropdown(name="division") + span(class='form-section') + label Team + span(class='form-section-input') + select#team-dropdown(name="team" class="form-main-dropdown") + span(class='form-section') + div + h2#games-table-header + span#no-scores-message + table + colgroup + col#score-column(span="1") + col#opponent-column(span="1") + col#date-column(span="1") + tbody#games-table + + +block scripts + script(src='/scripts/index.js' type="module") \ No newline at end of file diff --git a/views/submit.pug b/views/submit.pug index 97d7b37..85f352f 100644 --- a/views/submit.pug +++ b/views/submit.pug @@ -2,36 +2,38 @@ extends layout block stylesheets link(rel='stylesheet', href='/stylesheets/submit.css') + link(rel='stylesheet', href='/stylesheets/form.css') block content - h1 Submit Score - form(action='/submit', method='POST') - span(class='form-section') - label Year - span(class='form-section-input') - select#year-dropdown(name="year" class="main-dropdown") - span(class='form-section') - label Sport - span(class='form-section-input') - select#sport-dropdown(name="sport" class="main-dropdown") - select#gender-dropdown(name="gender") - select#division-dropdown(name="division") - span(class='form-section') - label Date of match - span(class='form-section-input') - input(type="date", name="date", value=date) - span(class='form-section') - label Your team - span(class='form-section-input') - select#team1-dropdown(name="team1" class="main-dropdown") - input(class="score-input", type="number", name="team1-score", value="0") - span(class='form-section') - label Opponent - span(class='form-section-input') - select#team2-dropdown(name="team2" class="main-dropdown") - input(class="score-input", type="number", name="team2-score", value="0") - span(class='form-section') - button(type="submit") Submit + div#mobile-view + h1 Submit Score + form(action='/submit', method='POST') + span(class='form-section') + label Year + span(class='form-section-input') + select#year-dropdown(name="year" class="form-main-dropdown") + span(class='form-section') + label Sport + span(class='form-section-input') + select#sport-dropdown(name="sport" class="form-main-dropdown") + select#gender-dropdown(name="gender") + select#division-dropdown(name="division") + span(class='form-section') + label Date of match + span(class='form-section-input') + input(type="date", name="date", value=date) + span(class='form-section') + label Your team + span(class='form-section-input') + select#team1-dropdown(name="team1" class="form-main-dropdown") + input(class="form-score-input", type="number", name="team1-score", value="0") + span(class='form-section') + label Opponent + span(class='form-section-input') + select#team2-dropdown(name="team2" class="form-main-dropdown") + input(class="form-score-input", type="number", name="team2-score", value="0") + span(class='form-section') + button#submit-button(type="submit") Submit block scripts script(src='/scripts/submit.js' type="module") \ No newline at end of file