From 3953adedd385bcc4cc08b3ba8942e25146c5752c Mon Sep 17 00:00:00 2001 From: "exe.dev user" Date: Sat, 4 Apr 2026 03:47:57 +0000 Subject: [PATCH] Allowed renaming of teams in Finska score card --- site/finska/index.html | 14 ++++- site/finska/scripts/controllers.js | 95 +++++++++++++++++++++++++++++- site/finska/style.css | 65 +++++++++++++++++++- 3 files changed, 170 insertions(+), 4 deletions(-) diff --git a/site/finska/index.html b/site/finska/index.html index c9e5918..b68d16b 100644 --- a/site/finska/index.html +++ b/site/finska/index.html @@ -20,8 +20,18 @@ - - + + diff --git a/site/finska/scripts/controllers.js b/site/finska/scripts/controllers.js index 03fd023..acb321f 100644 --- a/site/finska/scripts/controllers.js +++ b/site/finska/scripts/controllers.js @@ -4,7 +4,7 @@ import { Scorecard, getStoreDAO } from "./models.js"; const storeDao = getStoreDAO(); export class FinskaScorecardController extends Controller { - static targets = ["score1Input", "score2Input", "scoreTable"]; + static targets = ["score1Input", "score2Input", "scoreTable", "team1Header", "team2Header"]; static values = { maxScore: Number, overflowScoreTo: Number @@ -18,8 +18,95 @@ export class FinskaScorecardController extends Controller { this._undoStack = []; this._scorecard = storeDao.loadOrCreate(rules); + this._loadTeamNames(); this.updateTable(); } + + _loadTeamNames() { + const stored1 = localStorage.getItem('finska-team1-name'); + const stored2 = localStorage.getItem('finska-team2-name'); + this._team1Name = stored1 || 'Team A'; + this._team2Name = stored2 || 'Team B'; + this._renderTeamHeader(this.team1HeaderTarget, this._team1Name, 'editTeam1'); + this._renderTeamHeader(this.team2HeaderTarget, this._team2Name, 'editTeam2'); + } + + _renderTeamHeader(td, name, editAction) { + td.innerHTML = ` + ${this._escapeHtml(name)} + + `; + } + + _renderEditHeader(td, currentName, teamNum) { + td.innerHTML = ` + + + + `; + td.querySelector('input').focus(); + td.querySelector('input').select(); + } + + editTeam1() { + this._renderEditHeader(this.team1HeaderTarget, this._team1Name, '1'); + } + + editTeam2() { + this._renderEditHeader(this.team2HeaderTarget, this._team2Name, '2'); + } + + confirmTeam1() { + const input = this.team1HeaderTarget.querySelector('input'); + const newName = input.value.trim() || 'Team A'; + this._team1Name = newName; + localStorage.setItem('finska-team1-name', newName); + this._renderTeamHeader(this.team1HeaderTarget, this._team1Name, 'editTeam1'); + } + + confirmTeam2() { + const input = this.team2HeaderTarget.querySelector('input'); + const newName = input.value.trim() || 'Team B'; + this._team2Name = newName; + localStorage.setItem('finska-team2-name', newName); + this._renderTeamHeader(this.team2HeaderTarget, this._team2Name, 'editTeam2'); + } + + cancelTeam1() { + this._renderTeamHeader(this.team1HeaderTarget, this._team1Name, 'editTeam1'); + } + + cancelTeam2() { + this._renderTeamHeader(this.team2HeaderTarget, this._team2Name, 'editTeam2'); + } + + editKeyDown1(e) { + this._editKeyDown(e, this.confirmTeam1.bind(this), this.cancelTeam1.bind(this)); + } + + editKeyDown2(e) { + this._editKeyDown(e, this.confirmTeam2.bind(this), this.cancelTeam2.bind(this)); + } + + _editKeyDown(e, confirmFn, cancelFn) { + if (e.key === 'Enter') { + e.preventDefault(); + confirmFn(); + } else if (e.key === 'Escape') { + e.preventDefault(); + cancelFn(); + } + } + + _escapeHtml(str) { + const div = document.createElement('div'); + div.textContent = str; + return div.innerHTML; + } + + _escapeAttr(str) { + return str.replace(/&/g, '&').replace(/"/g, '"').replace(//g, '>'); + } updateTable() { let tableBody = this.scoreTableTarget; @@ -155,6 +242,12 @@ export class FinskaScorecardController extends Controller { this._scorecard.reset(); storeDao.clear(); this._undoStack = []; + this._team1Name = 'Team A'; + this._team2Name = 'Team B'; + localStorage.removeItem('finska-team1-name'); + localStorage.removeItem('finska-team2-name'); + this._renderTeamHeader(this.team1HeaderTarget, this._team1Name, 'editTeam1'); + this._renderTeamHeader(this.team2HeaderTarget, this._team2Name, 'editTeam2'); this.updateTable(); } } diff --git a/site/finska/style.css b/site/finska/style.css index e2cd398..9bf0432 100644 --- a/site/finska/style.css +++ b/site/finska/style.css @@ -18,4 +18,67 @@ tfoot input { color: #394D00; background-color: #DEFC85; font-weight: bold; -} \ No newline at end of file +} + +.team-header { + display: flex; + align-items: center; + justify-content: center; + gap: 0.25rem; +} + +.team-header .team-name { + font-weight: bold; +} + +.team-header .edit-btn { + background: none; + border: none; + cursor: pointer; + padding: 0.1rem 0.3rem; + font-size: 0.9rem; + margin: 0; + width: auto; + line-height: 1; + opacity: 0.5; +} + +.team-header .edit-btn:hover { + opacity: 1; +} + +.team-header-edit { + display: flex; + align-items: center; + justify-content: center; + gap: 0.25rem; +} + +.team-header-edit input { + border-width: 1px; + margin: 0; + padding: 0.2rem 0.4rem; + font-size: 0.9rem; + width: 6rem; + text-align: center; +} + +.team-header-edit .confirm-btn, +.team-header-edit .cancel-btn { + background: none; + border: none; + cursor: pointer; + padding: 0.1rem 0.3rem; + font-size: 1rem; + margin: 0; + width: auto; + line-height: 1; +} + +.team-header-edit .confirm-btn { + color: #2e7d32; +} + +.team-header-edit .cancel-btn { + color: #c62828; +}
Team ATeam B + + Team A + + + + + Team B + + +