diff options
| -rw-r--r-- | .gitignore | 143 | ||||
| -rw-r--r-- | court.mjs | 53 | ||||
| -rw-r--r-- | favicon.ico | bin | 13054 -> 0 bytes | |||
| -rw-r--r-- | game.mjs | 185 | ||||
| -rw-r--r-- | guest.mjs | 69 | ||||
| -rw-r--r-- | icon.png | bin | 1453 -> 0 bytes | |||
| -rw-r--r-- | icon.svg | 54 | ||||
| -rw-r--r-- | index.css | 12 | ||||
| -rw-r--r-- | index.js | 15 | ||||
| -rw-r--r-- | main.html | 102 | ||||
| -rw-r--r-- | player.mjs | 150 | ||||
| -rw-r--r-- | timer.js | 88 | ||||
| -rw-r--r-- | utils.mjs | 51 |
13 files changed, 141 insertions, 781 deletions
@@ -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 Binary files differdeleted file mode 100644 index 6cb5040..0000000 --- a/favicon.ico +++ /dev/null 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 Binary files differdeleted file mode 100644 index 655915f..0000000 --- a/icon.png +++ /dev/null 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; -} |
