Files
WKVS/www/intern/wk-leitung/logindata.php
2026-04-12 21:25:44 +02:00

1012 lines
36 KiB
PHP

<?php
use Dotenv\Dotenv;
if (session_status() !== PHP_SESSION_ACTIVE) session_start();
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);
$access_granted_wkl = $_SESSION['access_granted_wk_leitung'] ?? false;
if (!isset($baseDir)) {
$baseDir = $_SERVER['DOCUMENT_ROOT'];
}
if ( ! $access_granted_wkl ) :
$logintype = 'wk_leitung';
require $baseDir . '/../scripts/login/login.php';
$logintype = '';
else :
echo '<link rel="icon" type="png" href="/intern/img/icon.png">';
require $baseDir . '/../scripts/db/db-functions.php';
require $baseDir . '/../scripts/db/db-tables.php';
require $baseDir . '/../scripts/csrf_functions.php';
$type = 'wkl';
$dbconnection = require $baseDir . '/../scripts/db/db-verbindung-script.php';
if ($dbconnection['success'] !== true){
echo 'Critical DB Error.';
exit;
}
require $baseDir . '/../composer/vendor/autoload.php';
$envFile = realpath($baseDir . '/../config/.env.pw-encryption-key');
if ($envFile === false) {
http_response_code(500);
echo json_encode([
'success' => false,
'message' => "Environment file not found"
]);
exit;
}
try {
$envDir = dirname($envFile);
$dotenv = Dotenv::createImmutable($envDir, '.env.pw-encryption-key');
$dotenv->load();
} catch (Throwable $e) {
http_response_code(500);
echo json_encode([
'success' => false,
'message' => "Dotenv error"
]);
}
?>
<!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 - Logindata</title>
<link rel="stylesheet" href="/files/fonts/fonts.css">
<link rel="stylesheet" href="/intern/css/logindata.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/qr-code/qrcode.min.js"></script>
<script src="/intern/js/custom-msg-display.js"></script>
<link rel="stylesheet" href="/intern/css/custom-msg-display.css">
</head>
<body>
<?php
$currentPage = 'logindata';
require $baseDir . '/intern/scripts/sidebar/sidebar.php';
?>
<!-- Loading Overlay -->
<div id="loading-overlay">
<div>Aktualisiere...</div>
</div>
<div id="oturldiv" class="ot-modal">
<div class="ot-modal-content">
<div class="ot-modal-top-content">
<div class="ot-title">One-Time Login URL:</div>
<button id="otClose" class="ot-close-btn">✕</button>
</div>
<a id="aOturl" class="ot-url" target="_blank" href="/"></a>
<p id="oturlGb"></p>
<button id="otCopy" class="ot-copy-btn">Copy URL</button>
<div class="qrcodeWrapper">
<div id="qrcode"></div>
</div>
<button id="btnDownloadQRCode" class="ot-copy-btn">QR-Code herunterladen</button>
</div>
</div>
<script>
const otModal = document.getElementById("oturldiv");
const otUrl = document.getElementById("aOturl");
const otCopy = document.getElementById("otCopy");
const otClose = document.getElementById("otClose");
function showOneTimeUrl(fullUrl) {
otUrl.innerHTML = fullUrl;
otUrl.href = fullUrl;
otModal.style.display = "flex";
}
otCopy.addEventListener("click", () => {
navigator.clipboard.writeText(otUrl.href)
.then(() => {
otCopy.innerText = "Copied!";
setTimeout(() => otCopy.innerText = "Copy URL", 1500);
});
});
otClose.addEventListener("click", () => {
otModal.style.display = "none";
});
otModal.addEventListener("click", (e) => {
if (e.target === otModal) otModal.style.display = "none";
});
</script>
<!-- Loading Overlay -->
<div id="new-overlay">
<div>Füge Benutzer hinzu...</div>
</div>
<!-- Reload Overlay -->
<div id="new-reload">
<div>Seite wird neu geladen...</div>
</div>
<!-- Success Overlay -->
<div id="success-overlay" class="divSucsess">
<span class="textSucsess">Success!</span>
</div>
<!-- Error Overlay -->
<div id="error-overlay" class="divError">
<span class="textError">Error!</span>
</div>
<div class="headerDivTrainer">
<div class="headingPanelDiv">
<h2 class="headingPanel">Benutzerverwaltung</h2>
</div>
<?php sidebarRender('button'); ?>
</div>
<?php sidebarRender('modal'); ?>
<section class="bgSection">
<div class="bg-erfassen">
<div id="secure-password-msg"></div>
<form id="secure-password-form-new">
<input type="hidden" id="username-new" name="username" value="Neuer Benutzer">
<input type="hidden" id="password-new" name="password" value="TemporaeresPasswort">
<input type="hidden" id="nonce-new" value="<?php echo csrf_token(); ?>">
<input type="hidden" id="field_id-new" name="field_id" value="0">
<button type="submit">Neuer Benutzer</button>
</form>
</div>
<?php
$stmt = $mysqli->prepare("SELECT `name` FROM $tableGeraete ORDER BY start_index ASC");
if (!$stmt->execute()) {
http_response_code(500);
exit;
}
$result = $stmt->get_result();
$disciplines = array_map(
'strtolower',
array_column($result->fetch_all(MYSQLI_ASSOC), 'name')
);
$stmt->close();
$vereine = db_select($mysqli, $tableVereine, "id, verein, email", '', [], 'verein ASC');
$entrys = db_select($mysqli, $tableInternUsers, "id, username, password_cipher, freigabe", '', [], 'username ASC');
echo '<h3 class="benutzer">Benutzer</h3><section class="inner-pw-set-bg" id="section-benutzer">';
foreach ($entrys as $entry){
$freigabe_values = json_decode($entry['freigabe'], true) ?: [];
$freigaben_types = $freigabe_values['types'] ?? [];
$freigabenTrainer = (in_array('trainer', $freigaben_types)) ? $freigabe_values['freigabenTrainer'] : [];
$freigabenKampfrichter = (in_array('kampfrichter', $freigaben_types)) ? $freigabe_values['freigabenKampfrichter'] : [];
$decrypted_password = '';
if ($entry && $entry['password_cipher']) {
$data = base64_decode($entry['password_cipher']);
$iv_length = openssl_cipher_iv_length('aes-256-cbc');
$iv = substr($data, 0, $iv_length);
$encrypted = substr($data, $iv_length);
$decrypted_password = openssl_decrypt($encrypted, 'aes-256-cbc', $_ENV['PW_ENCRYPTION_KEY'], 0, $iv);
}
// Count active permissions per section
$role_keys = ['wk_leitung', 'trainer', 'kampfrichter'];
$active_roles = array_intersect($role_keys, $freigaben_types);
$active_disciplines = array_intersect($disciplines, $freigabenKampfrichter);
$active_vereine_list = array_intersect(array_column($vereine, 'verein'), $freigabenTrainer);
echo '<div class="single_pwedit" id="div-single_pwedit-'.$entry['id'].'">';
?>
<form id="secure-password-form-<?php echo $entry['id']; ?>">
<div class="field-group">
<label for="username-<?php echo $entry['id']; ?>">Benutzername</label>
<input type="text" id="username-<?php echo $entry['id']; ?>" name="username" value="<?php echo $entry['username']; ?>" required>
</div>
<div class="field-group">
<label for="password-<?php echo $entry['id']; ?>">Passwort</label>
<?php if ($decrypted_password === 'SET_BY_OTL'){
echo '<input type="text" id="password-'.$entry['id'].'" name="password" value="" placeholder="Passwort durch Benutzer gesetzt">';
} else {
echo '<input type="text" id="password-'.$entry['id'].'" name="password" value="'. $decrypted_password.'" required>';
} ?>
</div>
<!-- Permission dropdown: Zugang (Roles) -->
<div class="perm-section perm-section-types open" id="perm-zugang-<?php echo $entry['id']; ?>">
<div class="perm-section-header" onclick="this.parentElement.classList.toggle('open')">
<span class="perm-section-title">
Zugang
<span class="perm-badge" id="badge-zugang-<?php echo $entry['id']; ?>"><?php echo count($active_roles); ?></span>
</span>
<svg class="perm-section-chevron" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M6 9l6 6 6-6"/></svg>
</div>
<div class="perm-section-body">
<label>
<input type="checkbox" name="freigabe[]" value="wk_leitung"
<?php echo in_array('wk_leitung', $freigaben_types) ? 'checked' : ''; ?>>
WK-Leitung
</label>
<label>
<input type="checkbox" name="freigabe[]" value="trainer"
<?php echo in_array('trainer', $freigaben_types) ? 'checked' : ''; ?>>
Trainer
</label>
<label>
<input type="checkbox" name="freigabe[]" value="kampfrichter"
<?php echo in_array('kampfrichter', $freigaben_types) ? 'checked' : ''; ?>>
Kampfrichter
</label>
</div>
</div>
<!-- Permission dropdown: Trainer Vereine -->
<div class="perm-section perm-section-trainer" id="perm-tr-<?php echo $entry['id']; ?>">
<div class="perm-section-header" onclick="this.parentElement.classList.toggle('open')">
<span class="perm-section-title">
Trainer Vereine
<span class="perm-badge" id="badge-tr-<?php echo $entry['id']; ?>"><?php echo count($active_vereine_list); ?></span>
</span>
<svg class="perm-section-chevron" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M6 9l6 6 6-6"/></svg>
</div>
<div class="perm-section-body">
<label>
<input type="checkbox" name="freigabeTrainer[]" value="admin"
<?php echo in_array('admin', $freigabenTrainer) ? 'checked' : ''; ?>>
Admin (alle Vereine)
</label>
<?php foreach ($vereine as $verein): ?>
<label>
<input type="checkbox" name="freigabeTrainer[]" value="<?php echo $verein['verein']; ?>"
<?php echo in_array($verein['verein'], $freigabenTrainer) ? 'checked' : ''; ?>>
<?php echo ucfirst($verein['verein']); ?>
</label>
<?php endforeach; ?>
</div>
</div>
<!-- Permission dropdown: Kampfrichter Geräte -->
<div class="perm-section perm-section-kampfrichter" id="perm-kr-<?php echo $entry['id']; ?>">
<div class="perm-section-header" onclick="this.parentElement.classList.toggle('open')">
<span class="perm-section-title">
Kampfrichter Geräte
<span class="perm-badge" id="badge-kr-<?php echo $entry['id']; ?>"><?php echo count($active_disciplines); ?></span>
</span>
<svg class="perm-section-chevron" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M6 9l6 6 6-6"/></svg>
</div>
<div class="perm-section-body">
<label>
<input type="checkbox" name="freigabeKampfrichter[]" value="admin"
<?php echo in_array('admin', $freigabenKampfrichter) ? 'checked' : ''; ?>>
Admin (alle Geräte)
</label>
<?php foreach ($disciplines as $discipline): ?>
<label>
<input type="checkbox" name="freigabeKampfrichter[]" value="<?php echo $discipline; ?>"
<?php echo in_array($discipline, $freigabenKampfrichter) ? 'checked' : ''; ?>>
<?php echo ucfirst($discipline); ?>
</label>
<?php endforeach; ?>
</div>
</div>
<button type="submit">Benutzer aktualisieren</button>
<input type="hidden" id="nonce-<?php echo $entry['id']; ?>" value="<?php echo csrf_token(); ?>">
<input type="hidden" id="field_id-<?php echo $entry['id']; ?>" name="field_id" value="<?php echo intval($entry['id']); ?>">
</form>
<button
id="delete-user-<?php echo intval($entry['id']); ?>"
class="delete-user-btn"
data-id="<?php echo intval($entry['id']); ?>"
data-nonce="<?php echo csrf_token(); ?>"
type="button">
Benutzer löschen
</button>
<button
id="createOturl-<?php echo intval($entry['id']); ?>"
class="createOturl"
data-username="<?php echo $entry['username']; ?>"
data-id="<?php echo intval($entry['id']); ?>"
type="button">
Einmallogin erstellen
</button>
</div>
<?php
}
?>
</section>
<section class="containerSection">
<div>
<h3 class="vereine">Vereine</h3>
<table class="wkvsTabelle trainer">
<thead>
<tr>
<th>Verein</th>
<th>Speichern</th>
<th>Löschen</th>
</tr>
</thead>
<tbody>
<?php foreach ($vereine as $entryvaer): ?>
<tr id="div_verein-<?php echo $entryvaer['id']; ?>">
<form id="<?php echo $entryvaer['id']; ?>-verein">
<td>
<input type="text" id="verein-<?php echo $entryvaer['id']; ?>" name="verein" value="<?php echo htmlspecialchars($entryvaer['verein']); ?>" required style="padding: 6px 10px; border: 1px dashed #999; border-radius: 4px; font-size: 0.9rem; width: 100%;">
</td>
<td>
<button type="submit" style="padding: 6px 14px; border: 1px solid #7777778e; background: #7777778e; color: #fff; border-radius: 4px; font-size: 0.85rem; cursor: pointer; transition: all 0.2s;">Speichern</button>
<input type="hidden" id="nonceverein-<?php echo $entryvaer['id']; ?>" value="<?php echo csrf_token(); ?>">
<input type="hidden" id="field_idverein-<?php echo $entryvaer['id']; ?>" name="field_id" value="<?php echo intval($entryvaer['id']); ?>">
</td>
</form>
<td>
<button
id="delete-verein-<?php echo intval($entryvaer['id']); ?>"
class="delete-verein-btn deleteProgramm"
data-id="<?php echo intval($entryvaer['id']); ?>"
data-nonce="<?php echo csrf_token(); ?>"
type="button" style="border:none; background:none; cursor:pointer;">
<svg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" style="color: #b91c1c;">
<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; ?>
<!-- Row for creating a new Verein -->
<tr id="div_verein-new" class="addRow">
<form id="new-verein">
<td>
<input type="text" id="verein-new" name="verein" placeholder="Neuer Verein..." required>
</td>
<td>
<button type="submit">Hinzufügen</button>
<input type="hidden" id="nonceverein-new" value="<?php echo csrf_token(); ?>">
<input type="hidden" id="field_idverein-new" name="field_id" value="0">
</td>
</form>
<td></td> <!-- No delete button for the new row -->
</tr>
</tbody>
</table>
</div>
</section>
<section class="containerSection">
<div>
<h3 class="vereine">Programme</h3>
<table id="programmTable" class="wkvsTabelle trainer">
<thead>
<tr>
<th>Programm</th>
<th>Aktiv</th>
<th>Startgebüren</th>
<th>Löschen</th>
</tr>
</thead>
<tbody>
<?php
$programme = db_select($mysqli, $tableProgramme, "*", '', [], 'programm ASC');
if (isset($programme) && is_array($programme) && count($programme) > 0){
foreach ($programme as $entry){
$aktiv = ($entry['aktiv'] == 1) ? 'checked' : '';
echo '<tr>
<td>'.$entry['programm'].'</td>
<td>
<label class="checkbox">
<input type="checkbox" class="anmeldencheckbox inputAktivProgramm" '.$aktiv.' data-field-id="'.$entry['id'].'"/>
<span class="checkbox-ui"></span>
</label>
</td>
<td>CHF <input type="number" class="inputPreisProgramm" data-field-id="'.$entry['id'].'" value='.$entry['preis'].'></td>
<td>
<button class="deleteProgramm"
data-field-id="'.$entry['id'].'">
<svg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="var(--accent)" 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>';
}
}
?>
<tr class="addRow">
<td><input type="text" required placeholder="Programmname" class="inputProgrammName"></td>
<td colspan="2"></td>
<td><button type="submit" class="neuProgrammBtn">Neues Programm erstellen</button></td>
</tr>
</tbody>
</table>
</div>
</section>
</section>
<script>
jQuery(document).ready(function($) {
$(document).on('change', '.inputPreisProgramm', function() {
const $input = $(this);
const url = `/intern/scripts/logindata/ajax-update_programm_preis.php` +
`?id=${encodeURIComponent($input.data('field-id'))}` +
`&value=${encodeURIComponent($input.val())}` +
`&token=k7uweziEUWZiJhwe7687UWIQZ28SQIH2ug74pINKyxHxPerB6wUZ`;
fetch(url)
.then(response => response.json())
.then(data => {
if (data.success) {
displayMsg(1, 'Startgebühr erfolgreich aktualisiert');
} else {
displayMsg(0, 'Startgebühr konnte nicht aktualisiert werden');
}
})
.catch(err => {
displayMsg(0, 'Startgebühr konnte nicht aktualisiert werden');
console.error('AJAX fetch error:', err);
});
});
$(document).on('change', '.inputAktivProgramm', function() {
const $input = $(this);
const url = `/intern/scripts/logindata/ajax-update_programm_aktiv.php` +
`?id=${encodeURIComponent($input.data('field-id'))}` +
`&value=${encodeURIComponent($input.is(':checked') ? 1 : 0)}` +
`&token=0UgBVHutbxTRTYsB04ujFKMjMRA8GgdqRJjVh3DKU1LRJfwtcDfrpDc7jpMxcrg9rYurAEwYPy5gu15R77MsgKsDMkFZEykx0A67`;
fetch(url)
.then(response => response.json())
.then(data => {
if (data.success) {
displayMsg(1, 'Programmstatus erfolgreich geändert');
} else {
displayMsg(0, 'Programmstatus konnte nicht geändert werden');
}
})
.catch(err => {
displayMsg(0, 'Programmstatus konnte nicht geändert werden');
console.error('AJAX fetch error:', err);
});
});
function rebuildProgrammeTable(programmes) {
const $tableBody = $('#programmTable tbody');
const $inputRow = $tableBody.find('tr.addRow');
const $input = $inputRow.find('.inputProgrammName');
$input.val('');
$tableBody.empty();
programmes.forEach(entry => {
const aktiv = entry.aktiv === 1 ? 'checked' : '';
const row = `
<tr>
<td>${entry.programm}</td>
<td>
<label class="checkbox">
<input type="checkbox" class="anmeldencheckbox inputAktivProgramm" ${aktiv} data-field-id="${entry.id}"/>
<span class="checkbox-ui"></span>
</label>
</td>
<td>
CHF <input type="number" class="inputPreisProgramm"
data-field-id="${entry.id}" step="0.01"
value="${entry.preis}">
</td>
<td>
<button class="deleteProgramm"
data-field-id="${entry.id}'">
<svg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="var(--accent)" 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>
`;
$tableBody.append(row);
});
$tableBody.append($inputRow);
}
$(document).on('click', '.neuProgrammBtn', async function(e) {
e.preventDefault();
const $input = $(this).closest('tr').find('.inputProgrammName');
let value = $input.val();
if (!value) {
displayMsg(0, 'Bitte Programmname eingeben');
return;
}
const url = `/intern/scripts/logindata/ajax-neu_programm.php` +
`?value=${encodeURIComponent(value)}` +
`&token=sWZ4GxbsoVhUPk5zhjH0uU9hets3zV2KsV8CZUvAWCCRk4uuuDr9vfFVgxWqr5FtDttbtm50EdWK9YxuMPswGZBQZFHAUAET1aG1`;
fetch(url)
.then(response => response.json())
.then(data => {
if (data.success) {
displayMsg(1, 'Programm erfolgreich hinzugefügt');
if (data.output) {
rebuildProgrammeTable(data.output);
}
} else {
displayMsg(0, 'Programm konnte nicht hinzugefügt werden');
}
})
.catch(err => {
displayMsg(0, 'Programm konnte nicht hinzugefügt werden');
console.error('AJAX fetch error:', err);
});
});
$(document).on('click', '.deleteProgramm', function() {
const $input = $(this);
const url = `/intern/scripts/logindata/ajax-remove_programm.php` +
`?id=${encodeURIComponent($input.data('field-id'))}` +
`&token=bKqBAPjwojZdarJaE7jwvRrIEf2WzJUlFlufQadfLJ98qJcrWZK5pRlGoUQOHp1L06urGRbEdE9v5oIRirPiUCjm93wATghO4qx`;
fetch(url)
.then(response => response.json())
.then(data => {
if (data.success) {
displayMsg(1, 'Programm erfolgreich gelöscht');
if (data.output) {
rebuildProgrammeTable(data.output);
} else {
displayMsg(0, 'Programm konnte nicht gelöscht werden');
}
}
})
.catch(err => {
displayMsg(0, 'Programm konnte nicht gelöscht werden');
console.error('AJAX fetch error:', err);
});
});
});
function toggleFreigabenDropdowns(el) {
const $input = $(el);
const type = $input.val();
if (type !== 'kampfrichter' && type !== 'trainer') {
return;
}
const dropdown = $input.closest('.single_pwedit').find('.perm-section-' + type);
if ($input.is(':checked')) {
dropdown.show();
} else {
dropdown.hide();
}
}
const targetCheckboxes = '#section-benutzer .perm-section-types input[type="checkbox"]';
$(targetCheckboxes).each(function() {
toggleFreigabenDropdowns(this);
});
$(document).on('change', targetCheckboxes, function() {
toggleFreigabenDropdowns(this);
});
// ----------------------------------------------------
// ----------------------------------------------------
// ----------------------------------------------------
// ----------------------------------------------------
// ----------------------------------------------------
// ----------------------------------------------------
// User Form Submission Handling
// ----------------------------------------------------
document.querySelectorAll('[id^="secure-password-form-"], #secure-password-form-new').forEach(form => {
form.addEventListener('submit', e => {
e.preventDefault();
const id = form.id === 'secure-password-form-new' ? 'new' : form.id.split('-').pop();
const password = document.getElementById('password-' + id)?.value || document.getElementById('password-new').value || 'TemporaeresPasswort';
const username = document.getElementById('username-' + id)?.value || document.getElementById('username-new').value;
const field_id = document.getElementById('field_id-' + id)?.value || document.getElementById('field_id-new').value;
// Collect all checked freigabe checkboxes within THIS form
const checkboxesFreigaben = form.querySelectorAll('input[name="freigabe[]"]:checked');
const freigaben = Array.from(checkboxesFreigaben).map(cb => cb.value);
const checkboxesTrainer = form.querySelectorAll('input[name="freigabeTrainer[]"]:checked');
const freigabenTrainer = Array.from(checkboxesTrainer).map(cb => cb.value);
const checkboxesKampfrichter = form.querySelectorAll('input[name="freigabeKampfrichter[]"]:checked');
const freigabenKampfrichter = Array.from(checkboxesKampfrichter).map(cb => cb.value);
const params = new URLSearchParams();
params.append('action', 'set_general_password');
params.append('password', password);
params.append('username', username);
params.append('field_id', field_id);
// We send an empty pwtype or 'all' to satisfy backend temporarily if it still checks it
params.append('pwtype', 'all');
freigaben.forEach(value => params.append('freigaben[]', value));
freigabenTrainer.forEach(value => params.append('freigabenTrainer[]', value));
freigabenKampfrichter.forEach(value => params.append('freigabenKampfrichter[]', value));
// Show loading overlay
if (id === 'new'){
document.getElementById('new-overlay').style.display = 'block';
} else {
document.getElementById('loading-overlay').style.display = 'block';
}
fetch('/intern/scripts/logindata/ajax-update-user-information.php', {
method: 'POST',
body: params
})
.then(res => res.json())
.then(data => {
if (id === 'new'){
document.getElementById('new-overlay').style.display = 'none';
} else {
document.getElementById('loading-overlay').style.display = 'none';
}
if (data.success) {
if (id === 'new') {
// Show success and reload
document.getElementById('new-reload').style.display = 'block';
setTimeout(() => { window.location.reload(); }, 1000);
return;
}
// Update existing user badges
const role_keys = ['wk_leitung', 'trainer', 'kampfrichter'];
let zugangCount = 0;
let krCount = 0;
let trCount = 0;
freigaben.forEach(val => {
if (role_keys.includes(val) || val === 'admin') {
if (val !== 'admin') zugangCount++;
} else if (document.querySelector(`#perm-kr-${id} input[value="${val}"]`)) {
krCount++;
} else if (document.querySelector(`#perm-tr-${id} input[value="${val}"]`)) {
trCount++;
}
});
const bZugang = document.getElementById(`badge-zugang-${id}`);
if(bZugang) bZugang.textContent = zugangCount;
const bKr = document.getElementById(`badge-kr-${id}`);
if(bKr) bKr.textContent = krCount;
const bTr = document.getElementById(`badge-tr-${id}`);
if(bTr) bTr.textContent = trCount;
const success = document.getElementById('success-overlay');
displayMsg(1, data.message || 'Erfolgreich gespeichert!');
} else {
const error = document.getElementById('error-overlay');
displayMsg(0, data.message || data || 'Es trat ein Fehler auf.');
}
})
.catch(err => {
console.error(err);
if (id === 'new'){
document.getElementById('new-overlay').style.display = 'none';
} else {
document.getElementById('loading-overlay').style.display = 'none';
}
displayMsg(0, data.message || data || 'Es trat ein Fehler auf. Siehe Konsole.');
});
});
});
document.querySelectorAll('[id$="-verein"], #new-verein').forEach(form => {
form.addEventListener('submit', e => {
e.preventDefault();
const id = form.id === 'new-verein' ? 'new' : form.id.split('-')[0];
const verein = document.getElementById('verein-' + id)?.value || document.getElementById('verein-new').value;
const field_id = document.getElementById('field_idverein-' + id)?.value || document.getElementById('field_idverein-new').value;
const nonce = document.getElementById('nonceverein-' + id)?.value || document.getElementById('nonceverein-new').value;
const params = new URLSearchParams();
params.append('action', 'set_verein');
params.append('verein', verein);
params.append('field_id', field_id);
// Show loading overlay
if (id === 'new'){
document.getElementById('new-overlay').style.display = 'block';
} else {
document.getElementById('loading-overlay').style.display = 'block';
}
fetch('/intern/scripts/logindata/ajax-vereine-handler.php', {
method: 'POST',
body: params
})
.then(res => res.json())
.then(data => {
if (id === 'new'){
document.getElementById('new-overlay').style.display = 'none';
} else {
document.getElementById('loading-overlay').style.display = 'none';
}
if (data.success) {
if (id === 'new') {
// Show success and reload
document.getElementById('new-reload').style.display = 'block';
setTimeout(() => { window.location.reload(); }, 1000);
return;
}
}
})
.catch(err => {
console.error(err);
document.getElementById('loading-overlay').style.display = 'none';
const error = document.getElementById('error-overlay');
error.querySelector('.textError').textContent = 'Error, see console';
error.classList.add('show');
setTimeout(() => { error.classList.remove('show'); }, 2500);
});
});
});
document.querySelectorAll('.delete-user-btn').forEach(btn => {
btn.addEventListener('click', e => {
e.preventDefault();
const id = btn.dataset.id;
const nonce = btn.dataset.nonce;
if (!confirm("Benutzer wirklich löschen?")) {
return;
}
// Show loading overlay
document.getElementById('loading-overlay').style.display = 'block';
const params = new URLSearchParams();
params.append('action', 'delete_secure_user');
params.append('field_id', id);
fetch('/intern/scripts/logindata/ajax02.php', {
method: 'POST',
body: params
})
.then(res => res.json())
.then(data => {
document.getElementById('loading-overlay').style.display = 'none';
if (data.success) {
// Remove the div for that user
const div = document.getElementById('div-single_pwedit-' + id);
if (div) div.remove();
const success = document.getElementById('success-overlay');
success.querySelector('.textSucsess').textContent = data.message || 'Benutzer gelöscht!';
success.classList.add('show');
setTimeout(() => { success.classList.remove('show'); }, 2500);
} else {
const error = document.getElementById('error-overlay');
error.querySelector('.textError').textContent = data.data || 'Fehler beim Löschen';
error.classList.add('show');
setTimeout(() => { error.classList.remove('show'); }, 2500);
}
})
.catch(err => {
console.error(err);
document.getElementById('loading-overlay').style.display = 'none';
const error = document.getElementById('error-overlay');
error.querySelector('.textError').textContent = 'Error, see console';
error.classList.add('show');
setTimeout(() => { error.classList.remove('show'); }, 2500);
});
});
});
function germanDate(date) {
return date.toLocaleString("de-DE", {
weekday: "long",
day: "numeric",
month: "long",
hour: "2-digit",
minute: "2-digit"
}) + " Uhr";
}
document.querySelectorAll('.createOturl').forEach(btn => {
btn.addEventListener('click', e => {
e.preventDefault();
const id = btn.dataset.id;
const username = btn.getAttribute("data-username");
const params = new URLSearchParams();
params.append('user_id', id);
fetch('/intern/scripts/logindata/ajax05.php', {
method: 'POST',
body: params
})
.then(res => res.json())
.then(data => {
if (data.success) {
let urlDiv = document.getElementById('oturldiv');
if (!urlDiv){
return
}
urlDiv.style.display = 'flex';
let fullUrl = window.location.origin + '/intern/otlogin?otl=' + data.url;
console.log(fullUrl);
let aOturl = document.getElementById('aOturl');
if (!aOturl){
return
}
aOturl.innerHTML = fullUrl;
aOturl.href = fullUrl;
let oturlGb = document.getElementById('oturlGb');
if (!oturlGb){
return
}
const tomorrow = new Date();
tomorrow.setDate(tomorrow.getDate() + 1);
oturlGb.innerHTML = 'Link gültig bis: ' + germanDate(tomorrow);
const qrcodeContainer = document.getElementById("qrcode");
qrcodeContainer.innerHTML = '';
// 1. Generate the QR Code
const qr = new QRCode(qrcodeContainer, {
text: fullUrl,
width: 256,
height: 256
});
// 2. Add Download Logic
document.getElementById("btnDownloadQRCode").addEventListener("click", () => {
// Find the canvas element inside the qrcode div
const canvas = qrcodeContainer.querySelector("canvas");
if (canvas) {
const image = canvas.toDataURL("image/png");
const link = document.createElement("a");
link.href = image;
link.download = `QR_Code_Einmallogin_${username}.png`;
link.click();
} else {
alert("QR Code not ready yet!");
}
});
}
})
.catch(err => {
console.error(err);
const error = document.getElementById('error-overlay');
error.querySelector('.textError').textContent = 'Error, see console';
error.classList.add('show');
setTimeout(() => { error.classList.remove('show'); }, 2500);
});
});
});
document.querySelectorAll('.delete-verein-btn').forEach(btn => {
btn.addEventListener('click', e => {
e.preventDefault();
const id = btn.dataset.id;
const nonce = btn.dataset.nonce;
if (!confirm("Verein wirklich löschen?")) {
return;
}
// Show loading overlay
document.getElementById('loading-overlay').style.display = 'block';
const params = new URLSearchParams();
params.append('field_id', id);
fetch('/intern/scripts/logindata/ajax04.php', {
method: 'POST',
body: params
})
.then(res => res.json())
.then(data => {
document.getElementById('loading-overlay').style.display = 'none';
if (data.success) {
// Remove the tr for that verein
const tr = document.getElementById('div_verein-' + id);
if (tr) tr.remove();
const success = document.getElementById('success-overlay');
success.querySelector('.textSucsess').textContent = data.message || 'Verein gelöscht!';
success.classList.add('show');
setTimeout(() => { success.classList.remove('show'); }, 2500);
} else {
const error = document.getElementById('error-overlay');
error.querySelector('.textError').textContent = data || 'Fehler beim Löschen';
error.classList.add('show');
setTimeout(() => { error.classList.remove('show'); }, 2500);
}
})
.catch(err => {
console.error(err);
document.getElementById('loading-overlay').style.display = 'none';
const error = document.getElementById('error-overlay');
error.querySelector('.textError').textContent = 'Error, see console';
error.classList.add('show');
setTimeout(() => { error.classList.remove('show'); }, 2500);
});
});
});
</script>
</body>
</html>
<?php endif; ?>