From 665360d3ef9c741d34cd2d55a58041f5478a5d6b Mon Sep 17 00:00:00 2001 From: Pandipipas <62224708+Pandipipas@users.noreply.github.com> Date: Fri, 13 Feb 2026 00:38:07 +0100 Subject: [PATCH 01/10] Add underlined preview selectors between images and score --- .../example/components/ScoreboardPanel.vue | 306 ++++++++++++++++++ 1 file changed, 306 insertions(+) diff --git a/src/dashboard/example/components/ScoreboardPanel.vue b/src/dashboard/example/components/ScoreboardPanel.vue index ebf0e56..cc4cba1 100644 --- a/src/dashboard/example/components/ScoreboardPanel.vue +++ b/src/dashboard/example/components/ScoreboardPanel.vue @@ -52,6 +52,9 @@ const rightCharacterImage = computed(() => { return match?.image ?? ''; }); +const leftPanelImage = computed(() => leftCharacterImage.value); +const rightPanelImage = computed(() => rightCharacterImage.value); + const normalizeName = (value: string) => value.trim().toLowerCase(); @@ -386,6 +389,14 @@ const onRightSelect = (playerId: string) => { applyRightPlayerData(playerId); }; +const adjustLeftScore = (delta: number) => { + scoreboardStore.leftScore = Math.max(0, scoreboardStore.leftScore + delta); +}; + +const adjustRightScore = (delta: number) => { + scoreboardStore.rightScore = Math.max(0, scoreboardStore.rightScore + delta); +}; + const createPlayerId = (name: string) => { const base = name .trim() @@ -630,6 +641,162 @@ watch( + +
+
+ +
+ Left image +
+
+
+ + + +
+
+ +
+
+ + {{ scoreboardStore.scoreboard.leftScore }} + +
+ + - + +
+ + {{ scoreboardStore.scoreboard.rightScore }} + +
+
+ +
+
+ +
+ Right image +
+
+
+ + + +
+
+
+
Date: Fri, 13 Feb 2026 00:46:47 +0100 Subject: [PATCH 02/10] Reposition preview fields and restore edit/save behavior --- .../example/components/ScoreboardPanel.vue | 321 ++++++++++++------ 1 file changed, 212 insertions(+), 109 deletions(-) diff --git a/src/dashboard/example/components/ScoreboardPanel.vue b/src/dashboard/example/components/ScoreboardPanel.vue index cc4cba1..5e1ae49 100644 --- a/src/dashboard/example/components/ScoreboardPanel.vue +++ b/src/dashboard/example/components/ScoreboardPanel.vue @@ -647,55 +647,102 @@ watch( class="scoreboard-preview" >
-
- -
- Left image +
+
+ +
+ Left image +
+
+
+ + + + + + + + +
-
-
- - -
@@ -744,55 +791,102 @@ watch(
-
- -
- Right image +
+
+ + + + + + + + + +
+
+ +
+ Right image +
-
-
- - -
@@ -1123,14 +1217,22 @@ watch( .scoreboard-preview__side { display: flex; - flex-direction: column; - gap: 8px; - align-items: flex-start; + align-items: center; +} + +.scoreboard-preview__side-inner { + width: 100%; + display: flex; + align-items: center; + gap: 10px; } .scoreboard-preview__side--right { text-align: right; - align-items: flex-end; +} + +.scoreboard-preview__side--right .scoreboard-preview__side-inner { + justify-content: flex-end; } .scoreboard-preview__image-wrap { @@ -1161,15 +1263,8 @@ watch( font-weight: 600; } -.scoreboard-preview__name { - font-size: 1.1rem; - font-weight: 700; - line-height: 1.2; -} - - .scoreboard-preview__controls { - width: min(100%, 320px); + width: min(100%, 260px); display: flex; flex-direction: column; gap: 6px; @@ -1268,9 +1363,17 @@ watch( width: min(100%, 280px); } + .scoreboard-preview__side-inner { + flex-direction: column; + align-items: flex-start; + } + .scoreboard-preview__side--right { text-align: left; - align-items: flex-start; + } + + .scoreboard-preview__side--right .scoreboard-preview__side-inner { + justify-content: flex-start; } } From 0d40b8ed6a7e59c979b5acc2e606a6f8a844bb5b Mon Sep 17 00:00:00 2001 From: Pandipipas <62224708+Pandipipas@users.noreply.github.com> Date: Fri, 13 Feb 2026 00:54:44 +0100 Subject: [PATCH 03/10] Center preview metadata between image and score --- src/dashboard/example/components/ScoreboardPanel.vue | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/dashboard/example/components/ScoreboardPanel.vue b/src/dashboard/example/components/ScoreboardPanel.vue index 5e1ae49..02c81a8 100644 --- a/src/dashboard/example/components/ScoreboardPanel.vue +++ b/src/dashboard/example/components/ScoreboardPanel.vue @@ -1222,9 +1222,10 @@ watch( .scoreboard-preview__side-inner { width: 100%; - display: flex; + display: grid; + grid-template-columns: auto minmax(0, 1fr); align-items: center; - gap: 10px; + gap: 12px; } .scoreboard-preview__side--right { @@ -1232,7 +1233,7 @@ watch( } .scoreboard-preview__side--right .scoreboard-preview__side-inner { - justify-content: flex-end; + grid-template-columns: minmax(0, 1fr) auto; } .scoreboard-preview__image-wrap { @@ -1265,6 +1266,7 @@ watch( .scoreboard-preview__controls { width: min(100%, 260px); + justify-self: center; display: flex; flex-direction: column; gap: 6px; @@ -1364,7 +1366,7 @@ watch( } .scoreboard-preview__side-inner { - flex-direction: column; + grid-template-columns: 1fr; align-items: flex-start; } @@ -1373,7 +1375,7 @@ watch( } .scoreboard-preview__side--right .scoreboard-preview__side-inner { - justify-content: flex-start; + grid-template-columns: 1fr; } } From 63c4daf7416d7462f7ec09205e748137f9f52616 Mon Sep 17 00:00:00 2001 From: Pandipipas <62224708+Pandipipas@users.noreply.github.com> Date: Fri, 13 Feb 2026 01:02:26 +0100 Subject: [PATCH 04/10] Fix preview spacing so controls sit between image and score --- .../example/components/ScoreboardPanel.vue | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/dashboard/example/components/ScoreboardPanel.vue b/src/dashboard/example/components/ScoreboardPanel.vue index 02c81a8..5872b50 100644 --- a/src/dashboard/example/components/ScoreboardPanel.vue +++ b/src/dashboard/example/components/ScoreboardPanel.vue @@ -1209,8 +1209,8 @@ watch( .scoreboard-preview { display: grid; - grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr); - gap: 10px; + grid-template-columns: minmax(0, 1fr) minmax(320px, auto) minmax(0, 1fr); + gap: 18px; padding: 16px; align-items: center; } @@ -1222,10 +1222,10 @@ watch( .scoreboard-preview__side-inner { width: 100%; - display: grid; - grid-template-columns: auto minmax(0, 1fr); + display: flex; align-items: center; - gap: 12px; + justify-content: space-between; + gap: 14px; } .scoreboard-preview__side--right { @@ -1233,7 +1233,7 @@ watch( } .scoreboard-preview__side--right .scoreboard-preview__side-inner { - grid-template-columns: minmax(0, 1fr) auto; + justify-content: space-between; } .scoreboard-preview__image-wrap { @@ -1266,7 +1266,6 @@ watch( .scoreboard-preview__controls { width: min(100%, 260px); - justify-self: center; display: flex; flex-direction: column; gap: 6px; @@ -1299,7 +1298,7 @@ watch( display: flex; align-items: center; justify-content: center; - gap: 10px; + gap: 18px; } .scoreboard-preview__score-side { @@ -1366,8 +1365,9 @@ watch( } .scoreboard-preview__side-inner { - grid-template-columns: 1fr; + flex-direction: column; align-items: flex-start; + justify-content: flex-start; } .scoreboard-preview__side--right { @@ -1375,7 +1375,7 @@ watch( } .scoreboard-preview__side--right .scoreboard-preview__side-inner { - grid-template-columns: 1fr; + justify-content: flex-start; } } From 818ac56f533913a27f6527430ddc6bba1906f277 Mon Sep 17 00:00:00 2001 From: Pandipipas <62224708+Pandipipas@users.noreply.github.com> Date: Fri, 13 Feb 2026 01:08:24 +0100 Subject: [PATCH 05/10] Stabilize preview control centering across zoom levels --- .../example/components/ScoreboardPanel.vue | 22 ++++++++++++++----- 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/src/dashboard/example/components/ScoreboardPanel.vue b/src/dashboard/example/components/ScoreboardPanel.vue index 5872b50..0bb2f0f 100644 --- a/src/dashboard/example/components/ScoreboardPanel.vue +++ b/src/dashboard/example/components/ScoreboardPanel.vue @@ -1222,9 +1222,9 @@ watch( .scoreboard-preview__side-inner { width: 100%; - display: flex; + display: grid; + grid-template-columns: minmax(220px, 320px) minmax(180px, 1fr); align-items: center; - justify-content: space-between; gap: 14px; } @@ -1233,7 +1233,16 @@ watch( } .scoreboard-preview__side--right .scoreboard-preview__side-inner { - justify-content: space-between; + grid-template-columns: minmax(180px, 1fr) minmax(220px, 320px); +} + + +.scoreboard-preview__side .scoreboard-preview__image-wrap { + justify-self: start; +} + +.scoreboard-preview__side--right .scoreboard-preview__image-wrap { + justify-self: end; } .scoreboard-preview__image-wrap { @@ -1266,6 +1275,7 @@ watch( .scoreboard-preview__controls { width: min(100%, 260px); + justify-self: center; display: flex; flex-direction: column; gap: 6px; @@ -1365,9 +1375,9 @@ watch( } .scoreboard-preview__side-inner { - flex-direction: column; + grid-template-columns: 1fr; align-items: flex-start; - justify-content: flex-start; + justify-items: flex-start; } .scoreboard-preview__side--right { @@ -1375,7 +1385,7 @@ watch( } .scoreboard-preview__side--right .scoreboard-preview__side-inner { - justify-content: flex-start; + grid-template-columns: 1fr; } } From 26855eb43f679973984d4ada9a9117836b90fe85 Mon Sep 17 00:00:00 2001 From: Pandipipas <62224708+Pandipipas@users.noreply.github.com> Date: Fri, 13 Feb 2026 14:08:40 +0100 Subject: [PATCH 06/10] Add character selectors under preview images and center actions --- .../example/components/ScoreboardPanel.vue | 199 ++++++++++++------ 1 file changed, 139 insertions(+), 60 deletions(-) diff --git a/src/dashboard/example/components/ScoreboardPanel.vue b/src/dashboard/example/components/ScoreboardPanel.vue index 0bb2f0f..98b4b2f 100644 --- a/src/dashboard/example/components/ScoreboardPanel.vue +++ b/src/dashboard/example/components/ScoreboardPanel.vue @@ -648,19 +648,39 @@ watch( >
-
- -
- Left image +
+
+ +
+ Left image +
+
-
-
- - {{ scoreboardStore.scoreboard.leftScore }} - +
+
+
+ + {{ scoreboardStore.scoreboard.leftScore }} + +
+ + - + +
+ + {{ scoreboardStore.scoreboard.rightScore }} + +
- - - -
+
- {{ scoreboardStore.scoreboard.rightScore }}
@@ -873,19 +912,39 @@ watch(
-
- -
- Right image +
+
+ +
+ Right image +
+
@@ -1220,6 +1279,13 @@ watch( align-items: center; } +.scoreboard-preview__image-column { + width: min(100%, 320px); + display: flex; + flex-direction: column; + gap: 8px; +} + .scoreboard-preview__side-inner { width: 100%; display: grid; @@ -1237,11 +1303,11 @@ watch( } -.scoreboard-preview__side .scoreboard-preview__image-wrap { +.scoreboard-preview__side .scoreboard-preview__image-column { justify-self: start; } -.scoreboard-preview__side--right .scoreboard-preview__image-wrap { +.scoreboard-preview__side--right .scoreboard-preview__image-column { justify-self: end; } @@ -1304,6 +1370,13 @@ watch( color: rgba(255, 255, 255, 0.92); } +.scoreboard-preview__center { + display: flex; + flex-direction: column; + align-items: center; + gap: 10px; +} + .scoreboard-preview__score-controls { display: flex; align-items: center; @@ -1311,6 +1384,12 @@ watch( gap: 18px; } +.scoreboard-preview__actions { + display: flex; + align-items: center; + gap: 10px; +} + .scoreboard-preview__score-side { display: inline-flex; flex-direction: column; @@ -1365,7 +1444,7 @@ watch( gap: 12px; } - .scoreboard-preview__score-controls { + .scoreboard-preview__center { order: -1; justify-self: center; } From 1fda5c99e8b28e5a13b0f493c9dae17be8258332 Mon Sep 17 00:00:00 2001 From: Pandipipas <62224708+Pandipipas@users.noreply.github.com> Date: Fri, 13 Feb 2026 14:17:24 +0100 Subject: [PATCH 07/10] Tune preview action icons and character filter behavior --- .../example/components/ScoreboardPanel.vue | 61 ++++++++++++++++--- 1 file changed, 53 insertions(+), 8 deletions(-) diff --git a/src/dashboard/example/components/ScoreboardPanel.vue b/src/dashboard/example/components/ScoreboardPanel.vue index 98b4b2f..f04f02e 100644 --- a/src/dashboard/example/components/ScoreboardPanel.vue +++ b/src/dashboard/example/components/ScoreboardPanel.vue @@ -41,6 +41,9 @@ const fightingGameOptions = [ })); const characterOptions = computed(() => getCharactersByGame(scoreboardStore.scoreboard.game)); +type CharacterOption = ReturnType[number]; +const leftCharacterOptions = ref([]); +const rightCharacterOptions = ref([]); const leftCharacterImage = computed(() => { const match = characterOptions.value.find((option) => option.value === scoreboardStore.scoreboard.leftCharacter); @@ -93,6 +96,30 @@ const onRightCountryFilter = (value: string, update: (callback: () => void) => v filterCountries(value, update, rightCountryOptions); }; + +const filterCharacters = ( + value: string, + update: (callback: () => void) => void, + target: Ref, +) => { + update(() => { + const needle = value.toLowerCase().trim(); + if (!needle) { + target.value = characterOptions.value; + return; + } + target.value = characterOptions.value.filter((character) => character.label.toLowerCase().includes(needle)); + }); +}; + +const onLeftCharacterFilter = (value: string, update: (callback: () => void) => void) => { + filterCharacters(value, update, leftCharacterOptions); +}; + +const onRightCharacterFilter = (value: string, update: (callback: () => void) => void) => { + filterCharacters(value, update, rightCharacterOptions); +}; + const playerOptions = computed(() => { const base = [{ label: '(Sin asignar)', value: '' }]; const entries = Object.entries(playersStore.players) as [string, Schemas.Players[string]][]; @@ -598,6 +625,8 @@ watch( () => scoreboardStore.scoreboard.game, () => { const options = getCharactersByGame(scoreboardStore.scoreboard.game); + leftCharacterOptions.value = options; + rightCharacterOptions.value = options; const allowed = new Set(options.map((option) => option.value)); if (!allowed.has(scoreboardStore.scoreboard.leftCharacter)) { @@ -666,7 +695,7 @@ watch(
@@ -813,17 +843,17 @@ watch(
@@ -930,7 +960,7 @@ watch(
@@ -1351,6 +1382,10 @@ watch( margin: 0; } +.scoreboard-preview__character-field { + margin-top: 2px; +} + .scoreboard-preview__field :deep(.q-field__control) { min-height: 28px; padding: 0; @@ -1390,6 +1425,16 @@ watch( gap: 10px; } +.scoreboard-preview__action-btn { + color: #fff; + opacity: 0.85; +} + +.scoreboard-preview__action-btn:hover { + opacity: 1; + text-shadow: 0 0 10px rgba(255, 255, 255, 0.45); +} + .scoreboard-preview__score-side { display: inline-flex; flex-direction: column; From 494a6c42a6f26920c8a9fae84680aa7a772a3e96 Mon Sep 17 00:00:00 2001 From: Pandipipas <62224708+Pandipipas@users.noreply.github.com> Date: Fri, 13 Feb 2026 14:48:45 +0100 Subject: [PATCH 08/10] Add underlined game selector with typed filtering in preview center --- .../example/components/ScoreboardPanel.vue | 46 ++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/src/dashboard/example/components/ScoreboardPanel.vue b/src/dashboard/example/components/ScoreboardPanel.vue index f04f02e..4a0c3f0 100644 --- a/src/dashboard/example/components/ScoreboardPanel.vue +++ b/src/dashboard/example/components/ScoreboardPanel.vue @@ -26,8 +26,9 @@ const rightCountryOptions = ref(countryOptions); const leftCharacterInput = ref(''); const rightCharacterInput = ref(''); +const gameInput = ref(''); -const fightingGameOptions = [ +const allFightingGameOptions = [ 'Street Fighter 6', 'TEKKEN 8', 'Guilty Gear -Strive-', @@ -40,6 +41,8 @@ const fightingGameOptions = [ value: game, })); +const fightingGameOptions = ref(allFightingGameOptions); + const characterOptions = computed(() => getCharactersByGame(scoreboardStore.scoreboard.game)); type CharacterOption = ReturnType[number]; const leftCharacterOptions = ref([]); @@ -120,6 +123,17 @@ const onRightCharacterFilter = (value: string, update: (callback: () => void) => filterCharacters(value, update, rightCharacterOptions); }; +const onGameFilter = (value: string, update: (callback: () => void) => void) => { + update(() => { + const needle = value.toLowerCase().trim(); + if (!needle) { + fightingGameOptions.value = allFightingGameOptions; + return; + } + fightingGameOptions.value = allFightingGameOptions.filter((game) => game.label.toLowerCase().includes(needle)); + }); +}; + const playerOptions = computed(() => { const base = [{ label: '(Sin asignar)', value: '' }]; const entries = Object.entries(playersStore.players) as [string, Schemas.Players[string]][]; @@ -621,6 +635,16 @@ watchEffect(() => { } }); + +watch( + () => scoreboardStore.scoreboard.game, + (value) => { + const match = allFightingGameOptions.find((option) => option.value === value); + gameInput.value = match?.label ?? ''; + }, + { immediate: true }, +); + watch( () => scoreboardStore.scoreboard.game, () => { @@ -797,6 +821,22 @@ watch(
+ +
Date: Fri, 13 Feb 2026 14:54:59 +0100 Subject: [PATCH 09/10] Pin preview game selector to top with larger score gap --- src/dashboard/example/components/ScoreboardPanel.vue | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/dashboard/example/components/ScoreboardPanel.vue b/src/dashboard/example/components/ScoreboardPanel.vue index 4a0c3f0..9b77e4a 100644 --- a/src/dashboard/example/components/ScoreboardPanel.vue +++ b/src/dashboard/example/components/ScoreboardPanel.vue @@ -1449,11 +1449,15 @@ watch( display: flex; flex-direction: column; align-items: center; + align-self: stretch; + justify-content: flex-start; + padding-top: 2px; gap: 10px; } .scoreboard-preview__game-field { width: min(100%, 240px); + margin-bottom: 56px; } .scoreboard-preview__score-controls { From 6756832f33b9408c1443580acbaf60a0f232cf2a Mon Sep 17 00:00:00 2001 From: Pandipipas <62224708+Pandipipas@users.noreply.github.com> Date: Fri, 13 Feb 2026 15:01:09 +0100 Subject: [PATCH 10/10] Remove legacy side panels and old center controls --- .../example/components/ScoreboardPanel.vue | 347 +----------------- 1 file changed, 4 insertions(+), 343 deletions(-) diff --git a/src/dashboard/example/components/ScoreboardPanel.vue b/src/dashboard/example/components/ScoreboardPanel.vue index 9b77e4a..596ee88 100644 --- a/src/dashboard/example/components/ScoreboardPanel.vue +++ b/src/dashboard/example/components/ScoreboardPanel.vue @@ -1020,312 +1020,6 @@ watch(
- -
-
- - -
- Left side -
-
- - - - - - -
- Left character preview -
- - - - - - - -
-
-
- -
- - -
-
- - -
- -
-
-
-
- -
- - -
- Right side -
-
- - - - - - -
- Right character preview -
- - - - - - - -
-
-
-
@@ -1504,31 +1198,11 @@ watch( font-weight: 700; } -.scoreboard-grid { - display: grid; - grid-template-columns: 1fr; - gap: 24px; - align-items: start; -} -.scoreboard-grid__side, -.scoreboard-grid__center { - min-width: 0; -} - -.character-preview { - width: 100%; - border-radius: 8px; - overflow: hidden; - border: 1px solid rgba(255, 255, 255, 0.12); - background: rgba(0, 0, 0, 0.25); -} - -.character-preview img { - display: block; - width: 100%; - height: 88px; - object-fit: cover; +@media (min-width: 1024px) { + .scoreboard-preview { + grid-template-columns: minmax(0, 1fr) minmax(320px, auto) minmax(0, 1fr); + } } @media (max-width: 900px) { @@ -1561,17 +1235,4 @@ watch( } } -@media (min-width: 1024px) { - .scoreboard-preview { - grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr); - } - - .scoreboard-grid { - grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr); - } - - .scoreboard-grid__center { - width: 220px; - } -}