aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore143
-rw-r--r--court.mjs53
-rw-r--r--favicon.icobin13054 -> 0 bytes
-rw-r--r--game.mjs185
-rw-r--r--guest.mjs69
-rw-r--r--icon.pngbin1453 -> 0 bytes
-rw-r--r--icon.svg54
-rw-r--r--index.css12
-rw-r--r--index.js15
-rw-r--r--main.html102
-rw-r--r--player.mjs150
-rw-r--r--timer.js88
-rw-r--r--utils.mjs51
13 files changed, 141 insertions, 781 deletions
diff --git a/.gitignore b/.gitignore
index e8f5eb9..bb4dc45 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,144 @@
# Data files
*.csv
-# Output files
-public \ No newline at end of file
+# Logs
+logs
+*.log
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+lerna-debug.log*
+
+# Diagnostic reports (https://nodejs.org/api/report.html)
+report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
+
+# Runtime data
+pids
+*.pid
+*.seed
+*.pid.lock
+
+# Directory for instrumented libs generated by jscoverage/JSCover
+lib-cov
+
+# Coverage directory used by tools like istanbul
+coverage
+*.lcov
+
+# nyc test coverage
+.nyc_output
+
+# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
+.grunt
+
+# Bower dependency directory (https://bower.io/)
+bower_components
+
+# node-waf configuration
+.lock-wscript
+
+# Compiled binary addons (https://nodejs.org/api/addons.html)
+build/Release
+
+# Dependency directories
+node_modules/
+jspm_packages/
+
+# Snowpack dependency directory (https://snowpack.dev/)
+web_modules/
+
+# TypeScript cache
+*.tsbuildinfo
+
+# Optional npm cache directory
+.npm
+
+# Optional eslint cache
+.eslintcache
+
+# Optional stylelint cache
+.stylelintcache
+
+# Optional REPL history
+.node_repl_history
+
+# Output of 'npm pack'
+*.tgz
+
+# Yarn Integrity file
+.yarn-integrity
+
+# dotenv environment variable files
+.env
+.env.*
+!.env.example
+
+# parcel-bundler cache (https://parceljs.org/)
+.cache
+.parcel-cache
+
+# Next.js build output
+.next
+out
+
+# Nuxt.js build / generate output
+.nuxt
+dist
+.output
+
+# Gatsby files
+.cache/
+# Comment in the public line in if your project uses Gatsby and not Next.js
+# https://nextjs.org/blog/next-9-1#public-directory-support
+# public
+
+# vuepress build output
+.vuepress/dist
+
+# vuepress v2.x temp and cache directory
+.temp
+.cache
+
+# Sveltekit cache directory
+.svelte-kit/
+
+# vitepress build output
+**/.vitepress/dist
+
+# vitepress cache directory
+**/.vitepress/cache
+
+# Docusaurus cache and generated files
+.docusaurus
+
+# Serverless directories
+.serverless/
+
+# FuseBox cache
+.fusebox/
+
+# DynamoDB Local files
+.dynamodb/
+
+# Firebase cache directory
+.firebase/
+
+# TernJS port file
+.tern-port
+
+# Stores VSCode versions used for testing VSCode extensions
+.vscode-test
+
+# yarn v3
+.pnp.*
+.yarn/*
+!.yarn/patches
+!.yarn/plugins
+!.yarn/releases
+!.yarn/sdks
+!.yarn/versions
+
+# Vite files
+vite.config.js.timestamp-*
+vite.config.ts.timestamp-*
+.vite/ \ No newline at end of file
diff --git a/court.mjs b/court.mjs
deleted file mode 100644
index 713c488..0000000
--- a/court.mjs
+++ /dev/null
@@ -1,53 +0,0 @@
-import { Manager } from "./utils.mjs";
-
-class Court {
- constructor(id, status) {
- this.id = id;
- this.status = typeof status !== "undefined" ? status : true;
- this.name = "Court " + (id + 1);
- }
- toggle() {
- this.status = !this.status;
- this.print();
- }
- print() {
- let status = this.status ? "active" : "inactive";
- console.log(this.name + " is currently " + status);
- }
- render() {
- let color = this.status ? "is-success" : "is-danger";
- let type = `class="button is-medium ${color}"`;
- return `<button id=${"court_" + this.id} ${type}>${this.name}</button>`;
- }
-}
-
-export class CourtManager extends Manager {
- maxCourtCount = 12;
-
- constructor() {
- super("court", []);
- console.log("Loading court data.");
- let data = JSON.parse(localStorage.getItem(this.description));
- if (data === null || data.length != this.maxCourtCount) {
- console.log("Court data unavailable: " + data);
- this.generate();
- return;
- }
- for (let i = 0; i < this.maxCourtCount; i++) {
- this.listData.push(new Court(data[i].id, data[i].status));
- }
- console.log("Loaded " + this.listData.length + " courts.");
- this.render();
- this.addBehaviour();
- }
- generate() {
- console.log("Generating court data.");
- for (let i = 0; i < this.maxCourtCount; i++) {
- this.listData.push(new Court(i));
- }
- console.log("Generated data for " + this.listData.length + " courts");
- this.store();
- this.render();
- this.addBehaviour();
- }
-}
diff --git a/favicon.ico b/favicon.ico
deleted file mode 100644
index 6cb5040..0000000
--- a/favicon.ico
+++ /dev/null
Binary files differ
diff --git a/game.mjs b/game.mjs
deleted file mode 100644
index c67041f..0000000
--- a/game.mjs
+++ /dev/null
@@ -1,185 +0,0 @@
-import { Manager } from "./utils.mjs";
-import { CourtManager } from "./court.mjs";
-import { PlayerManager } from "./player.mjs";
-
-class Team {
- constructor(playerOne, playerTwo) {
- this.playerOne = playerOne;
- this.playerTwo = playerTwo;
- }
- print() {
- console.log(this.playerOne + " and " + this.playerTwo);
- }
- render() {
- let p1 = `<td style="width: 23%; text-align: right;">${this.playerOne}</td>`;
- let p2 = `<td style="width: 23%; text-align: right;">${this.playerTwo}</td>`;
- return p1 + p2;
- }
-}
-
-class Game {
- constructor(id, teamOne, teamTwo, status) {
- this.id = id;
- this.teamOne = teamOne;
- this.teamTwo = teamTwo;
- this.status = typeof status !== "undefined" ? status : false;
- }
- print() {
- let teamOne = this.teamOne.playerOne + " and " + this.teamOne.playerTwo;
- let teamTwo = this.teamTwo.playerOne + " and " + this.teamTwo.playerTwo;
- console.log(teamOne + " is playing against " + teamTwo);
- }
- render() {
- let blockedState = this.teamOne.playerOne === "RESERVED";
- let type = blockedState ? `class="is-danger is-dark"` : ``;
- return `<tr ${type}><td style="width: 8%; text-align: center;">${
- this.id + 1
- }</td>${this.teamOne.render()}${this.teamTwo.render()}</tr>`;
- }
-}
-
-function generateDummyGames(courts, description) {
- let team = new Team(description, description);
- let games = [];
- for (const court of courts) {
- let game = new Game(court.id, team, team);
- games.push(game);
- }
- return games;
-}
-
-export class GameManager extends Manager {
- courts = new CourtManager();
- players = new PlayerManager();
-
- constructor() {
- super("game", []);
- this.round = Number(localStorage.getItem("round")) || 0;
- console.log("Loading game data.");
- let data = JSON.parse(localStorage.getItem(this.description));
- if (data === null || data.length === 0) {
- console.log("Game data unavailable: " + data);
- this.generate();
- return;
- }
- for (let i = 0; i < data.length; i++) {
- let id = Number(data[i].id);
- let teamOne = new Team(
- data[i].teamOne.playerOne,
- data[i].teamOne.playerTwo
- );
- let teamTwo = new Team(
- data[i].teamTwo.playerOne,
- data[i].teamTwo.playerTwo
- );
- let status = Boolean(data[i].status);
- this.listData.push(new Game(id, teamOne, teamTwo, status));
- }
- console.log("Loaded " + this.listData.length + " games.");
- this.render();
- }
- isConfirmed() {
- return this.listData[0].status;
- }
- generate() {
- console.log("Generating the dummy round.");
- this.listData = generateDummyGames(this.courts.listData, "---");
- console.log("Loaded " + this.listData.length + " dummy round.");
- for (let i = 0; i < this.listData.length; i++) {
- this.listData[i].status = true;
- }
- console.log(this.listData);
- this.store();
- this.render();
- }
- addBehaviour() {
- let description = this.isConfirmed() ? "Round " + this.round : "Proposal";
- document.getElementById("game_description").innerHTML = description;
- }
- getBlockedGames() {
- const inactiveCourts = this.courts.inactive();
- console.log("Total reserved courts are " + inactiveCourts.length + ".");
- return generateDummyGames(inactiveCourts, "RESERVED");
- }
- inactive(courts) {
- return generateDummyGames(courts, "---");
- }
- active(courts, players) {
- let games = [];
- for (let index = 0; index < courts.length; index++) {
- const startIndex = 4 * index;
- const endIndex = startIndex + 4;
- const courtPlayers = players.slice(startIndex, endIndex);
- const team_1 = new Team(courtPlayers[0].name, courtPlayers[3].name);
- const team_2 = new Team(courtPlayers[1].name, courtPlayers[2].name);
- const game = new Game(courts[index].id, team_1, team_2);
- game.print();
- games.push(game);
- }
- return games;
- }
- propose() {
- console.log("Proposing new games!");
- let possibleMatches = getMatchCount(
- this.players.listData,
- this.courts.listData
- );
- console.log("Total possible matches are " + possibleMatches + ".");
- this.listData = this.getBlockedGames();
- const activeCourts = this.courts.active();
- const unusedCourts = activeCourts.slice(possibleMatches + 1);
- this.listData = this.listData.concat(this.inactive(unusedCourts));
- const usedCourts = activeCourts.slice(0, possibleMatches);
- let requiredPlayerCount = possibleMatches * 4;
- const selectedPlayers = this.players.propose(requiredPlayerCount);
- console.log("The matches are:");
- this.listData = this.listData.concat(
- this.active(usedCourts, selectedPlayers)
- );
- this.listData.sort((a, b) => a.id - b.id);
- this.render();
- }
- confirm() {
- if (this.isConfirmed()) {
- const notification = new Notyf();
- notification.error("Create a proposal first!");
- return;
- }
- console.log("Confirm the proposal for round " + this.round + ".");
- this.round += 1;
- localStorage.setItem("round", this.round);
- for (let i = 0; i < this.listData.length; i++) {
- this.listData[i].status = true;
- }
- // Need to update the number of games played here
- this.store();
- this.render();
- document.getElementById("timer-start").click();
- const notification = new Notyf();
- notification.success("Round confirmed!");
- }
- reset() {
- localStorage.removeItem("round");
- localStorage.removeItem(this.description);
- localStorage.removeItem(this.courts.description);
- document.getElementById("timer-stop").click();
- window.location.reload();
- const notification = new Notyf();
- notification.error("Session has been reset!");
- }
-}
-
-function getMatchCount(players, courts) {
- courts = courts.filter(function (c) {
- return c.status;
- });
- console.log("There are a total of " + courts.length + " courts available.");
- console.log(players);
- players = players.filter(function (p) {
- return p.status;
- });
- console.log("There are a total of " + players.length + " players available.");
- var possibleMatches = Math.floor(players.length / 4);
- possibleMatches = Math.min(possibleMatches, courts.length);
- return possibleMatches;
-}
diff --git a/guest.mjs b/guest.mjs
deleted file mode 100644
index ba9e8cc..0000000
--- a/guest.mjs
+++ /dev/null
@@ -1,69 +0,0 @@
-import { Manager } from "./utils.mjs";
-
-export class Guest {
- constructor(id, name, level, status, totalPlayed) {
- this.id = id;
- this.status = typeof status !== "undefined" ? status : false;
- this.name = name;
- this.level = typeof level !== "undefined" ? level : 1;
- this.totalPlayed = typeof totalPlayed !== "undefined" ? status : 0;
- }
- toggle() {
- this.status = !this.status;
- this.print();
- }
- print() {
- let status = this.status ? "active" : "inactive";
- console.log(this.name + " is currently " + status);
- }
- render() {
- let color = this.status ? "is-success" : "is-danger";
- let type = `class="button is-medium ${color}"`;
- return `<button id=${"regular_" + this.id} ${type}>${this.name}</button>`;
- }
-}
-
-export class GuestManager extends Manager {
- constructor() {
- super("guest", []);
- console.log("Loading guest data.");
- let data = JSON.parse(localStorage.getItem(this.description));
- if (data === null || data.length === 0) {
- console.log("Guest data unavailable: " + data);
- this.generate();
- return;
- }
- for (let i = 0; i < data.length; i++) {
- let id = Number(data[i].id);
- let name = data[i].name;
- let level = data[i].level;
- let status = data[i].status;
- let totalPlayed = data[i].totalPlayed;
- this.listData.push(new Player(id, name, level, status, totalPlayed));
- }
- console.log("Loaded " + this.listData.length + " players.");
- this.render();
- }
- generate() {
- console.log("Generating guest data.");
- let maxPlayerCount = 12;
- for (let i = 0; i < maxPlayerCount; i++) {
- let level = i < 3 ? 1 : ( i < 6 ? 3 : 7);
- let p = new Player(i, "Player " + i, level, false, 0);
- this.listData.push(p);
- }
- console.log("Generated data for " + this.listData.length + " guest");
- this.store();
- this.render();
- }
- active(factor) {
- factor = typeof factor !== "undefined" ? factor : 1;
- let data = super.active();
- console.log("Normalize skill by a factor of " + factor + ".");
- let players = data.map(function (p) {
- p.skill = Math.ceil(p.skill / factor);
- return p;
- });
- return players;
- }
-} \ No newline at end of file
diff --git a/icon.png b/icon.png
deleted file mode 100644
index 655915f..0000000
--- a/icon.png
+++ /dev/null
Binary files differ
diff --git a/icon.svg b/icon.svg
deleted file mode 100644
index 278a070..0000000
--- a/icon.svg
+++ /dev/null
@@ -1,54 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="187" height="50" viewBox="0 0 187 50">
-<defs>
-<g>
-<g id="glyph-0-0">
-<path d="M 5.171875 -16.53125 C 5.03125 -16.90625 5 -16.921875 4.484375 -16.921875 L 1.3125 -16.921875 L 1.3125 -16.28125 C 3.015625 -16.28125 3.296875 -16.28125 3.296875 -15.171875 L 3.296875 -2.421875 C 3.296875 -1.8125 3.296875 -0.640625 1.3125 -0.640625 L 1.3125 0 C 1.890625 -0.046875 2.921875 -0.046875 3.546875 -0.046875 C 4.15625 -0.046875 5.203125 -0.046875 5.78125 0 L 5.78125 -0.640625 C 3.796875 -0.640625 3.796875 -1.8125 3.796875 -2.421875 L 3.796875 -16.1875 L 3.8125 -16.1875 L 9.640625 -0.390625 C 9.734375 -0.15625 9.78125 0 9.984375 0 C 10.1875 0 10.234375 -0.15625 10.328125 -0.390625 L 16.203125 -16.3125 L 16.234375 -16.3125 L 16.234375 -1.765625 C 16.234375 -0.640625 15.953125 -0.640625 14.25 -0.640625 L 14.25 0 C 14.921875 -0.046875 16.25 -0.046875 16.96875 -0.046875 C 17.6875 -0.046875 19.0625 -0.046875 19.71875 0 L 19.71875 -0.640625 C 18.015625 -0.640625 17.75 -0.640625 17.75 -1.765625 L 17.75 -15.171875 C 17.75 -16.28125 18.015625 -16.28125 19.71875 -16.28125 L 19.71875 -16.921875 L 16.578125 -16.921875 C 16.0625 -16.921875 16.03125 -16.90625 15.890625 -16.53125 L 10.53125 -2 Z M 5.171875 -16.53125 "/>
-</g>
-<g id="glyph-0-1">
-<path d="M 9 -17.125 C 8.875 -17.453125 8.828125 -17.515625 8.578125 -17.515625 C 8.328125 -17.515625 8.28125 -17.453125 8.15625 -17.125 L 2.90625 -2.25 C 2.421875 -0.921875 1.4375 -0.640625 0.5625 -0.640625 L 0.5625 0 C 1.015625 -0.046875 2 -0.046875 2.484375 -0.046875 C 3.09375 -0.046875 4.09375 -0.046875 4.6875 0 L 4.6875 -0.640625 C 3.515625 -0.6875 3.34375 -1.484375 3.34375 -1.78125 C 3.34375 -2 3.390625 -2.125 3.4375 -2.28125 L 4.765625 -5.96875 L 11.25 -5.96875 L 12.734375 -1.765625 C 12.859375 -1.46875 12.859375 -1.40625 12.859375 -1.3125 C 12.859375 -0.640625 11.796875 -0.640625 11.328125 -0.640625 L 11.328125 0 C 12.046875 -0.046875 13.328125 -0.046875 14.09375 -0.046875 C 14.75 -0.046875 15.984375 -0.046875 16.578125 0 L 16.578125 -0.640625 C 15.265625 -0.640625 14.8125 -0.640625 14.5 -1.5625 Z M 8 -15.140625 L 11.03125 -6.609375 L 4.984375 -6.609375 Z M 8 -15.140625 "/>
-</g>
-<g id="glyph-0-2">
-<path d="M 15.40625 -16.84375 L 1.109375 -16.84375 L 0.6875 -11.375 L 1.140625 -11.375 C 1.46875 -15.484375 1.8125 -16.203125 5.625 -16.203125 C 6.078125 -16.203125 6.796875 -16.203125 6.984375 -16.1875 C 7.453125 -16.109375 7.453125 -15.8125 7.453125 -15.234375 L 7.453125 -1.8125 C 7.453125 -0.921875 7.390625 -0.640625 5.328125 -0.640625 L 4.640625 -0.640625 L 4.640625 0 C 5.828125 -0.03125 7.0625 -0.046875 8.28125 -0.046875 C 9.484375 -0.046875 10.734375 -0.03125 11.921875 0 L 11.921875 -0.640625 L 11.21875 -0.640625 C 9.171875 -0.640625 9.09375 -0.921875 9.09375 -1.8125 L 9.09375 -15.234375 C 9.09375 -15.78125 9.09375 -16.078125 9.546875 -16.1875 C 9.734375 -16.203125 10.453125 -16.203125 10.90625 -16.203125 C 14.6875 -16.203125 15.0625 -15.484375 15.390625 -11.375 L 15.828125 -11.375 Z M 15.40625 -16.84375 "/>
-</g>
-<g id="glyph-0-3">
-<path d="M 15.390625 -16.828125 C 15.390625 -17.265625 15.359375 -17.296875 15.21875 -17.296875 C 15.109375 -17.296875 15.09375 -17.265625 14.921875 -16.96875 L 13.828125 -14.890625 C 12.609375 -16.4375 11.125 -17.328125 9.21875 -17.328125 C 4.984375 -17.328125 1.140625 -13.578125 1.140625 -8.46875 C 1.140625 -3.328125 4.984375 0.390625 9.25 0.390625 C 13.03125 0.390625 15.390625 -2.953125 15.390625 -5.796875 C 15.390625 -6.046875 15.390625 -6.140625 15.171875 -6.140625 C 14.96875 -6.140625 14.96875 -6.078125 14.9375 -5.84375 C 14.75 -2.375 12.265625 -0.25 9.59375 -0.25 C 7.0625 -0.25 3.015625 -2.03125 3.015625 -8.46875 C 3.015625 -14.9375 7.140625 -16.671875 9.546875 -16.671875 C 12.34375 -16.671875 14.375 -14.25 14.84375 -10.796875 C 14.890625 -10.5 14.890625 -10.453125 15.109375 -10.453125 C 15.390625 -10.453125 15.390625 -10.5 15.390625 -10.953125 Z M 15.390625 -16.828125 "/>
-</g>
-<g id="glyph-0-4">
-<path d="M 13.90625 -15.171875 C 13.90625 -16.28125 14.171875 -16.28125 15.890625 -16.28125 L 15.890625 -16.921875 C 15.171875 -16.875 13.859375 -16.875 13.078125 -16.875 C 12.3125 -16.875 11 -16.875 10.28125 -16.921875 L 10.28125 -16.28125 C 12 -16.28125 12.265625 -16.28125 12.265625 -15.171875 L 12.265625 -9.125 L 4.875 -9.125 L 4.875 -15.171875 C 4.875 -16.28125 5.15625 -16.28125 6.859375 -16.28125 L 6.859375 -16.921875 C 6.140625 -16.875 4.828125 -16.875 4.0625 -16.875 C 3.296875 -16.875 1.984375 -16.875 1.265625 -16.921875 L 1.265625 -16.28125 C 2.96875 -16.28125 3.25 -16.28125 3.25 -15.171875 L 3.25 -1.765625 C 3.25 -0.640625 2.96875 -0.640625 1.265625 -0.640625 L 1.265625 0 C 1.984375 -0.046875 3.296875 -0.046875 4.0625 -0.046875 C 4.828125 -0.046875 6.140625 -0.046875 6.859375 0 L 6.859375 -0.640625 C 5.15625 -0.640625 4.875 -0.640625 4.875 -1.765625 L 4.875 -8.46875 L 12.265625 -8.46875 L 12.265625 -1.765625 C 12.265625 -0.640625 12 -0.640625 10.28125 -0.640625 L 10.28125 0 C 11 -0.046875 12.3125 -0.046875 13.078125 -0.046875 C 13.859375 -0.046875 15.171875 -0.046875 15.890625 0 L 15.890625 -0.640625 C 14.171875 -0.640625 13.90625 -0.640625 13.90625 -1.765625 Z M 13.90625 -15.171875 "/>
-</g>
-<g id="glyph-0-5">
-<path d="M 13.375 -5.671875 C 13.375 -2.359375 11.21875 -0.25 8.875 -0.25 C 7.609375 -0.25 6.46875 -0.921875 5.78125 -1.953125 C 4.984375 -3.140625 4.875 -4.6875 4.875 -5.546875 L 4.875 -15.171875 C 4.875 -16.28125 5.15625 -16.28125 6.859375 -16.28125 L 6.859375 -16.921875 C 6.140625 -16.875 4.828125 -16.875 4.0625 -16.875 C 3.296875 -16.875 1.984375 -16.875 1.265625 -16.921875 L 1.265625 -16.28125 C 2.96875 -16.28125 3.25 -16.28125 3.25 -15.171875 L 3.25 -5.671875 C 3.25 -2.109375 5.953125 0.390625 8.828125 0.390625 C 12.046875 0.390625 13.90625 -2.90625 13.90625 -5.328125 L 13.90625 -14.75 C 13.90625 -16.125 15.171875 -16.28125 15.890625 -16.28125 L 15.890625 -16.921875 C 15.3125 -16.875 14.28125 -16.875 13.65625 -16.875 C 13.03125 -16.875 11.96875 -16.875 11.40625 -16.921875 L 11.40625 -16.28125 C 13.375 -16.28125 13.375 -15.109375 13.375 -14.5 Z M 13.375 -5.671875 "/>
-</g>
-<g id="glyph-0-6">
-<path d="M 4.90625 -7.953125 L 8.875 -7.953125 C 12.0625 -7.953125 14.390625 -10.03125 14.390625 -12.390625 C 14.390625 -14.75 12.125 -16.921875 8.875 -16.921875 L 1.28125 -16.921875 L 1.28125 -16.28125 C 3 -16.28125 3.265625 -16.28125 3.265625 -15.171875 L 3.265625 -1.765625 C 3.265625 -0.640625 3 -0.640625 1.28125 -0.640625 L 1.28125 0 C 2 -0.046875 3.328125 -0.046875 4.09375 -0.046875 C 4.859375 -0.046875 6.171875 -0.046875 6.890625 0 L 6.890625 -0.640625 C 5.171875 -0.640625 4.90625 -0.640625 4.90625 -1.765625 Z M 4.859375 -8.46875 L 4.859375 -15.3125 C 4.859375 -16.15625 4.90625 -16.28125 5.890625 -16.28125 L 8.40625 -16.28125 C 11.59375 -16.28125 12.515625 -14.453125 12.515625 -12.390625 C 12.515625 -10.140625 11.421875 -8.46875 8.40625 -8.46875 Z M 4.859375 -8.46875 "/>
-</g>
-</g>
-<clipPath id="clip-0">
-<path clip-rule="nonzero" d="M 59 16.535156 L 185 16.535156 L 185 33.46875 L 59 33.46875 Z M 59 16.535156 "/>
-</clipPath>
-</defs>
-<path fill-rule="evenodd" fill="rgb(100%, 100%, 100%)" fill-opacity="1" stroke-width="0.4" stroke-linecap="butt" stroke-linejoin="round" stroke="rgb(0%, 0%, 0%)" stroke-opacity="1" stroke-miterlimit="10" d="M 36 832 C 33 820 31.5 814 32 808 C 32.5 802 35 796 40 784 C 40 784 41.5 790 42.75 795 C 44 800 45 804 44.25 809 C 43.5 814 41 820 36 832 Z M 36 832 " transform="matrix(1, 0, 0, -1, -22, 833)"/>
-<path fill-rule="evenodd" fill="rgb(100%, 100%, 100%)" fill-opacity="1" stroke-width="0.4" stroke-linecap="butt" stroke-linejoin="round" stroke="rgb(0%, 0%, 0%)" stroke-opacity="1" stroke-miterlimit="10" d="M 36 832 C 29 820 25.5 814 24 808 C 22.5 802 23 796 24 784 C 24 784 27.5 790 30.417969 795 C 33.332031 800 35.667969 804 36.582031 809 C 37.5 814 37 820 36 832 Z M 36 832 " transform="matrix(1, 0, 0, -1, -22, 833)"/>
-<path fill-rule="evenodd" fill="rgb(100%, 100%, 100%)" fill-opacity="1" stroke-width="0.4" stroke-linecap="butt" stroke-linejoin="round" stroke="rgb(0%, 0%, 0%)" stroke-opacity="1" stroke-miterlimit="10" d="M 36 832 C 30 820 27 814 26 808 C 25 802 26 796 28 784 C 28 784 31 790 33.5 795 C 36 800 38 804 38.5 809 C 39 814 38 820 36 832 Z M 36 832 " transform="matrix(1, 0, 0, -1, -22, 833)"/>
-<path fill-rule="evenodd" fill="rgb(100%, 100%, 100%)" fill-opacity="1" stroke-width="0.4" stroke-linecap="butt" stroke-linejoin="round" stroke="rgb(0%, 0%, 0%)" stroke-opacity="1" stroke-miterlimit="10" d="M 36 832 C 32 820 30 814 30 808 C 30 802 32 796 36 784 C 36 784 38 790 39.667969 795 C 41.332031 800 42.667969 804 42.332031 809 C 42 814 40 820 36 832 Z M 36 832 " transform="matrix(1, 0, 0, -1, -22, 833)"/>
-<path fill-rule="evenodd" fill="rgb(100%, 100%, 100%)" fill-opacity="1" stroke-width="0.4" stroke-linecap="butt" stroke-linejoin="round" stroke="rgb(0%, 0%, 0%)" stroke-opacity="1" stroke-miterlimit="10" d="M 36 832 C 31 820 28.5 814 28 808 C 27.5 802 29 796 32 784 C 32 784 34.5 790 36.582031 795 C 38.667969 800 40.332031 804 40.417969 809 C 40.5 814 39 820 36 832 Z M 36 832 " transform="matrix(1, 0, 0, -1, -22, 833)"/>
-<path fill-rule="evenodd" fill="rgb(100%, 100%, 100%)" fill-opacity="1" stroke-width="0.4" stroke-linecap="butt" stroke-linejoin="round" stroke="rgb(0%, 0%, 0%)" stroke-opacity="1" stroke-miterlimit="10" d="M 31.667969 828 C 32.109375 833.332031 40.109375 833.332031 39.667969 828 L 39.332031 824 L 31.332031 824 Z M 31.667969 828 " transform="matrix(1, 0, 0, -1, -22, 833)"/>
-<path fill-rule="evenodd" fill="rgb(100%, 100%, 100%)" fill-opacity="1" stroke-width="0.4" stroke-linecap="butt" stroke-linejoin="round" stroke="rgb(0%, 0%, 0%)" stroke-opacity="1" stroke-miterlimit="10" d="M 48 832 C 43 820 40.5 814 40 808 C 39.5 802 41 796 44 784 C 44 784 46.5 790 48.582031 795 C 50.667969 800 52.332031 804 52.417969 809 C 52.5 814 51 820 48 832 Z M 48 832 " transform="matrix(1, 0, 0, -1, -22, 833)"/>
-<path fill-rule="evenodd" fill="rgb(100%, 100%, 100%)" fill-opacity="1" stroke-width="0.4" stroke-linecap="butt" stroke-linejoin="round" stroke="rgb(0%, 0%, 0%)" stroke-opacity="1" stroke-miterlimit="10" d="M 48 832 C 47 820 46.5 814 48 808 C 49.5 802 53 796 60 784 C 60 784 60.5 790 60.917969 795 C 61.332031 800 61.667969 804 60.082031 809 C 58.5 814 55 820 48 832 Z M 48 832 " transform="matrix(1, 0, 0, -1, -22, 833)"/>
-<path fill-rule="evenodd" fill="rgb(100%, 100%, 100%)" fill-opacity="1" stroke-width="0.4" stroke-linecap="butt" stroke-linejoin="round" stroke="rgb(0%, 0%, 0%)" stroke-opacity="1" stroke-miterlimit="10" d="M 48 832 C 44 820 42 814 42 808 C 42 802 44 796 48 784 C 48 784 50 790 51.667969 795 C 53.332031 800 54.667969 804 54.332031 809 C 54 814 52 820 48 832 Z M 48 832 " transform="matrix(1, 0, 0, -1, -22, 833)"/>
-<path fill-rule="evenodd" fill="rgb(100%, 100%, 100%)" fill-opacity="1" stroke-width="0.4" stroke-linecap="butt" stroke-linejoin="round" stroke="rgb(0%, 0%, 0%)" stroke-opacity="1" stroke-miterlimit="10" d="M 48 832 C 46 820 45 814 46 808 C 47 802 50 796 56 784 C 56 784 57 790 57.832031 795 C 58.667969 800 59.332031 804 58.167969 809 C 57 814 54 820 48 832 Z M 48 832 " transform="matrix(1, 0, 0, -1, -22, 833)"/>
-<path fill-rule="evenodd" fill="rgb(100%, 100%, 100%)" fill-opacity="1" stroke-width="0.4" stroke-linecap="butt" stroke-linejoin="round" stroke="rgb(0%, 0%, 0%)" stroke-opacity="1" stroke-miterlimit="10" d="M 48 832 C 45 820 43.5 814 44 808 C 44.5 802 47 796 52 784 C 52 784 53.5 790 54.75 795 C 56 800 57 804 56.25 809 C 55.5 814 53 820 48 832 Z M 48 832 " transform="matrix(1, 0, 0, -1, -22, 833)"/>
-<path fill-rule="evenodd" fill="rgb(100%, 100%, 100%)" fill-opacity="1" stroke-width="0.4" stroke-linecap="butt" stroke-linejoin="round" stroke="rgb(0%, 0%, 0%)" stroke-opacity="1" stroke-miterlimit="10" d="M 44.332031 828 C 43.890625 833.332031 51.890625 833.332031 52.332031 828 L 52.667969 824 L 44.667969 824 Z M 44.332031 828 " transform="matrix(1, 0, 0, -1, -22, 833)"/>
-<g clip-path="url(#clip-0)">
-<g fill="rgb(0%, 0%, 0%)" fill-opacity="1">
-<use xlink:href="#glyph-0-0" x="58.5835" y="33.467"/>
-<use xlink:href="#glyph-0-1" x="79.652535" y="33.467"/>
-<use xlink:href="#glyph-0-2" x="94.896602" y="33.467"/>
-<use xlink:href="#glyph-0-3" x="111.429597" y="33.467"/>
-<use xlink:href="#glyph-0-4" x="127.962593" y="33.467"/>
-<use xlink:href="#glyph-0-5" x="152.625757" y="33.467"/>
-<use xlink:href="#glyph-0-6" x="169.803218" y="33.467"/>
-</g>
-</g>
-</svg>
diff --git a/index.css b/index.css
deleted file mode 100644
index 8e3b713..0000000
--- a/index.css
+++ /dev/null
@@ -1,12 +0,0 @@
-.button-grid {
- display: grid;
- grid-template-columns: repeat(4, 1fr);
- grid-gap: 15px;
-}
-#timer-display {
- text-align: center;
- width: fit-content;
-}
-table {
- font-size: 1.5em;
-} \ No newline at end of file
diff --git a/index.js b/index.js
deleted file mode 100644
index 9494abb..0000000
--- a/index.js
+++ /dev/null
@@ -1,15 +0,0 @@
-import { GameManager } from "./game.mjs";
-
-// Court and player handling
-let g = new GameManager();
-
-// Game handling
-document.getElementById("propose").addEventListener("click", () => {
- g.propose();
-});
-document.getElementById("confirm").addEventListener("click", () => {
- g.confirm();
-});
-document.getElementById("reset").addEventListener("click", () => {
- g.reset();
-});
diff --git a/main.html b/main.html
deleted file mode 100644
index b3f2f0a..0000000
--- a/main.html
+++ /dev/null
@@ -1,102 +0,0 @@
-<!DOCTYPE html>
-<html lang="en" data-theme="light">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <title>Match Up!</title>
- <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/notyf@3/notyf.min.css">
- <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.7.2/css/all.min.css">
- <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@1.0.4/css/bulma.min.css">
- <link rel="stylesheet" href="index.css">
- </head>
- <body>
- <section class="section">
- <nav class="navbar" role="navigation" aria-label="main navigation">
- <div class="navbar-brand">
- <div class="navbar-item">
- <img src="icon.png">
- </div>
- <div class="navbar-item">
- Match Up
- </div>
- </div>
- <div class="navbar-end">
- <div class="field is-grouped is-grouped-right">
- <button class="button is-medium is-dark" id="timer-dec">-</button>
- <input class="input is-medium is-dark" id="timer-display" type="text" readonly></input>
- <button class="button is-medium is-dark" id="timer-inc">+</button>
- <button class="button is-medium is-dark" id="timer-start">Start</button>
- <button class="button is-medium is-dark" id="timer-stop">Stop</button>
- </div>
- </div>
- </nav>
- <div class="container">
- <section class="section">
- <table class="table is-fullwidth">
- <thead>
- <tr><th colspan="5"><div id="game_description"></div></th></tr>
- <tr>
- <th>Court</th>
- <th colspan='2' style="text-align: center;">Team 1</th>
- <th colspan='2' style="text-align: center;">Team 2</th>
- </tr>
- </thead>
- <tbody id="game_list"></tbody>
- </table>
- </section>
- <section class="section">
- <div class="field is-grouped is-grouped-centered">
- <button class="button is-medium is-dark" id="propose">Propose</button>
- <div class="select is-medium is-dark">
- <select name="skill" id="skill">
- <option value="10">All Levels</option>
- <option value="5">2 Levels</option>
- <option value="3">3 Levels</option>
- <option value="1">Skill Based</option>
- </select>
- </div>
- <button class="button is-medium is-dark" id="confirm">Confirm</button>
- <button class="button is-medium is-danger" id="reset">Reset</button>
- </div>
- </section>
- <section class="section">
- <h1 class="title">Courts</h1>
- <div id="court_list" class="button-grid"></div>
- </section>
- <section class="section">
- <h1 class="title">Regulars</h1>
- <div id="regular_list" class="button-grid"></div>
- </section>
- <section class="section">
- <h1 class="title">Guests</h1>
- <div id="guest_list" class="button-grid"></div>
- </section>
- <section class="section">
- <h1 class="title">Player Update</h1>
- <div id="player-load" class="file is-danger has-name is-boxed">
- <label class="file-label">
- <input class="file-input" type="file" name="players" accept=".csv"/>
- <span class="file-cta">
- <span class="file-icon">
- <i class="fas fa-cloud-upload-alt"></i>
- </span>
- <span class="file-label"> Update players... </span>
- </span>
- <span class="file-name"> No file selected... </span>
- </label>
- </div>
- </section>
- </div>
- </section>
- <script src="index.js" type="module"></script>
- <script src="timer.js"></script>
- <script src="https://cdn.jsdelivr.net/npm/notyf@3/notyf.min.js"></script>
- </body>
- <footer class="footer">
- <div class="content has-text-centered">
- <p>
- <strong>Match Up</strong> made with ❤️ by <a href="https://karanj.com">Karan</a>. The source code is licensed <a href="https://creativecommons.org/licenses/by-sa/4.0/deed.en">CC BY-SA 4.0</a>. Logo from <a href="https://www.flaticon.com/free-icons/shuttle-cock" title="shuttle cock icons">Flaticon</a>.
- </p>
- </div>
- </footer>
-</html> \ No newline at end of file
diff --git a/player.mjs b/player.mjs
deleted file mode 100644
index 594bb7b..0000000
--- a/player.mjs
+++ /dev/null
@@ -1,150 +0,0 @@
-import { GuestManager } from "./guest.mjs";
-import { shuffle, Manager } from "./utils.mjs";
-
-class Player {
- constructor(id, name, level, status, totalPlayed) {
- this.id = id;
- this.status = typeof status !== "undefined" ? status : false;
- this.name = name;
- this.level = typeof level !== "undefined" ? level : 1;
- this.totalPlayed = typeof totalPlayed !== "undefined" ? status : 0;
- }
- toggle() {
- this.status = !this.status;
- this.print();
- }
- print() {
- let status = this.status ? "active" : "inactive";
- console.log(this.name + " is currently " + status);
- }
- render() {
- let color = this.status ? "is-success" : "is-danger";
- let type = `class="button is-medium ${color}"`;
- return `<button id=${"regular_" + this.id} ${type}>${this.name}</button>`;
- }
-}
-
-function randomLevel() {
- const max_level = 10;
- return Math.floor(Math.random() * max_level + 1);
-}
-
-function randomStatus() {
- return Math.random() < 0.5;
-}
-
-function parseLineToPlayer(data) {
- var info = data.split(",");
- var id = Number(info[0].trim());
- var name = info[1].trim() + " " + info[2].trim();
- var level = Number(info[3].trim());
- return new Player(id, name, level, true, 0);
-}
-
-export class PlayerManager extends Manager {
- g = new GuestManager();
-
- constructor() {
- super("regular", []);
- console.log("Loading player data.");
- let data = JSON.parse(localStorage.getItem(this.description));
- if (data === null || data.length === 0) {
- console.log("Player data unavailable: " + data);
- this.generate();
- return;
- }
- for (let i = 0; i < data.length; i++) {
- let id = Number(data[i].id);
- let name = data[i].name;
- let level = data[i].level;
- let status = data[i].status;
- let totalPlayed = data[i].totalPlayed;
- this.listData.push(new Player(id, name, level, status, totalPlayed));
- }
- console.log("Loaded " + this.listData.length + " players.");
- this.render();
- this.addBehaviour();
- addLoadBehaviour(this);
- }
- generate() {
- console.log("Generating player data.");
- let maxPlayerCount = 71;
- for (let i = 0; i < maxPlayerCount; i++) {
- let p = new Player(i, "Player " + i, randomLevel(), randomStatus(), 0);
- this.listData.push(p);
- }
- console.log("Generated data for " + this.listData.length + " players");
- this.store();
- this.render();
- }
- import(data) {
- var lines = data.split("\n");
- var players = [];
- for (var i = 1; i < lines.length; i++) {
- if (lines[i] == undefined || lines[i].trim() == "") {
- continue;
- }
- players.push(parseLineToPlayer(lines[i]));
- }
- console.log("Loaded " + players.length + " Players");
- for (var i = 0; i < players.length; i++) {
- players[i].print();
- }
- this.listData = players;
- this.store();
- this.render();
- }
- active(factor) {
- factor = typeof factor !== "undefined" ? factor : 1;
- let data = super.active();
- console.log("Normalize skill by a factor of " + factor + ".");
- let players = data.map(function (p) {
- p.skill = Math.ceil(p.skill / factor);
- return p;
- });
- return players;
- }
- propose(count) {
- console.log("Required players are " + count);
- let factor = Number(document.getElementById("skill").value);
- console.log("Skill normalized by a factor of " + factor + ".");
- const activePlayers = this.active(factor);
- console.log("Active players are:");
- console.log(
- activePlayers
- .map((i) => {
- return i.name;
- })
- .join(",")
- );
- const shuffledPlayers = shuffle(activePlayers);
- shuffledPlayers.sort((a, b) => a.totalPlayed - b.totalPlayed);
- const selectedPlayers = shuffledPlayers.slice(0, count);
- selectedPlayers.sort((a, b) => a.level - b.level);
- console.log("Selected players are:");
- console.log(
- selectedPlayers
- .map((i) => {
- return i.name;
- })
- .join(",")
- );
- return selectedPlayers;
- }
-}
-
-// TODO Add load behaviour to constructor
-export function addLoadBehaviour(p) {
- const f = document.querySelector("#player-load input[type=file]");
- f.addEventListener("change", () => {
- const file = f.files[0];
- let importData;
- console.log("Loading data from " + file.name);
- const reader = new FileReader();
- reader.onload = function (e) {
- importData = reader.result;
- p.import(importData);
- };
- reader.readAsText(file);
- });
-}
diff --git a/timer.js b/timer.js
deleted file mode 100644
index 09189c0..0000000
--- a/timer.js
+++ /dev/null
@@ -1,88 +0,0 @@
-let minsPerRound = Number(sessionStorage.getItem("minsPerRound")) || 12;
-let timerRunningFlag = Number(sessionStorage.getItem("timerRunningFlag")) || 0;
-let deadline =
- Number(sessionStorage.getItem("deadline")) || new Date().getTime();
-let clock = 0;
-
-function setTimer(m, s) {
- let timer = document.getElementById("timer-display");
- m = m < 10 ? "0" + m : m;
- s = s < 10 ? "0" + s : s;
- timer.value = `${m}:${s}`;
-}
-
-function setSessionData() {
- sessionStorage.setItem("deadline", deadline);
- sessionStorage.setItem("minsPerRound", minsPerRound);
- sessionStorage.setItem("timerRunningFlag", timerRunningFlag);
-}
-
-function resetTimer() {
- clearInterval(clock);
- let mins = Math.floor(minsPerRound);
- let secs = (minsPerRound - mins) * 60;
- setTimer(mins, secs);
- timerRunningFlag = 0;
- setSessionData();
-}
-
-function updateTimer(milliseconds) {
- const m = Math.floor((milliseconds % (1000 * 60 * 60)) / (1000 * 60));
- const s = Math.floor((milliseconds % (1000 * 60)) / 1000);
- setTimer(m, s);
-}
-
-function refreshTimer() {
- const now = new Date().getTime();
- const millisecondsToDeadline = deadline - now;
- if (millisecondsToDeadline > 0) {
- updateTimer(millisecondsToDeadline);
- return;
- }
- resetTimer();
- const notification = new Notyf({
- duration: 0,
- position: { x: "center", y: "top" },
- dismissible: true,
- });
- notification.error("Round completed");
-}
-
-function startTimer(fresh) {
- if (fresh) {
- let now = new Date().getTime();
- const millisecondsToDeadline = minsPerRound * 60 * 1000;
- deadline = now + millisecondsToDeadline;
- }
- timerRunningFlag = 1;
- setSessionData();
- clock = setInterval(refreshTimer, 1000);
-}
-
-window.onload = function () {
- if (timerRunningFlag) startTimer(0);
- else resetTimer();
-
- document.getElementById("timer-start").addEventListener("click", () => {
- if (timerRunningFlag != 0) return;
- startTimer(1);
- });
-
- document.getElementById("timer-stop").addEventListener("click", () => {
- resetTimer();
- });
-
- document.getElementById("timer-inc").addEventListener("click", () => {
- if (timerRunningFlag == 0) {
- minsPerRound += 0.5;
- resetTimer();
- }
- });
-
- document.getElementById("timer-dec").addEventListener("click", () => {
- if (timerRunningFlag == 0 && minsPerRound != 0) {
- minsPerRound -= 0.5;
- resetTimer();
- }
- });
-};
diff --git a/utils.mjs b/utils.mjs
deleted file mode 100644
index 06a2519..0000000
--- a/utils.mjs
+++ /dev/null
@@ -1,51 +0,0 @@
-export class Manager {
- constructor(description, listData) {
- this.description = description;
- this.listData = listData;
- this.count = listData.length;
- }
- store() {
- let stringData = JSON.stringify(this.listData);
- localStorage.setItem(this.description, stringData);
- }
- render() {
- let renderedHTML = this.listData
- .map((i) => {
- return i.render();
- })
- .join("");
- let elementId = this.description + "_list";
- document.getElementById(elementId).innerHTML = renderedHTML;
- this.addBehaviour();
- }
- addBehaviour() {
- for (let idx = 0; idx < this.listData.length; ++idx) {
- const elementId = this.description + "_" + this.listData[idx].id;
- const p = document.getElementById(elementId);
- p.addEventListener("click", () => {
- this.listData[idx].toggle();
- this.store();
- p.classList.toggle("is-success");
- p.classList.toggle("is-danger");
- });
- }
- }
- active() {
- return this.listData.filter(function (c) {
- return c.status;
- });
- }
- inactive() {
- return this.listData.filter(function (c) {
- return !c.status;
- });
- }
-}
-
-export function shuffle(array) {
- for (let i = array.length - 1; i > 0; i--) {
- const j = Math.floor(Math.random() * (i + 1));
- [array[i], array[j]] = [array[j], array[i]];
- }
- return array;
-}