commit
46194f6e46
|
@ -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.
|
||||
|
|
2
app.js
2
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
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "score-tracker",
|
||||
"version": "1.0.3-pre",
|
||||
"version": "1.2.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"start": "node ./bin/www"
|
||||
|
|
|
@ -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,17 +44,23 @@ 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;
|
||||
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
||||
|
@ -76,7 +65,10 @@ 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');
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -49,3 +49,7 @@ form {
|
|||
.flat-form-section {
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
#submission-form {
|
||||
visibility: hidden;
|
||||
}
|
|
@ -32,3 +32,7 @@ tr {
|
|||
#login-button {
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
#dropdowns-div {
|
||||
visibility: hidden;
|
||||
}
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
|
@ -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)
|
||||
|
|
|
@ -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')
|
||||
|
|
|
@ -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...
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Reference in New Issue