feat(controller): dialog set vinto con transizione automatica al set successivo

Quando una squadra raggiunge il punteggio di vittoria (25 con +2 di
scarto, 15 nel set decisivo), il controller mostra un dialog "SET VINTO"
con il nome della squadra vincente.

Alla conferma: invia l'azione nuovoSet (incrementa il set, azzera punti,
striscia, storico servizio e formazioni) e apre automaticamente il dialog
di configurazione per inserire le formazioni del set successivo.
This commit is contained in:
2026-05-12 13:18:18 +02:00
parent eec4ef0526
commit 3188994299
3 changed files with 117 additions and 0 deletions
+56
View File
@@ -78,6 +78,18 @@
</div>
</div>
<!-- Finestra set vinto -->
<div class="overlay" v-if="showSetVinto">
<div class="dialog">
<div class="dialog-title">SET VINTO</div>
<div class="dialog-winner">{{ state.sp.nomi[setVintoTeam] }}</div>
<div class="dialog-subtitle">Configura le formazioni per il prossimo set</div>
<div class="dialog-buttons">
<button class="btn btn-confirm" @click="doNuovoSet()">VAI AL SET SUCCESSIVO</button>
</div>
</div>
</div>
<!-- Finestra configurazione -->
<div class="overlay" v-if="showConfig" @click.self="showConfig = false">
<div class="dialog dialog-config">
@@ -187,6 +199,8 @@ export default {
reconnectAttempts: 0,
maxReconnectDelay: 30000,
confirmReset: false,
showSetVinto: false,
setVintoTeam: null,
showConfig: false,
showCambiTeam: false,
showCambi: false,
@@ -227,6 +241,15 @@ export default {
isPunteggioZeroZero() {
return this.state.sp.punt.home === 0 && this.state.sp.punt.guest === 0
},
squadraVincente() {
const { home, guest } = this.state.sp.punt
const totSet = this.state.sp.set.home + this.state.sp.set.guest
const isSetDecisivo = this.state.modalitaPartita === '2/3' ? totSet >= 2 : totSet >= 4
const soglia = isSetDecisivo ? 15 : 25
if (home >= soglia && home - guest >= 2) return 'home'
if (guest >= soglia && guest - home >= 2) return 'guest'
return null
},
cambiValid() {
let hasComplete = false
let allValid = true
@@ -240,6 +263,14 @@ export default {
return allValid && hasComplete
}
},
watch: {
squadraVincente(val) {
if (val && !this.showSetVinto) {
this.setVintoTeam = val
this.showSetVinto = true
}
},
},
mounted() {
this.connectWebSocket()
@@ -440,6 +471,17 @@ export default {
this.confirmReset = false
},
doNuovoSet() {
this.sendAction({ type: 'nuovoSet', team: this.setVintoTeam })
this.showSetVinto = false
this.configData.nomeHome = this.state.sp.nomi.home
this.configData.nomeGuest = this.state.sp.nomi.guest
this.configData.modalita = this.state.modalitaPartita
this.configData.formHome = ["1", "2", "3", "4", "5", "6"]
this.configData.formGuest = ["1", "2", "3", "4", "5", "6"]
this.showConfig = true
},
openConfig() {
this.configData.nomeHome = this.state.sp.nomi.home
this.configData.nomeGuest = this.state.sp.nomi.guest
@@ -747,6 +789,20 @@ export default {
border: 1px solid rgba(255,255,255,0.12);
}
.dialog-winner {
font-size: 28px;
font-weight: 900;
text-align: center;
margin-bottom: 8px;
}
.dialog-subtitle {
font-size: 13px;
color: #aaa;
text-align: center;
margin-bottom: 4px;
}
.dialog-config {
max-height: 85vh;
overflow-y: auto;
+15
View File
@@ -110,6 +110,21 @@ export function applyAction(state, action) {
break
}
case "nuovoSet": {
const team = action.team
if (team !== 'home' && team !== 'guest') break
s.sp.set[team]++
s.sp.punt.home = 0
s.sp.punt.guest = 0
s.sp.striscia = { home: [0], guest: [0] }
s.sp.storicoServizio = []
s.sp.form = {
home: ["1", "2", "3", "4", "5", "6"],
guest: ["1", "2", "3", "4", "5", "6"],
}
break
}
case "cambiaPalla": {
if (s.sp.punt.home === 0 && s.sp.punt.guest === 0) {
s.sp.servHome = !s.sp.servHome
+46
View File
@@ -231,6 +231,52 @@ describe('Game Logic (gameState.js)', () => {
})
})
// =============================================
// NUOVO SET (nuovoSet)
// =============================================
describe('nuovoSet', () => {
it('dovrebbe incrementare il set della squadra vincente', () => {
state.sp.punt.home = 25
const s = applyAction(state, { type: 'nuovoSet', team: 'home' })
expect(s.sp.set.home).toBe(1)
expect(s.sp.set.guest).toBe(0)
})
it('dovrebbe azzerare i punti', () => {
state.sp.punt.home = 25
state.sp.punt.guest = 10
const s = applyAction(state, { type: 'nuovoSet', team: 'home' })
expect(s.sp.punt.home).toBe(0)
expect(s.sp.punt.guest).toBe(0)
})
it('dovrebbe resettare la striscia', () => {
state.sp.punt.home = 25
const s = applyAction(state, { type: 'nuovoSet', team: 'home' })
expect(s.sp.striscia).toEqual({ home: [0], guest: [0] })
})
it('dovrebbe resettare lo storico servizio', () => {
state.sp.storicoServizio = [{ servHome: true, cambioPalla: false }]
const s = applyAction(state, { type: 'nuovoSet', team: 'home' })
expect(s.sp.storicoServizio).toEqual([])
})
it('dovrebbe resettare le formazioni', () => {
state.sp.form.home = ['7', '8', '9', '10', '11', '12']
state.sp.form.guest = ['7', '8', '9', '10', '11', '12']
const s = applyAction(state, { type: 'nuovoSet', team: 'home' })
expect(s.sp.form.home).toEqual(['1', '2', '3', '4', '5', '6'])
expect(s.sp.form.guest).toEqual(['1', '2', '3', '4', '5', '6'])
})
it('dovrebbe ignorare team non valido', () => {
const s = applyAction(state, { type: 'nuovoSet', team: 'invalid' })
expect(s.sp.set.home).toBe(0)
expect(s.sp.set.guest).toBe(0)
})
})
// =============================================
// CAMBIO PALLA (cambiaPalla)
// =============================================