initial dashboard config
This commit is contained in:
parent
07e13afb2a
commit
0ee2a554a4
|
|
@ -0,0 +1,314 @@
|
||||||
|
<?php
|
||||||
|
// dashboard.php
|
||||||
|
|
||||||
|
// Gemeinsame Datenbank-Verbindungskonfiguration
|
||||||
|
$host = 'localhost';
|
||||||
|
$db = 'web35_vysion';
|
||||||
|
$user = 'vysion_api';
|
||||||
|
$pass = '7e0pn9~2Z';
|
||||||
|
$charset = 'utf8mb4';
|
||||||
|
$dsn = "mysql:host=$host;dbname=$db;charset=$charset";
|
||||||
|
$options = [
|
||||||
|
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
|
||||||
|
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
|
||||||
|
];
|
||||||
|
|
||||||
|
try {
|
||||||
|
$pdo = new PDO($dsn, $user, $pass, $options);
|
||||||
|
} catch (PDOException $e) {
|
||||||
|
header('Content-Type: application/json');
|
||||||
|
echo json_encode(['error' => 'Database connection failed: ' . $e->getMessage()]);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bearer Token für Mastodon-API (falls benötigt – hier nicht direkt in diesem File)
|
||||||
|
$bearerToken = 'your_bearer_token_here';
|
||||||
|
|
||||||
|
// Falls eine AJAX-Anfrage vorliegt, wird über den Parameter "action" unterschieden.
|
||||||
|
if (isset($_POST['action'])) {
|
||||||
|
$action = $_POST['action'];
|
||||||
|
header('Content-Type: application/json');
|
||||||
|
|
||||||
|
if ($action === 'save_hashtags') {
|
||||||
|
// Erwartet ein Array "hashtags" (JSON-dekodiert via AJAX)
|
||||||
|
$hashtags = isset($_POST['hashtags']) ? $_POST['hashtags'] : [];
|
||||||
|
$response = ['saved' => 0, 'updated' => 0];
|
||||||
|
|
||||||
|
foreach ($hashtags as $row) {
|
||||||
|
// Falls eine ID vorhanden ist, update ansonsten insert
|
||||||
|
if (isset($row['hashtag_id']) && !empty($row['hashtag_id'])) {
|
||||||
|
// Update vorhandener Eintrag
|
||||||
|
$stmt = $pdo->prepare("UPDATE hashtags SET hashtag = :hashtag, active = :active WHERE hashtag_id = :hashtag_id");
|
||||||
|
$stmt->execute([
|
||||||
|
'hashtag' => $row['hashtag'],
|
||||||
|
'active' => !empty($row['active']) ? 1 : 0,
|
||||||
|
'hashtag_id' => $row['hashtag_id']
|
||||||
|
]);
|
||||||
|
$response['updated']++;
|
||||||
|
} else {
|
||||||
|
// Insert neuer Eintrag
|
||||||
|
$stmt = $pdo->prepare("INSERT INTO hashtags (hashtag, active) VALUES (:hashtag, :active)");
|
||||||
|
$stmt->execute([
|
||||||
|
'hashtag' => $row['hashtag'],
|
||||||
|
'active' => !empty($row['active']) ? 1 : 0
|
||||||
|
]);
|
||||||
|
$response['saved']++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
echo json_encode($response);
|
||||||
|
exit;
|
||||||
|
} elseif ($action === 'save_accounts') {
|
||||||
|
// Erwartet ein Array "accounts" (JSON)
|
||||||
|
$accounts = isset($_POST['accounts']) ? $_POST['accounts'] : [];
|
||||||
|
$response = ['updated' => 0];
|
||||||
|
|
||||||
|
foreach ($accounts as $row) {
|
||||||
|
// Aktualisiere den active-Status in der Tabelle "users"
|
||||||
|
// Annahme: Tabelle "users" hat die Spalten: acc_id, username, active
|
||||||
|
$stmt = $pdo->prepare("UPDATE users SET active = :active WHERE acc_id = :acc_id");
|
||||||
|
$stmt->execute([
|
||||||
|
'active' => !empty($row['active']) ? 1 : 0,
|
||||||
|
'acc_id' => $row['acc_id']
|
||||||
|
]);
|
||||||
|
$response['updated']++;
|
||||||
|
}
|
||||||
|
echo json_encode($response);
|
||||||
|
exit;
|
||||||
|
} elseif ($action === 'sync_accounts') {
|
||||||
|
// Synchronisation: Aus der findings-Tabelle werden alle getrackten Accounts (acc_id, username) ermittelt
|
||||||
|
// Für jeden Account, der noch nicht in der "users"-Tabelle existiert, erfolgt ein Insert mit active=0
|
||||||
|
$stmt = $pdo->query("SELECT DISTINCT acc_id, username FROM findings");
|
||||||
|
$tracked = $stmt->fetchAll();
|
||||||
|
|
||||||
|
foreach ($tracked as $acc) {
|
||||||
|
// Prüfen, ob der Account bereits in der users-Tabelle existiert
|
||||||
|
$checkStmt = $pdo->prepare("SELECT COUNT(*) as cnt FROM users WHERE acc_id = :acc_id");
|
||||||
|
$checkStmt->execute(['acc_id' => $acc['acc_id']]);
|
||||||
|
$exists = $checkStmt->fetch();
|
||||||
|
if ($exists['cnt'] == 0) {
|
||||||
|
// Neuer Account – unaktiv in die Tabelle schreiben
|
||||||
|
$insertStmt = $pdo->prepare("INSERT INTO users (acc_id, username, active) VALUES (:acc_id, :username, 0)");
|
||||||
|
$insertStmt->execute([
|
||||||
|
'acc_id' => $acc['acc_id'],
|
||||||
|
'username' => $acc['username']
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Nun alle Accounts aus der users-Tabelle abrufen
|
||||||
|
$stmt = $pdo->query("SELECT acc_id, username, active FROM users ORDER BY username ASC");
|
||||||
|
$accountsList = $stmt->fetchAll();
|
||||||
|
echo json_encode($accountsList);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
// Weitere Aktionen können hier ergänzt werden
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wenn kein "action" gesetzt ist, wird der HTML-Teil (Dashboard) ausgegeben.
|
||||||
|
// Der Konfigbereich ist über den Parameter "setup" erreichbar.
|
||||||
|
?>
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="de">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Dashboard & Konfiguration</title>
|
||||||
|
<!-- jQuery einbinden -->
|
||||||
|
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
|
||||||
|
<style>
|
||||||
|
table { border-collapse: collapse; width: 100%; margin-bottom: 1em; }
|
||||||
|
th, td { border: 1px solid #ccc; padding: 5px; text-align: left; }
|
||||||
|
.error { color: red; }
|
||||||
|
.config-section { margin-bottom: 2em; padding: 1em; border: 1px solid #ddd; }
|
||||||
|
.config-section h2 { margin-top: 0; }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Dashboard - Konfigurationsbereich</h1>
|
||||||
|
<!-- Zeitraum Konfiguration -->
|
||||||
|
<div class="config-section" id="zeitraum-config">
|
||||||
|
<h2>Zeitraum definieren (von - bis)</h2>
|
||||||
|
<label for="von">Von:</label>
|
||||||
|
<input type="datetime-local" id="von" name="von">
|
||||||
|
<label for="bis">Bis:</label>
|
||||||
|
<input type="datetime-local" id="bis" name="bis">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Hashtag Konfiguration -->
|
||||||
|
<div class="config-section" id="hashtag-config">
|
||||||
|
<h2>Hashtags</h2>
|
||||||
|
<table id="hashtag-table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Hashtag</th>
|
||||||
|
<th>Aktiv</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<?php
|
||||||
|
// Lade alle Hashtags aus der Datenbank (nur aktive ? oder alle)
|
||||||
|
$stmt = $pdo->query("SELECT hashtag_id, hashtag, active FROM hashtags ORDER BY hashtag ASC");
|
||||||
|
while ($row = $stmt->fetch()) {
|
||||||
|
echo "<tr data-id=\"{$row['hashtag_id']}\">";
|
||||||
|
echo "<td><input type=\"text\" class=\"hashtag-text\" value=\"" . htmlspecialchars($row['hashtag']) . "\"></td>";
|
||||||
|
$checked = ($row['active'] == 1) ? "checked" : "";
|
||||||
|
echo "<td><input type=\"checkbox\" class=\"hashtag-active\" $checked></td>";
|
||||||
|
echo "</tr>";
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<button id="add-hashtag">+1</button>
|
||||||
|
<button id="save-hashtags" disabled>Speichern</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Account Konfiguration -->
|
||||||
|
<div class="config-section" id="account-config">
|
||||||
|
<h2>Getrackte Accounts</h2>
|
||||||
|
<div>
|
||||||
|
<label for="sync-interval">Sync Intervall (Sekunden):</label>
|
||||||
|
<input type="text" id="sync-interval" value="30" size="3">
|
||||||
|
<label for="autosync">Autosync</label>
|
||||||
|
<input type="checkbox" id="autosync" checked>
|
||||||
|
</div>
|
||||||
|
<table id="account-table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Acc_ID</th>
|
||||||
|
<th>Username</th>
|
||||||
|
<th>Aktiv</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<!-- Die Tabelle wird per AJAX befüllt -->
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<button id="save-accounts" disabled>Speichern</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
$(document).ready(function(){
|
||||||
|
var hashtagChanged = false;
|
||||||
|
var accountChanged = false;
|
||||||
|
var autosyncTimer;
|
||||||
|
|
||||||
|
// Markiere Änderung in der Hashtag-Tabelle
|
||||||
|
$('#hashtag-table').on('input change', 'input', function(){
|
||||||
|
hashtagChanged = true;
|
||||||
|
$('#save-hashtags').prop('disabled', false);
|
||||||
|
});
|
||||||
|
|
||||||
|
// +1 Button: Fügt eine neue Zeile ein (ohne ID, active standardmäßig false)
|
||||||
|
$('#add-hashtag').click(function(){
|
||||||
|
var newRow = '<tr data-id="">' +
|
||||||
|
'<td><input type="text" class="hashtag-text" value=""></td>' +
|
||||||
|
'<td><input type="checkbox" class="hashtag-active"></td>' +
|
||||||
|
'</tr>';
|
||||||
|
$('#hashtag-table tbody').append(newRow);
|
||||||
|
hashtagChanged = true;
|
||||||
|
$('#save-hashtags').prop('disabled', false);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Speichern-Button für Hashtags
|
||||||
|
$('#save-hashtags').click(function(){
|
||||||
|
var hashtags = [];
|
||||||
|
$('#hashtag-table tbody tr').each(function(){
|
||||||
|
var id = $(this).data('id');
|
||||||
|
var text = $(this).find('.hashtag-text').val().trim();
|
||||||
|
var active = $(this).find('.hashtag-active').is(':checked') ? 1 : 0;
|
||||||
|
if(text !== ""){
|
||||||
|
hashtags.push({hashtag_id: id, hashtag: text, active: active});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
$.ajax({
|
||||||
|
url: 'dashboard.php',
|
||||||
|
type: 'POST',
|
||||||
|
dataType: 'json',
|
||||||
|
data: { action: 'save_hashtags', hashtags: hashtags },
|
||||||
|
success: function(resp){
|
||||||
|
alert('Hashtags gespeichert: Neu ' + resp.saved + ', Aktualisiert ' + resp.updated);
|
||||||
|
hashtagChanged = false;
|
||||||
|
$('#save-hashtags').prop('disabled', true);
|
||||||
|
// Seite neu laden oder Tabelle aktualisieren
|
||||||
|
location.reload();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Funktion zum Laden der Accounts (sync)
|
||||||
|
function loadAccounts(){
|
||||||
|
$.ajax({
|
||||||
|
url: 'dashboard.php',
|
||||||
|
type: 'POST',
|
||||||
|
dataType: 'json',
|
||||||
|
data: { action: 'sync_accounts' },
|
||||||
|
success: function(accounts){
|
||||||
|
var tbody = $('#account-table tbody');
|
||||||
|
tbody.empty();
|
||||||
|
$.each(accounts, function(i, acc){
|
||||||
|
var checked = (acc.active == 1) ? 'checked' : '';
|
||||||
|
tbody.append('<tr data-id="'+acc.acc_id+'"><td>'+acc.acc_id+'</td><td>'+acc.username+'</td><td><input type="checkbox" class="account-active" '+checked+'></td></tr>');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initiales Laden der Accounts
|
||||||
|
loadAccounts();
|
||||||
|
|
||||||
|
// Markiere Änderung in der Accounts-Tabelle
|
||||||
|
$('#account-table').on('change', 'input.account-active', function(){
|
||||||
|
accountChanged = true;
|
||||||
|
$('#save-accounts').prop('disabled', false);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Speichern-Button für Accounts
|
||||||
|
$('#save-accounts').click(function(){
|
||||||
|
var accounts = [];
|
||||||
|
$('#account-table tbody tr').each(function(){
|
||||||
|
var acc_id = $(this).data('id');
|
||||||
|
var active = $(this).find('.account-active').is(':checked') ? 1 : 0;
|
||||||
|
accounts.push({acc_id: acc_id, active: active});
|
||||||
|
});
|
||||||
|
$.ajax({
|
||||||
|
url: 'dashboard.php',
|
||||||
|
type: 'POST',
|
||||||
|
dataType: 'json',
|
||||||
|
data: { action: 'save_accounts', accounts: accounts },
|
||||||
|
success: function(resp){
|
||||||
|
alert('Accounts aktualisiert: ' + resp.updated + ' Einträge.');
|
||||||
|
accountChanged = false;
|
||||||
|
$('#save-accounts').prop('disabled', true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Autosync: Prüfe Intervallfeld und starte einen Loop, wenn aktiviert
|
||||||
|
function startAutosync(){
|
||||||
|
clearInterval(autosyncTimer);
|
||||||
|
var interval = parseInt($('#sync-interval').val(), 10);
|
||||||
|
if(isNaN(interval) || interval <= 0){
|
||||||
|
$('#sync-interval').addClass('error');
|
||||||
|
interval = 30; // Standardwert
|
||||||
|
} else {
|
||||||
|
$('#sync-interval').removeClass('error');
|
||||||
|
}
|
||||||
|
autosyncTimer = setInterval(function(){
|
||||||
|
if($('#autosync').is(':checked')){
|
||||||
|
loadAccounts();
|
||||||
|
} else {
|
||||||
|
clearInterval(autosyncTimer);
|
||||||
|
}
|
||||||
|
}, interval * 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Starte Autosync beim Laden
|
||||||
|
startAutosync();
|
||||||
|
|
||||||
|
// Ändert sich das Intervall, neu starten
|
||||||
|
$('#sync-interval, #autosync').on('change keyup', function(){
|
||||||
|
startAutosync();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
Loading…
Reference in New Issue