Files

431 lines
17 KiB
PHP

<?php
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
if (!isset($baseDir)) {
$baseDir = $_SERVER['DOCUMENT_ROOT'];
}
require_once $baseDir . '/../scripts/session_functions.php';
ini_wkvs_session(true);
$csrf_token = $_SESSION['csrf_token'] ?? '';
$access_granted_wkl = check_user_permission('wk_leitung', true) ?? false;
if (!$access_granted_wkl):
$logintype = 'wk_leitung';
require $baseDir . '/../scripts/login/login.php';
$logintype = '';
else:
?>
<!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 - Wettkämpfe</title>
<link rel="stylesheet" href="/intern/css/einstellungen-ai.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">
<link rel="stylesheet" href="/intern/css/user.css">
<link rel="stylesheet" href="/externe-geraete/css/display.css">
<script src="/intern/js/ace/ace.js"></script>
<link rel="stylesheet" href="/intern/css/coloris/coloris.min.css" />
<script src="/intern/js/coloris/coloris.min.js"></script>
</head>
<body class="wettkaempfe">
<?php
require $baseDir . '/../scripts/db/db-functions.php';
require $baseDir . '/../scripts/db/db-tables.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 = 'wettkaempfe';
require $baseDir . '/../scripts/sidebar/sidebar.php';
$wettkaempfe = db_select($mysqli, $db_tabelle_wettkaempfe, '*', '', [], 'id ASC');
$current_wk_id = (int) db_get_variable($mysqli, $db_tabelle_var, ['current_wk_id']) ?: 0;
?>
<section class="bgSection">
<?php sidebarRender('modal'); ?>
<div class="headerDivTrainer">
<div class="headingPanelDiv">
<h2 class="headingPanel">Wettkämpfe</h2>
</div>
<div class="menuWrapper">
<?php sidebarRender('button'); ?>
</div>
</div>
<div class="dashboardGrid">
<div class="containerDiv">
<div>
<h3 class="containerHeading">Wettkämpfe</h3>
<table id="programmTable" class="wkvsTabelle">
<thead>
<tr>
<th>Wettkampf ID</th>
<th>Name</th>
<th>Slug</th>
<th>Status</th>
<th>Löschen</th>
</tr>
</thead>
<tbody>
<?php foreach ($wettkaempfe as $s_wk) :
$aktiv = ((int) $s_wk['id'] === $current_wk_id); ?>
<tr>
<td><?= (int) $s_wk['id'] ?></td>
<td>
<input class="ajaxInput" data-type="name" data-id="<?= (int) $s_wk['id'] ?>" value="<?= htmlspecialchars($s_wk['name'] ?? '') ?>">
</td>
<td>
<input class="ajaxInput" data-type="slug" data-id="<?= (int) $s_wk['id'] ?>" value="<?= htmlspecialchars($s_wk['slug'] ?? '') ?>">
</td>
<td>
<span class="statusSpan <?= $aktiv ? 'activeWk' : 'inactiveWk' ?>"><?= $aktiv ? 'Aktiv' : 'Inaktiv' ?></span>
<span class="activateSpan <?= $aktiv ? 'hidden' : '' ?>" data-id="<?= (int) $s_wk['id'] ?>">Aktivieren</span>
</td>
<td>
<button class="deleteWk deleteBtn" data-id="<?= (int) $s_wk['id'] ?>">
<svg xmlns="http://www.w3.org/2000/svg" width="22" height="22"
viewBox="0 0 24 24" fill="none" stroke="var(--ui-danger)"
stroke-width="1.75" 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>
<line x1="10" y1="11" x2="10" y2="17"></line>
<line x1="14" y1="11" x2="14" y2="17"></line>
</svg>
</button>
</td>
</tr>
<?php endforeach; ?>
<tr class="addRow">
<td></td>
<td>
<input type="text" required placeholder="Bezeichnung" class="inputNewWkName">
</td>
<td>
<input type="text" required placeholder="Bsp. wkvs-2026" class="inputNewWkSlug">
</td>
<td colspan="2">
<button type="submit" class="blackBtn neuWkBtn">Neuen Wettkampf erstellen</button>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="msgDiv"></div>
</section>
<script>
const csrf_token = "<?= $csrf_token ?>";
$('.neuWkBtn').on('click', function () {
const $btn = $(this);
const $row = $btn.closest(".addRow");
const $nameInput = $row.find(".inputNewWkName");
const $slugInput = $row.find(".inputNewWkSlug");
if ($nameInput.length !== 1 || $slugInput.length !== 1) return;
const name = $nameInput.val().trim();
if (name === '') {
displayMsg(2, "Der Wettkampfname darf nicht leer sein");
return;
}
const slug = $slugInput.val().trim();
if (slug === '') {
displayMsg(2, "Der Slug darf nicht leer sein");
return;
}
if (/\s/.test(slug)) {
displayMsg(2, "Der Slug darf keine Leerzeichen enthalten");
return;
}
if (!/^[a-z0-9-]+$/.test(slug)) {
displayMsg(2, "Der Slug darf nur Kleinbuchstaben, Zahlen und Bindestriche enthalten");
return;
}
$.ajax({
url: '/intern/scripts/wettkaempfe/ajax-add-wettkampf.php',
type: "POST",
data: {
csrf_token,
name,
slug
},
success: function(response) {
if (!response.success) {
displayMsg(0, response.message || "Der Wettkampf konnte nicht hinzugefügt werden");
return;
}
const $newRow = $('<tr>', {});
// 1. ID Column (Plain text)
const $tdId = $('<td>', { text: response.id });
// 2. Name Column (with nested <input>)
const $tdName = $('<td>');
const $inputName = $('<input>', {
class: 'ajaxInput',
'data-type': 'name',
'data-id': response.id,
val: name // Sets the input value securely
});
$tdName.append($inputName);
// 3. Slug Column (with nested <input>)
const $tdSlug = $('<td>');
const $inputSlug = $('<input>', {
class: 'ajaxInput',
'data-type': 'slug',
'data-id': response.id,
val: slug // Sets the input value securely
});
$tdSlug.append($inputSlug);
// 4. Empty Column
const $tdStatus = $('<td>', {});
const $spanStatus = $('<span>', {
text: 'Inaktiv',
class: "statusSpan inactiveWk"
});
const $spanActivate = $('<span>', {
text: 'aktivieren',
'data-id': response.id,
class: "activateSpan"
});
$tdStatus.append($spanStatus, $spanActivate);
// 5. Action Column (Delete button with SVG)
const $tdAction = $('<td>', {});
const $deleteBtn = $('<button>', {
class: 'deleteWk deleteBtn',
'data-id': response.id
});
const $svgIcon = $(`
<svg xmlns="http://www.w3.org/2000/svg" width="22" height="22"
viewBox="0 0 24 24" fill="none" stroke="var(--ui-danger)"
stroke-width="1.75" 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>
<line x1="10" y1="11" x2="10" y2="17"></line>
<line x1="14" y1="11" x2="14" y2="17"></line>
</svg>
`);
$deleteBtn.append($svgIcon);
$tdAction.append($deleteBtn);
// 6. Assemble everything
$newRow.append($tdId, $tdName, $tdSlug, $tdStatus, $tdAction);
// 7. Insert into the DOM
// Note: If you want to insert the new row *before* an existing row ($row), use this:
$newRow.insertBefore($row);
displayMsg(1, "Neuer Wettkampf hinzugefügt");
},
error: () => {
displayMsg(0, "Fehler beim Hinzufügen des Wettkampfes");
}
});
});
$(document).on('click', '.deleteWk', async function () {
const $btn = $(this);
const $row = $btn.closest("tr");
const name = $row.find('.ajaxInput[data-type="name"]').val() || '';
if (!await displayConfirm(`Wettkampf "${name}" wirklich unwiederruflich löschen? Diese Aktion löscht alle Ergebnisse dieses Wettkampfes!`)) return;
const dataId = $btn.data('id');
$.ajax({
url: '/intern/scripts/wettkaempfe/ajax-delete-wettkampf.php',
type: "DELETE",
data: {
csrf_token,
id: dataId
},
success: function(response) {
if (!response.success) {
displayMsg(0, response.message || "Der Wettkampf konnte nicht gelöscht werden");
return;
}
$row.remove();
displayMsg(1, "Wettkampf gelöscht");
},
error: () => {
displayMsg(0, "Fehler beim Löschen des Wettkampfes");
}
});
});
$(document).on('change', '.ajaxInput', function () {
const $input = $(this);
const value = $input.val().trim();
const inputType = $input.data('type');
const dataId = $input.data('id');
if (value === '') {
displayMsg(2, "Dieses Feld darf nicht leer sein");
return;
}
if (inputType === "slug") {
if (/\s/.test(value)) {
displayMsg(2, "Der Slug darf keine Leerzeichen enthalten");
return;
}
if (!/^[a-z0-9-]+$/.test(value)) {
displayMsg(2, "Der Slug darf nur Kleinbuchstaben, Zahlen und Bindestriche enthalten");
return;
}
}
$.ajax({
url: '/intern/scripts/wettkaempfe/ajax-update-wettkampf.php',
type: "POST",
data: {
csrf_token,
id: dataId,
value,
inputType
},
success: function(response) {
if (!response.success) {
displayMsg(0, response.message || "Wert konnte nicht geändert werden");
return;
}
displayMsg(1, "Wert geändert");
},
error: () => {
displayMsg(0, "Fehler beim Ändern des Wertes");
}
});
});
$(document).on('click', '.activateSpan', async function() {
const $btn = $(this);
const dataId = $btn.data('id');
if (!await displayConfirm(`Das wechseln des Wettkampfes lädt alle Daten in der Kampfrichteransicht und RankLive neu.`)) return;
$.ajax({
url: '/intern/scripts/wettkaempfe/ajax-update-aktiv-wettkampf.php',
type: "POST",
data: {
csrf_token,
id: dataId
},
success: function(response) {
if (!response.success) {
displayMsg(0, response.message || "Aktiver Wettkampf konnte nicht geändert werden");
return;
}
const $tbody = $btn.closest('tbody');
// 1. Show ALL activation triggers in the table again
$tbody.find('.activateSpan').removeClass('hidden');
// 2. Hide only the trigger that was just clicked
$btn.addClass('hidden');
// 3. Find the single currently active swatch and turn it inactive
$tbody.find('.statusSpan.activeWk')
.removeClass('activeWk')
.addClass('inactiveWk')
.text('Inaktiv');
// 4. Find the swatch in the CURRENT row and turn it active
// (Using .closest('tr') ensures we look inside the same row)
$btn.closest('tr')
.find('.statusSpan')
.removeClass('inactiveWk')
.addClass('activeWk')
.text('Aktiv');
displayMsg(1, "Aktiver Wettkampf wurde gewechselt");
},
error: () => {
displayMsg(0, "Fehler beim Ändern des aktiven Wettkampfes");
}
});
});
</script>
</body>
</html>
<?php endif; ?>