New Filestructure for Docker
This commit is contained in:
@@ -0,0 +1,431 @@
|
||||
<?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; ?>
|
||||
Reference in New Issue
Block a user