Compare commits
3
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
133b1d57ed | ||
|
|
1ad59a9881 | ||
|
|
c540d06939 |
No files matched your search
@@ -0,0 +1,105 @@
|
||||
<?php
|
||||
session_set_cookie_params([
|
||||
'lifetime' => 0,
|
||||
'path' => '/',
|
||||
'domain' => '',
|
||||
'secure' => false,
|
||||
'httponly' => true,
|
||||
'samesite' => 'Lax'
|
||||
]);
|
||||
session_start();
|
||||
|
||||
header('Content-Type: application/json');
|
||||
error_reporting(E_ALL);
|
||||
ini_set('display_errors', '0');
|
||||
|
||||
if (empty($_SESSION['user_logged_in'])) {
|
||||
http_response_code(401);
|
||||
echo json_encode(['error' => 'Nicht eingeloggt']);
|
||||
exit;
|
||||
}
|
||||
|
||||
if (empty($_SESSION['is_admin'])) {
|
||||
http_response_code(403);
|
||||
echo json_encode(['error' => 'Keine Berechtigung']);
|
||||
exit;
|
||||
}
|
||||
|
||||
include_once(__DIR__ . '/../../../controller/DatabaseController.php');
|
||||
include_once(__DIR__ . '/../../../controller/NotifyController.php');
|
||||
|
||||
$daten = json_decode(file_get_contents('php://input'), true) ?? [];
|
||||
$action = $daten['action'] ?? '';
|
||||
|
||||
try {
|
||||
$notificationCtl = new Notification();
|
||||
|
||||
switch ($action) {
|
||||
|
||||
case 'get_entries': {
|
||||
$entries = $notificationCtl->getAllMessages();
|
||||
|
||||
foreach ($entries as &$entry) {
|
||||
$entry['GESEHEN_ANZAHL'] = $notificationCtl->countSeenBy((int)$entry['ID']);
|
||||
}
|
||||
|
||||
echo json_encode(['success' => true, 'entries' => array_values($entries)]);
|
||||
break;
|
||||
}
|
||||
|
||||
case 'add_entry': {
|
||||
$titel = trim($daten['titel'] ?? '');
|
||||
$nachricht = trim($daten['nachricht'] ?? '');
|
||||
|
||||
if ($titel === '' || $nachricht === '') {
|
||||
throw new InvalidArgumentException('Titel und Nachricht erforderlich');
|
||||
}
|
||||
|
||||
$notificationCtl->createMessage($titel, $nachricht);
|
||||
|
||||
echo json_encode(['success' => true]);
|
||||
break;
|
||||
}
|
||||
|
||||
case 'edit_entry': {
|
||||
$id = $daten['id'] ?? null;
|
||||
$titel = trim($daten['titel'] ?? '');
|
||||
$nachricht = trim($daten['nachricht'] ?? '');
|
||||
|
||||
if (!is_numeric($id)) {
|
||||
throw new InvalidArgumentException('Ungültige ID');
|
||||
}
|
||||
if ($titel === '' || $nachricht === '') {
|
||||
throw new InvalidArgumentException('Titel und Nachricht erforderlich');
|
||||
}
|
||||
|
||||
$notificationCtl->updateMessage((int)$id, $titel, $nachricht);
|
||||
|
||||
echo json_encode(['success' => true]);
|
||||
break;
|
||||
}
|
||||
|
||||
case 'delete_entry': {
|
||||
$id = $daten['id'] ?? null;
|
||||
|
||||
if (!is_numeric($id)) {
|
||||
throw new InvalidArgumentException('Ungültige ID');
|
||||
}
|
||||
|
||||
$notificationCtl->deleteMessage((int)$id);
|
||||
|
||||
echo json_encode(['success' => true]);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
throw new InvalidArgumentException("Unbekannte Aktion: $action");
|
||||
}
|
||||
} catch (InvalidArgumentException $e) {
|
||||
http_response_code(400);
|
||||
echo json_encode(['error' => $e->getMessage()]);
|
||||
} catch (Throwable $e) {
|
||||
http_response_code(500);
|
||||
error_log($e->getMessage());
|
||||
echo json_encode(['error' => 'Serverfehler']);
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
session_set_cookie_params([
|
||||
'lifetime' => 0,
|
||||
'path' => '/',
|
||||
'domain' => '',
|
||||
'secure' => false,
|
||||
'httponly' => true,
|
||||
'samesite' => 'Lax'
|
||||
]);
|
||||
session_start();
|
||||
|
||||
header('Content-Type: application/json');
|
||||
error_reporting(E_ALL);
|
||||
ini_set('display_errors', '0');
|
||||
|
||||
if (empty($_SESSION['user_logged_in'])) {
|
||||
http_response_code(401);
|
||||
echo json_encode(['error' => 'Nicht eingeloggt']);
|
||||
exit;
|
||||
}
|
||||
|
||||
include_once(__DIR__ . '/../../../controller/DatabaseController.php');
|
||||
include_once(__DIR__ . '/../../../controller/NotifyController.php');
|
||||
|
||||
$daten = json_decode(file_get_contents('php://input'), true) ?? [];
|
||||
$action = $daten['action'] ?? '';
|
||||
|
||||
try {
|
||||
switch ($action) {
|
||||
|
||||
case 'mark_seen': {
|
||||
$nachrichtId = $daten['nachricht_id'] ?? null;
|
||||
|
||||
if (!is_numeric($nachrichtId)) {
|
||||
throw new InvalidArgumentException('Ungültige Nachrichten-ID');
|
||||
}
|
||||
|
||||
$notificationCtl = new Notification();
|
||||
$notificationCtl->markAsSeen((int)$nachrichtId);
|
||||
|
||||
echo json_encode(['success' => true]);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
throw new InvalidArgumentException("Unbekannte Aktion: $action");
|
||||
}
|
||||
} catch (InvalidArgumentException $e) {
|
||||
http_response_code(400);
|
||||
echo json_encode(['error' => $e->getMessage()]);
|
||||
} catch (Throwable $e) {
|
||||
http_response_code(500);
|
||||
error_log($e->getMessage());
|
||||
echo json_encode(['error' => 'Serverfehler']);
|
||||
}
|
||||
@@ -0,0 +1,177 @@
|
||||
<?php
|
||||
|
||||
include_once(__DIR__ . '/DatabaseController.php');
|
||||
include_once(__DIR__ . '/DataController.php');
|
||||
|
||||
class Notification
|
||||
{
|
||||
protected $table;
|
||||
protected $seenTable;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->table = "Benachrichtigung";
|
||||
$this->seenTable = "Benachrichtigung_Gesehen";
|
||||
}
|
||||
|
||||
/**
|
||||
* Ermittelt die Benutzer-ID des aktuell eingeloggten Nutzers.
|
||||
*/
|
||||
private function getCurrentUserId(): ?int
|
||||
{
|
||||
$username = $_SESSION['username'] ?? null;
|
||||
if (!$username) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$rows = DatabaseShow(
|
||||
"Benutzer",
|
||||
"ID",
|
||||
"NAME = ?",
|
||||
$username
|
||||
);
|
||||
|
||||
return $rows[0]['ID'] ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Alle Nachrichten (z.B. für eine Verwaltungsansicht).
|
||||
*/
|
||||
public function getAllMessages(): array
|
||||
{
|
||||
return DatabaseShow(
|
||||
$this->table,
|
||||
"ID, TITEL, NACHRICHT"
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Nur die Nachrichten, die der aktuelle Nutzer noch NICHT gesehen hat.
|
||||
* Genau das braucht das Modal, um zu entscheiden ob/was es anzeigt.
|
||||
*/
|
||||
public function getUnseenMessages(): array
|
||||
{
|
||||
$userId = $this->getCurrentUserId();
|
||||
if ($userId === null) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$alleNachrichten = DatabaseShow(
|
||||
$this->table,
|
||||
"ID, TITEL, NACHRICHT"
|
||||
);
|
||||
|
||||
$gesehenRows = DatabaseShow(
|
||||
$this->seenTable,
|
||||
"NACHRICHTEN_ID",
|
||||
"BENUTZER_ID = ?",
|
||||
$userId
|
||||
);
|
||||
|
||||
$gesehenIds = array_column($gesehenRows, 'NACHRICHTEN_ID');
|
||||
|
||||
return array_values(array_filter(
|
||||
$alleNachrichten,
|
||||
fn($nachricht) => !in_array($nachricht['ID'], $gesehenIds)
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt eine neue Nachricht im Pool an (z.B. für eine Admin-Funktion).
|
||||
*/
|
||||
public function createMessage(string $titel, string $nachricht): bool
|
||||
{
|
||||
try {
|
||||
DatabaseInsert(
|
||||
$this->table,
|
||||
"TITEL, NACHRICHT",
|
||||
$titel,
|
||||
$nachricht
|
||||
);
|
||||
return true;
|
||||
} catch (Exception $e) {
|
||||
throw new Exception($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Markiert eine bestimmte Nachricht als vom aktuellen Nutzer gesehen/bestätigt.
|
||||
*/
|
||||
public function markAsSeen(int $nachrichtId): bool
|
||||
{
|
||||
$userId = $this->getCurrentUserId();
|
||||
if ($userId === null) {
|
||||
throw new Exception('Kein eingeloggter Benutzer gefunden.');
|
||||
}
|
||||
|
||||
// Prüfen, ob schon als gesehen markiert, um Duplikate zu vermeiden
|
||||
$bereitsGesehen = DatabaseShow(
|
||||
$this->seenTable,
|
||||
"ID",
|
||||
"BENUTZER_ID = ? AND NACHRICHTEN_ID = ?",
|
||||
$userId,
|
||||
$nachrichtId
|
||||
);
|
||||
|
||||
if (!empty($bereitsGesehen)) {
|
||||
return true; // war schon markiert, kein Fehler
|
||||
}
|
||||
|
||||
try {
|
||||
DatabaseInsert(
|
||||
$this->seenTable,
|
||||
"BENUTZER_ID, NACHRICHTEN_ID",
|
||||
$userId,
|
||||
$nachrichtId
|
||||
);
|
||||
return true;
|
||||
} catch (Exception $e) {
|
||||
throw new Exception($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function updateMessage(int $id, string $titel, string $nachricht): bool
|
||||
{
|
||||
try {
|
||||
DatabaseUpdate(
|
||||
$this->table,
|
||||
"TITEL = ?, NACHRICHT = ?",
|
||||
"ID = ?",
|
||||
$titel,
|
||||
$nachricht,
|
||||
$id
|
||||
);
|
||||
return true;
|
||||
} catch (Exception $e) {
|
||||
throw new Exception($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Löscht eine Nachricht komplett, inkl. aller "Gesehen"-Einträge dazu.
|
||||
*/
|
||||
public function deleteMessage(int $id): bool
|
||||
{
|
||||
try {
|
||||
DatabaseDelete($this->seenTable, "NACHRICHTEN_ID = ?", $id);
|
||||
DatabaseDelete($this->table, "ID = ?", $id);
|
||||
return true;
|
||||
} catch (Exception $e) {
|
||||
throw new Exception($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Anzahl Nutzer, die eine bestimmte Nachricht bereits bestätigt haben.
|
||||
*/
|
||||
public function countSeenBy(int $id): int
|
||||
{
|
||||
$rows = DatabaseShow(
|
||||
$this->seenTable,
|
||||
"ID",
|
||||
"NACHRICHTEN_ID = ?",
|
||||
$id
|
||||
);
|
||||
return count($rows);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
const BENACHRICHTIGUNGEN_HANDLER_URL = '/api/js/handler/BenachrichtigungenAjaxHandler';
|
||||
|
||||
async function benachrichtigungenAjaxRequest(payload) {
|
||||
try {
|
||||
const response = await fetch(BENACHRICHTIGUNGEN_HANDLER_URL, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(payload)
|
||||
});
|
||||
const data = await parseJsonResponse(response);
|
||||
|
||||
if (data.error) {
|
||||
throw new Error(data.error);
|
||||
}
|
||||
return data;
|
||||
|
||||
} catch (error) {
|
||||
console.error('Benachrichtigungen-Ajax-Fehler:', error.message);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
function getNotificationEntries() {
|
||||
return benachrichtigungenAjaxRequest({ action: 'get_entries' });
|
||||
}
|
||||
|
||||
function addNotificationEntry(titel, nachricht) {
|
||||
return benachrichtigungenAjaxRequest({ action: 'add_entry', titel, nachricht });
|
||||
}
|
||||
|
||||
function editNotificationEntry(id, titel, nachricht) {
|
||||
return benachrichtigungenAjaxRequest({ action: 'edit_entry', id, titel, nachricht });
|
||||
}
|
||||
|
||||
function deleteNotificationEntry(id) {
|
||||
return benachrichtigungenAjaxRequest({ action: 'delete_entry', id });
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
const NOTIFICATION_HANDLER_URL = '/api/js/handler/NotificationAjaxHandler';
|
||||
|
||||
async function notificationAjaxRequest(payload) {
|
||||
try {
|
||||
const response = await fetch(NOTIFICATION_HANDLER_URL, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(payload)
|
||||
});
|
||||
const data = await parseJsonResponse(response);
|
||||
|
||||
if (data.error) {
|
||||
throw new Error(data.error);
|
||||
}
|
||||
return data;
|
||||
|
||||
} catch (error) {
|
||||
console.error('Notification-Ajax-Fehler:', error.message);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
function markNotificationAsSeen(nachrichtId) {
|
||||
return notificationAjaxRequest({ action: 'mark_seen', nachricht_id: nachrichtId });
|
||||
}
|
||||
@@ -0,0 +1,134 @@
|
||||
<?php
|
||||
include_once(__DIR__ . '/../controller/NotifyController.php');
|
||||
?>
|
||||
|
||||
<div class="arbeitsberichte-wrapper">
|
||||
<div class="vergabe-form">
|
||||
<h3>Neue Nachricht anlegen</h3>
|
||||
<form id="addNotificationForm" class="vergabe-grid">
|
||||
|
||||
<div class="form-group">
|
||||
<label>Titel</label>
|
||||
<input type="text" name="titel" id="in-titel" required>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Nachricht</label>
|
||||
<input type="text" name="nachricht" id="in-nachricht" required>
|
||||
</div>
|
||||
|
||||
<button type="submit" class="btn-submit-vergabe">💾 Speichern</button>
|
||||
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="table-container" style="margin-top: 30px;">
|
||||
<h3>Nachrichten Verwaltung</h3>
|
||||
<div id="tableWrapper">
|
||||
<p>Lade Daten...</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="/js/AjaxMethods.js"></script>
|
||||
<script src="/js/ajaxApi/BenachrichtigungenAjaxMethods.js"></script>
|
||||
<script src="/js/AjaxRenderTables.js"></script>
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
const tableWrapper = document.getElementById('tableWrapper');
|
||||
|
||||
function renderNotificationsTabelle(entries) {
|
||||
if (!entries || entries.length === 0) {
|
||||
tableWrapper.innerHTML = '<p>Keine Nachrichten vorhanden.</p>';
|
||||
return;
|
||||
}
|
||||
|
||||
let html = `
|
||||
<table class="db-table mobile-responsive-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Titel</th><th>Nachricht</th><th>Gesehen von</th>
|
||||
<th style="width: 220px;">Aktion</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
`;
|
||||
for (const e of entries) {
|
||||
html += `
|
||||
<tr data-id="${escapeHtml(e.ID)}">
|
||||
<td data-label="Titel">
|
||||
<input type="text" class="edit-titel" value="${escapeHtml(e.TITEL)}">
|
||||
</td>
|
||||
<td data-label="Nachricht">
|
||||
<input type="text" class="edit-nachricht" value="${escapeHtml(e.NACHRICHT)}">
|
||||
</td>
|
||||
<td data-label="Gesehen von">${escapeHtml(e.GESEHEN_ANZAHL)} Nutzer</td>
|
||||
<td data-label="Aktion">
|
||||
<div style="display:flex; flex-direction:column; gap:6px; align-items:stretch;">
|
||||
<button type="button" class="btn-edit" data-id="${escapeHtml(e.ID)}">Speichern</button>
|
||||
<button type="button" class="btn-delete" data-id="${escapeHtml(e.ID)}">Löschen</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>`;
|
||||
}
|
||||
html += `</tbody></table>`;
|
||||
tableWrapper.innerHTML = html;
|
||||
|
||||
tableWrapper.querySelectorAll('.btn-edit').forEach(btn => {
|
||||
btn.addEventListener('click', async () => {
|
||||
const row = tableWrapper.querySelector(`tr[data-id="${btn.dataset.id}"]`);
|
||||
const titel = row.querySelector('.edit-titel').value.trim();
|
||||
const nachricht = row.querySelector('.edit-nachricht').value.trim();
|
||||
|
||||
if (!titel || !nachricht) return;
|
||||
|
||||
try {
|
||||
await editNotificationEntry(btn.dataset.id, titel, nachricht);
|
||||
await ladeListe();
|
||||
} catch (err) {
|
||||
alert('Fehler beim Speichern: ' + err.message);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
tableWrapper.querySelectorAll('.btn-delete').forEach(btn => {
|
||||
btn.addEventListener('click', async () => {
|
||||
if (!confirm('Möchtest du diese Nachricht wirklich löschen? Dies entfernt auch alle "Gesehen"-Markierungen dazu.')) return;
|
||||
try {
|
||||
await deleteNotificationEntry(btn.dataset.id);
|
||||
await ladeListe();
|
||||
} catch (err) {
|
||||
alert('Fehler beim Löschen: ' + err.message);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
async function ladeListe() {
|
||||
try {
|
||||
const data = await getNotificationEntries();
|
||||
renderNotificationsTabelle(data.entries);
|
||||
} catch (err) {
|
||||
tableWrapper.innerHTML = `<p>❌ ${escapeHtml(err.message)}</p>`;
|
||||
}
|
||||
}
|
||||
|
||||
document.getElementById('addNotificationForm').addEventListener('submit', async (e) => {
|
||||
e.preventDefault();
|
||||
const titel = document.getElementById('in-titel').value.trim();
|
||||
const nachricht = document.getElementById('in-nachricht').value.trim();
|
||||
|
||||
if (!titel || !nachricht) return;
|
||||
|
||||
try {
|
||||
await addNotificationEntry(titel, nachricht);
|
||||
e.target.reset();
|
||||
await ladeListe();
|
||||
} catch (err) {
|
||||
alert('Fehler beim Speichern: ' + err.message);
|
||||
}
|
||||
});
|
||||
|
||||
ladeListe();
|
||||
});
|
||||
</script>
|
||||
@@ -1,4 +1,6 @@
|
||||
<?php
|
||||
include_once(__DIR__ . '/../controller/NotifyController.php');
|
||||
|
||||
$username = $_SESSION['username'] ?? 'Gast';
|
||||
$is_superuser = $_SESSION['is_superuser'] ?? false;
|
||||
$is_admin = $_SESSION['is_admin'] ?? false;
|
||||
@@ -10,8 +12,24 @@ $db_res = DatabaseShow(
|
||||
$username
|
||||
);
|
||||
|
||||
// --- Ungesehene Benachrichtigung ermitteln ---
|
||||
$notificationCtl = new Notification();
|
||||
$offeneNachrichten = $notificationCtl->getUnseenMessages();
|
||||
$aktuelleNachricht = $offeneNachrichten[0] ?? null; // immer nur die erste anzeigen
|
||||
|
||||
?>
|
||||
|
||||
<?php if ($aktuelleNachricht): ?>
|
||||
<div class="notification-overlay open" id="notificationModal" data-nachricht-id="<?= htmlspecialchars($aktuelleNachricht['ID']) ?>">
|
||||
<div class="notification-box">
|
||||
<div class="notification-icon">📢</div>
|
||||
<h3><?= htmlspecialchars($aktuelleNachricht['TITEL']) ?></h3>
|
||||
<p><?= nl2br(htmlspecialchars($aktuelleNachricht['NACHRICHT'])) ?></p>
|
||||
<button type="button" id="notificationConfirm">Verstanden</button>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="home-dashboard">
|
||||
<div class="links-container">
|
||||
|
||||
@@ -20,18 +38,18 @@ $db_res = DatabaseShow(
|
||||
<div class="group-links" style="padding: 10px; color: inherit;">
|
||||
<p style="margin: 5px 0;"><strong>Name:</strong> <code><?= htmlspecialchars($username) ?></code></p>
|
||||
<?php if ($username != 'gast'): ?>
|
||||
<p style="margin: 5px 0;"><strong>Nachname:</strong>
|
||||
<code><?= htmlspecialchars($db_res[0]['NACHNAME']) ?></code>
|
||||
</p>
|
||||
<p style="margin: 5px 0;"><strong>E-Mail:</strong>
|
||||
<code><?= htmlspecialchars($db_res[0]['EMAIL']) ?></code>
|
||||
</p>
|
||||
<p style="margin: 5px 0;"><strong>Benutzerrolle:</strong>
|
||||
<code><?= htmlspecialchars($db_res[0]['ROLLE']) ?></code>
|
||||
</p>
|
||||
<p style="margin: 5px 0;"><strong>Home IP:</strong>
|
||||
<code><?= htmlspecialchars($db_res[0]['HOME_IP']) ?></code>
|
||||
</p>
|
||||
<p style="margin: 5px 0;"><strong>Nachname:</strong>
|
||||
<code><?= htmlspecialchars($db_res[0]['NACHNAME']) ?></code>
|
||||
</p>
|
||||
<p style="margin: 5px 0;"><strong>E-Mail:</strong>
|
||||
<code><?= htmlspecialchars($db_res[0]['EMAIL']) ?></code>
|
||||
</p>
|
||||
<p style="margin: 5px 0;"><strong>Benutzerrolle:</strong>
|
||||
<code><?= htmlspecialchars($db_res[0]['ROLLE']) ?></code>
|
||||
</p>
|
||||
<p style="margin: 5px 0;"><strong>Home IP:</strong>
|
||||
<code><?= htmlspecialchars($db_res[0]['HOME_IP']) ?></code>
|
||||
</p>
|
||||
<?php endif ?>
|
||||
</div>
|
||||
</div>
|
||||
@@ -41,18 +59,18 @@ $db_res = DatabaseShow(
|
||||
<div class="group-links"
|
||||
style="padding: 10px; display: flex; flex-direction: row; gap: 10px; flex-wrap: wrap;">
|
||||
<?php if ((new getSpecificData())->getIsAdmin()): ?>
|
||||
<span
|
||||
style="background: #dc3545; color: white; padding: 4px 10px; border-radius: 15px; font-size: 0.8rem; font-weight: bold;">Admin</span>
|
||||
<span
|
||||
style="background: #dc3545; color: white; padding: 4px 10px; border-radius: 15px; font-size: 0.8rem; font-weight: bold;">Admin</span>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ((new getSpecificData())->getIsSuperuser()): ?>
|
||||
<span
|
||||
style="background: #ffc107; color: #000; padding: 4px 10px; border-radius: 15px; font-size: 0.8rem; font-weight: bold;">Superuser</span>
|
||||
<span
|
||||
style="background: #ffc107; color: #000; padding: 4px 10px; border-radius: 15px; font-size: 0.8rem; font-weight: bold;">Superuser</span>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (!(new getSpecificData())->getIsSuperuser() && !(new getSpecificData())->getIsAdmin()): ?>
|
||||
<span
|
||||
style="background: #6c757d; color: white; padding: 4px 10px; border-radius: 15px; font-size: 0.8rem; font-weight: bold;">Standard-Nutzer</span>
|
||||
<span
|
||||
style="background: #6c757d; color: white; padding: 4px 10px; border-radius: 15px; font-size: 0.8rem; font-weight: bold;">Standard-Nutzer</span>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
@@ -67,21 +85,21 @@ $db_res = DatabaseShow(
|
||||
<code>Aktiv</code>
|
||||
</p>
|
||||
<?php if ($is_admin): ?>
|
||||
<p style="margin: 5px 0;"><strong>Client IP:</strong>
|
||||
<code><?= htmlspecialchars((new getSpecificData())->getClientIP()) ?></code>
|
||||
</p>
|
||||
<p style="margin: 5px 0;"><strong>Server IP:</strong>
|
||||
<code><?= htmlspecialchars((new getSpecificData())->getServerIP()) ?></code>
|
||||
</p>
|
||||
<p style="margin: 5px 0;"><strong>Geo IP:</strong>
|
||||
<code><?= htmlspecialchars((new getSpecificData())->getGeoIP((new getSpecificData())->getClientIP())) ?></code>
|
||||
</p>
|
||||
<p style="margin: 5px 0;"><strong>Database IP:</strong>
|
||||
<code><?= htmlspecialchars((new getSpecificData())->getDatabase()) ?></code>
|
||||
</p>
|
||||
<p style="margin: 5px 0;"><strong>Wetter:</strong>
|
||||
<code><?= htmlspecialchars((new getSpecificData())->getWeather()['aktuell']) ?></code>
|
||||
</p>
|
||||
<p style="margin: 5px 0;"><strong>Client IP:</strong>
|
||||
<code><?= htmlspecialchars((new getSpecificData())->getClientIP()) ?></code>
|
||||
</p>
|
||||
<p style="margin: 5px 0;"><strong>Server IP:</strong>
|
||||
<code><?= htmlspecialchars((new getSpecificData())->getServerIP()) ?></code>
|
||||
</p>
|
||||
<p style="margin: 5px 0;"><strong>Geo IP:</strong>
|
||||
<code><?= htmlspecialchars((new getSpecificData())->getGeoIP((new getSpecificData())->getClientIP())) ?></code>
|
||||
</p>
|
||||
<p style="margin: 5px 0;"><strong>Database IP:</strong>
|
||||
<code><?= htmlspecialchars((new getSpecificData())->getDatabase()) ?></code>
|
||||
</p>
|
||||
<p style="margin: 5px 0;"><strong>Wetter:</strong>
|
||||
<code><?= htmlspecialchars((new getSpecificData())->getWeather()['aktuell']) ?></code>
|
||||
</p>
|
||||
<?php endif ?>
|
||||
</div>
|
||||
</div>
|
||||
@@ -89,32 +107,55 @@ $db_res = DatabaseShow(
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="/js/ajaxApi/NotificationAjaxMethods.js"></script>
|
||||
<script src="/js/AjaxMethods.js"></script>
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
const modal = document.getElementById('notificationModal');
|
||||
const confirmBtn = document.getElementById('notificationConfirm');
|
||||
|
||||
if (!modal || !confirmBtn) return; // keine offene Nachricht vorhanden
|
||||
|
||||
confirmBtn.addEventListener('click', async () => {
|
||||
const nachrichtId = modal.dataset.nachrichtId;
|
||||
|
||||
try {
|
||||
await markNotificationAsSeen(nachrichtId);
|
||||
modal.classList.remove('open');
|
||||
setTimeout(() => modal.remove(), 200); // nach dem Fade-out entfernen
|
||||
} catch (err) {
|
||||
alert('Fehler beim Bestätigen: ' + err.message);
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<style>
|
||||
/* Zusätzliche Inline-Styles für die Feinabstimmung in der home_info */
|
||||
.home-dashboard {
|
||||
animation: fadeIn 0.5s ease-in-out;
|
||||
}
|
||||
|
||||
code {
|
||||
background: rgba(0, 0, 0, 0.1);
|
||||
padding: 2px 5px;
|
||||
border-radius: 4px;
|
||||
font-family: monospace;
|
||||
}
|
||||
|
||||
body.dark-mode code {
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
|
||||
@keyframes fadeIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(10px);
|
||||
/* Zusätzliche Inline-Styles für die Feinabstimmung in der home_info */
|
||||
.home-dashboard {
|
||||
animation: fadeIn 0.5s ease-in-out;
|
||||
}
|
||||
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
code {
|
||||
background: rgba(0, 0, 0, 0.1);
|
||||
padding: 2px 5px;
|
||||
border-radius: 4px;
|
||||
font-family: monospace;
|
||||
}
|
||||
|
||||
body.dark-mode code {
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
|
||||
@keyframes fadeIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(10px);
|
||||
}
|
||||
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1460,4 +1460,88 @@ body.dark-mode .autocomplete-suggestions div.active {
|
||||
.register-form input {
|
||||
margin-bottom: 0;
|
||||
/* gap übernimmt jetzt den Abstand, kein doppeltes Spacing mehr */
|
||||
}
|
||||
|
||||
/* ===== Benachrichtigungs-Modal ===== */
|
||||
.notification-overlay {
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
background: rgba(0, 0, 0, 0.6);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 2000;
|
||||
|
||||
opacity: 0;
|
||||
pointer-events: none;
|
||||
transition: opacity 0.2s ease;
|
||||
}
|
||||
|
||||
.notification-overlay.open {
|
||||
opacity: 1;
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
.notification-box {
|
||||
background-color: white;
|
||||
border-radius: 10px;
|
||||
border-top: 4px solid #007bff;
|
||||
width: 420px;
|
||||
max-width: 90%;
|
||||
padding: 28px 32px;
|
||||
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.25);
|
||||
text-align: center;
|
||||
|
||||
transform: translateY(-10px);
|
||||
transition: transform 0.2s ease;
|
||||
}
|
||||
|
||||
.notification-overlay.open .notification-box {
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
body.dark-mode .notification-box {
|
||||
background-color: #1a1a1a;
|
||||
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.6);
|
||||
}
|
||||
|
||||
.notification-box .notification-icon {
|
||||
font-size: 2.2rem;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.notification-box h3 {
|
||||
margin-top: 0;
|
||||
margin-bottom: 12px;
|
||||
font-size: 1.3rem;
|
||||
}
|
||||
|
||||
body.dark-mode .notification-box h3 {
|
||||
color: #f0f0f0;
|
||||
}
|
||||
|
||||
.notification-box p {
|
||||
margin-bottom: 24px;
|
||||
line-height: 1.5;
|
||||
color: #555;
|
||||
white-space: pre-line;
|
||||
}
|
||||
|
||||
body.dark-mode .notification-box p {
|
||||
color: #ccc;
|
||||
}
|
||||
|
||||
.notification-box button {
|
||||
padding: 10px 28px;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
font-size: 1rem;
|
||||
cursor: pointer;
|
||||
background-color: #007bff;
|
||||
color: white;
|
||||
transition: background-color 0.2s ease;
|
||||
}
|
||||
|
||||
.notification-box button:hover {
|
||||
background-color: #0056b3;
|
||||
}
|
||||
Reference in new issue
Block a user