First version, for githup; UNSTABLE, DO NOT USE!
This commit is contained in:
696
www/intern/wk-leitung/einstellungen.php
Normal file
696
www/intern/wk-leitung/einstellungen.php
Normal file
@@ -0,0 +1,696 @@
|
||||
<?php
|
||||
|
||||
ini_set('display_errors', 1);
|
||||
ini_set('display_startup_errors', 1);
|
||||
// Show all errors except deprecation notices (these come from vendor libraries
|
||||
// that aren't yet typed for newer PHP versions). Long-term fix: update
|
||||
// dependencies to versions compatible with your PHP runtime.
|
||||
error_reporting(E_ALL & ~E_DEPRECATED & ~E_USER_DEPRECATED);
|
||||
|
||||
if (!isset($baseDir)) {
|
||||
$baseDir = $_SERVER['DOCUMENT_ROOT'];
|
||||
}
|
||||
|
||||
if (session_status() !== PHP_SESSION_ACTIVE) {
|
||||
session_start();
|
||||
}
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="icon" type="png" href="/intern/img/icon.png">
|
||||
<title>WK-leitung - Einstellungen</title>
|
||||
|
||||
|
||||
<link rel="stylesheet" href="/intern/css/einstellungen.css">
|
||||
<link rel="stylesheet" href="/intern/css/sidebar.css">
|
||||
<script src="/intern/js/jquery/jquery-3.7.1.min.js"></script>
|
||||
<script src="/intern/js/custom-msg-display.js"></script>
|
||||
<link rel="stylesheet" href="/intern/css/custom-msg-display.css">
|
||||
<script src="/intern/js/custom-select.js"></script>
|
||||
<link rel="stylesheet" href="/intern/css/custom-select.css">
|
||||
<link rel="stylesheet" href="/files/fonts/fonts.css">
|
||||
</head>
|
||||
<body>
|
||||
<?php
|
||||
$access_granted_wkl = $_SESSION['access_granted_wk_leitung'] ?? false;
|
||||
|
||||
if ( ! $access_granted_wkl ) :
|
||||
|
||||
$logintype = 'wk_leitung';
|
||||
|
||||
require $baseDir . '/../scripts/login/login.php';
|
||||
|
||||
$logintype = '';
|
||||
|
||||
else :
|
||||
|
||||
|
||||
require $baseDir . '/../scripts/db/db-functions.php';
|
||||
require $baseDir . '/../scripts/db/db-tables.php';
|
||||
require $baseDir . '/../scripts/csrf_functions.php';
|
||||
require $baseDir . '/../scripts/websocket/ws-create-token.php';
|
||||
|
||||
|
||||
$type = 'wkl';
|
||||
|
||||
$dbconnection = require $baseDir . '/../scripts/db/db-verbindung-script.php';
|
||||
|
||||
if ($dbconnection['success'] !== true){
|
||||
echo 'Critical DB Error.';
|
||||
exit;
|
||||
}
|
||||
|
||||
$currentPage = 'einstellungen';
|
||||
|
||||
require $baseDir . '/intern/scripts/sidebar/sidebar.php';
|
||||
|
||||
$wkName = db_get_var($mysqli, "SELECT `value` FROM $tableVar WHERE `name` = ?", ['wkName']);
|
||||
|
||||
$displayColor = db_get_var($mysqli, "SELECT `value` FROM $tableVar WHERE `name` = ?", ['displayColourLogo']);
|
||||
$textColor = db_get_var($mysqli, "SELECT `value` FROM $tableVar WHERE `name` = ?", ['displayTextColourLogo']);
|
||||
$displayColorScoringBg = db_get_var($mysqli, "SELECT `value` FROM $tableVar WHERE `name` = ?", ['displayColorScoringBg']);
|
||||
$displayColorScoringBgSoft = db_get_var($mysqli, "SELECT `value` FROM $tableVar WHERE `name` = ?", ['displayColorScoringBgSoft']);
|
||||
$displayColorScoringPanel = db_get_var($mysqli, "SELECT `value` FROM $tableVar WHERE `name` = ?", ['displayColorScoringPanel']);
|
||||
$displayColorScoringPanelSoft = db_get_var($mysqli, "SELECT `value` FROM $tableVar WHERE `name` = ?", ['displayColorScoringPanelSoft']);
|
||||
|
||||
$displayColorScoringPanelText = db_get_var($mysqli, "SELECT `value` FROM $tableVar WHERE `name` = ?", ['displayColorScoringPanelText']);
|
||||
$displayColorScoringPanelTextSoft = db_get_var($mysqli, "SELECT `value` FROM $tableVar WHERE `name` = ?", ['displayColorScoringPanelTextSoft']);
|
||||
|
||||
$displayColorScoringPanelTextNoteL = db_get_var($mysqli, "SELECT `value` FROM $tableVar WHERE `name` = ?", ['displayColorScoringPanelTextNoteL']);
|
||||
$displayColorScoringPanelTextNoteR = db_get_var($mysqli, "SELECT `value` FROM $tableVar WHERE `name` = ?", ['displayColorScoringPanelTextNoteR']);
|
||||
|
||||
$displayIdNoteL = db_get_var($mysqli, "SELECT `value` FROM $tableVar WHERE `name` = ?", ['displayIdNoteL']);
|
||||
$displayIdNoteR = db_get_var($mysqli, "SELECT `value` FROM $tableVar WHERE `name` = ?", ['displayIdNoteR']);
|
||||
$rechnungenName = db_get_var($mysqli, "SELECT `value` FROM $tableVar WHERE `name` = ?", ['rechnungenName']);
|
||||
$rechnungenVorname = db_get_var($mysqli, "SELECT `value` FROM $tableVar WHERE `name` = ?", ['rechnungenVorname']);
|
||||
$rechnungenStrasse = db_get_var($mysqli, "SELECT `value` FROM $tableVar WHERE `name` = ?", ['rechnungenStrasse']);
|
||||
$rechnungenHausnummer = db_get_var($mysqli, "SELECT `value` FROM $tableVar WHERE `name` = ?", ['rechnungenHausnummer']);
|
||||
$rechnungenPostleitzahl = db_get_var($mysqli, "SELECT `value` FROM $tableVar WHERE `name` = ?", ['rechnungenPostleitzahl']);
|
||||
$rechnungenOrt = db_get_var($mysqli, "SELECT `value` FROM $tableVar WHERE `name` = ?", ['rechnungenOrt']);
|
||||
$rechnungenIBAN = db_get_var($mysqli, "SELECT `value` FROM $tableVar WHERE `name` = ?", ['rechnungenIBAN']);
|
||||
$linkWebseite = db_get_var($mysqli, "SELECT `value` FROM $tableVar WHERE `name` = ?", ['linkWebseite']);
|
||||
|
||||
|
||||
$maxLengthMusic = db_get_var($mysqli, "SELECT `value` FROM $tableVar WHERE `name` = ?", ['maxLengthMusic']);
|
||||
|
||||
$rangNote = db_get_var($mysqli, "SELECT `value` FROM $tableVar WHERE `name` = ?", ['rangNote']);
|
||||
$orderBestRang = db_get_var($mysqli, "SELECT `value` FROM $tableVar WHERE `name` = ?", ['orderBestRang']);
|
||||
|
||||
$geraete = db_select($mysqli, $tableGeraete, '*', '', [], 'start_index ASC');
|
||||
$noten = db_select($mysqli, $tableNotenBezeichnungen, '*', '', [], '`id` ASC');
|
||||
|
||||
setlocale(LC_TIME, 'de_DE.UTF-8');
|
||||
|
||||
?>
|
||||
<section class="bgSection">
|
||||
<?php sidebarRender('modal'); ?>
|
||||
<div class="headerDivTrainer">
|
||||
<div class="headingPanelDiv">
|
||||
<h2 class="headingPanel">Einstellungen</h2>
|
||||
</div>
|
||||
<div class="menuWrapper">
|
||||
<?php sidebarRender('button'); ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="containerDiv">
|
||||
<h3 class="containerHeading">Wettkampf:</h3>
|
||||
<div class="settingsGrid">
|
||||
<div class="settingsRow"><span>Wettkampfname: </span><input type="text" class="ajaxInput" data-key="wkName" placeholder="Test WKVS" value="<?= $wkName ?>"></div>
|
||||
<div class="settingsRow"><span>Anzahl Tage: </span><input type="number" id="anzahlTageWK" placeholder="2"></div>
|
||||
<div id="divTageInputs" style="display: contents;"></div>
|
||||
<div class="settingsRow"><span>Hintergrundfarbe Displays (bei Logo): </span><input type="color" class="ajaxInput" data-key="displayColourLogo" value="<?= $displayColor ?>"></div>
|
||||
<div class="settingsRow"><span>Textfarbe Displays (bei Logo): </span><input type="color" class="ajaxInput" data-key="displayTextColourLogo" value="<?= $textColor ?>"></div>
|
||||
<div class="settingsRow"><span>Hintergrundfarbe Displays primär (bei Notenanzeige): </span><input type="color" class="ajaxInput" data-key="displayColorScoringBg" value="<?= $displayColorScoringBg ?>"></div>
|
||||
<div class="settingsRow"><span>Hintergrundfarbe Displays sekundär (bei Notenanzeige): </span><input type="color" class="ajaxInput" data-key="displayColorScoringBgSoft" value="<?= $displayColorScoringBgSoft ?>"></div>
|
||||
<div class="settingsRow"><span>Hintergrundfarbe Kacheln Displays primär (bei Notenanzeige): </span><input type="color" class="ajaxInput" data-key="displayColorScoringPanel" value="<?= $displayColorScoringPanel ?>"></div>
|
||||
<div class="settingsRow"><span>Hintergrundfarbe Kacheln Displays sekundär (bei Notenanzeige): </span><input type="color" class="ajaxInput" data-key="displayColorScoringPanelSoft" value="<?= $displayColorScoringPanelSoft ?>"></div>
|
||||
<div class="settingsRow"><span>Textfarbe Displays (bei Notenanzeige): </span><input type="color" class="ajaxInput" data-key="displayColorScoringPanelText" value="<?= $displayColorScoringPanelText ?>"></div>
|
||||
<div class="settingsRow"><span>Sekundäre Textfarbe Displays (bei Notenanzeige): </span><input type="color" class="ajaxInput" data-key="displayColorScoringPanelTextSoft" value="<?= $displayColorScoringPanelTextSoft ?>"></div>
|
||||
<div class="settingsRow"><span>Textfarbe Note Links Displays (bei Notenanzeige): </span><input type="color" class="ajaxInput" data-key="displayColorScoringPanelTextNoteL" value="<?= $displayColorScoringPanelTextNoteL ?>"></div>
|
||||
<div class="settingsRow"><span>Textfarbe Note Rechts Displays (bei Notenanzeige): </span><input type="color" class="ajaxInput" data-key="displayColorScoringPanelTextNoteR" value="<?= $displayColorScoringPanelTextNoteR ?>"></div>
|
||||
<div class="settingsRow"><span>Id Note links auf Display: </span><input type="number" class="ajaxInput" data-key="displayIdNoteL" placeholder="10" value="<?= $displayIdNoteL ?>"></div>
|
||||
<div class="settingsRow"><span>Id Note rechts auf Display: </span><input type="number" class="ajaxInput" data-key="displayIdNoteR" placeholder="10" value="<?= $displayIdNoteR ?>"></div>
|
||||
<div class="settingsRow"><span>Link Webseite: </span><input type="text" class="ajaxInput" data-key="linkWebseite" placeholder="www.wkvs.ch" value="<?= $linkWebseite ?>"></div>
|
||||
<div class="settingsRow"><span>Maximale Länge Musik (in Sekunden) (0 = keine Beschränkung): </span><input type="number" class="ajaxInput" data-key="maxLengthMusic" placeholder="0" value="<?= $maxLengthMusic ?>"></div>
|
||||
</div>
|
||||
<div>
|
||||
<h3 class="containerHeading">Rechnungen:</h3>
|
||||
<div class="settingsGrid">
|
||||
<div class="settingsRow"><span>Name: </span><input type="text" class="ajaxInput" data-key="rechnungenName" placeholder="Mustermann" value="<?= $rechnungenName ?>"></div>
|
||||
<div class="settingsRow"><span>Vorname: </span><input type="text" class="ajaxInput" data-key="rechnungenVorname" placeholder="Max" value="<?= $rechnungenVorname ?>"></div>
|
||||
<div class="settingsRow"><span>Strasse: </span><input type="text" class="ajaxInput" data-key="rechnungenStrasse" placeholder="Musterstrasse" value="<?= $rechnungenStrasse ?>"></div>
|
||||
<div class="settingsRow"><span>Hausnummer: </span><input type="text" class="ajaxInput" data-key="rechnungenHausnummer" placeholder="123" value="<?= $rechnungenHausnummer ?>"></div>
|
||||
<div class="settingsRow"><span>Postleitzahl: </span><input type="text" class="ajaxInput" data-key="rechnungenPostleitzahl" placeholder="4000" value="<?= $rechnungenPostleitzahl ?>"></div>
|
||||
<div class="settingsRow"><span>Ort: </span><input type="text" class="ajaxInput" data-key="rechnungenOrt" placeholder="Basel" value="<?= $rechnungenOrt ?>"></div>
|
||||
<div class="settingsRow"><span>IBAN: </span><input type="text" class="ajaxInput" data-key="rechnungenIBAN" placeholder="CH44 3199 9123 0008 8901 2" value="<?= $rechnungenIBAN ?>"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="containerDiv">
|
||||
<h3 class="containerHeading">Geräte management:</h3>
|
||||
<table class="wkvsTabelle trainer" id="geraeteTable">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>Name</th>
|
||||
<th>Start Index</th>
|
||||
<th>Farbe Kampfrichter</th>
|
||||
<th>Löschen</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($geraete as $g): ?>
|
||||
<tr data-id="<?= $g['id'] ?>">
|
||||
<td><?= $g['id'] ?></td>
|
||||
<td><input type="text" class="ajaxGeraete" data-field="name" value="<?= htmlspecialchars($g['name'] ?? '') ?>" style="width: 100%; padding: 6px; border: 1px dashed #777; border-radius: 4px;"></td>
|
||||
<td><input type="number" class="ajaxGeraete" data-field="start_index" value="<?= $g['start_index'] ?>" style="width: 80px; padding: 6px; border: 1px dashed #777; border-radius: 4px;"></td>
|
||||
<td><input type="color" class="ajaxGeraete" data-field="color_kampfrichter" value="<?= $g['color_kampfrichter'] ?>" style="width: 50px; height: 35px; padding: 2px; border: 1px dashed #777; border-radius: 4px;"></td>
|
||||
<td>
|
||||
<button class="deleteGeraete" data-id="<?= $g['id'] ?>" style="border:none; background:none; cursor:pointer;">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="#b91c1c" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="3 6 5 6 21 6"></polyline><path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"></path></svg>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
<tr class="addRow">
|
||||
<td></td>
|
||||
<td><input type="text" id="newGeraeteName" placeholder="Neues Gerät..." style="width: 100%; padding: 6px; border: 1px solid #777; border-radius: 4px;"></td>
|
||||
<td><input type="number" id="newGeraeteIndex" value="0" style="width: 80px; padding: 6px; border: 1px solid #777; border-radius: 4px;"></td>
|
||||
<td><input type="color" id="newGeraeteColor" value="#424242" style="width: 50px; height: 35px; padding: 2px; border: 1px solid #777; border-radius: 4px;"></td>
|
||||
<td><button id="addGeraeteBtn" style="padding: 6px 12px; background: var(--bg-top); color: #fff; border: none; border-radius: 4px; cursor: pointer;">Hinzufügen</button></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="containerDiv">
|
||||
<h3 class="containerHeading">Noten Bezeichnungen:</h3>
|
||||
<div class="tableWraperOverflowY">
|
||||
<table class="wkvsTabelle trainer" id="notenTable">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>Name</th>
|
||||
<th>Typ</th>
|
||||
<th>Standardwert</th>
|
||||
<th>Berechnung</th>
|
||||
<th>Min Wert</th>
|
||||
<th>Max Wert</th>
|
||||
<th>Pro Gerät</th>
|
||||
<th>Gerät</th>
|
||||
<th>Läufe (JSON)</th>
|
||||
<th>In Tabelle</th>
|
||||
<th>In Tabelle (mobile)</th>
|
||||
<th>In Tabelle (admin)</th>
|
||||
<th>Auf Rangliste</th>
|
||||
<th>Nullstellen</th>
|
||||
<th>Prefix Display</th>
|
||||
<th>Löschen</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($noten as $n): ?>
|
||||
<tr data-id="<?= $n['id'] ?>">
|
||||
<td><?= htmlspecialchars($n['id'] ?? '') ?></td>
|
||||
<td><input type="text" class="ajaxNoten" data-field="name" value="<?= htmlspecialchars($n['name'] ?? '') ?>" style="width: 100%; padding: 6px; border: 1px dashed #777; border-radius: 4px;"></td>
|
||||
<td>
|
||||
<select class="ajaxNoten" data-field="type" style="padding: 6px; border: 1px dashed #777; border-radius: 4px;">
|
||||
<option value="input" <?= $n['type'] === 'input' ? 'selected' : '' ?>>Input</option>
|
||||
<option value="berechnung" <?= $n['type'] === 'berechnung' ? 'selected' : '' ?>>Berechnung</option>
|
||||
</select>
|
||||
</td>
|
||||
<td><input type="number" class="ajaxNoten" data-field="default_value" value="<?= htmlspecialchars($n['default_value'] ?? '') ?>" placeholder="<?= htmlspecialchars(($n['default_value'] === null) ? 'Kein Standartwert' : '') ?>" style="width: 100%; padding: 6px; border: 1px dashed #777; border-radius: 4px;"></td>
|
||||
<td><input type="text" class="ajaxNoten" data-field="berechnung" value="<?= htmlspecialchars($n['berechnung'] ?? '') ?>" style="min-width: 300px; padding: 6px; border: 1px dashed #777; border-radius: 4px;"></td>
|
||||
<td><input type="number" class="ajaxNoten" data-field="min_value" value="<?= htmlspecialchars($n['min_value'] ?? '') ?>" placeholder="<?= htmlspecialchars(($n['min_value'] === null) ? 'Kein Minimalwert' : '') ?>" style="width: 100%; padding: 6px; border: 1px dashed #777; border-radius: 4px;"></td>
|
||||
<td><input type="number" class="ajaxNoten" data-field="max_value" value="<?= htmlspecialchars($n['max_value'] ?? '') ?>" placeholder="<?= htmlspecialchars(($n['max_value'] === null) ? 'Kein Maximalwert' : '') ?>" style="width: 100%; padding: 6px; border: 1px dashed #777; border-radius: 4px;"></td>
|
||||
<td>
|
||||
<label class="checkbox">
|
||||
<input type="checkbox" class="ajaxNoten" data-field="pro_geraet" <?= $n['pro_geraet'] ? 'checked' : '' ?>>
|
||||
<span class="checkbox-ui"></span>
|
||||
</label>
|
||||
</td>
|
||||
<td>
|
||||
<?php
|
||||
// 1. JSON sicher decodieren.
|
||||
// json_decode gibt null zurück, wenn null übergeben wird, daher der erste Teil.
|
||||
$arrayGerateJson = !empty($n['geraete_json']) ? json_decode($n['geraete_json'], true) : [];
|
||||
|
||||
// Sicherheit: Stelle sicher, dass es ein Array ist
|
||||
if (!is_array($arrayGerateJson)) {
|
||||
$arrayGerateJson = [];
|
||||
}
|
||||
|
||||
$arrayGerateJsonNamen = [];
|
||||
|
||||
$geraeteIdName = array_column($geraete, 'name', 'id');
|
||||
$geraeteIdName[0] = 'Keine Gerätezuweisung';
|
||||
|
||||
foreach ($arrayGerateJson as $id) {
|
||||
$arrayGerateJsonNamen[$id] = $geraeteIdName[$id] ?? '';
|
||||
}
|
||||
?>
|
||||
<div class="customSelect" id="selectedOption" data-value="[<?= implode(",", $arrayGerateJsonNamen)?>]">
|
||||
<button type="button" id="selectTriggergeraete_json" class="selectTriggerBulk" aria-expanded="false">
|
||||
<span class="selectLabel placeholder"><?= ($arrayGerateJsonNamen !== []) ? implode(", ", $arrayGerateJsonNamen) : 'Bitte auswählen…' ?></span>
|
||||
<svg class="selectArrow" xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' height="14" width="14">
|
||||
<path d='M6 9L12 15L18 9' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/>
|
||||
</svg>
|
||||
</button>
|
||||
<ul class="selectOptionsBulk">
|
||||
<?php foreach ($geraete as $g): ?>
|
||||
<?php
|
||||
// 2. ID als String umwandeln für den sicheren Vergleich
|
||||
$currentId = (int) $g['id'];
|
||||
|
||||
// 3. Prüfen, ob die aktuelle ID im Array der zugewiesenen Geräte enthalten ist
|
||||
$isSelected = in_array($currentId, $arrayGerateJson);
|
||||
?>
|
||||
|
||||
<li data-value="<?= $g['id'] ?>" class="<?= $isSelected ? 'selected' : '' ?>">
|
||||
<?= $g['name'] ?>
|
||||
</li>
|
||||
<?php endforeach; ?>
|
||||
|
||||
<?php $isSelected = in_array(0, $arrayGerateJson); ?>
|
||||
|
||||
<li data-value="0" class="<?= $isSelected ? 'selected' : '' ?>">Keine Gerätezuweisung</li>
|
||||
</ul>
|
||||
<input type="hidden" name="geraete_json" class="selectValue ajaxNoten" data-field="geraete_json" value="[<?= implode(",", $arrayGerateJson)?>]">
|
||||
</div>
|
||||
</td>
|
||||
<td><input type="text" class="ajaxNoten" data-field="anzahl_laeufe_json" value="<?= htmlspecialchars($n['anzahl_laeufe_json'] ?? '') ?>" placeholder='{"default": 1, "ID": 2}' style="min-width: 200px; padding: 6px; border: 1px dashed #777; border-radius: 4px;"></td>
|
||||
<td>
|
||||
<label class="checkbox">
|
||||
<input type="checkbox" class="ajaxNoten" data-field="zeige_in_tabelle" <?= $n['zeige_in_tabelle'] ? 'checked' : '' ?>>
|
||||
<span class="checkbox-ui"></span>
|
||||
</label>
|
||||
</td>
|
||||
<td>
|
||||
<label class="checkbox">
|
||||
<input type="checkbox" class="ajaxNoten" data-field="zeige_in_tabelle_mobile" <?= $n['zeige_in_tabelle_mobile'] ? 'checked' : '' ?>>
|
||||
<span class="checkbox-ui"></span>
|
||||
</label>
|
||||
</td>
|
||||
<td>
|
||||
<label class="checkbox">
|
||||
<input type="checkbox" class="ajaxNoten" data-field="zeige_in_tabelle_admin" <?= $n['zeige_in_tabelle_admin'] ? 'checked' : '' ?>>
|
||||
<span class="checkbox-ui"></span>
|
||||
</label>
|
||||
</td>
|
||||
<td>
|
||||
<label class="checkbox">
|
||||
<input type="checkbox" class="ajaxNoten" data-field="zeige_auf_rangliste" <?= $n['zeige_auf_rangliste'] ? 'checked' : '' ?>>
|
||||
<span class="checkbox-ui"></span>
|
||||
</label>
|
||||
</td>
|
||||
<td><input type="number" class="ajaxNoten" data-field="nullstellen" value="<?= htmlspecialchars($n['nullstellen'] ?? '') ?>" style="width: 100%; padding: 6px; border: 1px dashed #777; border-radius: 4px;"></td>
|
||||
<td><input type="text" class="ajaxNoten" data-field="prefix_display" value="<?= htmlspecialchars($n['prefix_display'] ?? '') ?>" style="width: 100%; padding: 6px; border: 1px dashed #777; border-radius: 4px;"></td>
|
||||
<td>
|
||||
<button class="deleteNoten" data-id="<?= $n['id'] ?>" style="border:none; background:none; cursor:pointer;">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="#b91c1c" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="3 6 5 6 21 6"></polyline><path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"></path></svg>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
<tr class="addRow">
|
||||
<td><input type="number" id="newNotenId" placeholder="Neue einzigartige ID..." style="width: 100%; padding: 6px; border: 1px solid #777; border-radius: 4px;"></td>
|
||||
<td><input type="text" id="newNotenName" placeholder="Neue Note..." style="width: 100%; padding: 6px; border: 1px solid #777; border-radius: 4px;"></td>
|
||||
|
||||
<td><button id="addNotenBtn" style="padding: 6px 12px; background: var(--bg-top); color: #fff; border: none; border-radius: 4px; cursor: pointer;">Hinzufügen</button></td>
|
||||
<td colspan="13"></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="settingsRow"><span>ID der Note, welche für die Berechnung der Ränge verwendet wird: </span><input type="number" class="ajaxInput" data-key="rangNote" placeholder="Bitte Eingeben…" value="<?= $rangNote ?>"></div>
|
||||
<div class="settingsRow">
|
||||
<span>Wert, welcher Rang 1 erhält: </span>
|
||||
<select class="ajaxInput" data-key="orderBestRang">
|
||||
<option disabled <?= ($orderBestRang !== "DESC" && $orderBestRang !== "ASC") ? "selected" : "" ?>>Bitte Auswählen…</option>
|
||||
<option value="DESC" <?= ($orderBestRang === "DESC") ? "selected" : "" ?>>Höchster Wert</option>
|
||||
<option value="ASC" <?= ($orderBestRang === "ASC") ? "selected" : "" ?>>Niedrigster Wert</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="containerDiv">
|
||||
<h3 class="containerHeading">Bilder:</h3>
|
||||
<div class="containerImages">
|
||||
<div><span>Kampfrichter: </span><label for="imgKampfrichter">Bild auswählen…</label><input type="file" data-key="Kampfrichter" accept="image/png, image/jpeg" id="imgKampfrichter"><img src="/intern/img/login/bgKampfrichter.webp"></div>
|
||||
<div><span>Trainer: </span><label for="imgTrainer">Bild auswählen…</label><input type="file" data-key="Trainer" accept="image/png, image/jpeg" id="imgTrainer"><img src="/intern/img/login/bgTrainer.webp"></div>
|
||||
<div><span>WK-Leitung: </span><label for="imgWk_leitung">Bild auswählen…</label><input type="file" data-key="Wk_leitung" accept="image/png, image/jpeg" id="imgWk_leitung"><img src="/intern/img/login/bgWk_leitung.webp"></div>
|
||||
<div><span>Einmal Login: </span><label for="imgOtl">Bild auswählen…</label><input type="file" data-key="Otl" accept="image/png, image/jpeg" id="imgOtl"><img src="/intern/img/login/bgOtl.webp"></div>
|
||||
<div><span>Icon Webseite: </span><label for="imgIcon">Bild auswählen…</label><input type="file" data-key="icon" accept="image/png, image/jpeg" id="imgIcon"><img src="/intern/img/icon.png"></div>
|
||||
<div><span>Logo: </span><label for="imgLogo_normal">Bild auswählen…</label><input type="file" data-key="logo-normal" accept="image/png, image/jpeg" id="imgLogo_normal"><img src="/intern/img/logo-normal.png"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="msgDiv"></div>
|
||||
</section>
|
||||
|
||||
<script>
|
||||
|
||||
let ws;
|
||||
|
||||
const $inputAnzahlTage = $('#anzahlTageWK');
|
||||
const $divTageInputs = $('#divTageInputs');
|
||||
|
||||
function displayNDayFields() {
|
||||
console.log('ja');
|
||||
const anzTageRoh = parseInt($inputAnzahlTage.val(), 10);
|
||||
const anzTage = anzTageRoh + 1;
|
||||
const $children = $divTageInputs.children();
|
||||
const anzChildren = $children.length + 1;
|
||||
|
||||
if (anzChildren < anzTage) {
|
||||
for(let i = anzChildren; i < anzTage; i++) {
|
||||
$divTageInputs.append($('<div class="settingsRow"><span for="' + i + '-wk-date">' + i + '. Wettkampftag: </span><input type="date" id="' + i + '-wk-date"></div>'));
|
||||
}
|
||||
} else if (anzChildren > anzTage) {
|
||||
for(let i = anzChildren; i > anzTage; i--) {
|
||||
$divTageInputs.find('div:last-child').remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
displayNDayFields();
|
||||
|
||||
$inputAnzahlTage.on('change', displayNDayFields);
|
||||
|
||||
const arrayWSSend = [
|
||||
'wkName',
|
||||
'displayColourLogo',
|
||||
'displayTextColourLogo',
|
||||
'displayColorScoringBg',
|
||||
'displayColorScoringBgSoft',
|
||||
'displayColorScoringPanel',
|
||||
'displayColorScoringPanelSoft',
|
||||
'displayColorScoringPanelText',
|
||||
'displayColorScoringPanelTextSoft',
|
||||
'displayColorScoringPanelTextNoteL',
|
||||
'displayColorScoringPanelTextNoteR'
|
||||
];
|
||||
|
||||
$('input[type="file"][data-key]').on('change', function() {
|
||||
const $input = $(this);
|
||||
const file = this.files[0];
|
||||
const type = $input.data('key');
|
||||
|
||||
if (!file) return;
|
||||
|
||||
const formData = new FormData();
|
||||
formData.append('image', file);
|
||||
formData.append('type', type);
|
||||
|
||||
$('.msgDiv').html('<p style="color: #007bff; font-weight: 500;">Wird hochgeladen...</p>');
|
||||
$input.closest('div').css('opacity', '0.5');
|
||||
|
||||
$.ajax({
|
||||
url: '/intern/scripts/einstellungen/ajax-upload-image.php',
|
||||
type: 'POST',
|
||||
data: formData,
|
||||
processData: false,
|
||||
contentType: false,
|
||||
success: function(response) {
|
||||
$input.closest('div').css('opacity', '1');
|
||||
if (response.success) {
|
||||
$('.msgDiv').html('<p style="color: #28a745; font-weight: 500;">Bild "' + type + '" erfolgreich aktualisiert!</p>');
|
||||
setTimeout(() => { $('.msgDiv').fadeOut(500, function() { $(this).empty().show(); }); }, 3000);
|
||||
const timestamp = new Date().getTime();
|
||||
|
||||
if (type === 'icon') {
|
||||
$input.parent().find('img').attr('src', '/intern/img/icon.png?t=' + timestamp);
|
||||
} else if (type === 'logo-normal') {
|
||||
$input.parent().find('img').attr('src', '/intern/img/logo-normal.png?t=' + timestamp);
|
||||
ws.send(JSON.stringify({type: 'EINSTELLUNGEN_DISPLAY_UPDATE', payload: {key: type, value: null}}));
|
||||
} else {
|
||||
$input.parent().find('img').attr('src', '/intern/img/login/bg' + type + '.webp?t=' + timestamp);
|
||||
}
|
||||
} else {
|
||||
$('.msgDiv').html('<p style="color: #dc3545; font-weight: 500;">Fehler: ' + response.message + '</p>');
|
||||
}
|
||||
},
|
||||
error: function(xhr) {
|
||||
$input.closest('div').css('opacity', '1');
|
||||
$('.msgDiv').html('<p style="color: #dc3545; font-weight: 500;">Kritischer Fehler beim Hochladen.</p>');
|
||||
console.error(xhr);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$('.ajaxInput').on('change', function() {
|
||||
const $input = $(this);
|
||||
const val = $input.val();
|
||||
const type = $input.data('key');
|
||||
|
||||
if (!val) return;
|
||||
|
||||
$.ajax({
|
||||
url: '/intern/scripts/einstellungen/ajax-change-value.php',
|
||||
type: 'POST',
|
||||
data: {
|
||||
type: type,
|
||||
value: val
|
||||
},
|
||||
success: function(response) {
|
||||
|
||||
if (response.success) {
|
||||
if (arrayWSSend.includes(type)) {
|
||||
ws.send(JSON.stringify({type: 'EINSTELLUNGEN_DISPLAY_UPDATE', payload: {key: type, value: val}}));
|
||||
}
|
||||
} else {
|
||||
|
||||
}
|
||||
},
|
||||
error: function(xhr) {
|
||||
$input.closest('div').css('opacity', '1');
|
||||
$('.msgDiv').html('<p style="color: #dc3545; font-weight: 500;">Kritischer Fehler beim Hochladen.</p>');
|
||||
console.error(xhr);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Gerate management
|
||||
$(document).on('change', '.ajaxGeraete', function() {
|
||||
const $input = $(this);
|
||||
const id = $input.closest('tr').data('id');
|
||||
const field = $input.data('field');
|
||||
const value = $input.val();
|
||||
|
||||
$.ajax({
|
||||
url: '/intern/scripts/einstellungen/ajax-gereate-management.php',
|
||||
type: 'POST',
|
||||
data: { action: 'update', id: id, field: field, value: value },
|
||||
success: function(response) {
|
||||
if (response.success) {
|
||||
displayMsg(1, "Gerät aktualisiert");
|
||||
} else {
|
||||
displayMsg(0, "Fehler: " + response.message);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$(document).on('click', '#addGeraeteBtn', function() {
|
||||
const name = $('#newGeraeteName').val();
|
||||
const index = $('#newGeraeteIndex').val();
|
||||
const color = $('#newGeraeteColor').val();
|
||||
|
||||
if (!name) {
|
||||
displayMsg(0, "Name erforderlich");
|
||||
return;
|
||||
}
|
||||
|
||||
$.ajax({
|
||||
url: '/intern/scripts/einstellungen/ajax-gereate-management.php',
|
||||
type: 'POST',
|
||||
data: { action: 'add', name: name, start_index: index, color: color },
|
||||
success: function(response) {
|
||||
if (response.success) {
|
||||
window.location.reload();
|
||||
} else {
|
||||
displayMsg(0, "Fehler: " + response.message);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$(document).on('click', '.deleteGeraete', function() {
|
||||
if (!confirm("Gerät wirklich löschen?")) return;
|
||||
const id = $(this).data('id');
|
||||
const $tr = $(this).closest('tr');
|
||||
|
||||
$.ajax({
|
||||
url: '/intern/scripts/einstellungen/ajax-gereate-management.php',
|
||||
type: 'POST',
|
||||
data: { action: 'delete', id: id },
|
||||
success: function(response) {
|
||||
if (response.success) {
|
||||
$tr.remove();
|
||||
displayMsg(1, "Gerät gelöscht");
|
||||
} else {
|
||||
displayMsg(0, "Fehler: " + response.message);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Noten management
|
||||
$(document).on('change', '.ajaxNoten', function() {
|
||||
const $input = $(this);
|
||||
const id = $input.closest('tr').data('id');
|
||||
const field = $input.data('field');
|
||||
let value = $input.val();
|
||||
|
||||
if ($input.attr('type') === 'checkbox') {
|
||||
value = $input.is(':checked') ? 1 : 0;
|
||||
}
|
||||
|
||||
$.ajax({
|
||||
url: '/intern/scripts/einstellungen/ajax-noten-management.php',
|
||||
type: 'POST',
|
||||
data: { action: 'update', id: id, field: field, value: value },
|
||||
success: function(response) {
|
||||
if (response.success) {
|
||||
displayMsg(1, "Note aktualisiert");
|
||||
} else {
|
||||
displayMsg(0, "Fehler: " + response.message);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$(document).on('click', '#addNotenBtn', function() {
|
||||
const id = $('#newNotenId').val();
|
||||
const name = $('#newNotenName').val();
|
||||
const type_val = $('#newNotenType').val();
|
||||
const berechnung = $('#newNotenBerechnung').val();
|
||||
const pro_geraet = $('#newNotenProGeraet').is(':checked') ? 1 : 0;
|
||||
|
||||
if (!name) {
|
||||
displayMsg(0, "Name erforderlich");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!id) {
|
||||
displayMsg(0, "Id erforderlich");
|
||||
return;
|
||||
}
|
||||
|
||||
$.ajax({
|
||||
url: '/intern/scripts/einstellungen/ajax-noten-management.php',
|
||||
type: 'POST',
|
||||
data: { action: 'add', id: id, name: name, type_val: type_val, berechnung: berechnung, pro_geraet: pro_geraet },
|
||||
success: function(response) {
|
||||
if (response.success) {
|
||||
window.location.reload();
|
||||
} else {
|
||||
displayMsg(0, "Fehler: " + response.message);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$(document).on('click', '.deleteNoten', function() {
|
||||
if (!confirm("Note wirklich löschen?")) return;
|
||||
const id = $(this).data('id');
|
||||
const $tr = $(this).closest('tr');
|
||||
|
||||
$.ajax({
|
||||
url: '/intern/scripts/einstellungen/ajax-noten-management.php',
|
||||
type: 'POST',
|
||||
data: { action: 'delete', id: id },
|
||||
success: function(response) {
|
||||
if (response.success) {
|
||||
$tr.remove();
|
||||
displayMsg(1, "Note gelöscht");
|
||||
} else {
|
||||
displayMsg(0, "Fehler: " + response.message);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
let firstConnect = true;
|
||||
const RETRY_DELAY = 2000;
|
||||
|
||||
const urlAjaxNewWSToken = '/intern/scripts/ajax-create-ws-token.php';
|
||||
|
||||
async function fetchNewWSToken(freigabe) {
|
||||
try {
|
||||
const response = await fetch(urlAjaxNewWSToken, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
'Content-Type': 'application/x-www-form-urlencoded',
|
||||
},
|
||||
body: new URLSearchParams({ access: freigabe })
|
||||
});
|
||||
|
||||
if (!response.ok) return null;
|
||||
|
||||
const data = await response.json();
|
||||
return data.success ? data.token : null;
|
||||
} catch (error) {
|
||||
console.error("Token fetch failed:", error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async function startWebSocket() {
|
||||
console.log("Attempting WebSocket connection...");
|
||||
|
||||
let token;
|
||||
if (firstConnect) {
|
||||
token = '<?= generateWSToken('einstellungen') ?>';
|
||||
} else {
|
||||
token = await fetchNewWSToken('einstellungen');
|
||||
}
|
||||
|
||||
if (!token) {
|
||||
console.error("No valid token available. Retrying...");
|
||||
scheduleRetry();
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
ws = new WebSocket(`wss://${window.location.hostname}/ws/?access=token&token=${token}`);
|
||||
} catch (err) {
|
||||
console.error("Malformed WebSocket URL", err);
|
||||
scheduleRetry();
|
||||
return;
|
||||
}
|
||||
|
||||
ws.onopen = () => {
|
||||
console.log("WebSocket connected!");
|
||||
if (!firstConnect) {
|
||||
displayMsg(1, "Live Syncronisation wieder verfügbar");
|
||||
}
|
||||
firstConnect = true;
|
||||
};
|
||||
|
||||
ws.onerror = (event) => {
|
||||
console.error("WebSocket error observed.");
|
||||
};
|
||||
|
||||
ws.onclose = (event) => {
|
||||
displayMsg(0, "Live Syncronisation verloren");
|
||||
firstConnect = false;
|
||||
|
||||
scheduleRetry();
|
||||
};
|
||||
}
|
||||
|
||||
function scheduleRetry() {
|
||||
console.log(`Retrying in ${RETRY_DELAY}ms...`);
|
||||
setTimeout(startWebSocket, RETRY_DELAY);
|
||||
}
|
||||
|
||||
startWebSocket();
|
||||
</script>
|
||||
<?php endif; ?>
|
||||
Reference in New Issue
Block a user