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 @@
- | Team A |
- Team B |
+
+
+ |
+
+
+ |
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 = ``;
+ }
+
+ _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;
+}