diff --git a/README.md b/README.md index 3835188..6d558c8 100644 --- a/README.md +++ b/README.md @@ -12,11 +12,11 @@ A web app designed to collect and display scores for sports ## Installation -This repository is designed to be pushed to Heroku/Dokku/etc. +This repository can be cloned and then pushed to Heroku/Dokku/etc. ### Requirements -- PostgreSQL (with empty database created and an account to access it) +- PostgreSQL (with an empty database created and an account to access it) ### Environment Variables @@ -32,6 +32,8 @@ This repository is designed to be pushed to Heroku/Dokku/etc. This program uses Node.js/Express.js for the backend, PostgreSQL for the database (with node-postgres), and Passport.js for managing users and sessions. +To view the code, clone the repository and open it in VSCode/VSCodium. + ### Structure - `database` folder contains backend scripts for managing and storing data. @@ -44,6 +46,7 @@ This program uses Node.js/Express.js for the backend, PostgreSQL for the databas - `auth.js` deals with logging in and out (`/auth/*`). - `checkLoginStatus.js` contains functions for checking the login status of the current user. - `data.js` sends various data to the client in JSON format (`/data/*`). + - `fetch.js` sends more specific data formatted for specific pages in JSON format (`/fetch/*`) - `index.js` directs to the home page (`/`). - `manage.js` contains various functions that allows the user to add and edit items through the web browser (`/manage/*`). - `views` folder contains pug templates for each webpage, and a `layout` template for the base layout of each page. diff --git a/app.js b/app.js index 9764a31..da69f40 100644 --- a/app.js +++ b/app.js @@ -15,6 +15,7 @@ var dataRouter = require('./routes/data'); var manageRouter = require('./routes/manage'); var authRouter = require('./routes/auth'); var aboutRouter = require('./routes/about'); +var fetchRouter = require('./routes/fetch'); var app = express(); @@ -53,6 +54,7 @@ app.use('/data', dataRouter); app.use('/manage', manageRouter); app.use('/auth', authRouter); app.use('/about', aboutRouter); +app.use('/fetch', fetchRouter); // catch 404 and forward to error handler diff --git a/package.json b/package.json index b504c93..2e017a4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "score-tracker", - "version": "1.0.3-pre", + "version": "1.2.0", "private": true, "scripts": { "start": "node ./bin/www" diff --git a/public/scripts/form.js b/public/scripts/form.js index 631b404..acc3eaa 100644 --- a/public/scripts/form.js +++ b/public/scripts/form.js @@ -1,9 +1,14 @@ import * as Data from "./data.js"; -export async function populateSports(sportDropdown, selectedSportID = undefined) { +export async function populateSports(sportDropdown, selectedSportID = undefined, data = undefined) { sportDropdown.innerHTML = ""; - const sportsList = await Data.getSports(); + let sportsList; + if(data) { + sportsList = data.sports; + } else { + sportsList = await Data.getSports(); + } let currentIndex = 0; let selectedSportIndex; @@ -13,17 +18,23 @@ export async function populateSports(sportDropdown, selectedSportID = undefined) option.value = sport.id; sportDropdown.appendChild(option); - if(sport.id == selectedSportID) selectedSportIndex = currentIndex; + if(sport.id == selectedSportID || (data && sport.id == data.latestGame.sportID)) selectedSportIndex = currentIndex; currentIndex++; }); if(selectedSportIndex) sportDropdown.selectedIndex = selectedSportIndex; } -export async function populateSeasons(seasonDropdown, selectedSeasonID = undefined) { +export async function populateSeasons(seasonDropdown, selectedSeasonID = undefined, data = undefined) { seasonDropdown.innerHTML = ""; - - const seasonsList = await Data.getSeasons(); + + let seasonsList; + + if(data) { + seasonsList = data.seasons; + } else { + seasonsList = await Data.getSeasons(); + } let currentIndex = 0; let selectedSeasonIndex; @@ -33,18 +44,24 @@ export async function populateSeasons(seasonDropdown, selectedSeasonID = undefin option.value = season.id; seasonDropdown.appendChild(option); - if(season.id == selectedSeasonID) selectedSeasonIndex = currentIndex; + if(season.id == selectedSeasonID || (data && season.id == data.latestGame.seasonID)) selectedSeasonIndex = currentIndex; currentIndex++; }); if(selectedSeasonIndex) seasonDropdown.selectedIndex = selectedSeasonIndex; } -export async function populateGenders(genderDropdown, selectedSportID, selectedGender = undefined) { +export async function populateGenders(genderDropdown, selectedSportID, selectedGender = undefined, data = undefined) { genderDropdown.innerHTML = ""; - const gendersList = await Data.getGenders(selectedSportID); - + let gendersList; + if(data) { + gendersList = data.genders; + selectedSportID = data.latestGame.sportID; + } else { + gendersList = await Data.getGenders(selectedSportID); + } + if(selectedSportID) { let currentIndex = 0; let selectedGenderIndex; @@ -54,7 +71,7 @@ export async function populateGenders(genderDropdown, selectedSportID, selectedG option.value = gender.name; genderDropdown.appendChild(option); - if(gender.name == selectedGender) selectedGenderIndex = currentIndex; + if(gender.name == selectedGender || (data && gender.name == data.latestGame.gender.name)) selectedGenderIndex = currentIndex; currentIndex++; }); @@ -62,11 +79,21 @@ export async function populateGenders(genderDropdown, selectedSportID, selectedG } } -export async function populateDivisions (divisionDropdown, selectedSportID, selectedGender, selectedDivisionID = undefined) { +export async function populateDivisions (divisionDropdown, selectedSportID, selectedGender, selectedDivisionID = undefined, data = undefined) { divisionDropdown.innerHTML = ""; + if(data) { + selectedSportID = data.latestGame.sportID; + selectedGender = data.latestGame.gender; + } if(selectedSportID && selectedGender) { - const divisionsList = await Data.getDivisions(selectedSportID, selectedGender); + let divisionsList; + + if(data) { + divisionsList = data.divisions; + } else { + divisionsList = await Data.getDivisions(selectedSportID, selectedGender); + } let currentIndex = 0; let selectedDivisionIndex; @@ -76,7 +103,7 @@ export async function populateDivisions (divisionDropdown, selectedSportID, sele option.value = division.id; divisionDropdown.appendChild(option); - if(division.id == selectedDivisionID) selectedDivisionIndex = currentIndex; + if(division.id == selectedDivisionID || (data && division.id == data.latestGame.divisionID)) selectedDivisionIndex = currentIndex; currentIndex++; }); @@ -84,14 +111,28 @@ export async function populateDivisions (divisionDropdown, selectedSportID, sele } } -export async function populateTeams(teamDropdown, selectedSportID, selectedTeamID = undefined) { +export async function populateTeams(teamDropdown, selectedSportID, selectedTeamID = undefined, data = undefined, useOpponent = false) { teamDropdown.innerHTML = ""; + if(data) { + selectedSportID = data.latestGame.sportID; + } + if(selectedSportID) { - const teamsList = await Data.getTeams(selectedSportID); + let teamsList; + if(data) { + teamsList = data.teams; + } else { + teamsList = await Data.getTeams(selectedSportID); + } let currentIndex = 0; let selectedTeamIndex; + + if(data) { + selectedTeamID = useOpponent ? data.latestGame.team2ID : data.latestGame.team1ID; + } + teamsList.forEach(team => { const option = document.createElement('option'); option.text = team.name; diff --git a/public/scripts/index.js b/public/scripts/index.js index 1b70ca3..de182c7 100644 --- a/public/scripts/index.js +++ b/public/scripts/index.js @@ -1,6 +1,7 @@ import * as Data from "./data.js"; import * as Form from "./form.js"; +const dropdownsDiv = document.getElementById('dropdowns-div'); const sportDropdown = document.getElementById('sport-dropdown'); const seasonDropdown = document.getElementById('year-dropdown'); const genderDropdown = document.getElementById('gender-dropdown'); @@ -11,35 +12,20 @@ const gamesTableHeader = document.getElementById('games-table-header'); const noScoresMessage = document.getElementById('no-scores-message'); const addScoreButton = document.getElementById('add-score-button'); const manageButton = document.getElementById('manage-button'); +const loadingSpan = document.getElementById('loading'); async function initializeForm() { - let latestGame; + const data = await (await fetch(`/fetch/index/dropdown`)).json(); - try { - latestGame = await Data.getLatestGame(); - } catch { - latestGame = null; - } - - if(latestGame) { - Form.populateSeasons(seasonDropdown, latestGame.seasonID); - - const division = await Data.getDivision(latestGame.divisionID); - await Form.populateSports(sportDropdown, division.sportID); - await Form.populateGenders(genderDropdown, sportDropdown.value, division.gender.name); - await Form.populateDivisions(divisionDropdown, sportDropdown.value, genderDropdown.value, latestGame.divisionID); - await Form.populateTeams(teamDropdown, sportDropdown.value, latestGame.team1ID); - } else { - Form.populateSeasons(seasonDropdown); - await Form.populateSports(sportDropdown); - await Form.populateGenders(genderDropdown, sportDropdown.value); - await Form.populateDivisions(divisionDropdown, sportDropdown.value, genderDropdown.value); - await Form.populateTeams(teamDropdown, sportDropdown.value); - } + await Form.populateSeasons(seasonDropdown, null, data); + await Form.populateSports(sportDropdown, null, data); + await Form.populateGenders(genderDropdown, null, null, data); + await Form.populateDivisions(divisionDropdown, null, null, null, data); + await Form.populateTeams(teamDropdown, null, null, data); seasonDropdown.onchange = loadTable; @@ -58,6 +44,9 @@ async function initializeForm() { divisionDropdown.onchange = loadTable; teamDropdown.onchange = loadTable; + loadingSpan.textContent = ''; + dropdownsDiv.style.visibility = 'visible'; + loadTable(); @@ -75,8 +64,11 @@ async function loadTable() { if(selectedTeamID && selectedDivisionID) { gamesTableHeader.textContent = `Scores for ${teamDropdown.options[teamDropdown.selectedIndex].text}`; - - const gamesList = await Data.getGames(selectedTeamID, selectedDivisionID, selectedSeasonID); + + noScoresMessage.textContent = "Loading scores..."; + const requestURL = `/fetch/index/scores?team=${+selectedTeamID}&division=${+selectedDivisionID}&season=${+selectedSeasonID}`; + const gamesList = await (await fetch(requestURL)).json(); + noScoresMessage.textContent = ""; if(gamesList.length > 0) { await setupGamesTableHeaders(); @@ -93,8 +85,7 @@ async function loadTable() { row.appendChild(scoreCell); const opponentCell = document.createElement('td'); - Data.getTeam(game.team2ID) - .then(data => opponentCell.textContent = data.name); + opponentCell.textContent = game.opponent.name; row.appendChild(opponentCell); const dateCell = document.createElement('td'); diff --git a/public/scripts/manage.js b/public/scripts/manage.js index a77a7d6..db29cad 100644 --- a/public/scripts/manage.js +++ b/public/scripts/manage.js @@ -3,6 +3,7 @@ import * as Data from "./data.js"; const categoryDropdown = document.getElementById('category-dropdown'); const itemsListTable = document.getElementById('items-list'); const addNewButton = document.getElementById('add-new-button'); +const loadingSpan = document.getElementById('loading-message'); function getGenderLetter(genderName) { @@ -114,7 +115,7 @@ CATEGORIES.push(new Category( CATEGORIES.push(new Category( "divisions", async function getDivisions() { - return await Data.getDivisions(); + return await (await fetch('/fetch/manage/divisions')).json(); }, async function listDivisionHeaders() { const headerRow = document.createElement('tr'); @@ -150,8 +151,8 @@ CATEGORIES.push(new Category( row.appendChild(spacerCell); const sportCell = document.createElement('td'); - Data.getSportName(division.sportID) - .then(data => sportCell.textContent = data); + let sportName = division.sport.name; + sportCell.textContent = sportName; row.appendChild(sportCell); }, async function addDivision() { @@ -165,7 +166,7 @@ CATEGORIES.push(new Category( CATEGORIES.push(new Category( "teams", async function getTeams() { - return await Data.getTeams(); + return await (await fetch('/fetch/manage/teams')).json(); }, async function listTeamHeaders() { const headerRow = document.createElement('tr'); @@ -193,8 +194,8 @@ CATEGORIES.push(new Category( row.appendChild(spacerCell); const sportCell = document.createElement('td'); - Data.getSportName(team.sportID) - .then(data => sportCell.textContent = data); + let sportName = team.sport.name; + sportCell.textContent = sportName; row.appendChild(sportCell); }, async function addTeam() { @@ -208,7 +209,7 @@ CATEGORIES.push(new Category( CATEGORIES.push(new Category( "games", async function getGames() { - return await Data.getGames(); + return await (await fetch('/fetch/manage/games')).json(); }, async function listGameHeaders() { const headerRow = document.createElement('tr'); @@ -241,12 +242,12 @@ CATEGORIES.push(new Category( function listGame(game, row) { const teamsCell = document.createElement('td'); const team1NameSpan = document.createElement('span'); - Data.getTeam(game.team1ID) - .then(data => team1NameSpan.textContent = data.name); + let team1Name = game.team1.name; + team1NameSpan.textContent = team1Name; teamsCell.appendChild(team1NameSpan); const team2NameSpan = document.createElement('span'); - Data.getTeam(game.team2ID) - .then(data => team2NameSpan.textContent = data.name); + let team2Name = game.team2.name; + team2NameSpan.textContent = team2Name; teamsCell.appendChild(team2NameSpan); row.appendChild(teamsCell); @@ -270,13 +271,11 @@ CATEGORIES.push(new Category( const divisionGenderSpan = document.createElement('span'); divisionSpan.appendChild(divisionNameSpan); divisionSpan.appendChild(divisionGenderSpan); - Data.getDivision(game.divisionID) - .then(data => { - Data.getSportName(data.sportID) - .then(data => sportSpan.textContent = data); - divisionNameSpan.textContent = data.name; - divisionGenderSpan.textContent = getGenderLetter(data.gender.name); - }); + let divisionName = game.division.name; + let sportName = game.sport.name; + divisionNameSpan.textContent = divisionName; + sportSpan.textContent = sportName; + divisionGenderSpan.textContent = getGenderLetter(game.division.gender.name); sportCell.appendChild(sportSpan); sportCell.appendChild(divisionSpan); row.appendChild(sportCell); @@ -292,11 +291,10 @@ CATEGORIES.push(new Category( const submitterCell = document.createElement('td'); if(game.submitterID) { - Data.getAccount(game.submitterID) - .then(data => submitterCell.textContent = data.name); + let submitterName = game.submitter.name; + submitterCell.textContent = submitterName; } else { submitterCell.textContent = game.submitterName; - console.log(game.submitterName); } row.appendChild(submitterCell); }, @@ -362,6 +360,8 @@ CATEGORIES.push(new Category( async function listItems(category) { + loadingSpan.textContent = "Loading..."; + itemsListTable.innerHTML = ""; const itemsList = await category.getItems(); @@ -389,6 +389,8 @@ async function listItems(category) { itemsListTable.appendChild(row); }); + + loadingSpan.textContent = ''; } if(window.location.hash) { let correctIndex; diff --git a/public/scripts/manage/account.js b/public/scripts/manage/account.js index f9a7370..3e14638 100644 --- a/public/scripts/manage/account.js +++ b/public/scripts/manage/account.js @@ -9,6 +9,7 @@ const adminCheckboxSection = document.getElementById('admin-checkbox-section'); const adminCheckbox = document.getElementById('admin-checkbox'); const submitButton = document.getElementById('submit-button'); const deleteButton = document.getElementById('delete-button'); +const loadingSpan = document.getElementById('loading-message'); async function Initialize() { let params = new URLSearchParams(location.search); @@ -46,6 +47,9 @@ async function Initialize() { passwordTextbox.disabled = false; passwordTextbox.addEventListener('keyup', checkDataValidity); checkDataValidity(); + + loadingSpan.textContent = ''; + submissionForm.style.visibility = 'visible'; } Initialize(); diff --git a/public/scripts/manage/division.js b/public/scripts/manage/division.js index a542a65..8474b4b 100644 --- a/public/scripts/manage/division.js +++ b/public/scripts/manage/division.js @@ -8,13 +8,14 @@ const genderDropdown = document.getElementById('gender-dropdown'); const nameTextbox = document.getElementById('name-textbox'); const submitButton = document.getElementById('submit-button'); const deleteButton = document.getElementById('delete-button'); +const loadingSpan = document.getElementById('loading-message'); async function initializeForm() { let params = new URLSearchParams(location.search); let divisionID = params.get('division'); if(divisionID) { - const division = await Data.getDivision(divisionID); + const division = await (await fetch(`/fetch/manage/division?division=${divisionID}`)).json(); nameTextbox.value = division.name; @@ -26,7 +27,11 @@ async function initializeForm() { if(gender == 'female') genderDropdown.selectedIndex = 1; else genderDropdown.selectedIndex = 2; - Form.populateSports(sportDropdown, division.sportID); + let data = {}; + data.sports = [division.sport]; + data.latestGame = {sportID : division.sportID }; + + Form.populateSports(sportDropdown, null, data); Form.addHiddenValue('division', divisionID, submissionForm); } @@ -40,6 +45,9 @@ async function initializeForm() { nameTextbox.disabled = false; nameTextbox.addEventListener('keyup', checkDataValidity); + + loadingSpan.textContent = ''; + submissionForm.style.visibility = 'visible'; } initializeForm(); diff --git a/public/scripts/manage/game.js b/public/scripts/manage/game.js index 5d0bd29..c61d05b 100644 --- a/public/scripts/manage/game.js +++ b/public/scripts/manage/game.js @@ -15,6 +15,7 @@ const team2ScoreTextbox = document.getElementById('team2-score-textbox'); const nameTextbox = document.getElementById('name-textbox'); const submitButton = document.getElementById('submit-button'); const deleteButton = document.getElementById('delete-button'); +const loadingSpan = document.getElementById('loading-span'); async function initializeForm() { @@ -41,24 +42,23 @@ async function initializeForm() { team2ScoreTextbox.value = game.team2Score; } else { - try { - const game = await Data.getLatestGame(true); + /*try {*/ + const data = await (await fetch(`/fetch/index/dropdown`)).json(); - Form.populateSeasons(seasonDropdown, game.seasonID); - const data = await Data.getDivision(game.divisionID) - await Form.populateSports(sportDropdown, data.sportID) - await Form.populateGenders(genderDropdown, sportDropdown.value, data.gender.name) - await Form.populateDivisions(divisionDropdown, sportDropdown.value, genderDropdown.value, game.divisionID); - await Form.populateTeams(team1Dropdown, sportDropdown.value, game.team1ID); - await Form.populateTeams(team2Dropdown, sportDropdown.value, game.team2ID); - } catch { + await Form.populateSeasons(seasonDropdown, null, data); + await Form.populateSports(sportDropdown, null, data); + await Form.populateGenders(genderDropdown, null, null, data); + await Form.populateDivisions(divisionDropdown, null, null, null, data); + await Form.populateTeams(team1Dropdown, null, null, data); + await Form.populateTeams(team2Dropdown, null, null, data, true); + /*} catch { await Form.populateSeasons(seasonDropdown); await Form.populateSports(sportDropdown) await Form.populateGenders(genderDropdown, sportDropdown.value) await Form.populateDivisions(divisionDropdown, sportDropdown.value, genderDropdown.value); await Form.populateTeams(team1Dropdown, sportDropdown.value); await Form.populateTeams(team2Dropdown, sportDropdown.value); - } + }*/ dateInput.value = (new Date()).toISOString().slice(0,10); } @@ -95,6 +95,9 @@ async function initializeForm() { team2ScoreTextbox.addEventListener('keyup', checkDataValidity); if(nameTextbox) nameTextbox.addEventListener('keyup', checkDataValidity); + loadingSpan.textContent = ''; + submissionForm.style.visibility = 'visible'; + checkDataValidity(); } initializeForm(); diff --git a/public/scripts/manage/sport.js b/public/scripts/manage/sport.js index 20ad2cb..b44b41a 100644 --- a/public/scripts/manage/sport.js +++ b/public/scripts/manage/sport.js @@ -5,6 +5,7 @@ const nameTextbox = document.getElementById('name-textbox'); const submitButton = document.getElementById('submit-button'); const deleteButton = document.getElementById('delete-button'); const submissionForm = document.getElementById('submission-form'); +const loadingSpan = document.getElementById('loading-message'); async function initializeForm() { @@ -26,6 +27,9 @@ async function initializeForm() { nameTextbox.disabled = false; nameTextbox.addEventListener('keyup', checkDataValidity); + + loadingSpan.textContent = ''; + submissionForm.style.visibility = 'visible'; } initializeForm(); diff --git a/public/scripts/manage/team.js b/public/scripts/manage/team.js index 4bc643e..a7eadce 100644 --- a/public/scripts/manage/team.js +++ b/public/scripts/manage/team.js @@ -7,19 +7,25 @@ const sportDropdown = document.getElementById('sport-dropdown'); const nameTextbox = document.getElementById('name-textbox'); const submitButton = document.getElementById('submit-button'); const deleteButton = document.getElementById('delete-button'); +const loadingSpan = document.getElementById('loading-message'); + async function initializeForm() { let params = new URLSearchParams(location.search); let teamID = params.get('team'); if(teamID) { - const team = await Data.getTeam(teamID); + const team = await (await fetch(`/fetch/manage/team?team=${teamID}`)).json(); nameTextbox.value = team.name; deleteButton.style.visibility = "visible"; deleteButton.disabled = false; - Form.populateSports(sportDropdown, team.sportID); + let data = {}; + data.sports = [team.sport]; + data.latestGame = {sportID : team.sportID }; + + Form.populateSports(sportDropdown, null, data); Form.addHiddenValue('team', teamID, submissionForm); } @@ -31,6 +37,9 @@ async function initializeForm() { nameTextbox.disabled = false; nameTextbox.addEventListener('keyup', checkDataValidity); + + loadingSpan.textContent = ''; + submissionForm.style.visibility = 'visible'; } initializeForm(); diff --git a/public/stylesheets/form.css b/public/stylesheets/form.css index 43fee2e..c040b27 100644 --- a/public/stylesheets/form.css +++ b/public/stylesheets/form.css @@ -48,4 +48,8 @@ form { .flat-form-section { flex-direction: row; - } \ No newline at end of file + } + +#submission-form { + visibility: hidden; +} \ No newline at end of file diff --git a/public/stylesheets/index.css b/public/stylesheets/index.css index eb71b13..bf0a4ae 100644 --- a/public/stylesheets/index.css +++ b/public/stylesheets/index.css @@ -32,3 +32,7 @@ tr { #login-button { margin-left: auto; } + +#dropdowns-div { + visibility: hidden; +} \ No newline at end of file diff --git a/routes/data.js b/routes/data.js index b6769d5..55c1970 100644 --- a/routes/data.js +++ b/routes/data.js @@ -98,7 +98,7 @@ router.get('/team', async function(req, res, next) { console.error("ERROR: " + err.message); res.status(500).send("An error has occurred"); } -}) +}); router.get('/games', async function(req, res, next) { try { diff --git a/routes/fetch.js b/routes/fetch.js new file mode 100644 index 0000000..4958fd3 --- /dev/null +++ b/routes/fetch.js @@ -0,0 +1,200 @@ +var express = require('express'); +var router = express.Router(); + +var sports = require('../database/scores/sports'); +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'); +var accounts = require('../database/accounts/accounts'); + +var checkLoginStatus = require('./checkLoginStatus'); + +router.get('/index/dropdown', async function(req, res, next) { + let latestGame; + let seasonsData; + let sportsData; + let gendersData; + let divisionsData; + let teamsData; + + try { + latestGame = await games.getLatest(); + + let division = await divisions.getFromID(latestGame.divisionID); + latestGame.sportID = division.sportID; + latestGame.gender = division.gender; + } catch { + latestGame = null; + } + + + try { + if(latestGame) { + seasonsData = await seasons.retrieveAll(); + sportsData = await sports.retrieveAll(); + gendersData = await genders.retrieveBySport(latestGame.sportID); + divisionsData = await divisions.retrieve(latestGame.sportID); + teamsData = await teams.retrieve(latestGame.sportID); + } else { + seasonsData = await seasons.retrieveAll(); + sportsData = await sports.retrieveAll(); + gendersData = await genders.retrieveBySport(sportsData[0].id); + divisionsData = await divisions.retrieve(sportsData[0].id); + teamsData = await teams.retrieve(sportsData[0].id); + } + + res.json({ + seasons : seasonsData, + sports : sportsData, + genders : gendersData, + divisions : divisionsData, + teams: teamsData, + latestGame + }); + } catch(err) { + console.error("ERROR: " + err.message); + res.status(500).send("An error has occurred"); + } +}); + +router.get('/index/scores', async function (req, res, next) { + try { + const seasonID = req.query.season; + const divisionID = req.query.division; + const teamID = req.query.team; + const data = await games.retrieve(teamID, divisionID, seasonID); + for (const game of data) { + game.opponent = await teams.getFromID(game.team2ID); + } + res.json(data); + } catch(err) { + console.error("ERROR: " + err.message); + res.status(500).send("An error has occurred"); + } +}); + + +router.get('/submit', async function(req, res, next) { + let latestGame; + let seasonsData; + let sportsData; + let gendersData; + let divisionsData; + let teamsData; + + const userID = req.user ? req.user[0] : null; + + try { + latestGame = await games.getLatest(userID); + + let division = await divisions.getFromID(latestGame.divisionID); + latestGame.sportID = division.sportID; + latestGame.gender = division.gender; + } catch { + latestGame = null; + } + + + try { + if(latestGame) { + seasonsData = await seasons.retrieveAll(); + sportsData = await sports.retrieveAll(); + gendersData = await genders.retrieveBySport(latestGame.sportID); + divisionsData = await divisions.retrieve(latestGame.sportID); + teamsData = await teams.retrieve(latestGame.sportID); + } else { + seasonsData = await seasons.retrieveAll(); + sportsData = await sports.retrieveAll(); + gendersData = await genders.retrieveBySport(sportsData[0].id); + divisionsData = await divisions.retrieve(sportsData[0].id); + teamsData = await teams.retrieve(sportsData[0].id); + } + + res.json({ + seasons : seasonsData, + sports : sportsData, + genders : gendersData, + divisions : divisionsData, + teams: teamsData, + latestGame + }); + } catch(err) { + console.error("ERROR: " + err.message); + res.status(500).send("An error has occurred"); + } +}); + +router.get('/manage/divisions', async function (req, res, next) { + const data = await divisions.retrieve(); + + for(const division of data) { + division.sport = await sports.getFromID(division.sportID); + } + + res.json(data); +}); + +router.get('/manage/division', async function (req, res, next) { + try { + const divisionID = req.query.division; + const data = await divisions.getFromID(divisionID); + data.sport = await sports.getFromID(data.sportID); + res.json(data); + } catch(err) { + console.error("ERROR: " + err.message); + res.status(500).send("An error has occurred"); + } +}); + +router.get('/manage/teams', async function (req, res, next) { + const data = await teams.retrieve(); + + for(const team of data) { + team.sport = await sports.getFromID(team.sportID); + } + + res.json(data); +}); + +router.get('/manage/team', async function (req, res, next) { + try { + const teamID = req.query.team; + const data = await teams.getFromID(teamID); + data.sport = await sports.getFromID(data.sportID); + res.json(data); + } catch(err) { + console.error("ERROR: " + err.message); + res.status(500).send("An error has occurred"); + } +}); + +router.get('/manage/games', checkLoginStatus.user, async function (req, res, next) { + try{ + const userIsAdmin = req.user[2]; + const loggedInAccountID = req.user[0]; + + if(!userIsAdmin) { + res.status(403).send("ACCESS DENIED"); + } else { + const data = await games.retrieve(); + + for(const game of data) { + game.team1 = await teams.getFromID(game.team1ID); + game.team2 = await teams.getFromID(game.team2ID); + game.division = await divisions.getFromID(game.divisionID); + game.sport = await sports.getFromID(game.division.sportID); + game.submitter = game.submitterName || (await accounts.getFromID(game.submitterID)); + } + + res.json(data); + } + } catch(err) { + console.error("ERROR: " + err.message); + res.status(500).send("An error has occurred"); + } + +}); + +module.exports = router; \ No newline at end of file diff --git a/views/accounts/createuser.pug b/views/accounts/createuser.pug index b0c0ca2..a43aad9 100644 --- a/views/accounts/createuser.pug +++ b/views/accounts/createuser.pug @@ -5,6 +5,7 @@ block stylesheets link(rel='stylesheet', href='/stylesheets/form.css') block content + span#loading-message Loading... form#submission-form(action='/manage/account', method='POST') if accountID input#account-id(type="hidden" name="account" value=accountID) diff --git a/views/index.pug b/views/index.pug index a1b7d2d..1a22bbe 100644 --- a/views/index.pug +++ b/views/index.pug @@ -11,7 +11,8 @@ block actions block content - div + span#loading Loading... + div#dropdowns-div span(class='form-section') label Year span(class='form-section-input') diff --git a/views/manage.pug b/views/manage.pug index 63d76ec..bd8a228 100644 --- a/views/manage.pug +++ b/views/manage.pug @@ -18,6 +18,7 @@ block content option(value="accounts") Accounts div h2#table-header + span#loading-message Loading... table#items-list button#add-new-button Add new... diff --git a/views/manage/adddivision.pug b/views/manage/adddivision.pug index 1a17aaf..3471bc5 100644 --- a/views/manage/adddivision.pug +++ b/views/manage/adddivision.pug @@ -5,6 +5,7 @@ block stylesheets link(rel='stylesheet', href='/stylesheets/form.css') block content + span#loading-message Loading... form#submission-form(action='./division', method='POST') span(class='form-section') label Sport diff --git a/views/manage/addgame.pug b/views/manage/addgame.pug index bdc362c..dc56f5d 100644 --- a/views/manage/addgame.pug +++ b/views/manage/addgame.pug @@ -5,6 +5,7 @@ block stylesheets link(rel='stylesheet', href='/stylesheets/form.css') block content + span#loading-span Loading... form#submission-form(action='./game', method='POST') span(class='form-section') label Year diff --git a/views/manage/addsport.pug b/views/manage/addsport.pug index b4caa50..6530488 100644 --- a/views/manage/addsport.pug +++ b/views/manage/addsport.pug @@ -5,6 +5,7 @@ block stylesheets link(rel='stylesheet', href='/stylesheets/form.css') block content + span#loading-message Loading... form#submission-form(action='./sport', method='POST') span(class='form-section') label Sport name diff --git a/views/manage/addteam.pug b/views/manage/addteam.pug index 78746a6..17d42d3 100644 --- a/views/manage/addteam.pug +++ b/views/manage/addteam.pug @@ -5,6 +5,7 @@ block stylesheets link(rel='stylesheet', href='/stylesheets/form.css') block content + span#loading-message Loading... form#submission-form(action='./team', method='POST') span(class='form-section') label Sport