commit
46194f6e46
|
@ -12,11 +12,11 @@ A web app designed to collect and display scores for sports
|
||||||
|
|
||||||
## Installation
|
## 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
|
### 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
|
### 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.
|
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
|
### Structure
|
||||||
|
|
||||||
- `database` folder contains backend scripts for managing and storing data.
|
- `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/*`).
|
- `auth.js` deals with logging in and out (`/auth/*`).
|
||||||
- `checkLoginStatus.js` contains functions for checking the login status of the current user.
|
- `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/*`).
|
- `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 (`/`).
|
- `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/*`).
|
- `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.
|
- `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 manageRouter = require('./routes/manage');
|
||||||
var authRouter = require('./routes/auth');
|
var authRouter = require('./routes/auth');
|
||||||
var aboutRouter = require('./routes/about');
|
var aboutRouter = require('./routes/about');
|
||||||
|
var fetchRouter = require('./routes/fetch');
|
||||||
|
|
||||||
var app = express();
|
var app = express();
|
||||||
|
|
||||||
|
@ -53,6 +54,7 @@ app.use('/data', dataRouter);
|
||||||
app.use('/manage', manageRouter);
|
app.use('/manage', manageRouter);
|
||||||
app.use('/auth', authRouter);
|
app.use('/auth', authRouter);
|
||||||
app.use('/about', aboutRouter);
|
app.use('/about', aboutRouter);
|
||||||
|
app.use('/fetch', fetchRouter);
|
||||||
|
|
||||||
|
|
||||||
// catch 404 and forward to error handler
|
// catch 404 and forward to error handler
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "score-tracker",
|
"name": "score-tracker",
|
||||||
"version": "1.0.3-pre",
|
"version": "1.2.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "node ./bin/www"
|
"start": "node ./bin/www"
|
||||||
|
|
|
@ -1,9 +1,14 @@
|
||||||
import * as Data from "./data.js";
|
import * as Data from "./data.js";
|
||||||
|
|
||||||
export async function populateSports(sportDropdown, selectedSportID = undefined) {
|
export async function populateSports(sportDropdown, selectedSportID = undefined, data = undefined) {
|
||||||
sportDropdown.innerHTML = "";
|
sportDropdown.innerHTML = "";
|
||||||
|
|
||||||
const sportsList = await Data.getSports();
|
let sportsList;
|
||||||
|
if(data) {
|
||||||
|
sportsList = data.sports;
|
||||||
|
} else {
|
||||||
|
sportsList = await Data.getSports();
|
||||||
|
}
|
||||||
|
|
||||||
let currentIndex = 0;
|
let currentIndex = 0;
|
||||||
let selectedSportIndex;
|
let selectedSportIndex;
|
||||||
|
@ -13,17 +18,23 @@ export async function populateSports(sportDropdown, selectedSportID = undefined)
|
||||||
option.value = sport.id;
|
option.value = sport.id;
|
||||||
sportDropdown.appendChild(option);
|
sportDropdown.appendChild(option);
|
||||||
|
|
||||||
if(sport.id == selectedSportID) selectedSportIndex = currentIndex;
|
if(sport.id == selectedSportID || (data && sport.id == data.latestGame.sportID)) selectedSportIndex = currentIndex;
|
||||||
currentIndex++;
|
currentIndex++;
|
||||||
});
|
});
|
||||||
|
|
||||||
if(selectedSportIndex) sportDropdown.selectedIndex = selectedSportIndex;
|
if(selectedSportIndex) sportDropdown.selectedIndex = selectedSportIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function populateSeasons(seasonDropdown, selectedSeasonID = undefined) {
|
export async function populateSeasons(seasonDropdown, selectedSeasonID = undefined, data = undefined) {
|
||||||
seasonDropdown.innerHTML = "";
|
seasonDropdown.innerHTML = "";
|
||||||
|
|
||||||
const seasonsList = await Data.getSeasons();
|
let seasonsList;
|
||||||
|
|
||||||
|
if(data) {
|
||||||
|
seasonsList = data.seasons;
|
||||||
|
} else {
|
||||||
|
seasonsList = await Data.getSeasons();
|
||||||
|
}
|
||||||
|
|
||||||
let currentIndex = 0;
|
let currentIndex = 0;
|
||||||
let selectedSeasonIndex;
|
let selectedSeasonIndex;
|
||||||
|
@ -33,18 +44,24 @@ export async function populateSeasons(seasonDropdown, selectedSeasonID = undefin
|
||||||
option.value = season.id;
|
option.value = season.id;
|
||||||
seasonDropdown.appendChild(option);
|
seasonDropdown.appendChild(option);
|
||||||
|
|
||||||
if(season.id == selectedSeasonID) selectedSeasonIndex = currentIndex;
|
if(season.id == selectedSeasonID || (data && season.id == data.latestGame.seasonID)) selectedSeasonIndex = currentIndex;
|
||||||
currentIndex++;
|
currentIndex++;
|
||||||
});
|
});
|
||||||
|
|
||||||
if(selectedSeasonIndex) seasonDropdown.selectedIndex = selectedSeasonIndex;
|
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 = "";
|
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) {
|
if(selectedSportID) {
|
||||||
let currentIndex = 0;
|
let currentIndex = 0;
|
||||||
let selectedGenderIndex;
|
let selectedGenderIndex;
|
||||||
|
@ -54,7 +71,7 @@ export async function populateGenders(genderDropdown, selectedSportID, selectedG
|
||||||
option.value = gender.name;
|
option.value = gender.name;
|
||||||
genderDropdown.appendChild(option);
|
genderDropdown.appendChild(option);
|
||||||
|
|
||||||
if(gender.name == selectedGender) selectedGenderIndex = currentIndex;
|
if(gender.name == selectedGender || (data && gender.name == data.latestGame.gender.name)) selectedGenderIndex = currentIndex;
|
||||||
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 = "";
|
divisionDropdown.innerHTML = "";
|
||||||
|
|
||||||
|
if(data) {
|
||||||
|
selectedSportID = data.latestGame.sportID;
|
||||||
|
selectedGender = data.latestGame.gender;
|
||||||
|
}
|
||||||
if(selectedSportID && selectedGender) {
|
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 currentIndex = 0;
|
||||||
let selectedDivisionIndex;
|
let selectedDivisionIndex;
|
||||||
|
@ -76,7 +103,7 @@ export async function populateDivisions (divisionDropdown, selectedSportID, sele
|
||||||
option.value = division.id;
|
option.value = division.id;
|
||||||
divisionDropdown.appendChild(option);
|
divisionDropdown.appendChild(option);
|
||||||
|
|
||||||
if(division.id == selectedDivisionID) selectedDivisionIndex = currentIndex;
|
if(division.id == selectedDivisionID || (data && division.id == data.latestGame.divisionID)) selectedDivisionIndex = currentIndex;
|
||||||
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 = "";
|
teamDropdown.innerHTML = "";
|
||||||
|
|
||||||
|
if(data) {
|
||||||
|
selectedSportID = data.latestGame.sportID;
|
||||||
|
}
|
||||||
|
|
||||||
if(selectedSportID) {
|
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 currentIndex = 0;
|
||||||
let selectedTeamIndex;
|
let selectedTeamIndex;
|
||||||
|
|
||||||
|
if(data) {
|
||||||
|
selectedTeamID = useOpponent ? data.latestGame.team2ID : data.latestGame.team1ID;
|
||||||
|
}
|
||||||
|
|
||||||
teamsList.forEach(team => {
|
teamsList.forEach(team => {
|
||||||
const option = document.createElement('option');
|
const option = document.createElement('option');
|
||||||
option.text = team.name;
|
option.text = team.name;
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import * as Data from "./data.js";
|
import * as Data from "./data.js";
|
||||||
import * as Form from "./form.js";
|
import * as Form from "./form.js";
|
||||||
|
|
||||||
|
const dropdownsDiv = document.getElementById('dropdowns-div');
|
||||||
const sportDropdown = document.getElementById('sport-dropdown');
|
const sportDropdown = document.getElementById('sport-dropdown');
|
||||||
const seasonDropdown = document.getElementById('year-dropdown');
|
const seasonDropdown = document.getElementById('year-dropdown');
|
||||||
const genderDropdown = document.getElementById('gender-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 noScoresMessage = document.getElementById('no-scores-message');
|
||||||
const addScoreButton = document.getElementById('add-score-button');
|
const addScoreButton = document.getElementById('add-score-button');
|
||||||
const manageButton = document.getElementById('manage-button');
|
const manageButton = document.getElementById('manage-button');
|
||||||
|
const loadingSpan = document.getElementById('loading');
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
async function initializeForm() {
|
async function initializeForm() {
|
||||||
let latestGame;
|
const data = await (await fetch(`/fetch/index/dropdown`)).json();
|
||||||
|
|
||||||
try {
|
await Form.populateSeasons(seasonDropdown, null, data);
|
||||||
latestGame = await Data.getLatestGame();
|
await Form.populateSports(sportDropdown, null, data);
|
||||||
} catch {
|
await Form.populateGenders(genderDropdown, null, null, data);
|
||||||
latestGame = null;
|
await Form.populateDivisions(divisionDropdown, null, null, null, data);
|
||||||
}
|
await Form.populateTeams(teamDropdown, null, null, data);
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
seasonDropdown.onchange = loadTable;
|
seasonDropdown.onchange = loadTable;
|
||||||
|
|
||||||
|
@ -58,6 +44,9 @@ async function initializeForm() {
|
||||||
divisionDropdown.onchange = loadTable;
|
divisionDropdown.onchange = loadTable;
|
||||||
teamDropdown.onchange = loadTable;
|
teamDropdown.onchange = loadTable;
|
||||||
|
|
||||||
|
loadingSpan.textContent = '';
|
||||||
|
dropdownsDiv.style.visibility = 'visible';
|
||||||
|
|
||||||
loadTable();
|
loadTable();
|
||||||
|
|
||||||
|
|
||||||
|
@ -75,8 +64,11 @@ async function loadTable() {
|
||||||
|
|
||||||
if(selectedTeamID && selectedDivisionID) {
|
if(selectedTeamID && selectedDivisionID) {
|
||||||
gamesTableHeader.textContent = `Scores for ${teamDropdown.options[teamDropdown.selectedIndex].text}`;
|
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) {
|
if(gamesList.length > 0) {
|
||||||
await setupGamesTableHeaders();
|
await setupGamesTableHeaders();
|
||||||
|
|
||||||
|
@ -93,8 +85,7 @@ async function loadTable() {
|
||||||
row.appendChild(scoreCell);
|
row.appendChild(scoreCell);
|
||||||
|
|
||||||
const opponentCell = document.createElement('td');
|
const opponentCell = document.createElement('td');
|
||||||
Data.getTeam(game.team2ID)
|
opponentCell.textContent = game.opponent.name;
|
||||||
.then(data => opponentCell.textContent = data.name);
|
|
||||||
row.appendChild(opponentCell);
|
row.appendChild(opponentCell);
|
||||||
|
|
||||||
const dateCell = document.createElement('td');
|
const dateCell = document.createElement('td');
|
||||||
|
|
|
@ -3,6 +3,7 @@ import * as Data from "./data.js";
|
||||||
const categoryDropdown = document.getElementById('category-dropdown');
|
const categoryDropdown = document.getElementById('category-dropdown');
|
||||||
const itemsListTable = document.getElementById('items-list');
|
const itemsListTable = document.getElementById('items-list');
|
||||||
const addNewButton = document.getElementById('add-new-button');
|
const addNewButton = document.getElementById('add-new-button');
|
||||||
|
const loadingSpan = document.getElementById('loading-message');
|
||||||
|
|
||||||
|
|
||||||
function getGenderLetter(genderName) {
|
function getGenderLetter(genderName) {
|
||||||
|
@ -114,7 +115,7 @@ CATEGORIES.push(new Category(
|
||||||
CATEGORIES.push(new Category(
|
CATEGORIES.push(new Category(
|
||||||
"divisions",
|
"divisions",
|
||||||
async function getDivisions() {
|
async function getDivisions() {
|
||||||
return await Data.getDivisions();
|
return await (await fetch('/fetch/manage/divisions')).json();
|
||||||
},
|
},
|
||||||
async function listDivisionHeaders() {
|
async function listDivisionHeaders() {
|
||||||
const headerRow = document.createElement('tr');
|
const headerRow = document.createElement('tr');
|
||||||
|
@ -150,8 +151,8 @@ CATEGORIES.push(new Category(
|
||||||
row.appendChild(spacerCell);
|
row.appendChild(spacerCell);
|
||||||
|
|
||||||
const sportCell = document.createElement('td');
|
const sportCell = document.createElement('td');
|
||||||
Data.getSportName(division.sportID)
|
let sportName = division.sport.name;
|
||||||
.then(data => sportCell.textContent = data);
|
sportCell.textContent = sportName;
|
||||||
row.appendChild(sportCell);
|
row.appendChild(sportCell);
|
||||||
},
|
},
|
||||||
async function addDivision() {
|
async function addDivision() {
|
||||||
|
@ -165,7 +166,7 @@ CATEGORIES.push(new Category(
|
||||||
CATEGORIES.push(new Category(
|
CATEGORIES.push(new Category(
|
||||||
"teams",
|
"teams",
|
||||||
async function getTeams() {
|
async function getTeams() {
|
||||||
return await Data.getTeams();
|
return await (await fetch('/fetch/manage/teams')).json();
|
||||||
},
|
},
|
||||||
async function listTeamHeaders() {
|
async function listTeamHeaders() {
|
||||||
const headerRow = document.createElement('tr');
|
const headerRow = document.createElement('tr');
|
||||||
|
@ -193,8 +194,8 @@ CATEGORIES.push(new Category(
|
||||||
row.appendChild(spacerCell);
|
row.appendChild(spacerCell);
|
||||||
|
|
||||||
const sportCell = document.createElement('td');
|
const sportCell = document.createElement('td');
|
||||||
Data.getSportName(team.sportID)
|
let sportName = team.sport.name;
|
||||||
.then(data => sportCell.textContent = data);
|
sportCell.textContent = sportName;
|
||||||
row.appendChild(sportCell);
|
row.appendChild(sportCell);
|
||||||
},
|
},
|
||||||
async function addTeam() {
|
async function addTeam() {
|
||||||
|
@ -208,7 +209,7 @@ CATEGORIES.push(new Category(
|
||||||
CATEGORIES.push(new Category(
|
CATEGORIES.push(new Category(
|
||||||
"games",
|
"games",
|
||||||
async function getGames() {
|
async function getGames() {
|
||||||
return await Data.getGames();
|
return await (await fetch('/fetch/manage/games')).json();
|
||||||
},
|
},
|
||||||
async function listGameHeaders() {
|
async function listGameHeaders() {
|
||||||
const headerRow = document.createElement('tr');
|
const headerRow = document.createElement('tr');
|
||||||
|
@ -241,12 +242,12 @@ CATEGORIES.push(new Category(
|
||||||
function listGame(game, row) {
|
function listGame(game, row) {
|
||||||
const teamsCell = document.createElement('td');
|
const teamsCell = document.createElement('td');
|
||||||
const team1NameSpan = document.createElement('span');
|
const team1NameSpan = document.createElement('span');
|
||||||
Data.getTeam(game.team1ID)
|
let team1Name = game.team1.name;
|
||||||
.then(data => team1NameSpan.textContent = data.name);
|
team1NameSpan.textContent = team1Name;
|
||||||
teamsCell.appendChild(team1NameSpan);
|
teamsCell.appendChild(team1NameSpan);
|
||||||
const team2NameSpan = document.createElement('span');
|
const team2NameSpan = document.createElement('span');
|
||||||
Data.getTeam(game.team2ID)
|
let team2Name = game.team2.name;
|
||||||
.then(data => team2NameSpan.textContent = data.name);
|
team2NameSpan.textContent = team2Name;
|
||||||
teamsCell.appendChild(team2NameSpan);
|
teamsCell.appendChild(team2NameSpan);
|
||||||
row.appendChild(teamsCell);
|
row.appendChild(teamsCell);
|
||||||
|
|
||||||
|
@ -270,13 +271,11 @@ CATEGORIES.push(new Category(
|
||||||
const divisionGenderSpan = document.createElement('span');
|
const divisionGenderSpan = document.createElement('span');
|
||||||
divisionSpan.appendChild(divisionNameSpan);
|
divisionSpan.appendChild(divisionNameSpan);
|
||||||
divisionSpan.appendChild(divisionGenderSpan);
|
divisionSpan.appendChild(divisionGenderSpan);
|
||||||
Data.getDivision(game.divisionID)
|
let divisionName = game.division.name;
|
||||||
.then(data => {
|
let sportName = game.sport.name;
|
||||||
Data.getSportName(data.sportID)
|
divisionNameSpan.textContent = divisionName;
|
||||||
.then(data => sportSpan.textContent = data);
|
sportSpan.textContent = sportName;
|
||||||
divisionNameSpan.textContent = data.name;
|
divisionGenderSpan.textContent = getGenderLetter(game.division.gender.name);
|
||||||
divisionGenderSpan.textContent = getGenderLetter(data.gender.name);
|
|
||||||
});
|
|
||||||
sportCell.appendChild(sportSpan);
|
sportCell.appendChild(sportSpan);
|
||||||
sportCell.appendChild(divisionSpan);
|
sportCell.appendChild(divisionSpan);
|
||||||
row.appendChild(sportCell);
|
row.appendChild(sportCell);
|
||||||
|
@ -292,11 +291,10 @@ CATEGORIES.push(new Category(
|
||||||
|
|
||||||
const submitterCell = document.createElement('td');
|
const submitterCell = document.createElement('td');
|
||||||
if(game.submitterID) {
|
if(game.submitterID) {
|
||||||
Data.getAccount(game.submitterID)
|
let submitterName = game.submitter.name;
|
||||||
.then(data => submitterCell.textContent = data.name);
|
submitterCell.textContent = submitterName;
|
||||||
} else {
|
} else {
|
||||||
submitterCell.textContent = game.submitterName;
|
submitterCell.textContent = game.submitterName;
|
||||||
console.log(game.submitterName);
|
|
||||||
}
|
}
|
||||||
row.appendChild(submitterCell);
|
row.appendChild(submitterCell);
|
||||||
},
|
},
|
||||||
|
@ -362,6 +360,8 @@ CATEGORIES.push(new Category(
|
||||||
|
|
||||||
|
|
||||||
async function listItems(category) {
|
async function listItems(category) {
|
||||||
|
loadingSpan.textContent = "Loading...";
|
||||||
|
|
||||||
itemsListTable.innerHTML = "";
|
itemsListTable.innerHTML = "";
|
||||||
|
|
||||||
const itemsList = await category.getItems();
|
const itemsList = await category.getItems();
|
||||||
|
@ -389,6 +389,8 @@ async function listItems(category) {
|
||||||
|
|
||||||
itemsListTable.appendChild(row);
|
itemsListTable.appendChild(row);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
loadingSpan.textContent = '';
|
||||||
}
|
}
|
||||||
if(window.location.hash) {
|
if(window.location.hash) {
|
||||||
let correctIndex;
|
let correctIndex;
|
||||||
|
|
|
@ -9,6 +9,7 @@ const adminCheckboxSection = document.getElementById('admin-checkbox-section');
|
||||||
const adminCheckbox = document.getElementById('admin-checkbox');
|
const adminCheckbox = document.getElementById('admin-checkbox');
|
||||||
const submitButton = document.getElementById('submit-button');
|
const submitButton = document.getElementById('submit-button');
|
||||||
const deleteButton = document.getElementById('delete-button');
|
const deleteButton = document.getElementById('delete-button');
|
||||||
|
const loadingSpan = document.getElementById('loading-message');
|
||||||
|
|
||||||
async function Initialize() {
|
async function Initialize() {
|
||||||
let params = new URLSearchParams(location.search);
|
let params = new URLSearchParams(location.search);
|
||||||
|
@ -46,6 +47,9 @@ async function Initialize() {
|
||||||
passwordTextbox.disabled = false;
|
passwordTextbox.disabled = false;
|
||||||
passwordTextbox.addEventListener('keyup', checkDataValidity);
|
passwordTextbox.addEventListener('keyup', checkDataValidity);
|
||||||
checkDataValidity();
|
checkDataValidity();
|
||||||
|
|
||||||
|
loadingSpan.textContent = '';
|
||||||
|
submissionForm.style.visibility = 'visible';
|
||||||
}
|
}
|
||||||
Initialize();
|
Initialize();
|
||||||
|
|
||||||
|
|
|
@ -8,13 +8,14 @@ const genderDropdown = document.getElementById('gender-dropdown');
|
||||||
const nameTextbox = document.getElementById('name-textbox');
|
const nameTextbox = document.getElementById('name-textbox');
|
||||||
const submitButton = document.getElementById('submit-button');
|
const submitButton = document.getElementById('submit-button');
|
||||||
const deleteButton = document.getElementById('delete-button');
|
const deleteButton = document.getElementById('delete-button');
|
||||||
|
const loadingSpan = document.getElementById('loading-message');
|
||||||
|
|
||||||
|
|
||||||
async function initializeForm() {
|
async function initializeForm() {
|
||||||
let params = new URLSearchParams(location.search);
|
let params = new URLSearchParams(location.search);
|
||||||
let divisionID = params.get('division');
|
let divisionID = params.get('division');
|
||||||
if(divisionID) {
|
if(divisionID) {
|
||||||
const division = await Data.getDivision(divisionID);
|
const division = await (await fetch(`/fetch/manage/division?division=${divisionID}`)).json();
|
||||||
|
|
||||||
nameTextbox.value = division.name;
|
nameTextbox.value = division.name;
|
||||||
|
|
||||||
|
@ -26,7 +27,11 @@ async function initializeForm() {
|
||||||
if(gender == 'female') genderDropdown.selectedIndex = 1;
|
if(gender == 'female') genderDropdown.selectedIndex = 1;
|
||||||
else genderDropdown.selectedIndex = 2;
|
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);
|
Form.addHiddenValue('division', divisionID, submissionForm);
|
||||||
}
|
}
|
||||||
|
@ -40,6 +45,9 @@ async function initializeForm() {
|
||||||
|
|
||||||
nameTextbox.disabled = false;
|
nameTextbox.disabled = false;
|
||||||
nameTextbox.addEventListener('keyup', checkDataValidity);
|
nameTextbox.addEventListener('keyup', checkDataValidity);
|
||||||
|
|
||||||
|
loadingSpan.textContent = '';
|
||||||
|
submissionForm.style.visibility = 'visible';
|
||||||
}
|
}
|
||||||
initializeForm();
|
initializeForm();
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,7 @@ const team2ScoreTextbox = document.getElementById('team2-score-textbox');
|
||||||
const nameTextbox = document.getElementById('name-textbox');
|
const nameTextbox = document.getElementById('name-textbox');
|
||||||
const submitButton = document.getElementById('submit-button');
|
const submitButton = document.getElementById('submit-button');
|
||||||
const deleteButton = document.getElementById('delete-button');
|
const deleteButton = document.getElementById('delete-button');
|
||||||
|
const loadingSpan = document.getElementById('loading-span');
|
||||||
|
|
||||||
|
|
||||||
async function initializeForm() {
|
async function initializeForm() {
|
||||||
|
@ -41,24 +42,23 @@ async function initializeForm() {
|
||||||
team2ScoreTextbox.value = game.team2Score;
|
team2ScoreTextbox.value = game.team2Score;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
try {
|
/*try {*/
|
||||||
const game = await Data.getLatestGame(true);
|
const data = await (await fetch(`/fetch/index/dropdown`)).json();
|
||||||
|
|
||||||
Form.populateSeasons(seasonDropdown, game.seasonID);
|
await Form.populateSeasons(seasonDropdown, null, data);
|
||||||
const data = await Data.getDivision(game.divisionID)
|
await Form.populateSports(sportDropdown, null, data);
|
||||||
await Form.populateSports(sportDropdown, data.sportID)
|
await Form.populateGenders(genderDropdown, null, null, data);
|
||||||
await Form.populateGenders(genderDropdown, sportDropdown.value, data.gender.name)
|
await Form.populateDivisions(divisionDropdown, null, null, null, data);
|
||||||
await Form.populateDivisions(divisionDropdown, sportDropdown.value, genderDropdown.value, game.divisionID);
|
await Form.populateTeams(team1Dropdown, null, null, data);
|
||||||
await Form.populateTeams(team1Dropdown, sportDropdown.value, game.team1ID);
|
await Form.populateTeams(team2Dropdown, null, null, data, true);
|
||||||
await Form.populateTeams(team2Dropdown, sportDropdown.value, game.team2ID);
|
/*} catch {
|
||||||
} catch {
|
|
||||||
await Form.populateSeasons(seasonDropdown);
|
await Form.populateSeasons(seasonDropdown);
|
||||||
await Form.populateSports(sportDropdown)
|
await Form.populateSports(sportDropdown)
|
||||||
await Form.populateGenders(genderDropdown, sportDropdown.value)
|
await Form.populateGenders(genderDropdown, sportDropdown.value)
|
||||||
await Form.populateDivisions(divisionDropdown, sportDropdown.value, genderDropdown.value);
|
await Form.populateDivisions(divisionDropdown, sportDropdown.value, genderDropdown.value);
|
||||||
await Form.populateTeams(team1Dropdown, sportDropdown.value);
|
await Form.populateTeams(team1Dropdown, sportDropdown.value);
|
||||||
await Form.populateTeams(team2Dropdown, sportDropdown.value);
|
await Form.populateTeams(team2Dropdown, sportDropdown.value);
|
||||||
}
|
}*/
|
||||||
|
|
||||||
dateInput.value = (new Date()).toISOString().slice(0,10);
|
dateInput.value = (new Date()).toISOString().slice(0,10);
|
||||||
}
|
}
|
||||||
|
@ -95,6 +95,9 @@ async function initializeForm() {
|
||||||
team2ScoreTextbox.addEventListener('keyup', checkDataValidity);
|
team2ScoreTextbox.addEventListener('keyup', checkDataValidity);
|
||||||
if(nameTextbox) nameTextbox.addEventListener('keyup', checkDataValidity);
|
if(nameTextbox) nameTextbox.addEventListener('keyup', checkDataValidity);
|
||||||
|
|
||||||
|
loadingSpan.textContent = '';
|
||||||
|
submissionForm.style.visibility = 'visible';
|
||||||
|
|
||||||
checkDataValidity();
|
checkDataValidity();
|
||||||
}
|
}
|
||||||
initializeForm();
|
initializeForm();
|
||||||
|
|
|
@ -5,6 +5,7 @@ const nameTextbox = document.getElementById('name-textbox');
|
||||||
const submitButton = document.getElementById('submit-button');
|
const submitButton = document.getElementById('submit-button');
|
||||||
const deleteButton = document.getElementById('delete-button');
|
const deleteButton = document.getElementById('delete-button');
|
||||||
const submissionForm = document.getElementById('submission-form');
|
const submissionForm = document.getElementById('submission-form');
|
||||||
|
const loadingSpan = document.getElementById('loading-message');
|
||||||
|
|
||||||
|
|
||||||
async function initializeForm() {
|
async function initializeForm() {
|
||||||
|
@ -26,6 +27,9 @@ async function initializeForm() {
|
||||||
nameTextbox.disabled = false;
|
nameTextbox.disabled = false;
|
||||||
|
|
||||||
nameTextbox.addEventListener('keyup', checkDataValidity);
|
nameTextbox.addEventListener('keyup', checkDataValidity);
|
||||||
|
|
||||||
|
loadingSpan.textContent = '';
|
||||||
|
submissionForm.style.visibility = 'visible';
|
||||||
}
|
}
|
||||||
initializeForm();
|
initializeForm();
|
||||||
|
|
||||||
|
|
|
@ -7,19 +7,25 @@ const sportDropdown = document.getElementById('sport-dropdown');
|
||||||
const nameTextbox = document.getElementById('name-textbox');
|
const nameTextbox = document.getElementById('name-textbox');
|
||||||
const submitButton = document.getElementById('submit-button');
|
const submitButton = document.getElementById('submit-button');
|
||||||
const deleteButton = document.getElementById('delete-button');
|
const deleteButton = document.getElementById('delete-button');
|
||||||
|
const loadingSpan = document.getElementById('loading-message');
|
||||||
|
|
||||||
|
|
||||||
async function initializeForm() {
|
async function initializeForm() {
|
||||||
let params = new URLSearchParams(location.search);
|
let params = new URLSearchParams(location.search);
|
||||||
let teamID = params.get('team');
|
let teamID = params.get('team');
|
||||||
if(teamID) {
|
if(teamID) {
|
||||||
const team = await Data.getTeam(teamID);
|
const team = await (await fetch(`/fetch/manage/team?team=${teamID}`)).json();
|
||||||
|
|
||||||
nameTextbox.value = team.name;
|
nameTextbox.value = team.name;
|
||||||
|
|
||||||
deleteButton.style.visibility = "visible";
|
deleteButton.style.visibility = "visible";
|
||||||
deleteButton.disabled = false;
|
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);
|
Form.addHiddenValue('team', teamID, submissionForm);
|
||||||
}
|
}
|
||||||
|
@ -31,6 +37,9 @@ async function initializeForm() {
|
||||||
|
|
||||||
nameTextbox.disabled = false;
|
nameTextbox.disabled = false;
|
||||||
nameTextbox.addEventListener('keyup', checkDataValidity);
|
nameTextbox.addEventListener('keyup', checkDataValidity);
|
||||||
|
|
||||||
|
loadingSpan.textContent = '';
|
||||||
|
submissionForm.style.visibility = 'visible';
|
||||||
}
|
}
|
||||||
initializeForm();
|
initializeForm();
|
||||||
|
|
||||||
|
|
|
@ -48,4 +48,8 @@ form {
|
||||||
|
|
||||||
.flat-form-section {
|
.flat-form-section {
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#submission-form {
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
|
@ -32,3 +32,7 @@ tr {
|
||||||
#login-button {
|
#login-button {
|
||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#dropdowns-div {
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
|
@ -98,7 +98,7 @@ router.get('/team', async function(req, res, next) {
|
||||||
console.error("ERROR: " + err.message);
|
console.error("ERROR: " + err.message);
|
||||||
res.status(500).send("An error has occurred");
|
res.status(500).send("An error has occurred");
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
|
|
||||||
router.get('/games', async function(req, res, next) {
|
router.get('/games', async function(req, res, next) {
|
||||||
try {
|
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')
|
link(rel='stylesheet', href='/stylesheets/form.css')
|
||||||
|
|
||||||
block content
|
block content
|
||||||
|
span#loading-message Loading...
|
||||||
form#submission-form(action='/manage/account', method='POST')
|
form#submission-form(action='/manage/account', method='POST')
|
||||||
if accountID
|
if accountID
|
||||||
input#account-id(type="hidden" name="account" value=accountID)
|
input#account-id(type="hidden" name="account" value=accountID)
|
||||||
|
|
|
@ -11,7 +11,8 @@ block actions
|
||||||
|
|
||||||
|
|
||||||
block content
|
block content
|
||||||
div
|
span#loading Loading...
|
||||||
|
div#dropdowns-div
|
||||||
span(class='form-section')
|
span(class='form-section')
|
||||||
label Year
|
label Year
|
||||||
span(class='form-section-input')
|
span(class='form-section-input')
|
||||||
|
|
|
@ -18,6 +18,7 @@ block content
|
||||||
option(value="accounts") Accounts
|
option(value="accounts") Accounts
|
||||||
div
|
div
|
||||||
h2#table-header
|
h2#table-header
|
||||||
|
span#loading-message Loading...
|
||||||
table#items-list
|
table#items-list
|
||||||
button#add-new-button Add new...
|
button#add-new-button Add new...
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@ block stylesheets
|
||||||
link(rel='stylesheet', href='/stylesheets/form.css')
|
link(rel='stylesheet', href='/stylesheets/form.css')
|
||||||
|
|
||||||
block content
|
block content
|
||||||
|
span#loading-message Loading...
|
||||||
form#submission-form(action='./division', method='POST')
|
form#submission-form(action='./division', method='POST')
|
||||||
span(class='form-section')
|
span(class='form-section')
|
||||||
label Sport
|
label Sport
|
||||||
|
|
|
@ -5,6 +5,7 @@ block stylesheets
|
||||||
link(rel='stylesheet', href='/stylesheets/form.css')
|
link(rel='stylesheet', href='/stylesheets/form.css')
|
||||||
|
|
||||||
block content
|
block content
|
||||||
|
span#loading-span Loading...
|
||||||
form#submission-form(action='./game', method='POST')
|
form#submission-form(action='./game', method='POST')
|
||||||
span(class='form-section')
|
span(class='form-section')
|
||||||
label Year
|
label Year
|
||||||
|
|
|
@ -5,6 +5,7 @@ block stylesheets
|
||||||
link(rel='stylesheet', href='/stylesheets/form.css')
|
link(rel='stylesheet', href='/stylesheets/form.css')
|
||||||
|
|
||||||
block content
|
block content
|
||||||
|
span#loading-message Loading...
|
||||||
form#submission-form(action='./sport', method='POST')
|
form#submission-form(action='./sport', method='POST')
|
||||||
span(class='form-section')
|
span(class='form-section')
|
||||||
label Sport name
|
label Sport name
|
||||||
|
|
|
@ -5,6 +5,7 @@ block stylesheets
|
||||||
link(rel='stylesheet', href='/stylesheets/form.css')
|
link(rel='stylesheet', href='/stylesheets/form.css')
|
||||||
|
|
||||||
block content
|
block content
|
||||||
|
span#loading-message Loading...
|
||||||
form#submission-form(action='./team', method='POST')
|
form#submission-form(action='./team', method='POST')
|
||||||
span(class='form-section')
|
span(class='form-section')
|
||||||
label Sport
|
label Sport
|
||||||
|
|
Reference in New Issue