timerIncDec beendete den Timer auch beim Hinzufuegen von Zeit: die Pruefung verglich den Betrag des Werts mit der Restzeit, ohne die Richtung zu beachten. Bei 5s Restzeit fuehrte "+10s" damit zum Spielende statt zu 15s. Die Pruefung gilt jetzt nur noch fuer negative Werte. Beim Verringern unter 0 wird die Restzeit zusaetzlich sauber auf 00:00 gesetzt, sonst blieb sie stehen und der Timer war trotz "ENDE" auf dem Monitor wieder startbar. Im Debugfenster zeigten alle drei Label auf scoreSwitchEnable. Ein Klick auf den Text "Teamanzeige spiegeln" oder "Splashscreen anzeigen" blendete damit das Scoreboard aus. Jede Beschriftung zeigt jetzt auf ihren eigenen Schalter. scoreSetScore sendet den neuen Stand jetzt wie alterScore und clearScore an die Monitore; der Endpunkt wird vom Panel nicht verwendet, ist aber dokumentiert. alterScore laesst den Spielstand nicht mehr unter 0 laufen. Die toten Funktionsprototypen in timer.js und score.js sind entfernt: sie wurden durch Hoisting ohnehin ueberschrieben und listeten toggleReferenceMirrored und print schon nicht mehr auf. Ebenso die Wert-Snapshots duration, durationLeft und isPaused aus module.exports, die dauerhaft die Startwerte lieferten. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
370 lines
18 KiB
Handlebars
370 lines
18 KiB
Handlebars
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<title>Scoreboard Admin</title>
|
|
<link rel='stylesheet' href='/stylesheets/bootstrap/bootstrap.min.css' />
|
|
<link rel='stylesheet' href='/stylesheets/admin.css' />
|
|
|
|
<link href="/stylesheets/fontawesome/fontawesome.min.css" rel="stylesheet" />
|
|
<link href="/stylesheets/fontawesome/brands.min.css" rel="stylesheet" />
|
|
<link href="/stylesheets/fontawesome/solid.min.css" rel="stylesheet" />
|
|
</head>
|
|
<body onload="initialUpdate()">
|
|
<div class=" container-fluid-sm container-fluid-md container-fluid-lg my-4 mx-4">
|
|
|
|
<div class="row mb-4 justify-content-center">
|
|
<div class="col-sm-12 col-md-12 col-lg-4">
|
|
<div class="card text-center">
|
|
<div class="card-body">
|
|
<h1 id="durationLeft"></h1>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row mb-4">
|
|
<div class="col-sm-12 col-md-12 col-lg-4">
|
|
<div class="h-100 card text-center">
|
|
<div class="card-body">
|
|
<button class="mb-2 btn btn-lg btn-success" onclick="timerStart()" id="timerStartBtn"><i class="fa-solid fa-play"></i> Start</button>
|
|
<button class="mb-2 btn btn-lg btn-warning" onclick="timerPause()" id="timerPauseBtn"><i class="fa-solid fa-pause"></i> Pause</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-sm-12 col-md-12 col-lg-5">
|
|
<div class="h-100 card text-center">
|
|
<div class="card-body ">
|
|
<div class="btn-group align-middle" role="group" aria-label="Basic example">
|
|
<button type="button" class="btn btn-secondary" onclick="timerIncDec(-10)">-10s</button>
|
|
<button type="button" class="btn btn-secondary" onclick="timerIncDec(-5)">-5s</button>
|
|
<button type="button" class="btn btn-secondary" onclick="timerIncDec(-1)">-1s</button>
|
|
<button type="button" class="btn btn-secondary" onclick="timerIncDec(+1)">+1s</button>
|
|
<button type="button" class="btn btn-secondary" onclick="timerIncDec(+5)">+5s</button>
|
|
<button type="button" class="btn btn-secondary" onclick="timerIncDec(+10)">+10s</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-sm-12 col-md-12 col-lg-3">
|
|
<div class="h-100 card text-center">
|
|
<div class="card-body">
|
|
<button class="btn btn-lg btn-danger" data-bs-toggle="modal" data-bs-target="#timerResetModal">
|
|
<i class="fa-solid fa-rotate-right"></i> Zurücksetzen
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row mb-4 justify-content-center">
|
|
<div class="col-sm-12 col-md-12 col-lg-8">
|
|
<div class="card text-center">
|
|
<div class="card-body">
|
|
<div class="row">
|
|
<div class="col-sm-5 col-md-5 col-lg-4">
|
|
<h5 id="teamAcolName"></h5>
|
|
<div class="btn-group-vertical" role="group" aria-label="Vertical button group">
|
|
<button type="mb-2 button" class="btn btn-outline-success btn-lg" id="teamAinc"><i class="fa-solid fa-up-long"></i> +1</button>
|
|
<button type="mb-2 button" class="btn btn-outline-danger btn-lg" id="teamAdec"><i class="fa-solid fa-down-long"></i> -1</button>
|
|
</div>
|
|
</div>
|
|
<div class="col-sm-2 col-md-2 col-lg-4">
|
|
<h1 id="score"></h1>
|
|
</div>
|
|
<div class="col-sm-5 col-md-5 col-lg-4">
|
|
<h5 id="teamBcolName"></h5>
|
|
<div class="btn-group-vertical" role="group" aria-label="Vertical button group">
|
|
<button type="mb-2 button" class="btn btn-outline-success btn-lg" id="teamBinc"><i class="fa-solid fa-up-long"></i> +1</button>
|
|
<button type="mb-2 button" class="btn btn-outline-danger btn-lg" id="teamBdec"><i class="fa-solid fa-down-long"></i> -1</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row mb-4 justify-content-center">
|
|
<div class="col-sm-12 col-md-12 col-lg-4">
|
|
<div class="h-100 card text-center">
|
|
<div class="card-body">
|
|
<button class="mb-2 btn btn-lg btn-success" data-bs-toggle="modal" data-bs-target="#scoreConfigTeamsModal"><i class="fa-solid fa-people-group"></i> Teams konfigurieren</button>
|
|
<button class="mb-2 btn btn-lg btn-warning" data-bs-toggle="modal" data-bs-target="#scoreSwitchModal"><i class="fa-solid fa-repeat"></i> Seitenwechsel</button>
|
|
<button class="mb-2 btn btn-lg btn-danger" data-bs-toggle="modal" data-bs-target="#scoreResetModal"><i class="fa-solid fa-rotate-right"></i> Score zurücksetzen</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-sm-12 col-md-12 col-lg-4">
|
|
<div class="h-100 card text-center">
|
|
<div class="card-body">
|
|
<button class="mb-2 btn btn-lg btn-danger" data-bs-toggle="modal" data-bs-target="#debugModal"><i class="fa-solid fa-bug"></i> Debugfenster</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
</body>
|
|
<script src='/javascripts/bootstrap/bootstrap.bundle.min.js'></script>
|
|
<script src="/javascripts/socket.io.min.js"></script>
|
|
<script src="/javascripts/moment.js"></script>
|
|
<script src="/javascripts/admin.js"></script>
|
|
|
|
<!-- Modal -->
|
|
<div class="modal fade" id="timerResetModal" tabindex="-1" aria-labelledby="timerResetModalLabel" aria-hidden="true">
|
|
<div class="modal-dialog modal-dialog-centered">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h1 class="modal-title fs-5" id="timerResetModalLabel">Timer zurücksetzen?</h1>
|
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
|
</div>
|
|
<div class="modal-body">
|
|
<p>Möchtest du den Timer wirklich zurücksetzen?</p>
|
|
<p>Gewünschte Zeit:
|
|
<select class="form-select" id="timerSelectDuration" aria-label="Default select example">
|
|
<option value="0">0:00</option>
|
|
<option value="15">0:15</option>
|
|
<option value="30">0:30</option>
|
|
<option value="45">0:45</option>
|
|
<option value="60">1:00</option>
|
|
<option value="75">1:15</option>
|
|
<option value="90">1:30</option>
|
|
<option value="105">1:45</option>
|
|
<option value="120">2:00</option>
|
|
<option value="135">2:15</option>
|
|
<option value="150">2:30</option>
|
|
<option value="165">2:45</option>
|
|
<option value="180">3:00</option>
|
|
<option value="195">3:15</option>
|
|
<option value="210">3:30</option>
|
|
<option value="225">3:45</option>
|
|
<option value="240">4:00</option>
|
|
<option value="255">4:15</option>
|
|
<option value="270">4:30</option>
|
|
<option value="285">4:45</option>
|
|
<option value="300">5:00</option>
|
|
<option value="315">5:15</option>
|
|
<option value="330">5:30</option>
|
|
<option value="345">5:45</option>
|
|
<option value="360">6:00</option>
|
|
<option value="375">6:15</option>
|
|
<option value="390">6:30</option>
|
|
<option value="405">6:45</option>
|
|
<option selected value="420">7:00</option>
|
|
<option value="435">7:15</option>
|
|
<option value="450">7:30</option>
|
|
<option value="465">7:45</option>
|
|
<option value="480">8:00</option>
|
|
<option value="495">8:15</option>
|
|
<option value="510">8:30</option>
|
|
<option value="525">8:45</option>
|
|
<option value="540">9:00</option>
|
|
<option value="555">9:15</option>
|
|
<option value="570">9:30</option>
|
|
<option value="585">9:45</option>
|
|
<option value="600">10:00</option>
|
|
</select>
|
|
</p>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-danger" data-bs-dismiss="modal" onclick="timerReset()">Zurücksetzen</button>
|
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Schließen</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<!-- Modal -->
|
|
|
|
<!-- Score switch Modal -->
|
|
<div class="modal fade" id="scoreSwitchModal" tabindex="-1" aria-labelledby="scoreSwitchModalLabel" aria-hidden="true">
|
|
<div class="modal-dialog modal-dialog-centered">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h1 class="modal-title fs-5" id="scoreSwitchModalLabel">Seiten wechseln?</h1>
|
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
|
</div>
|
|
<div class="modal-body">
|
|
<p>Möchtest du die Seiten für den Score wirklich wechseln?</p>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-danger" data-bs-dismiss="modal" onclick="scoreToggleSideswitch()">Seitenwechsel</button>
|
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Schließen</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<!-- Score switch Modal -->
|
|
|
|
<!-- Score reset Modal -->
|
|
<div class="modal fade" id="scoreResetModal" tabindex="-1" aria-labelledby="scoreResetModalLabel" aria-hidden="true">
|
|
<div class="modal-dialog modal-dialog-centered">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h1 class="modal-title fs-5" id="scoreResetModalLabel">Score zurücksetzen?</h1>
|
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
|
</div>
|
|
<div class="modal-body">
|
|
<p>Möchtest du den Score wirklich zurücksetzen?</p>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-danger" data-bs-dismiss="modal" onclick="scoreClearScore()">Zurücksetzen</button>
|
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Schließen</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<!-- Score reset Modal -->
|
|
|
|
<!-- Config Team Modal -->
|
|
<div class="modal fade" id="scoreConfigTeamsModal" tabindex="-1" aria-labelledby="scoreConfigTeamsModalLabel" aria-hidden="true">
|
|
<div class="modal-dialog modal-dialog-centered">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h1 class="modal-title fs-5" id="timerResetModalLabel">Teams konfigurieren</h1>
|
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
|
</div>
|
|
<div class="modal-body">
|
|
<p class="fw-bold">Konfiguration von Team A bearbeiten:</p>
|
|
<form>
|
|
<div class="input-group mb-3">
|
|
<span class="input-group-text">Name</span>
|
|
<input type="text" class="form-control" id="teamAname" aria-describedby="teamAnameHelp">
|
|
<button class="btn btn-outline-secondary dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false">Auswählen</button>
|
|
<ul id="teamAnameDropdown" class="dropdown-menu dropdown-menu-end">
|
|
</ul>
|
|
</div>
|
|
|
|
<div class="form-check mb-3">
|
|
<input class="form-check-input" type="checkbox" id="teamAisSpielgemeinschaft">
|
|
<label class="form-check-label" for="teamAisSpielgemeinschaft">Team ist eine Spielgemeinschaft</label>
|
|
</div>
|
|
|
|
<div class="input-group">
|
|
<span class="input-group-text">Name2</span>
|
|
<input type="text" class="form-control" id="teamAname2" aria-describedby="teamAname2help">
|
|
<button class="btn btn-outline-secondary dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false">Auswählen</button>
|
|
<ul id="teamAname2Dropdown" class="dropdown-menu dropdown-menu-end">
|
|
</ul>
|
|
</div>
|
|
<div id="teamAname2help" class="form-text mb-5">Wird nur bei einer Spielgemeinschaft angezeigt, sonst leer lassen</div>
|
|
|
|
|
|
<p class="fw-bold">Konfiguration von Team B bearbeiten:</p>
|
|
<div class="input-group mb-3">
|
|
<span class="input-group-text">Name</span>
|
|
<input type="text" class="form-control" id="teamBname" aria-describedby="teamBnameHelp">
|
|
<button class="btn btn-outline-secondary dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false">Auswählen</button>
|
|
<ul id="teamBnameDropdown" class="dropdown-menu dropdown-menu-end">
|
|
</ul>
|
|
</div>
|
|
<div class="form-check mb-3">
|
|
<input class="form-check-input" type="checkbox" id="teamBisSpielgemeinschaft">
|
|
<label class="form-check-label" for="teamBisSpielgemeinschaft">Team ist eine Spielgemeinschaft</label>
|
|
</div>
|
|
<div class="input-group">
|
|
<span class="input-group-text">Name2</span>
|
|
<input type="text" class="form-control" id="teamBname2" aria-describedby="teamBname2help">
|
|
<button class="btn btn-outline-secondary dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false">Auswählen</button>
|
|
<ul id="teamBname2Dropdown" class="dropdown-menu dropdown-menu-end">
|
|
</ul>
|
|
</div>
|
|
<div id="teamBname2help" class="form-text mb-3">Wird nur bei einer Spielgemeinschaft angezeigt, sonst leer lassen</div>
|
|
</form>
|
|
|
|
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-success" data-bs-dismiss="modal" onclick="scoreConfigTeams()">Absenden</button>
|
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Schließen</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<!-- Config Team Modal -->
|
|
|
|
<!-- Debug Modal -->
|
|
<div class="modal fade" id="debugModal" tabindex="-1" aria-labelledby="debugModalLabel" aria-hidden="true">
|
|
<div class="modal-dialog modal-dialog-centered">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h1 class="modal-title fs-5" id="debugModalLabel">Debugfenster</h1>
|
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
|
</div>
|
|
<div class="modal-body">
|
|
<p>Achtung, eine Fehlbedienung kann unerwünschtes Verhalten hervorrufen.</p>
|
|
<div class="form-check form-switch">
|
|
<input class="form-check-input" onclick="scoreToggleReferenceMirrored()" type="checkbox" role="switch" id="scoreSwitchReferenceMirrored">
|
|
<label class="form-check-label" for="scoreSwitchReferenceMirrored">Teamanzeige im Adminpanel spiegeln?</label>
|
|
</div>
|
|
<div class="form-check form-switch">
|
|
<input class="form-check-input" onclick="scoreToggle()" type="checkbox" role="switch" id="scoreSwitchEnable">
|
|
<label class="form-check-label" for="scoreSwitchEnable">Scoreboard anzeigen?</label>
|
|
</div>
|
|
<div class="form-check form-switch">
|
|
<input class="form-check-input" onclick="etcToggleSplashscreen()" type="checkbox" role="switch" id="etcSwitchEnable">
|
|
<label class="form-check-label" for="etcSwitchEnable">SG-Arheilgen Splashscreen anzeigen?</label>
|
|
</div>
|
|
<button class="mb-2 btn btn-lg btn-warning" onclick="refreshMonitor()"><i class="fa-solid fa-rotate"></i> Monitor neu laden</button> <br>
|
|
<button class="mb-2 btn btn-lg btn-success" onclick="openBrowser()"><i class="fa-solid fa-rocket"></i> Browser öffnen</button> <br>
|
|
<button class="mb-3 btn btn-lg btn-danger" onclick="killBrowser()"><i class="fa-solid fa-stop"></i> Browser stoppen</button> <br>
|
|
|
|
|
|
<p class="fw-bold">Team Datenbank:</p>
|
|
<div class="input-group mb-3">
|
|
<span class="input-group-text"><i class="fa-solid fa-user-plus"></i></span>
|
|
<input type="text" class="form-control" id="dbTeamToAdd">
|
|
<button class="btn btn-outline-success" type="button" onclick="dbAddTeam()"><i class="fa-solid fa-plus"></i></button>
|
|
</div>
|
|
<div class="input-group mb-3">
|
|
<span class="input-group-text"><i class="fa-solid fa-user-minus"></i></span>
|
|
<select class="form-select" id="dbTeamToDelete" aria-label="Default select example">
|
|
</select>
|
|
<button class="btn btn-outline-danger" type="button" onclick="dbDeleteTeam()"><i class="fa-solid fa-trash"></i></button>
|
|
</div>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Schließen</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<!-- Debug Modal -->
|
|
|
|
|
|
<!-- Timer start error toast -->
|
|
<div class="toast-container position-fixed bottom-0 end-0 p-3">
|
|
<div id="timerStartErrorToast" class="toast" role="alert" aria-live="assertive" aria-atomic="true">
|
|
<div class="toast-header">
|
|
<i class="fa-solid fa-triangle-exclamation"> </i>
|
|
<strong class="me-auto"> Fehler</strong>
|
|
<small></small>
|
|
<button type="button" class="btn-close" data-bs-dismiss="toast" aria-label="Close"></button>
|
|
</div>
|
|
<div class="toast-body">
|
|
Der Timer ist bereits abgelaufen. Zum neustarten bitte zurücksetzen!
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<!-- Timer start error toast -->
|
|
|
|
<!-- Timer pause error toast -->
|
|
<div class="toast-container position-fixed bottom-0 end-0 p-3">
|
|
<div id="timerPauseErrorToast" class="toast" role="alert" aria-live="assertive" aria-atomic="true">
|
|
<div class="toast-header">
|
|
<i class="fa-solid fa-triangle-exclamation"> </i>
|
|
<strong class="me-auto"> Fehler</strong>
|
|
<small></small>
|
|
<button type="button" class="btn-close" data-bs-dismiss="toast" aria-label="Close"></button>
|
|
</div>
|
|
<div class="toast-body">
|
|
Der Timer ist bereits pausiert.
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<!-- Timer pause error toast -->
|
|
</html>
|
|
|