feat(partita): storico strisce multi-set, conferma fine set e avviso fine partita

- sp.strisce[] archivia la striscia di ogni set completato
- fine set rilevata automaticamente: controller mostra modale di conferma
- confermaSet salva il set, incrementa il contatore e prepara il successivo
- fine partita rilevata da checkVittoriaPartita(): display mostra overlay con
  vincitore e punteggio set; incPunt bloccato
- decPunt pulisce setFinito (undo dell'ultimo punto di vittoria)
- resetta azzera strisce[], setFinito e partitaFinita
This commit is contained in:
2026-02-21 17:49:19 +01:00
parent d1e8279608
commit d9e1ac751f
3 changed files with 132 additions and 1 deletions

View File

@@ -78,6 +78,20 @@
</div>
</div>
<!-- Finestra fine set -->
<div class="overlay" v-if="setFinito">
<div class="dialog">
<div class="dialog-title">SET FINITO</div>
<div class="set-finito-info">
<div class="set-vincitore">{{ state.sp.nomi[setFinito.vincitore] }}</div>
<div class="set-score">{{ state.sp.punt.home }} {{ state.sp.punt.guest }}</div>
</div>
<div class="dialog-buttons">
<button class="btn btn-confirm" @click="sendAction({ type: 'confermaSet' })">CONFERMA</button>
</div>
</div>
</div>
<!-- Finestra configurazione -->
<div class="overlay" v-if="showConfig" @click.self="showConfig = false">
<div class="dialog dialog-config">
@@ -209,6 +223,8 @@ export default {
visuStriscia: true,
modalitaPartita: "3/5",
sp: {
strisce: [],
setFinito: null,
striscia: { home: [0], guest: [0] },
servHome: true,
punt: { home: 0, guest: 0 },
@@ -227,6 +243,9 @@ export default {
isPunteggioZeroZero() {
return this.state.sp.punt.home === 0 && this.state.sp.punt.guest === 0
},
setFinito() {
return this.state.sp.setFinito
},
cambiValid() {
let hasComplete = false
let allValid = true
@@ -905,4 +924,21 @@ export default {
padding: 8px 0;
font-weight: 600;
}
/* Fine set */
.set-finito-info {
text-align: center;
padding: 16px 0;
}
.set-vincitore {
font-size: 22px;
font-weight: 800;
color: #fdd835;
text-transform: uppercase;
margin-bottom: 8px;
}
.set-score {
font-size: 36px;
font-weight: 900;
}
</style>

View File

@@ -112,6 +112,15 @@
{{ wsConnected ? '' : 'Disconnesso' }}
</div>
</div>
<!-- Overlay fine partita -->
<div class="partita-finita-overlay" v-if="state.sp.partitaFinita">
<div class="partita-finita-box">
<div class="partita-finita-label">PARTITA FINITA</div>
<div class="partita-finita-vincitore">{{ state.sp.nomi[state.sp.partitaFinita.vincitore] }}</div>
<div class="partita-finita-set">{{ state.sp.set.home }} {{ state.sp.set.guest }}</div>
</div>
</div>
</section>
</template>
@@ -132,6 +141,9 @@ export default {
visuStriscia: true,
modalitaPartita: "3/5",
sp: {
strisce: [],
setFinito: null,
partitaFinita: null,
striscia: { home: [0], guest: [0] },
servHome: true,
punt: { home: 0, guest: 0 },
@@ -436,4 +448,38 @@ export default {
overflow: hidden;
box-sizing: border-box;
}
/* Fine partita */
.partita-finita-overlay {
position: fixed;
inset: 0;
background: rgba(0, 0, 0, 0.88);
display: flex;
align-items: center;
justify-content: center;
z-index: 500;
}
.partita-finita-box {
text-align: center;
color: #fff;
}
.partita-finita-label {
font-size: 5vw;
font-weight: 700;
letter-spacing: 0.1em;
color: #aaa;
margin-bottom: 0.3em;
}
.partita-finita-vincitore {
font-size: 14vw;
font-weight: 900;
color: #fdd835;
text-transform: uppercase;
line-height: 1;
margin-bottom: 0.2em;
}
.partita-finita-set {
font-size: 8vw;
font-weight: 700;
}
</style>

View File

@@ -10,6 +10,9 @@ export function createInitialState() {
visuStriscia: true,
modalitaPartita: "3/5",
sp: {
strisce: [],
setFinito: null,
partitaFinita: null,
striscia: { home: [0], guest: [" "] },
servHome: true,
punt: { home: 0, guest: 0 },
@@ -24,6 +27,13 @@ export function createInitialState() {
}
}
export function checkVittoriaPartita(state) {
const setsToWin = state.modalitaPartita === "2/3" ? 2 : 3
if (state.sp.set.home >= setsToWin) return "home"
if (state.sp.set.guest >= setsToWin) return "guest"
return null
}
export function checkVittoria(state) {
const puntHome = state.sp.punt.home
const puntGuest = state.sp.punt.guest
@@ -58,7 +68,7 @@ export function applyAction(state, action) {
switch (action.type) {
case "incPunt": {
const team = action.team
if (checkVittoria(s)) break
if (s.sp.setFinito !== null || s.sp.partitaFinita !== null) break
s.sp.storicoServizio.push({
servHome: s.sp.servHome,
@@ -80,10 +90,17 @@ export function applyAction(state, action) {
}
s.sp.servHome = team === "home"
if (checkVittoria(s)) {
s.sp.setFinito = { vincitore: team }
}
break
}
case "decPunt": {
if (s.sp.setFinito !== null) {
s.sp.setFinito = null
}
if (s.sp.storicoServizio.length > 0) {
const tmpHome = s.sp.striscia.home.pop()
s.sp.striscia.guest.pop()
@@ -105,6 +122,35 @@ export function applyAction(state, action) {
break
}
case "confermaSet": {
if (!s.sp.setFinito) break
const vincitore = s.sp.setFinito.vincitore
s.sp.strisce.push({
home: [...s.sp.striscia.home],
guest: [...s.sp.striscia.guest],
vincitore,
punt: { ...s.sp.punt },
})
s.sp.set[vincitore]++
s.sp.punt.home = 0
s.sp.punt.guest = 0
s.sp.storicoServizio = []
s.sp.setFinito = null
const vincitorePartita = checkVittoriaPartita(s)
if (vincitorePartita) {
s.sp.partitaFinita = { vincitore: vincitorePartita }
} else {
s.sp.striscia = s.sp.servHome
? { home: [0], guest: [" "] }
: { home: [" "], guest: [0] }
}
break
}
case "incSet": {
const team = action.team
if (s.sp.set[team] === 2) {
@@ -139,6 +185,9 @@ export function applyAction(state, action) {
? { home: [0], guest: [" "] }
: { home: [" "], guest: [0] }
s.sp.storicoServizio = []
s.sp.strisce = []
s.sp.setFinito = null
s.sp.partitaFinita = null
break
}