Rechtesystem und Readmes überarbeitet
This commit is contained in:
@@ -0,0 +1,16 @@
|
|||||||
|
# Dokumentation
|
||||||
|
|
||||||
|
Hier liegen die internen Anleitungen und technischen Hilfen fuer das Projekt.
|
||||||
|
|
||||||
|
## Verfuegbar
|
||||||
|
|
||||||
|
- [`docs/README_PROJEKT.md`](README_PROJEKT.md)
|
||||||
|
Grundsaetzliche Erklaerung der Website, ihrer Bereiche und Datenfluesse
|
||||||
|
- [`docs/README_LOCAL_WEBSERVER.md`](README_LOCAL_WEBSERVER.md)
|
||||||
|
Lokale Startanleitung fuer den PHP-Webserver auf den bekannten Arbeitsplaetzen
|
||||||
|
- [`docs/README_RECHTESYSTEM.md`](README_RECHTESYSTEM.md)
|
||||||
|
Beschreibung des aktuellen Rollen- und Seitenrechtesystems
|
||||||
|
|
||||||
|
## Hinweis
|
||||||
|
|
||||||
|
Die bisherigen Dateien im Projekt-Root bleiben als kurze Verweise bestehen, damit bestehende Hinweise nicht sofort kaputtgehen.
|
||||||
@@ -0,0 +1,167 @@
|
|||||||
|
# Projektueberblick
|
||||||
|
|
||||||
|
Diese Datei beschreibt die Website grundsaetzlich: Worum es geht, welche Bereiche es gibt und wie die wichtigsten Bausteine zusammenspielen.
|
||||||
|
|
||||||
|
## Zweck der Website
|
||||||
|
|
||||||
|
`SkyView & AstroTools` ist eine Astronomie-Website des Astronomiemuseums der Sternwarte Sonneberg.
|
||||||
|
|
||||||
|
Die Seite verbindet:
|
||||||
|
|
||||||
|
- oeffentliche Astronomie-Werkzeuge
|
||||||
|
- persoenliche Benutzerfunktionen
|
||||||
|
- Import- und Auswerteprozesse fuer astronomische Daten
|
||||||
|
- Telegram-Anbindung fuer Benachrichtigungen und Tests
|
||||||
|
|
||||||
|
## Hauptbereiche
|
||||||
|
|
||||||
|
Die Website besteht im Kern aus vier Bereichen.
|
||||||
|
|
||||||
|
## 1. Oeffentliche Astronomie-Seiten
|
||||||
|
|
||||||
|
Unter [`public/`](../public) liegen die eigentlichen Seiten der Website.
|
||||||
|
|
||||||
|
Typische Inhalte sind:
|
||||||
|
|
||||||
|
- Mond und Mondphasen
|
||||||
|
- Planetensichtbarkeit
|
||||||
|
- Sternenhimmel
|
||||||
|
- Meteorstroeme
|
||||||
|
- Finsternisse und Bedeckungen
|
||||||
|
- Geocron und Geocron 3D
|
||||||
|
- Vorhersage-Seiten wie Monats- und Wochenvorhersage
|
||||||
|
- Spezialseiten wie die T-CrB-Lichtkurve
|
||||||
|
|
||||||
|
Diese Seiten nutzen in der Regel den gemeinsamen Header und Footer:
|
||||||
|
|
||||||
|
- [`public/header.php`](../public/header.php)
|
||||||
|
- [`public/footer.php`](../public/footer.php)
|
||||||
|
|
||||||
|
## 2. Benutzerkonten
|
||||||
|
|
||||||
|
Die Seite besitzt eigene Benutzerkonten mit Login.
|
||||||
|
|
||||||
|
Wichtige Konto-Seiten:
|
||||||
|
|
||||||
|
- [`public/login.php`](../public/login.php)
|
||||||
|
- [`public/register.php`](../public/register.php)
|
||||||
|
- [`public/settings.php`](../public/settings.php)
|
||||||
|
- [`public/my_favorites.php`](../public/my_favorites.php)
|
||||||
|
|
||||||
|
Benutzer koennen dort unter anderem:
|
||||||
|
|
||||||
|
- ihr Konto verwalten
|
||||||
|
- Telegram verbinden
|
||||||
|
- Standorte verwalten
|
||||||
|
- Favoriten pflegen
|
||||||
|
|
||||||
|
## 3. Rechtesystem
|
||||||
|
|
||||||
|
Die Seite hat ein Rollen- und Seitenrechtesystem.
|
||||||
|
|
||||||
|
Aktuell gibt es:
|
||||||
|
|
||||||
|
- `user`
|
||||||
|
- `admin`
|
||||||
|
- `master`
|
||||||
|
|
||||||
|
Wichtig:
|
||||||
|
|
||||||
|
- `admin` und `master` haben Vollzugriff auf die geschuetzten Seiten
|
||||||
|
- normale Benutzer erhalten gezielte Seitenfreigaben
|
||||||
|
- das Header-Menue passt sich an die Seitenrechte an
|
||||||
|
|
||||||
|
Die Details dazu stehen in:
|
||||||
|
|
||||||
|
- [`docs/README_RECHTESYSTEM.md`](README_RECHTESYSTEM.md)
|
||||||
|
|
||||||
|
## 4. Hintergrundprozesse und Datenimporte
|
||||||
|
|
||||||
|
Die Website arbeitet nicht nur mit statischen Seiten, sondern auch mit Import- und Cron-Skripten.
|
||||||
|
|
||||||
|
Wichtige Skripte liegen unter:
|
||||||
|
|
||||||
|
- [`scripts/import/`](../scripts/import)
|
||||||
|
- [`scripts/telegram/`](../scripts/telegram)
|
||||||
|
|
||||||
|
Beispiele:
|
||||||
|
|
||||||
|
- [`scripts/import/import_tcrb.php`](../scripts/import/import_tcrb.php)
|
||||||
|
Importiert AAVSO-WebObs-Daten fuer T CrB
|
||||||
|
- [`scripts/import/import_celestrak_active.php`](../scripts/import/import_celestrak_active.php)
|
||||||
|
Importiert Satellitendaten
|
||||||
|
- [`scripts/telegram/telegram_cron.php`](../scripts/telegram/telegram_cron.php)
|
||||||
|
Fuehrt Telegram-Aufgaben zeitgesteuert aus
|
||||||
|
|
||||||
|
## T CrB
|
||||||
|
|
||||||
|
Ein aktueller Spezialbereich ist `T CrB`.
|
||||||
|
|
||||||
|
Dazu gehoeren:
|
||||||
|
|
||||||
|
- Import der AAVSO-Daten
|
||||||
|
- Speicherung in der Datenbank
|
||||||
|
- grafische Darstellung als Lichtkurve
|
||||||
|
- Telegram-Benachrichtigung zum letzten `V`-Wert
|
||||||
|
|
||||||
|
Wichtige Dateien:
|
||||||
|
|
||||||
|
- [`scripts/import/import_tcrb.php`](../scripts/import/import_tcrb.php)
|
||||||
|
- [`public/tcrb_lightcurve.php`](../public/tcrb_lightcurve.php)
|
||||||
|
- [`scripts/telegram/telegram_cron.php`](../scripts/telegram/telegram_cron.php)
|
||||||
|
|
||||||
|
## Telegram
|
||||||
|
|
||||||
|
Die Website besitzt eine Telegram-Anbindung.
|
||||||
|
|
||||||
|
Damit koennen Benutzer:
|
||||||
|
|
||||||
|
- ihr Konto mit Telegram verknuepfen
|
||||||
|
- spaeter Nachrichten oder Diagramme erhalten
|
||||||
|
|
||||||
|
Wichtige Bausteine:
|
||||||
|
|
||||||
|
- [`public/settings.php`](../public/settings.php)
|
||||||
|
- [`public/telegram/connect.php`](../public/telegram/connect.php)
|
||||||
|
- [`public/telegram/webhook.php`](../public/telegram/webhook.php)
|
||||||
|
- [`public/telegram/broadcast_test.php`](../public/telegram/broadcast_test.php)
|
||||||
|
- [`scripts/telegram/telegram_cron.php`](../scripts/telegram/telegram_cron.php)
|
||||||
|
|
||||||
|
## Datenfluss grob
|
||||||
|
|
||||||
|
Vereinfacht sieht der Ablauf so aus:
|
||||||
|
|
||||||
|
1. Import-Skripte holen astronomische Daten aus externen Quellen
|
||||||
|
2. Die Daten werden in der Datenbank gespeichert
|
||||||
|
3. Seiten unter `public/` lesen diese Daten aus und stellen sie dar
|
||||||
|
4. Cron-Skripte koennen daraus Telegram-Nachrichten oder andere Folgeaktionen erzeugen
|
||||||
|
|
||||||
|
## Technischer Aufbau
|
||||||
|
|
||||||
|
Die Website ist aktuell klassisch in PHP aufgebaut.
|
||||||
|
|
||||||
|
Wichtige Verzeichnisse:
|
||||||
|
|
||||||
|
- [`public/`](../public)
|
||||||
|
Webroot und PHP-Seiten
|
||||||
|
- [`config/`](../config)
|
||||||
|
Konfigurationen und SQL
|
||||||
|
- [`scripts/`](../scripts)
|
||||||
|
Import- und Cron-Skripte
|
||||||
|
- [`docs/`](.)
|
||||||
|
Projektdokumentation
|
||||||
|
|
||||||
|
## Fuer neue Arbeit an der Seite wichtig
|
||||||
|
|
||||||
|
Wenn neue Funktionen dazukommen, sollte man immer an diese Punkte denken:
|
||||||
|
|
||||||
|
- braucht die Seite einen Eintrag im Rechtesystem
|
||||||
|
- soll sie im Header-Menue erscheinen
|
||||||
|
- braucht sie Datenimport oder Cron
|
||||||
|
- braucht sie Telegram-Anbindung
|
||||||
|
- braucht sie Dokumentation in `docs`
|
||||||
|
|
||||||
|
## Passende Zusatzdokumente
|
||||||
|
|
||||||
|
- [`docs/README_LOCAL_WEBSERVER.md`](README_LOCAL_WEBSERVER.md)
|
||||||
|
- [`docs/README_RECHTESYSTEM.md`](README_RECHTESYSTEM.md)
|
||||||
@@ -22,18 +22,18 @@ Es gibt zurzeit diese Rollen:
|
|||||||
- `master`
|
- `master`
|
||||||
Vollzugriff auf alle Seiten unter `public/` plus Verwaltung der Seitenfreigaben anderer Benutzer
|
Vollzugriff auf alle Seiten unter `public/` plus Verwaltung der Seitenfreigaben anderer Benutzer
|
||||||
|
|
||||||
Die Rollen-Helfer liegen in [auth_helpers.php](/c:/Users/ich/source/repos/skyview.astronomiemuseum.de/public/auth_helpers.php).
|
Die Rollen-Helfer liegen in [`public/auth_helpers.php`](../public/auth_helpers.php).
|
||||||
|
|
||||||
## Zentrale Logik
|
## Zentrale Logik
|
||||||
|
|
||||||
Die zentrale Rechtebasis besteht aus drei Bausteinen:
|
Die zentrale Rechtebasis besteht aus drei Bausteinen:
|
||||||
|
|
||||||
- [auth_helpers.php](/c:/Users/ich/source/repos/skyview.astronomiemuseum.de/public/auth_helpers.php)
|
- [`public/auth_helpers.php`](../public/auth_helpers.php)
|
||||||
Enthält Rollen-Helfer, Allowlist und die Liste der freigebbaren Seiten
|
Enthaelt Rollen-Helfer, Allowlist und die Liste der freigebbaren Seiten
|
||||||
- [header.php](/c:/Users/ich/source/repos/skyview.astronomiemuseum.de/public/header.php)
|
- [`public/header.php`](../public/header.php)
|
||||||
Prueft beim Aufruf einer Seite den Zugriff und baut das Menue passend zu den Rechten
|
Prueft beim Aufruf einer Seite den Zugriff und baut das Menue passend zu den Rechten
|
||||||
- [admin_users.php](/c:/Users/ich/source/repos/skyview.astronomiemuseum.de/public/admin_users.php)
|
- [`public/admin_users.php`](../public/admin_users.php)
|
||||||
Enthält die Benutzerverwaltung und die Seitenmatrix fuer `master`
|
Enthaelt die Benutzerverwaltung und die Seitenmatrix fuer `master`
|
||||||
|
|
||||||
## Datenbank
|
## Datenbank
|
||||||
|
|
||||||
@@ -59,7 +59,7 @@ Wichtig:
|
|||||||
|
|
||||||
## Oeffentliche Ausnahmen
|
## Oeffentliche Ausnahmen
|
||||||
|
|
||||||
Einige Seiten bleiben ohne Seitenfreigabe erreichbar. Diese stehen in der Allowlist in [auth_helpers.php](/c:/Users/ich/source/repos/skyview.astronomiemuseum.de/public/auth_helpers.php):
|
Einige Seiten bleiben ohne Seitenfreigabe erreichbar. Diese stehen in der Allowlist in [`public/auth_helpers.php`](../public/auth_helpers.php):
|
||||||
|
|
||||||
- `login.php`
|
- `login.php`
|
||||||
- `register.php`
|
- `register.php`
|
||||||
@@ -82,10 +82,11 @@ Wichtig:
|
|||||||
|
|
||||||
## Wie das Menue funktioniert
|
## Wie das Menue funktioniert
|
||||||
|
|
||||||
Das Header-Menue wird ebenfalls in [header.php](/c:/Users/ich/source/repos/skyview.astronomiemuseum.de/public/header.php) aufgebaut.
|
Das Header-Menue wird ebenfalls in [`public/header.php`](../public/header.php) aufgebaut.
|
||||||
|
|
||||||
Dabei gilt:
|
Dabei gilt:
|
||||||
|
|
||||||
|
- ausgeloggte Besucher sehen nur `Anmelden` und `Registrieren`
|
||||||
- `admin` und `master` sehen das volle Menue
|
- `admin` und `master` sehen das volle Menue
|
||||||
- normale Benutzer sehen nur die Menuepunkte, deren `href` in ihren Seitenfreigaben vorhanden ist
|
- normale Benutzer sehen nur die Menuepunkte, deren `href` in ihren Seitenfreigaben vorhanden ist
|
||||||
- auch der Kontobereich unten im Menue wird entsprechend gefiltert
|
- auch der Kontobereich unten im Menue wird entsprechend gefiltert
|
||||||
@@ -99,7 +100,7 @@ Beispiel:
|
|||||||
|
|
||||||
## Wie ein Master Seiten freigibt
|
## Wie ein Master Seiten freigibt
|
||||||
|
|
||||||
Die Freigaben werden in [admin_users.php](/c:/Users/ich/source/repos/skyview.astronomiemuseum.de/public/admin_users.php) verwaltet.
|
Die Freigaben werden in [`public/admin_users.php`](../public/admin_users.php) verwaltet.
|
||||||
|
|
||||||
Ablauf:
|
Ablauf:
|
||||||
|
|
||||||
@@ -116,7 +117,7 @@ Besonderheiten:
|
|||||||
|
|
||||||
## Wo die freigebaren Seiten definiert sind
|
## Wo die freigebaren Seiten definiert sind
|
||||||
|
|
||||||
Die Liste der freigebaren Seiten steht zentral in [auth_helpers.php](/c:/Users/ich/source/repos/skyview.astronomiemuseum.de/public/auth_helpers.php) in:
|
Die Liste der freigebaren Seiten steht zentral in [`public/auth_helpers.php`](../public/auth_helpers.php) in:
|
||||||
|
|
||||||
- `manageablePublicPages()`
|
- `manageablePublicPages()`
|
||||||
|
|
||||||
@@ -133,7 +134,7 @@ Wenn eine neue Seite unter `public/` dazukommt, sind in der Regel diese Schritte
|
|||||||
1. Seite anlegen
|
1. Seite anlegen
|
||||||
2. Seite so bauen, dass sie den gemeinsamen Header nutzt
|
2. Seite so bauen, dass sie den gemeinsamen Header nutzt
|
||||||
3. In `manageablePublicPages()` eintragen
|
3. In `manageablePublicPages()` eintragen
|
||||||
4. Falls noetig als Menuepunkt in [header.php](/c:/Users/ich/source/repos/skyview.astronomiemuseum.de/public/header.php) eintragen
|
4. Falls noetig als Menuepunkt in [`public/header.php`](../public/header.php) eintragen
|
||||||
5. Darauf achten, dass `href` und `page_key` exakt gleich sind
|
5. Darauf achten, dass `href` und `page_key` exakt gleich sind
|
||||||
|
|
||||||
Beispiel:
|
Beispiel:
|
||||||
@@ -160,7 +161,7 @@ Falsch:
|
|||||||
|
|
||||||
- `index.php`
|
- `index.php`
|
||||||
|
|
||||||
Die Seitenerkennung dafuer macht `currentPublicPageKey()` in [auth_helpers.php](/c:/Users/ich/source/repos/skyview.astronomiemuseum.de/public/auth_helpers.php).
|
Die Seitenerkennung dafuer macht `currentPublicPageKey()` in [`public/auth_helpers.php`](../public/auth_helpers.php).
|
||||||
|
|
||||||
## Aktueller Stand
|
## Aktueller Stand
|
||||||
|
|
||||||
@@ -294,6 +294,7 @@ if ($loggedIn && !$hasFullAdminAccess && $pdoHeader !== null) {
|
|||||||
<span></span>
|
<span></span>
|
||||||
</button>
|
</button>
|
||||||
<nav class="menu-panel" id="headerMenuPanel" hidden>
|
<nav class="menu-panel" id="headerMenuPanel" hidden>
|
||||||
|
<?php if ($loggedIn): ?>
|
||||||
<div class="menu-cols">
|
<div class="menu-cols">
|
||||||
<?php foreach ($menuGroups as $group): ?>
|
<?php foreach ($menuGroups as $group): ?>
|
||||||
<div class="menu-group">
|
<div class="menu-group">
|
||||||
@@ -307,6 +308,7 @@ if ($loggedIn && !$hasFullAdminAccess && $pdoHeader !== null) {
|
|||||||
<?php endforeach; ?>
|
<?php endforeach; ?>
|
||||||
</div>
|
</div>
|
||||||
<div class="menu-divider"></div>
|
<div class="menu-divider"></div>
|
||||||
|
<?php endif; ?>
|
||||||
<div class="menu-bottom">
|
<div class="menu-bottom">
|
||||||
<div class="menu-group">
|
<div class="menu-group">
|
||||||
<div class="menu-title">Konto</div>
|
<div class="menu-title">Konto</div>
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ $publicBasePath = '../';
|
|||||||
$pageTitle = 'Telegram-Testversand - AstroTools';
|
$pageTitle = 'Telegram-Testversand - AstroTools';
|
||||||
$headerIntroPre = 'Administration';
|
$headerIntroPre = 'Administration';
|
||||||
$headerIntroTitle = 'Telegram-Testversand';
|
$headerIntroTitle = 'Telegram-Testversand';
|
||||||
$headerIntroSub = 'Testnachricht an alle verknuepften Telegram-Konten senden.';
|
$headerIntroSub = 'Testnachrichten nur an verknuepfte Master-Konten senden.';
|
||||||
$errors = [];
|
$errors = [];
|
||||||
$successMessage = '';
|
$successMessage = '';
|
||||||
$resultRows = [];
|
$resultRows = [];
|
||||||
@@ -257,7 +257,7 @@ $currentUser = $stmtCurrentUser->fetch();
|
|||||||
|
|
||||||
if (
|
if (
|
||||||
!$currentUser ||
|
!$currentUser ||
|
||||||
!isAdminLikeRole((string) $currentUser['role']) ||
|
!isMasterRole((string) $currentUser['role']) ||
|
||||||
(int) $currentUser['is_active'] !== 1
|
(int) $currentUser['is_active'] !== 1
|
||||||
) {
|
) {
|
||||||
$_SESSION = [];
|
$_SESSION = [];
|
||||||
@@ -271,11 +271,13 @@ $stmtRecipients = $pdo->query("
|
|||||||
`id`,
|
`id`,
|
||||||
`username`,
|
`username`,
|
||||||
`display_name`,
|
`display_name`,
|
||||||
|
`role`,
|
||||||
`telegram_username`,
|
`telegram_username`,
|
||||||
`telegram_chat_id`,
|
`telegram_chat_id`,
|
||||||
`telegram_connected_at`
|
`telegram_connected_at`
|
||||||
FROM `app_users`
|
FROM `app_users`
|
||||||
WHERE `is_active` = 1
|
WHERE `is_active` = 1
|
||||||
|
AND `role` = 'master'
|
||||||
AND `telegram_chat_id` IS NOT NULL
|
AND `telegram_chat_id` IS NOT NULL
|
||||||
AND `telegram_chat_id` <> ''
|
AND `telegram_chat_id` <> ''
|
||||||
ORDER BY COALESCE(`display_name`, `username`) ASC, `id` ASC
|
ORDER BY COALESCE(`display_name`, `username`) ASC, `id` ASC
|
||||||
@@ -316,7 +318,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (empty($recipients)) {
|
if (empty($recipients)) {
|
||||||
$errors[] = 'Es gibt derzeit keine verknuepften Telegram-Nutzer.';
|
$errors[] = 'Es gibt derzeit keine verknuepften Master-Konten mit Telegram.';
|
||||||
}
|
}
|
||||||
|
|
||||||
$targetRecipients = [];
|
$targetRecipients = [];
|
||||||
@@ -387,7 +389,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$successMessage = sprintf(
|
$successMessage = sprintf(
|
||||||
'Versand abgeschlossen: %d von %d Telegram-Nutzern erfolgreich erreicht.',
|
'Versand abgeschlossen: %d von %d Master-Konten erfolgreich erreicht.',
|
||||||
$successCount,
|
$successCount,
|
||||||
count($targetRecipients)
|
count($targetRecipients)
|
||||||
);
|
);
|
||||||
@@ -412,11 +414,11 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|||||||
<div class="card">
|
<div class="card">
|
||||||
<h2>Testnachricht senden</h2>
|
<h2>Testnachricht senden</h2>
|
||||||
<p class="hint">
|
<p class="hint">
|
||||||
Diese Seite sendet eine Nachricht an alle aktiven Benutzerkonten mit hinterlegter Telegram-Chat-ID.
|
Diese Seite sendet Testnachrichten ausschliesslich an aktive Master-Konten mit hinterlegter Telegram-Chat-ID.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<table class="data-table mb-lg">
|
<table class="data-table mb-lg">
|
||||||
<tr><td>Verknuepfte Telegram-Nutzer</td><td><?= count($recipients) ?></td></tr>
|
<tr><td>Verknuepfte Master-Konten</td><td><?= count($recipients) ?></td></tr>
|
||||||
<tr><td>Bot</td><td><?= h(($telegramConfig['bot_username'] ?? '') !== '' ? '@' . (string) $telegramConfig['bot_username'] : 'nicht konfiguriert') ?></td></tr>
|
<tr><td>Bot</td><td><?= h(($telegramConfig['bot_username'] ?? '') !== '' ? '@' . (string) $telegramConfig['bot_username'] : 'nicht konfiguriert') ?></td></tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
@@ -436,7 +438,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|||||||
</label>
|
</label>
|
||||||
<label>
|
<label>
|
||||||
<input type="radio" name="send_mode" value="all" <?= $sendMode === 'all' ? 'checked' : '' ?>>
|
<input type="radio" name="send_mode" value="all" <?= $sendMode === 'all' ? 'checked' : '' ?>>
|
||||||
An alle verknuepften Nutzer senden
|
An alle verknuepften Master senden
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -465,14 +467,14 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|||||||
><?= h($messageText) ?></textarea>
|
><?= h($messageText) ?></textarea>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button type="submit" class="btn btn-primary">Testnachricht an alle senden</button>
|
<button type="submit" class="btn btn-primary">Testnachricht an Master senden</button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<h2>Empfaenger</h2>
|
<h2>Empfaenger</h2>
|
||||||
<?php if (empty($recipients)): ?>
|
<?php if (empty($recipients)): ?>
|
||||||
<p class="hint">Noch keine verknuepften Telegram-Konten vorhanden.</p>
|
<p class="hint">Noch keine verknuepften Master-Konten vorhanden.</p>
|
||||||
<?php else: ?>
|
<?php else: ?>
|
||||||
<table class="data-table">
|
<table class="data-table">
|
||||||
<thead>
|
<thead>
|
||||||
|
|||||||
Reference in New Issue
Block a user