Merge branch 'database' into 'develop'
Switch data collection method from email to PostgreSQL See merge request sudoer777/cvcs-score-tracker!5
This commit is contained in:
		
						commit
						db2d6f2aa6
					
				
					 21 changed files with 1093 additions and 73 deletions
				
			
		| 
						 | 
				
			
			@ -1,5 +1,11 @@
 | 
			
		|||
NODE_ENV=development
 | 
			
		||||
 | 
			
		||||
PGUSER=dbuser
 | 
			
		||||
PGHOST=database.server.com
 | 
			
		||||
PGPASSWORD=dbuserpassword
 | 
			
		||||
PGDATABASE=mydatabase
 | 
			
		||||
PGPORT=5432
 | 
			
		||||
 | 
			
		||||
MAIL_FROM=fromaddress@example.com
 | 
			
		||||
MAIL_HOST=smtp.smtphost.net
 | 
			
		||||
MAIL_PORT=465
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										4
									
								
								app.js
									
										
									
									
									
								
							
							
						
						
									
										4
									
								
								app.js
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -6,7 +6,8 @@ var logger = require('morgan');
 | 
			
		|||
 | 
			
		||||
var indexRouter = require('./routes/index');
 | 
			
		||||
var usersRouter = require('./routes/users');
 | 
			
		||||
var submitRouter = require('./routes/submit')
 | 
			
		||||
var submitRouter = require('./routes/submit');
 | 
			
		||||
var dataRouter = require('./routes/data');
 | 
			
		||||
 | 
			
		||||
var app = express();
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -23,6 +24,7 @@ app.use(express.static(path.join(__dirname, 'public')));
 | 
			
		|||
app.use('/', indexRouter);
 | 
			
		||||
app.use('/users', usersRouter);
 | 
			
		||||
app.use('/submit', submitRouter);
 | 
			
		||||
app.use('/data', dataRouter);
 | 
			
		||||
 | 
			
		||||
// catch 404 and forward to error handler
 | 
			
		||||
app.use(function(req, res, next) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										47
									
								
								database/database.js
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								database/database.js
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,47 @@
 | 
			
		|||
const app = require('../app');
 | 
			
		||||
const { Client } = require('pg');
 | 
			
		||||
const fs = require('fs');
 | 
			
		||||
 | 
			
		||||
if (process.env.NODE_ENV !== 'production' || process.env.NODE_ENV !== 'testing') {
 | 
			
		||||
  require('dotenv').config();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const client = new Client();
 | 
			
		||||
client.connect();
 | 
			
		||||
 | 
			
		||||
async function executeQuery(query, values = []) {
 | 
			
		||||
    const result = await client.query({
 | 
			
		||||
        rowMode: 'array',
 | 
			
		||||
        text: query,
 | 
			
		||||
        values: values
 | 
			
		||||
    });
 | 
			
		||||
    return result.rows;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
async function Initialize() {
 | 
			
		||||
    console.log("Initializing database...")
 | 
			
		||||
    const sql = fs.readFileSync('database/init_database.sql').toString();
 | 
			
		||||
    await executeQuery(sql);
 | 
			
		||||
    console.log("Database initialized.")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
async function checkForDatabaseInitialization() {
 | 
			
		||||
    const query = `SELECT schema_name FROM information_schema.schemata WHERE schema_name = 'scores'`;
 | 
			
		||||
    let result = await executeQuery(query);
 | 
			
		||||
    
 | 
			
		||||
    const scoresSchemaExists = result.length !== 0;
 | 
			
		||||
 | 
			
		||||
    if(!scoresSchemaExists) {
 | 
			
		||||
        Initialize();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
checkForDatabaseInitialization();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
exports.executeQuery = executeQuery;
 | 
			
		||||
							
								
								
									
										105
									
								
								database/init_database.sql
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										105
									
								
								database/init_database.sql
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,105 @@
 | 
			
		|||
/*  SCORE TRACKER DATABASE LAYOUT
 | 
			
		||||
 | 
			
		||||
scores:
 | 
			
		||||
 | 
			
		||||
    sports:
 | 
			
		||||
        *sport_id*   |   sport_name  |   currently_active
 | 
			
		||||
    
 | 
			
		||||
    divisions:
 | 
			
		||||
        *division_id*   |   division_name   |   gender   |   *sport_id*   |   currently_active
 | 
			
		||||
 | 
			
		||||
    teams:
 | 
			
		||||
        *team_id*   |   team_name   |   ~sport_id~  |   currently_active
 | 
			
		||||
 | 
			
		||||
    seasons:
 | 
			
		||||
        *season_id*   |   school_year
 | 
			
		||||
 | 
			
		||||
    games:
 | 
			
		||||
        *game_id*   |   ~division_id~   |   ~season_id~  |   game_date   |   ~team1_id~  |   ~team2_id~   |   team1_score   |   team2_score   |   ~submitter_id~   |   updated_timestamp
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
accounts:
 | 
			
		||||
 | 
			
		||||
    users:
 | 
			
		||||
        *user_id*   |   email   |   salt   |   password_hash   |   role   |   approved
 | 
			
		||||
 | 
			
		||||
    sessions:
 | 
			
		||||
        *session_id*   |   ~user_id~   |   expiration_date
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
BEGIN;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
CREATE SCHEMA IF NOT EXISTS scores;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
CREATE TABLE IF NOT EXISTS scores.sports(
 | 
			
		||||
        sport_id BIGINT GENERATED ALWAYS AS IDENTITY,
 | 
			
		||||
        sport_name TEXT UNIQUE NOT NULL,
 | 
			
		||||
        currently_active BOOLEAN DEFAULT TRUE,
 | 
			
		||||
        PRIMARY KEY(sport_id)
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
CREATE TABLE IF NOT EXISTS scores.divisions(
 | 
			
		||||
        division_id BIGINT GENERATED ALWAYS AS IDENTITY,
 | 
			
		||||
        division_name TEXT NOT NULL,
 | 
			
		||||
        gender VARCHAR(1) CHECK (gender IN ( 'F', 'M' ) ),
 | 
			
		||||
        sport_id BIGINT,
 | 
			
		||||
        currently_active BOOLEAN DEFAULT TRUE,
 | 
			
		||||
        PRIMARY KEY(division_id),
 | 
			
		||||
        CONSTRAINT fk_sport
 | 
			
		||||
            FOREIGN KEY(sport_id)
 | 
			
		||||
                REFERENCES scores.sports(sport_id)
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
CREATE TABLE IF NOT EXISTS scores.teams(
 | 
			
		||||
        team_id BIGINT GENERATED ALWAYS AS IDENTITY,
 | 
			
		||||
        team_name TEXT NOT NULL,
 | 
			
		||||
        sport_id BIGINT,
 | 
			
		||||
        currently_active BOOLEAN DEFAULT TRUE,
 | 
			
		||||
        PRIMARY KEY(team_id),
 | 
			
		||||
        CONSTRAINT fk_sport
 | 
			
		||||
            FOREIGN KEY(sport_id)
 | 
			
		||||
                REFERENCES scores.sports(sport_id)
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
CREATE TABLE IF NOT EXISTS scores.seasons(
 | 
			
		||||
        season_id BIGINT GENERATED ALWAYS AS IDENTITY,
 | 
			
		||||
        school_year INTEGER NOT NULL,
 | 
			
		||||
        PRIMARY KEY(season_id)
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
CREATE TABLE IF NOT EXISTS scores.games(
 | 
			
		||||
        game_id BIGINT GENERATED ALWAYS AS IDENTITY,
 | 
			
		||||
        division_id BIGINT,
 | 
			
		||||
        season_id BIGINT,
 | 
			
		||||
        game_date DATE,
 | 
			
		||||
        team1_id BIGINT,
 | 
			
		||||
        team2_id BIGINT,
 | 
			
		||||
        team1_score INTEGER,
 | 
			
		||||
        team2_score INTEGER,
 | 
			
		||||
/*        submitter_id BIGINT,*/
 | 
			
		||||
        updated_timestamp TIMESTAMP WITH TIME ZONE DEFAULT now(),
 | 
			
		||||
        PRIMARY KEY(game_id),
 | 
			
		||||
        CONSTRAINT fk_division
 | 
			
		||||
            FOREIGN KEY(division_id)
 | 
			
		||||
                REFERENCES scores.divisions(division_id),
 | 
			
		||||
        CONSTRAINT fk_season
 | 
			
		||||
            FOREIGN KEY(season_id)
 | 
			
		||||
                REFERENCES scores.seasons(season_id),
 | 
			
		||||
        CONSTRAINT fk_team1
 | 
			
		||||
            FOREIGN KEY(team1_id)
 | 
			
		||||
                REFERENCES scores.teams(team_id),
 | 
			
		||||
        CONSTRAINT fk_team2
 | 
			
		||||
            FOREIGN KEY(team2_id)
 | 
			
		||||
                REFERENCES scores.teams(team_id)
 | 
			
		||||
/*        CONSTRAINT fk_submitter
 | 
			
		||||
            FOREIGN KEY(submitter_id)
 | 
			
		||||
                REFERENCES accounts.users(user_id)*/
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
COMMIT;
 | 
			
		||||
							
								
								
									
										70
									
								
								database/scores/divisions.js
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										70
									
								
								database/scores/divisions.js
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,70 @@
 | 
			
		|||
const database = require('./../database');
 | 
			
		||||
const genders = require('./genders');
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Division {
 | 
			
		||||
    constructor(id, name) {
 | 
			
		||||
        this.id = id;
 | 
			
		||||
        this.name = name;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
function getGenderID(gender) {
 | 
			
		||||
    return (gender == genders.MALE) ? "M" : "F";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
async function add(name, gender, sportID) {
 | 
			
		||||
    const query = `INSERT INTO scores.divisions(division_name,gender,sport_id)
 | 
			
		||||
            VALUES($1,$2,$3)
 | 
			
		||||
            RETURNING division_id;`;
 | 
			
		||||
    const genderID = getGenderID(gender);
 | 
			
		||||
    const id = (await database.executeQuery(query, [name, genderID, sportID]))[0][0];
 | 
			
		||||
    return new Division(id, name);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
async function rename(id, division) {
 | 
			
		||||
    const query = `UPDATE scores.divisions
 | 
			
		||||
    SET division_name = $2
 | 
			
		||||
    WHERE division_id = $1;`;
 | 
			
		||||
    await database.executeQuery(query, [id, name]);
 | 
			
		||||
    return new Division(id, name);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
async function remove(id) {
 | 
			
		||||
    const query = `DELETE FROM scores.divisions
 | 
			
		||||
    WHERE division_id = $1
 | 
			
		||||
    RETURNING division_name;`;
 | 
			
		||||
    const name = (await database.executeQuery(query, [id]))[0][0];
 | 
			
		||||
    return new Division(id, name);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
async function retrieveBySportAndGender(sportID, gender) {
 | 
			
		||||
    const query = `SELECT *
 | 
			
		||||
            FROM scores.divisions
 | 
			
		||||
            WHERE sport_id = $1 AND gender = $2
 | 
			
		||||
            ORDER BY division_name;`;
 | 
			
		||||
    const genderID = getGenderID(gender);
 | 
			
		||||
    const table = await database.executeQuery(query, [sportID, genderID]);
 | 
			
		||||
 | 
			
		||||
    const divisionsList = [];
 | 
			
		||||
    table.forEach((row) => {
 | 
			
		||||
        divisionsList.push(new Division(row[0], row[1]));
 | 
			
		||||
    });
 | 
			
		||||
    return divisionsList;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
exports.add = add;
 | 
			
		||||
exports.rename = rename;
 | 
			
		||||
exports.remove = remove;
 | 
			
		||||
exports.retrieveBySportAndGender = retrieveBySportAndGender;
 | 
			
		||||
							
								
								
									
										65
									
								
								database/scores/games.js
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								database/scores/games.js
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,65 @@
 | 
			
		|||
const database = require('./../database');
 | 
			
		||||
const moment = require('moment');
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Game {
 | 
			
		||||
    constructor(id, date, team1ID, team2ID, team1Score, team2Score) {
 | 
			
		||||
        this.id = id;
 | 
			
		||||
        this.date = date;
 | 
			
		||||
        this.team1ID = team1ID;
 | 
			
		||||
        this.team2ID = team2ID;
 | 
			
		||||
        this.team1Score = team1Score;
 | 
			
		||||
        this.team2Score = team2Score;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
async function add(divisionID, seasonID, date, team1ID, team2ID, team1Score, team2Score) {
 | 
			
		||||
    const query = `INSERT INTO scores.games(division_id, season_id, game_date, team1_id, team2_id, team1_score, team2_score)
 | 
			
		||||
            VALUES($1, $2, $3, $4, $5, $6, $7)
 | 
			
		||||
            RETURNING game_id;`;
 | 
			
		||||
    
 | 
			
		||||
    const dateISO = date.format('YYYY-MM-DD');
 | 
			
		||||
 | 
			
		||||
    const id = (await database.executeQuery(query, [divisionID, seasonID, dateISO, team1ID, team2ID, team1Score, team2Score]))[0][0];
 | 
			
		||||
    return new Game(id, date, team1ID, team2ID, team1Score, team2Score);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
async function remove(id) {
 | 
			
		||||
    const query = `DELETE FROM scores.games
 | 
			
		||||
            WHERE game_id = $1
 | 
			
		||||
            RETURNING * ;`;
 | 
			
		||||
    const row = (await database.executeQuery(query, [id]))[0];
 | 
			
		||||
    return new Game(id, row[3], row[4], row[5], row[6], row[7]);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
async function retrieveByTeamDivisionAndSeason(teamID, divisionID, seasonID) {
 | 
			
		||||
    const query = `SELECT *
 | 
			
		||||
            FROM scores.games
 | 
			
		||||
            WHERE (team1_id = $1 OR team2_id = $1) AND division_id = $2 AND season_id = $3
 | 
			
		||||
            ORDER BY game_date DESC;`;
 | 
			
		||||
    const table = (await database.executeQuery(query, [teamID,divisionID,seasonID]));
 | 
			
		||||
 | 
			
		||||
    const gamesList = [];
 | 
			
		||||
    table.forEach((row) => {
 | 
			
		||||
        opponentIsTeam2 = teamID != row[5];
 | 
			
		||||
        opponentID = opponentIsTeam2 ? row[5] : row[4];
 | 
			
		||||
        teamScore = opponentIsTeam2 ? row[6] : row[7];
 | 
			
		||||
        opponentScore = opponentIsTeam2 ? row[7] : row[6];
 | 
			
		||||
 | 
			
		||||
        gamesList.push(new Game(row[0], moment(row[3]), teamID, opponentID, teamScore, opponentScore));
 | 
			
		||||
    });
 | 
			
		||||
    return gamesList;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
exports.add = add;
 | 
			
		||||
exports.remove = remove;
 | 
			
		||||
exports.retrieveByTeamDivisionAndSeason = retrieveByTeamDivisionAndSeason;
 | 
			
		||||
							
								
								
									
										48
									
								
								database/scores/genders.js
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								database/scores/genders.js
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,48 @@
 | 
			
		|||
const database = require('./../database');
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Gender {
 | 
			
		||||
    constructor(name) {
 | 
			
		||||
        this.name = name;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
const MALE = new Gender("male");
 | 
			
		||||
const FEMALE = new Gender("female");
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
async function retrieveBySport(sportID) {
 | 
			
		||||
    const query = `SELECT gender
 | 
			
		||||
            from scores.divisions
 | 
			
		||||
            WHERE sport_id = $1;`;
 | 
			
		||||
    const table = await database.executeQuery(query, [sportID]);
 | 
			
		||||
 | 
			
		||||
    const gendersList = [];
 | 
			
		||||
 | 
			
		||||
    if(table.length == 0) {
 | 
			
		||||
        return gendersList;
 | 
			
		||||
    }
 | 
			
		||||
    if(table.length == 2) {
 | 
			
		||||
        gendersList.push(FEMALE);
 | 
			
		||||
        gendersList.push(MALE);
 | 
			
		||||
        return gendersList;
 | 
			
		||||
    }
 | 
			
		||||
    else if(table[0][0] = "F") {
 | 
			
		||||
        gendersList.push(FEMALE);
 | 
			
		||||
        return gendersList;
 | 
			
		||||
    }
 | 
			
		||||
    else if(table[0][0] = "M") {
 | 
			
		||||
        gendersList.push(MALE);
 | 
			
		||||
        return gendersList;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
exports.MALE = MALE;
 | 
			
		||||
exports.FEMALE = FEMALE;
 | 
			
		||||
exports.retrieveBySport = retrieveBySport;
 | 
			
		||||
							
								
								
									
										51
									
								
								database/scores/seasons.js
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								database/scores/seasons.js
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,51 @@
 | 
			
		|||
const database = require('./../database');
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Season {
 | 
			
		||||
    constructor(id, year) {
 | 
			
		||||
        this.id = id;
 | 
			
		||||
        this.year = year;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
async function add(year) {
 | 
			
		||||
    const query = `INSERT INTO scores.seasons(school_year)
 | 
			
		||||
            VALUES($1)
 | 
			
		||||
            RETURNING season_id;`;
 | 
			
		||||
    const id = (await database.executeQuery(query, [year]))[0][0];
 | 
			
		||||
    return new Season(id, year);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
async function remove(id) {
 | 
			
		||||
    const query = `DELETE FROM scores.seasons
 | 
			
		||||
            WHERE season_id = $1
 | 
			
		||||
            RETURNING school_year;`;
 | 
			
		||||
    const year = (await database.executeQuery(query, [id]))[0][0];
 | 
			
		||||
    return new Season(id, year);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
async function retrieveAll() {
 | 
			
		||||
    const query = `SELECT *
 | 
			
		||||
            FROM scores.seasons
 | 
			
		||||
            ORDER BY school_year DESC;`;
 | 
			
		||||
    const table = await database.executeQuery(query);
 | 
			
		||||
 | 
			
		||||
    const seasonsList = [];
 | 
			
		||||
    table.forEach((row) => {
 | 
			
		||||
        seasonsList.push(new Season(row[0], row[1]));
 | 
			
		||||
    });
 | 
			
		||||
    return seasonsList;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
exports.add = add;
 | 
			
		||||
exports.remove = remove;
 | 
			
		||||
exports.retrieveAll = retrieveAll;
 | 
			
		||||
							
								
								
									
										58
									
								
								database/scores/sports.js
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								database/scores/sports.js
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,58 @@
 | 
			
		|||
const database = require('./../database');
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Sport {
 | 
			
		||||
    constructor(id, name) {
 | 
			
		||||
        this.id = id;
 | 
			
		||||
        this.name = name;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
async function add(name) {
 | 
			
		||||
    const query = `INSERT INTO scores.sports(sport_name)
 | 
			
		||||
            VALUES($1)
 | 
			
		||||
            RETURNING sport_id;`;
 | 
			
		||||
    const id = (await database.executeQuery(query, [name]))[0][0];
 | 
			
		||||
    return new Sport(id, name);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
async function rename(id, name) {
 | 
			
		||||
    const query = `UPDATE scores.sports
 | 
			
		||||
            SET sport_name = $2
 | 
			
		||||
            WHERE sport_id = $1;`;
 | 
			
		||||
    await database.executeQuery(query, [id, name]);
 | 
			
		||||
    return new Sport(id, name);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
async function remove(id) {
 | 
			
		||||
    const query = `DELETE FROM scores.sports
 | 
			
		||||
            WHERE sport_id = $1
 | 
			
		||||
            RETURNING sport_name;`;
 | 
			
		||||
    const name = (await database.executeQuery(query, [id]))[0][0];
 | 
			
		||||
    return new Sport(id, name);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
async function retrieveAll() {
 | 
			
		||||
    const query = `SELECT *
 | 
			
		||||
            FROM scores.sports
 | 
			
		||||
            ORDER BY sport_name;`;
 | 
			
		||||
    const table = await database.executeQuery(query);
 | 
			
		||||
    
 | 
			
		||||
    const sportsList = [];
 | 
			
		||||
    table.forEach((row) => {
 | 
			
		||||
        sportsList.push(new Sport(row[0], row[1]));
 | 
			
		||||
    });
 | 
			
		||||
    return sportsList;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
exports.add = add;
 | 
			
		||||
exports.rename = rename;
 | 
			
		||||
exports.remove = remove;
 | 
			
		||||
exports.retrieveAll = retrieveAll;
 | 
			
		||||
							
								
								
									
										61
									
								
								database/scores/teams.js
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								database/scores/teams.js
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,61 @@
 | 
			
		|||
const database = require('./../database');
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Team {
 | 
			
		||||
    constructor(id, name) {
 | 
			
		||||
        this.id = id;
 | 
			
		||||
        this.name = name;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
async function add(name, sportID) {
 | 
			
		||||
    const query = `INSERT INTO scores.teams(team_name, sport_id)
 | 
			
		||||
            VALUES($1, $2)
 | 
			
		||||
            RETURNING team_id;`;
 | 
			
		||||
    const id = (await database.executeQuery(query, [name, sportID]))[0][0];
 | 
			
		||||
    return new Team(id, name);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
async function rename(id, name) {
 | 
			
		||||
    const query = `UPDATE scores.teams
 | 
			
		||||
            SET team_name = $2
 | 
			
		||||
            WHERE team_id = $1;`;
 | 
			
		||||
    await database.executeQuery(query, [id, name]);
 | 
			
		||||
    return new Team(id, name);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
async function remove(id) {
 | 
			
		||||
    const query = `DELETE FROM scores.teams
 | 
			
		||||
            WHERE team_id = $1
 | 
			
		||||
            RETURNING team_name;`;
 | 
			
		||||
    const name = (await database.executeQuery(query, [id]))[0][0];
 | 
			
		||||
    return new Team(id, name);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
async function retrieveBySport(sportID) {
 | 
			
		||||
    const query = `SELECT *
 | 
			
		||||
            FROM scores.teams
 | 
			
		||||
            WHERE sport_id = $1
 | 
			
		||||
            ORDER BY team_name;`;
 | 
			
		||||
    const table = await database.executeQuery(query, [sportID]);
 | 
			
		||||
 | 
			
		||||
    const teamsList = [];
 | 
			
		||||
    table.forEach((row) => {
 | 
			
		||||
        teamsList.push(new Team(row[0], row[1]));
 | 
			
		||||
    });
 | 
			
		||||
    return teamsList;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
exports.add = add;
 | 
			
		||||
exports.rename = rename;
 | 
			
		||||
exports.remove = remove;
 | 
			
		||||
exports.retrieveBySport = retrieveBySport;
 | 
			
		||||
							
								
								
									
										347
									
								
								package-lock.json
									
										
									
										generated
									
									
									
								
							
							
						
						
									
										347
									
								
								package-lock.json
									
										
									
										generated
									
									
									
								
							| 
						 | 
				
			
			@ -8,13 +8,17 @@
 | 
			
		|||
      "name": "demo",
 | 
			
		||||
      "version": "0.0.0",
 | 
			
		||||
      "dependencies": {
 | 
			
		||||
        "async": "^3.2.2",
 | 
			
		||||
        "cookie-parser": "~1.4.3",
 | 
			
		||||
        "debug": "~2.6.9",
 | 
			
		||||
        "dotenv": "^10.0.0",
 | 
			
		||||
        "express": "~4.16.0",
 | 
			
		||||
        "http-errors": "~1.6.2",
 | 
			
		||||
        "moment": "^2.29.1",
 | 
			
		||||
        "morgan": "~1.9.0",
 | 
			
		||||
        "nodemailer": "^6.6.5",
 | 
			
		||||
        "passport": "^0.5.0",
 | 
			
		||||
        "pg": "^8.7.1",
 | 
			
		||||
        "pug": "2.0.0-beta11"
 | 
			
		||||
      },
 | 
			
		||||
      "devDependencies": {
 | 
			
		||||
| 
						 | 
				
			
			@ -108,6 +112,11 @@
 | 
			
		|||
      "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
 | 
			
		||||
      "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY="
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/async": {
 | 
			
		||||
      "version": "3.2.2",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/async/-/async-3.2.2.tgz",
 | 
			
		||||
      "integrity": "sha512-H0E+qZaDEfx/FY4t7iLRv1W2fFI6+pyCeTw1uN20AQPiwqwM6ojPxHxdLv4z8hi2DtnW9BOckSspLucW7pIE5g=="
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/asynckit": {
 | 
			
		||||
      "version": "0.4.0",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
 | 
			
		||||
| 
						 | 
				
			
			@ -195,6 +204,14 @@
 | 
			
		|||
      "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==",
 | 
			
		||||
      "dev": true
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/buffer-writer": {
 | 
			
		||||
      "version": "2.0.0",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/buffer-writer/-/buffer-writer-2.0.0.tgz",
 | 
			
		||||
      "integrity": "sha512-a7ZpuTZU1TRtnwyCNW3I5dc0wWNC3VR9S++Ewyk2HHZdrO3CQJqSpd+95Us590V6AL7JqUAH2IwZ/398PmNFgw==",
 | 
			
		||||
      "engines": {
 | 
			
		||||
        "node": ">=4"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/bytes": {
 | 
			
		||||
      "version": "3.0.0",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz",
 | 
			
		||||
| 
						 | 
				
			
			@ -893,6 +910,14 @@
 | 
			
		|||
        "ms": "2.0.0"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/moment": {
 | 
			
		||||
      "version": "2.29.1",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz",
 | 
			
		||||
      "integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==",
 | 
			
		||||
      "engines": {
 | 
			
		||||
        "node": "*"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/morgan": {
 | 
			
		||||
      "version": "1.9.0",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.9.0.tgz",
 | 
			
		||||
| 
						 | 
				
			
			@ -965,6 +990,11 @@
 | 
			
		|||
        "wrappy": "1"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/packet-reader": {
 | 
			
		||||
      "version": "1.0.0",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/packet-reader/-/packet-reader-1.0.0.tgz",
 | 
			
		||||
      "integrity": "sha512-HAKu/fG3HpHFO0AA8WE8q2g+gBJaZ9MG7fcKk+IJPLTGAD6Psw4443l+9DGRbOIh3/aXr7Phy0TjilYivJo5XQ=="
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/parseurl": {
 | 
			
		||||
      "version": "1.3.2",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz",
 | 
			
		||||
| 
						 | 
				
			
			@ -973,6 +1003,30 @@
 | 
			
		|||
        "node": ">= 0.8"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/passport": {
 | 
			
		||||
      "version": "0.5.0",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/passport/-/passport-0.5.0.tgz",
 | 
			
		||||
      "integrity": "sha512-ln+ue5YaNDS+fes6O5PCzXKSseY5u8MYhX9H5Co4s+HfYI5oqvnHKoOORLYDUPh+8tHvrxugF2GFcUA1Q1Gqfg==",
 | 
			
		||||
      "dependencies": {
 | 
			
		||||
        "passport-strategy": "1.x.x",
 | 
			
		||||
        "pause": "0.0.1"
 | 
			
		||||
      },
 | 
			
		||||
      "engines": {
 | 
			
		||||
        "node": ">= 0.4.0"
 | 
			
		||||
      },
 | 
			
		||||
      "funding": {
 | 
			
		||||
        "type": "github",
 | 
			
		||||
        "url": "https://github.com/sponsors/jaredhanson"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/passport-strategy": {
 | 
			
		||||
      "version": "1.0.0",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/passport-strategy/-/passport-strategy-1.0.0.tgz",
 | 
			
		||||
      "integrity": "sha1-tVOaqPwiWj0a0XlHbd8ja0QPUuQ=",
 | 
			
		||||
      "engines": {
 | 
			
		||||
        "node": ">= 0.4.0"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/path-is-absolute": {
 | 
			
		||||
      "version": "1.0.1",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
 | 
			
		||||
| 
						 | 
				
			
			@ -992,6 +1046,120 @@
 | 
			
		|||
      "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
 | 
			
		||||
      "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w="
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/pause": {
 | 
			
		||||
      "version": "0.0.1",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/pause/-/pause-0.0.1.tgz",
 | 
			
		||||
      "integrity": "sha1-HUCLP9t2kjuVQ9lvtMnf1TXZy10="
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/pg": {
 | 
			
		||||
      "version": "8.7.1",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/pg/-/pg-8.7.1.tgz",
 | 
			
		||||
      "integrity": "sha512-7bdYcv7V6U3KAtWjpQJJBww0UEsWuh4yQ/EjNf2HeO/NnvKjpvhEIe/A/TleP6wtmSKnUnghs5A9jUoK6iDdkA==",
 | 
			
		||||
      "dependencies": {
 | 
			
		||||
        "buffer-writer": "2.0.0",
 | 
			
		||||
        "packet-reader": "1.0.0",
 | 
			
		||||
        "pg-connection-string": "^2.5.0",
 | 
			
		||||
        "pg-pool": "^3.4.1",
 | 
			
		||||
        "pg-protocol": "^1.5.0",
 | 
			
		||||
        "pg-types": "^2.1.0",
 | 
			
		||||
        "pgpass": "1.x"
 | 
			
		||||
      },
 | 
			
		||||
      "engines": {
 | 
			
		||||
        "node": ">= 8.0.0"
 | 
			
		||||
      },
 | 
			
		||||
      "peerDependencies": {
 | 
			
		||||
        "pg-native": ">=2.0.0"
 | 
			
		||||
      },
 | 
			
		||||
      "peerDependenciesMeta": {
 | 
			
		||||
        "pg-native": {
 | 
			
		||||
          "optional": true
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/pg-connection-string": {
 | 
			
		||||
      "version": "2.5.0",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.5.0.tgz",
 | 
			
		||||
      "integrity": "sha512-r5o/V/ORTA6TmUnyWZR9nCj1klXCO2CEKNRlVuJptZe85QuhFayC7WeMic7ndayT5IRIR0S0xFxFi2ousartlQ=="
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/pg-int8": {
 | 
			
		||||
      "version": "1.0.1",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz",
 | 
			
		||||
      "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==",
 | 
			
		||||
      "engines": {
 | 
			
		||||
        "node": ">=4.0.0"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/pg-pool": {
 | 
			
		||||
      "version": "3.4.1",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.4.1.tgz",
 | 
			
		||||
      "integrity": "sha512-TVHxR/gf3MeJRvchgNHxsYsTCHQ+4wm3VIHSS19z8NC0+gioEhq1okDY1sm/TYbfoP6JLFx01s0ShvZ3puP/iQ==",
 | 
			
		||||
      "peerDependencies": {
 | 
			
		||||
        "pg": ">=8.0"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/pg-protocol": {
 | 
			
		||||
      "version": "1.5.0",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.5.0.tgz",
 | 
			
		||||
      "integrity": "sha512-muRttij7H8TqRNu/DxrAJQITO4Ac7RmX3Klyr/9mJEOBeIpgnF8f9jAfRz5d3XwQZl5qBjF9gLsUtMPJE0vezQ=="
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/pg-types": {
 | 
			
		||||
      "version": "2.2.0",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz",
 | 
			
		||||
      "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==",
 | 
			
		||||
      "dependencies": {
 | 
			
		||||
        "pg-int8": "1.0.1",
 | 
			
		||||
        "postgres-array": "~2.0.0",
 | 
			
		||||
        "postgres-bytea": "~1.0.0",
 | 
			
		||||
        "postgres-date": "~1.0.4",
 | 
			
		||||
        "postgres-interval": "^1.1.0"
 | 
			
		||||
      },
 | 
			
		||||
      "engines": {
 | 
			
		||||
        "node": ">=4"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/pgpass": {
 | 
			
		||||
      "version": "1.0.4",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.4.tgz",
 | 
			
		||||
      "integrity": "sha512-YmuA56alyBq7M59vxVBfPJrGSozru8QAdoNlWuW3cz8l+UX3cWge0vTvjKhsSHSJpo3Bom8/Mm6hf0TR5GY0+w==",
 | 
			
		||||
      "dependencies": {
 | 
			
		||||
        "split2": "^3.1.1"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/postgres-array": {
 | 
			
		||||
      "version": "2.0.0",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz",
 | 
			
		||||
      "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==",
 | 
			
		||||
      "engines": {
 | 
			
		||||
        "node": ">=4"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/postgres-bytea": {
 | 
			
		||||
      "version": "1.0.0",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz",
 | 
			
		||||
      "integrity": "sha1-AntTPAqokOJtFy1Hz5zOzFIazTU=",
 | 
			
		||||
      "engines": {
 | 
			
		||||
        "node": ">=0.10.0"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/postgres-date": {
 | 
			
		||||
      "version": "1.0.7",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz",
 | 
			
		||||
      "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==",
 | 
			
		||||
      "engines": {
 | 
			
		||||
        "node": ">=0.10.0"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/postgres-interval": {
 | 
			
		||||
      "version": "1.2.0",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz",
 | 
			
		||||
      "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==",
 | 
			
		||||
      "dependencies": {
 | 
			
		||||
        "xtend": "^4.0.0"
 | 
			
		||||
      },
 | 
			
		||||
      "engines": {
 | 
			
		||||
        "node": ">=0.10.0"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/process-nextick-args": {
 | 
			
		||||
      "version": "2.0.0",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz",
 | 
			
		||||
| 
						 | 
				
			
			@ -1294,6 +1462,27 @@
 | 
			
		|||
        "node": ">=0.8.0"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/split2": {
 | 
			
		||||
      "version": "3.2.2",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz",
 | 
			
		||||
      "integrity": "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==",
 | 
			
		||||
      "dependencies": {
 | 
			
		||||
        "readable-stream": "^3.0.0"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/split2/node_modules/readable-stream": {
 | 
			
		||||
      "version": "3.6.0",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
 | 
			
		||||
      "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
 | 
			
		||||
      "dependencies": {
 | 
			
		||||
        "inherits": "^2.0.3",
 | 
			
		||||
        "string_decoder": "^1.1.1",
 | 
			
		||||
        "util-deprecate": "^1.0.1"
 | 
			
		||||
      },
 | 
			
		||||
      "engines": {
 | 
			
		||||
        "node": ">= 6"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/statuses": {
 | 
			
		||||
      "version": "1.4.0",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz",
 | 
			
		||||
| 
						 | 
				
			
			@ -1306,7 +1495,6 @@
 | 
			
		|||
      "version": "1.1.1",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
 | 
			
		||||
      "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
 | 
			
		||||
      "dev": true,
 | 
			
		||||
      "dependencies": {
 | 
			
		||||
        "safe-buffer": "~5.1.0"
 | 
			
		||||
      }
 | 
			
		||||
| 
						 | 
				
			
			@ -1434,8 +1622,7 @@
 | 
			
		|||
    "node_modules/util-deprecate": {
 | 
			
		||||
      "version": "1.0.2",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
 | 
			
		||||
      "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
 | 
			
		||||
      "dev": true
 | 
			
		||||
      "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/utils-merge": {
 | 
			
		||||
      "version": "1.0.1",
 | 
			
		||||
| 
						 | 
				
			
			@ -1492,6 +1679,14 @@
 | 
			
		|||
      "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
 | 
			
		||||
      "dev": true
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/xtend": {
 | 
			
		||||
      "version": "4.0.2",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
 | 
			
		||||
      "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
 | 
			
		||||
      "engines": {
 | 
			
		||||
        "node": ">=0.4"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/yargs": {
 | 
			
		||||
      "version": "3.10.0",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz",
 | 
			
		||||
| 
						 | 
				
			
			@ -1572,6 +1767,11 @@
 | 
			
		|||
      "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
 | 
			
		||||
      "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY="
 | 
			
		||||
    },
 | 
			
		||||
    "async": {
 | 
			
		||||
      "version": "3.2.2",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/async/-/async-3.2.2.tgz",
 | 
			
		||||
      "integrity": "sha512-H0E+qZaDEfx/FY4t7iLRv1W2fFI6+pyCeTw1uN20AQPiwqwM6ojPxHxdLv4z8hi2DtnW9BOckSspLucW7pIE5g=="
 | 
			
		||||
    },
 | 
			
		||||
    "asynckit": {
 | 
			
		||||
      "version": "0.4.0",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
 | 
			
		||||
| 
						 | 
				
			
			@ -1650,6 +1850,11 @@
 | 
			
		|||
      "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==",
 | 
			
		||||
      "dev": true
 | 
			
		||||
    },
 | 
			
		||||
    "buffer-writer": {
 | 
			
		||||
      "version": "2.0.0",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/buffer-writer/-/buffer-writer-2.0.0.tgz",
 | 
			
		||||
      "integrity": "sha512-a7ZpuTZU1TRtnwyCNW3I5dc0wWNC3VR9S++Ewyk2HHZdrO3CQJqSpd+95Us590V6AL7JqUAH2IwZ/398PmNFgw=="
 | 
			
		||||
    },
 | 
			
		||||
    "bytes": {
 | 
			
		||||
      "version": "3.0.0",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz",
 | 
			
		||||
| 
						 | 
				
			
			@ -2204,6 +2409,11 @@
 | 
			
		|||
        }
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "moment": {
 | 
			
		||||
      "version": "2.29.1",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz",
 | 
			
		||||
      "integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ=="
 | 
			
		||||
    },
 | 
			
		||||
    "morgan": {
 | 
			
		||||
      "version": "1.9.0",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.9.0.tgz",
 | 
			
		||||
| 
						 | 
				
			
			@ -2258,11 +2468,30 @@
 | 
			
		|||
        "wrappy": "1"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "packet-reader": {
 | 
			
		||||
      "version": "1.0.0",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/packet-reader/-/packet-reader-1.0.0.tgz",
 | 
			
		||||
      "integrity": "sha512-HAKu/fG3HpHFO0AA8WE8q2g+gBJaZ9MG7fcKk+IJPLTGAD6Psw4443l+9DGRbOIh3/aXr7Phy0TjilYivJo5XQ=="
 | 
			
		||||
    },
 | 
			
		||||
    "parseurl": {
 | 
			
		||||
      "version": "1.3.2",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz",
 | 
			
		||||
      "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M="
 | 
			
		||||
    },
 | 
			
		||||
    "passport": {
 | 
			
		||||
      "version": "0.5.0",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/passport/-/passport-0.5.0.tgz",
 | 
			
		||||
      "integrity": "sha512-ln+ue5YaNDS+fes6O5PCzXKSseY5u8MYhX9H5Co4s+HfYI5oqvnHKoOORLYDUPh+8tHvrxugF2GFcUA1Q1Gqfg==",
 | 
			
		||||
      "requires": {
 | 
			
		||||
        "passport-strategy": "1.x.x",
 | 
			
		||||
        "pause": "0.0.1"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "passport-strategy": {
 | 
			
		||||
      "version": "1.0.0",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/passport-strategy/-/passport-strategy-1.0.0.tgz",
 | 
			
		||||
      "integrity": "sha1-tVOaqPwiWj0a0XlHbd8ja0QPUuQ="
 | 
			
		||||
    },
 | 
			
		||||
    "path-is-absolute": {
 | 
			
		||||
      "version": "1.0.1",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
 | 
			
		||||
| 
						 | 
				
			
			@ -2279,6 +2508,89 @@
 | 
			
		|||
      "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
 | 
			
		||||
      "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w="
 | 
			
		||||
    },
 | 
			
		||||
    "pause": {
 | 
			
		||||
      "version": "0.0.1",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/pause/-/pause-0.0.1.tgz",
 | 
			
		||||
      "integrity": "sha1-HUCLP9t2kjuVQ9lvtMnf1TXZy10="
 | 
			
		||||
    },
 | 
			
		||||
    "pg": {
 | 
			
		||||
      "version": "8.7.1",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/pg/-/pg-8.7.1.tgz",
 | 
			
		||||
      "integrity": "sha512-7bdYcv7V6U3KAtWjpQJJBww0UEsWuh4yQ/EjNf2HeO/NnvKjpvhEIe/A/TleP6wtmSKnUnghs5A9jUoK6iDdkA==",
 | 
			
		||||
      "requires": {
 | 
			
		||||
        "buffer-writer": "2.0.0",
 | 
			
		||||
        "packet-reader": "1.0.0",
 | 
			
		||||
        "pg-connection-string": "^2.5.0",
 | 
			
		||||
        "pg-pool": "^3.4.1",
 | 
			
		||||
        "pg-protocol": "^1.5.0",
 | 
			
		||||
        "pg-types": "^2.1.0",
 | 
			
		||||
        "pgpass": "1.x"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "pg-connection-string": {
 | 
			
		||||
      "version": "2.5.0",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.5.0.tgz",
 | 
			
		||||
      "integrity": "sha512-r5o/V/ORTA6TmUnyWZR9nCj1klXCO2CEKNRlVuJptZe85QuhFayC7WeMic7ndayT5IRIR0S0xFxFi2ousartlQ=="
 | 
			
		||||
    },
 | 
			
		||||
    "pg-int8": {
 | 
			
		||||
      "version": "1.0.1",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz",
 | 
			
		||||
      "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw=="
 | 
			
		||||
    },
 | 
			
		||||
    "pg-pool": {
 | 
			
		||||
      "version": "3.4.1",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.4.1.tgz",
 | 
			
		||||
      "integrity": "sha512-TVHxR/gf3MeJRvchgNHxsYsTCHQ+4wm3VIHSS19z8NC0+gioEhq1okDY1sm/TYbfoP6JLFx01s0ShvZ3puP/iQ==",
 | 
			
		||||
      "requires": {}
 | 
			
		||||
    },
 | 
			
		||||
    "pg-protocol": {
 | 
			
		||||
      "version": "1.5.0",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.5.0.tgz",
 | 
			
		||||
      "integrity": "sha512-muRttij7H8TqRNu/DxrAJQITO4Ac7RmX3Klyr/9mJEOBeIpgnF8f9jAfRz5d3XwQZl5qBjF9gLsUtMPJE0vezQ=="
 | 
			
		||||
    },
 | 
			
		||||
    "pg-types": {
 | 
			
		||||
      "version": "2.2.0",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz",
 | 
			
		||||
      "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==",
 | 
			
		||||
      "requires": {
 | 
			
		||||
        "pg-int8": "1.0.1",
 | 
			
		||||
        "postgres-array": "~2.0.0",
 | 
			
		||||
        "postgres-bytea": "~1.0.0",
 | 
			
		||||
        "postgres-date": "~1.0.4",
 | 
			
		||||
        "postgres-interval": "^1.1.0"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "pgpass": {
 | 
			
		||||
      "version": "1.0.4",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.4.tgz",
 | 
			
		||||
      "integrity": "sha512-YmuA56alyBq7M59vxVBfPJrGSozru8QAdoNlWuW3cz8l+UX3cWge0vTvjKhsSHSJpo3Bom8/Mm6hf0TR5GY0+w==",
 | 
			
		||||
      "requires": {
 | 
			
		||||
        "split2": "^3.1.1"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "postgres-array": {
 | 
			
		||||
      "version": "2.0.0",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz",
 | 
			
		||||
      "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA=="
 | 
			
		||||
    },
 | 
			
		||||
    "postgres-bytea": {
 | 
			
		||||
      "version": "1.0.0",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz",
 | 
			
		||||
      "integrity": "sha1-AntTPAqokOJtFy1Hz5zOzFIazTU="
 | 
			
		||||
    },
 | 
			
		||||
    "postgres-date": {
 | 
			
		||||
      "version": "1.0.7",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz",
 | 
			
		||||
      "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q=="
 | 
			
		||||
    },
 | 
			
		||||
    "postgres-interval": {
 | 
			
		||||
      "version": "1.2.0",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz",
 | 
			
		||||
      "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==",
 | 
			
		||||
      "requires": {
 | 
			
		||||
        "xtend": "^4.0.0"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "process-nextick-args": {
 | 
			
		||||
      "version": "2.0.0",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz",
 | 
			
		||||
| 
						 | 
				
			
			@ -2550,6 +2862,26 @@
 | 
			
		|||
        "amdefine": ">=0.0.4"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "split2": {
 | 
			
		||||
      "version": "3.2.2",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz",
 | 
			
		||||
      "integrity": "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==",
 | 
			
		||||
      "requires": {
 | 
			
		||||
        "readable-stream": "^3.0.0"
 | 
			
		||||
      },
 | 
			
		||||
      "dependencies": {
 | 
			
		||||
        "readable-stream": {
 | 
			
		||||
          "version": "3.6.0",
 | 
			
		||||
          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
 | 
			
		||||
          "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
 | 
			
		||||
          "requires": {
 | 
			
		||||
            "inherits": "^2.0.3",
 | 
			
		||||
            "string_decoder": "^1.1.1",
 | 
			
		||||
            "util-deprecate": "^1.0.1"
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "statuses": {
 | 
			
		||||
      "version": "1.4.0",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz",
 | 
			
		||||
| 
						 | 
				
			
			@ -2559,7 +2891,6 @@
 | 
			
		|||
      "version": "1.1.1",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
 | 
			
		||||
      "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
 | 
			
		||||
      "dev": true,
 | 
			
		||||
      "requires": {
 | 
			
		||||
        "safe-buffer": "~5.1.0"
 | 
			
		||||
      }
 | 
			
		||||
| 
						 | 
				
			
			@ -2662,8 +2993,7 @@
 | 
			
		|||
    "util-deprecate": {
 | 
			
		||||
      "version": "1.0.2",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
 | 
			
		||||
      "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
 | 
			
		||||
      "dev": true
 | 
			
		||||
      "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
 | 
			
		||||
    },
 | 
			
		||||
    "utils-merge": {
 | 
			
		||||
      "version": "1.0.1",
 | 
			
		||||
| 
						 | 
				
			
			@ -2705,6 +3035,11 @@
 | 
			
		|||
      "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
 | 
			
		||||
      "dev": true
 | 
			
		||||
    },
 | 
			
		||||
    "xtend": {
 | 
			
		||||
      "version": "4.0.2",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
 | 
			
		||||
      "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ=="
 | 
			
		||||
    },
 | 
			
		||||
    "yargs": {
 | 
			
		||||
      "version": "3.10.0",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz",
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,13 +7,17 @@
 | 
			
		|||
    "test": "mocha"
 | 
			
		||||
  },
 | 
			
		||||
  "dependencies": {
 | 
			
		||||
    "async": "^3.2.2",
 | 
			
		||||
    "cookie-parser": "~1.4.3",
 | 
			
		||||
    "debug": "~2.6.9",
 | 
			
		||||
    "dotenv": "^10.0.0",
 | 
			
		||||
    "express": "~4.16.0",
 | 
			
		||||
    "http-errors": "~1.6.2",
 | 
			
		||||
    "moment": "^2.29.1",
 | 
			
		||||
    "morgan": "~1.9.0",
 | 
			
		||||
    "nodemailer": "^6.6.5",
 | 
			
		||||
    "passport": "^0.5.0",
 | 
			
		||||
    "pg": "^8.7.1",
 | 
			
		||||
    "pug": "2.0.0-beta11"
 | 
			
		||||
  },
 | 
			
		||||
  "devDependencies": {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										29
									
								
								public/scripts/data.js
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								public/scripts/data.js
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,29 @@
 | 
			
		|||
export async function getSports() {
 | 
			
		||||
    const response = await fetch('/data/sports');
 | 
			
		||||
    const sportsList = await response.json();
 | 
			
		||||
    return sportsList;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export async function getSeasons() {
 | 
			
		||||
    const response = await fetch('/data/seasons');
 | 
			
		||||
    const seasonsList = await response.json();
 | 
			
		||||
    return seasonsList;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export async function getGenders(sportID) {
 | 
			
		||||
    const response = await fetch(`/data/genders?sport=${+sportID}`);
 | 
			
		||||
    const gendersList = await response.json();
 | 
			
		||||
    return gendersList;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export async function getDivisions(sportID, gender) {
 | 
			
		||||
    const response = await fetch(`/data/divisions?sport=${+sportID}&gender=${gender}`);
 | 
			
		||||
    const divisionsList = await response.json();
 | 
			
		||||
    return divisionsList;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export async function getTeams(sportID) {
 | 
			
		||||
    const response = await fetch(`/data/teams?sport=${+sportID}`);
 | 
			
		||||
    const teamsList = await response.json();
 | 
			
		||||
    return teamsList;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										113
									
								
								public/scripts/submit.js
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										113
									
								
								public/scripts/submit.js
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,113 @@
 | 
			
		|||
import * as Data from "./data.js";
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
const sportDropdown = document.getElementById('sport-dropdown');
 | 
			
		||||
const seasonDropdown = document.getElementById('year-dropdown');
 | 
			
		||||
const genderDropdown = document.getElementById('gender-dropdown');
 | 
			
		||||
const divisionDropdown = document.getElementById('division-dropdown');
 | 
			
		||||
const team1Dropdown = document.getElementById('team1-dropdown');
 | 
			
		||||
const team2Dropdown = document.getElementById('team2-dropdown');
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
async function listSeasons() {
 | 
			
		||||
    seasonDropdown.innerHTML = "";
 | 
			
		||||
    
 | 
			
		||||
    const seasonsList = await Data.getSeasons();
 | 
			
		||||
 | 
			
		||||
    seasonsList.forEach(season => {
 | 
			
		||||
        const option = document.createElement('option');
 | 
			
		||||
        option.text = season.year - 1 + "-" + season.year;
 | 
			
		||||
        option.value = season.id;
 | 
			
		||||
        seasonDropdown.appendChild(option);
 | 
			
		||||
    });
 | 
			
		||||
}
 | 
			
		||||
listSeasons();
 | 
			
		||||
 | 
			
		||||
async function listSports() {
 | 
			
		||||
    sportDropdown.innerHTML = "";
 | 
			
		||||
 | 
			
		||||
    const sportsList = await Data.getSports();
 | 
			
		||||
    
 | 
			
		||||
    sportsList.forEach(sport => {
 | 
			
		||||
        const option = document.createElement('option');
 | 
			
		||||
        option.text = sport.name;
 | 
			
		||||
        option.value = sport.id;
 | 
			
		||||
        sportDropdown.appendChild(option);
 | 
			
		||||
    });
 | 
			
		||||
    
 | 
			
		||||
    listGenders();
 | 
			
		||||
    listTeams();
 | 
			
		||||
}
 | 
			
		||||
listSports();
 | 
			
		||||
 | 
			
		||||
async function listGenders() {
 | 
			
		||||
    genderDropdown.innerHTML = "";
 | 
			
		||||
 | 
			
		||||
    const selectedSportID = sportDropdown.value;
 | 
			
		||||
    const gendersList = await Data.getGenders(selectedSportID);
 | 
			
		||||
 | 
			
		||||
    if(selectedSportID) {
 | 
			
		||||
        gendersList.forEach(gender => {
 | 
			
		||||
            const option = document.createElement('option');
 | 
			
		||||
            option.text = (gender.name == "female") ? "Female" : (gender.name == "male") ? "Male" : "";
 | 
			
		||||
            option.value = gender.name;
 | 
			
		||||
            genderDropdown.appendChild(option);
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    listDivisions();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
async function listDivisions() {
 | 
			
		||||
    divisionDropdown.innerHTML = "";
 | 
			
		||||
 | 
			
		||||
    const selectedSportID = sportDropdown.value;
 | 
			
		||||
    const selectedGender = genderDropdown.value;
 | 
			
		||||
 | 
			
		||||
    if(selectedGender) {
 | 
			
		||||
        const divisionsList = await Data.getDivisions(selectedSportID, selectedGender);
 | 
			
		||||
 | 
			
		||||
        divisionsList.forEach(division => {
 | 
			
		||||
            const option = document.createElement('option');
 | 
			
		||||
            option.text = division.name;
 | 
			
		||||
            option.value = division.id;
 | 
			
		||||
            divisionDropdown.appendChild(option);
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
async function listTeams() {
 | 
			
		||||
    team1Dropdown.innerHTML = "";
 | 
			
		||||
    team2Dropdown.innerHTML = "";
 | 
			
		||||
 | 
			
		||||
    const selectedSportID = sportDropdown.value;
 | 
			
		||||
 | 
			
		||||
    if(selectedSportID) {
 | 
			
		||||
        const teamsList = await Data.getTeams(selectedSportID);
 | 
			
		||||
 | 
			
		||||
        teamsList.forEach(team => {
 | 
			
		||||
            const optionT1 = document.createElement('option');
 | 
			
		||||
            optionT1.text = team.name;
 | 
			
		||||
            optionT1.value = team.id;
 | 
			
		||||
            team1Dropdown.appendChild(optionT1);
 | 
			
		||||
 | 
			
		||||
            const optionT2 = document.createElement('option');
 | 
			
		||||
            optionT2.text = team.name;
 | 
			
		||||
            optionT2.value = team.id;
 | 
			
		||||
            team2Dropdown.appendChild(optionT2);
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
sportDropdown.onchange = (() => { 
 | 
			
		||||
    listGenders();
 | 
			
		||||
    listTeams();
 | 
			
		||||
});
 | 
			
		||||
genderDropdown.onchange = listDivisions;
 | 
			
		||||
| 
						 | 
				
			
			@ -16,7 +16,7 @@ span {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#sport-dropdown {
 | 
			
		||||
.main-dropdown {
 | 
			
		||||
    width: 100%;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										37
									
								
								routes/data.js
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								routes/data.js
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,37 @@
 | 
			
		|||
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');
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
router.get('/sports', function(req, res, next) {
 | 
			
		||||
    sports.retrieveAll()
 | 
			
		||||
        .then(data => res.json(data));
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
router.get('/seasons', function(req, res, next) {
 | 
			
		||||
    seasons.retrieveAll()
 | 
			
		||||
        .then(data => res.json(data));
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
router.get('/genders', function(req, res, next) {
 | 
			
		||||
    genders.retrieveBySport(req.query.sport)
 | 
			
		||||
        .then(data => res.json(data));
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
router.get('/divisions', function(req, res, next) {
 | 
			
		||||
    const gender = req.body.gender == 'female' ? genders.FEMALE : genders.MALE;
 | 
			
		||||
 | 
			
		||||
    divisions.retrieveBySportAndGender(req.query.sport, gender)
 | 
			
		||||
        .then(data => res.json(data));
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
router.get('/teams', function(req, res, next) {
 | 
			
		||||
    teams.retrieveBySport(req.query.sport)
 | 
			
		||||
        .then(data => res.json(data));
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
module.exports = router;
 | 
			
		||||
| 
						 | 
				
			
			@ -1,5 +1,6 @@
 | 
			
		|||
var express = require('express');
 | 
			
		||||
var router = express.Router();
 | 
			
		||||
var database = require('../database/database');
 | 
			
		||||
 | 
			
		||||
/* GET home page. */
 | 
			
		||||
router.get('/', function(req, res, next) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,38 +1,28 @@
 | 
			
		|||
var express = require('express');
 | 
			
		||||
var mail = require('../mail/mail');
 | 
			
		||||
var router = express.Router();
 | 
			
		||||
var genders = require('../database/scores/genders');
 | 
			
		||||
var games = require('../database/scores/games');
 | 
			
		||||
var moment = require('moment');
 | 
			
		||||
 | 
			
		||||
/* GET submit page. */
 | 
			
		||||
router.get('/', function(req, res, next) {
 | 
			
		||||
  res.send('Nothing to send');
 | 
			
		||||
  res.render('submit', { title: 'Submit Score', date: moment().format('YYYY-MM-DD') });
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
/* POST submit page. */
 | 
			
		||||
router.post('/', function(req, res, next) {
 | 
			
		||||
  let sport = req.body.sport;
 | 
			
		||||
  let gender = req.body.gender;
 | 
			
		||||
  let division = req.body.division;
 | 
			
		||||
  let home = req.body['home-team'];
 | 
			
		||||
  let homeScore = req.body['home-team-score'];
 | 
			
		||||
  let visiting = req.body['visiting-team'];
 | 
			
		||||
  let visitingScore = req.body['visiting-team-score'];
 | 
			
		||||
  let submitter = req.body['submitter'];
 | 
			
		||||
  let recipient = req.body['email'];
 | 
			
		||||
  const seasonID = req.body['year'];
 | 
			
		||||
  const sportID = req.body['sport'];
 | 
			
		||||
  const gender = (req.body['gender'] == "female") ? genders.FEMALE : genders.MALE;
 | 
			
		||||
  const divisionID = req.body['division'];
 | 
			
		||||
  const date = moment(req.body['date']);
 | 
			
		||||
  const team1ID = req.body['team1'];
 | 
			
		||||
  const team1Score = req.body['team1-score'];
 | 
			
		||||
  const team2ID = req.body['team2'];
 | 
			
		||||
  const team2Score = req.body['team2-score'];
 | 
			
		||||
 | 
			
		||||
  let message = prepMailBody(sport, gender, division, home, homeScore, visiting, visitingScore, submitter);
 | 
			
		||||
 | 
			
		||||
  mail.send(recipient, "Score Report", message);
 | 
			
		||||
 | 
			
		||||
  res.send('Score sent');
 | 
			
		||||
  games.add(divisionID, seasonID, date, team1ID, team2ID, team1Score, team2Score)
 | 
			
		||||
    .then(res.send("SUCCESS"));
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
var prepMailBody = function(sport, gender, division, home, homeScore, visiting, visitingScore, submitter) {
 | 
			
		||||
  return(
 | 
			
		||||
    "Score report from <b>" + submitter + "</b><br><br>" +
 | 
			
		||||
    "<b>Sport:</b><br>" + sport + " - " + gender + " - " + division + "<br><br>" +
 | 
			
		||||
    "<b>Home team:</b><br>" + home + " - " + homeScore + "<br><br>" +
 | 
			
		||||
    "<b>Visiting team:</b><br>" + visiting + " - " + visitingScore + "<br><br>");
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
module.exports = router;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,40 +0,0 @@
 | 
			
		|||
extends layout
 | 
			
		||||
 | 
			
		||||
block stylesheets
 | 
			
		||||
  link(rel='stylesheet', href='/stylesheets/submit.css')
 | 
			
		||||
 | 
			
		||||
block content
 | 
			
		||||
  h1 Submit Score
 | 
			
		||||
  form(action='/submit', method='POST')
 | 
			
		||||
    span(class='form-section')
 | 
			
		||||
      label Sport
 | 
			
		||||
      span(class='form-section-input')
 | 
			
		||||
        select#sport-dropdown(name="sport") 
 | 
			
		||||
          option(value="Football" selected) Football
 | 
			
		||||
        select#gender-dropdown(name="gender")
 | 
			
		||||
          option(value="Male" selected) Male 
 | 
			
		||||
          option(value="Female") Female
 | 
			
		||||
        select#division-dropdown(name="division")
 | 
			
		||||
          option(value="Varsity") Varsity 
 | 
			
		||||
          option(value="JV-A") JV-A 
 | 
			
		||||
          option(value="JV-B") JV-B
 | 
			
		||||
    span(class='form-section')
 | 
			
		||||
      label Home Team
 | 
			
		||||
      span(class='form-section-input')
 | 
			
		||||
        input(type="text", name="home-team")
 | 
			
		||||
        input(class="score-input", type="number", name="home-team-score", value="0")
 | 
			
		||||
    span(class='form-section')
 | 
			
		||||
      label Visiting Team
 | 
			
		||||
      span(class='form-section-input')
 | 
			
		||||
        input(type="text", name="visiting-team")
 | 
			
		||||
        input(class="score-input", type="number", name="visiting-team-score", value="0")
 | 
			
		||||
    span(class='form-section')
 | 
			
		||||
      label Submitter
 | 
			
		||||
      span(class='form-section-input')
 | 
			
		||||
        input(type="text", name="submitter")
 | 
			
		||||
    span(class='form-section')
 | 
			
		||||
      label Send info to
 | 
			
		||||
      span(class='form-section-input')
 | 
			
		||||
        input(type="email", name="email", placeholder="email@example.com")
 | 
			
		||||
    span(class='form-section')
 | 
			
		||||
      button(type="submit") Submit
 | 
			
		||||
| 
						 | 
				
			
			@ -7,3 +7,4 @@ html
 | 
			
		|||
    block stylesheets
 | 
			
		||||
  body
 | 
			
		||||
    block content
 | 
			
		||||
    block scripts
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,37 @@
 | 
			
		|||
extends layout
 | 
			
		||||
 | 
			
		||||
block stylesheets
 | 
			
		||||
  link(rel='stylesheet', href='/stylesheets/submit.css')
 | 
			
		||||
 | 
			
		||||
block content
 | 
			
		||||
  h1 Submit Score
 | 
			
		||||
  form(action='/submit', method='POST')
 | 
			
		||||
    span(class='form-section')
 | 
			
		||||
      label Year
 | 
			
		||||
      span(class='form-section-input')
 | 
			
		||||
        select#year-dropdown(name="year" class="main-dropdown")
 | 
			
		||||
    span(class='form-section')
 | 
			
		||||
      label Sport
 | 
			
		||||
      span(class='form-section-input')
 | 
			
		||||
        select#sport-dropdown(name="sport" class="main-dropdown") 
 | 
			
		||||
        select#gender-dropdown(name="gender")
 | 
			
		||||
        select#division-dropdown(name="division")
 | 
			
		||||
    span(class='form-section')
 | 
			
		||||
      label Date of match
 | 
			
		||||
      span(class='form-section-input')
 | 
			
		||||
        input(type="date", name="date", value=date)
 | 
			
		||||
    span(class='form-section')
 | 
			
		||||
      label Your team
 | 
			
		||||
      span(class='form-section-input')
 | 
			
		||||
        select#team1-dropdown(name="team1" class="main-dropdown")
 | 
			
		||||
        input(class="score-input", type="number", name="team1-score", value="0")
 | 
			
		||||
    span(class='form-section')
 | 
			
		||||
      label Opponent
 | 
			
		||||
      span(class='form-section-input')
 | 
			
		||||
        select#team2-dropdown(name="team2" class="main-dropdown")
 | 
			
		||||
        input(class="score-input", type="number", name="team2-score", value="0")
 | 
			
		||||
    span(class='form-section')
 | 
			
		||||
      button(type="submit") Submit
 | 
			
		||||
 | 
			
		||||
block scripts 
 | 
			
		||||
  script(src='/scripts/submit.js' type="module")
 | 
			
		||||
		Reference in a new issue