diff --git a/resources/views/livewire/help/content/de/audit.blade.php b/resources/views/livewire/help/content/de/audit.blade.php
new file mode 100644
index 0000000..a51b621
--- /dev/null
+++ b/resources/views/livewire/help/content/de/audit.blade.php
@@ -0,0 +1,15 @@
+@php
+ $h = 'font-display text-base font-semibold text-ink';
+ $p = 'text-sm leading-relaxed text-ink-2';
+ $li = 'text-sm leading-relaxed text-ink-2';
+@endphp
+
+
+
Audit-Log
+
Das Audit-Log protokolliert sicherheits- und konfigurationsrelevante Aktionen — wer, wann, was, von welcher IP. So bleibt jede Änderung nachvollziehbar und einem Benutzer zugeordnet.
+
+ - Erfasst u. a.: Logins, 2FA-Änderungen, Domain-/TLS-Änderungen, Update-Anstöße, Server-Hardening und SSH-Aktionen.
+ - Aufbewahrung: die Vorhaltedauer lässt sich konfigurieren; ältere Einträge werden danach automatisch bereinigt.
+
+
Hinweis: Hinter einem externen Proxy zeigt das Audit-Log nur dann die echte Besucher-IP, wenn TRUSTED_PROXY_CIDR gesetzt ist (siehe „Domain, TLS & Reverse-Proxy").
+
diff --git a/resources/views/livewire/help/content/de/email.blade.php b/resources/views/livewire/help/content/de/email.blade.php
new file mode 100644
index 0000000..3f13a25
--- /dev/null
+++ b/resources/views/livewire/help/content/de/email.blade.php
@@ -0,0 +1,15 @@
+@php
+ $h = 'font-display text-base font-semibold text-ink';
+ $p = 'text-sm leading-relaxed text-ink-2';
+ $li = 'text-sm leading-relaxed text-ink-2';
+@endphp
+
+
+
E-Mail (SMTP)
+
Unter Einstellungen → E-Mail hinterlegst du einen SMTP-Server. Damit kann das Panel E-Mails versenden — vor allem den Passwort-Reset-Link über die „Passwort vergessen"-Seite.
+
+ - Host, Port, Verschlüsselung, Benutzer/Passwort und die Absenderadresse eintragen.
+ - Mit „Testmail senden" prüfst du die Konfiguration sofort.
+
+
Ohne SMTP funktioniert die Wiederherstellung weiterhin über den 2FA-Nachweis (E-Mail + TOTP oder Backup-Code) oder über die Host-Konsole — siehe „Konto-Wiederherstellung".
+
diff --git a/resources/views/livewire/help/content/de/recovery.blade.php b/resources/views/livewire/help/content/de/recovery.blade.php
new file mode 100644
index 0000000..34c74ea
--- /dev/null
+++ b/resources/views/livewire/help/content/de/recovery.blade.php
@@ -0,0 +1,24 @@
+@php
+ $h = 'font-display text-base font-semibold text-ink';
+ $p = 'text-sm leading-relaxed text-ink-2';
+ $li = 'text-sm leading-relaxed text-ink-2';
+ $code = 'rounded bg-inset px-1.5 py-0.5 font-mono text-[12px] text-accent-text';
+ $pre = 'overflow-x-auto rounded-md border border-line bg-inset p-3 font-mono text-[11px] leading-relaxed text-ink-2';
+@endphp
+
+
+
Konto-Wiederherstellung
+
Mehrere Wege, falls du nicht mehr reinkommst — vom bequemsten zum letzten Ausweg:
+
+ - Passwort vergessen: die „Passwort vergessen"-Seite bietet einen E-Mail-Reset-Link (wenn SMTP konfiguriert ist, gültig 15 Min) oder einen 2FA-Nachweis-Reset (E-Mail + TOTP oder Backup-Code → neues Passwort).
+ - Bare-IP-Zugang:
http://<Server-IP> bleibt immer erreichbar — falls die Domain (DNS/Zertifikat/Proxy) gerade nicht geht. Beachte: über diesen Weg kein Security-Key, nur TOTP oder Backup-Code (siehe „Sicherheit & 2FA").
+
+
+
+
+
Komplett ausgesperrt (letzter Ausweg)
+
Passwort und 2FA verloren, kein SMTP? Vom Host wiederherstellen — per SSH auf den Server einloggen und im Projektverzeichnis ausführen:
+
cd clusev
+docker compose -f docker-compose.prod.yml exec app php artisan clusev:reset-admin
+
clusev:reset-admin entfernt den zweiten Faktor, sodass du beim nächsten Login ein neues Passwort setzen kannst.
+
diff --git a/resources/views/livewire/help/content/de/servers.blade.php b/resources/views/livewire/help/content/de/servers.blade.php
new file mode 100644
index 0000000..a9d4b2c
--- /dev/null
+++ b/resources/views/livewire/help/content/de/servers.blade.php
@@ -0,0 +1,17 @@
+@php
+ $h = 'font-display text-base font-semibold text-ink';
+ $p = 'text-sm leading-relaxed text-ink-2';
+ $li = 'text-sm leading-relaxed text-ink-2';
+ $code = 'rounded bg-inset px-1.5 py-0.5 font-mono text-[12px] text-accent-text';
+@endphp
+
+
+
Server & SSH
+
Clusev verwaltet die Flotte agentenlos über SSH — auf den Zielservern wird nichts installiert. Du fügst Server mit Host/IP, Port und Zugangsdaten hinzu; im Dashboard und auf der Server-Detailseite siehst du Metriken, Dienste, Dateien und mehr.
+
+ - Zugangsdaten-Tresor: SSH-Passwörter/Schlüssel werden verschlüsselt gespeichert (App-Key), nie im Klartext.
+ - Hardening: auf der Server-Detailseite — UFW/firewalld-Regeln, fail2ban-Status, und ein Ein-Klick-Ablauf „SSH-Schlüssel erzeugen und Passwort-Login sicher abschalten".
+ - SSH-Key-Provisioning: erzeugt ein Schlüsselpaar, hinterlegt den öffentlichen Schlüssel auf dem Zielserver und stellt die Verbindung danach auf Key-Auth um.
+
+
Jede Aktion über SSH wird im Audit-Log dem ausführenden Benutzer zugeordnet.
+
diff --git a/resources/views/livewire/help/content/de/sessions.blade.php b/resources/views/livewire/help/content/de/sessions.blade.php
new file mode 100644
index 0000000..0076ada
--- /dev/null
+++ b/resources/views/livewire/help/content/de/sessions.blade.php
@@ -0,0 +1,16 @@
+@php
+ $h = 'font-display text-base font-semibold text-ink';
+ $p = 'text-sm leading-relaxed text-ink-2';
+ $li = 'text-sm leading-relaxed text-ink-2';
+@endphp
+
+
+
Sitzungen
+
Unter Einstellungen → Sitzungen siehst du alle aktiven Sitzungen deines Kontos (Gerät, Browser, IP, letzte Aktivität). Du kannst eine einzelne Sitzung beenden oder alle anderen außer der aktuellen abmelden.
+
Ein Passwortwechsel macht jede andere Sitzung automatisch ungültig — die aktive Sitzung bleibt bestehen.
+
+
+
+
Mehrere Administratoren
+
Unter Einstellungen → Benutzer legst du weitere Admin-Konten an. Jede Aktion wird im Audit-Log dem jeweiligen Benutzer zugeordnet, und du kannst aktive Sitzungen pro Gerät, pro Benutzer oder global widerrufen.
+
diff --git a/resources/views/livewire/help/content/de/updates.blade.php b/resources/views/livewire/help/content/de/updates.blade.php
new file mode 100644
index 0000000..48ab3dd
--- /dev/null
+++ b/resources/views/livewire/help/content/de/updates.blade.php
@@ -0,0 +1,16 @@
+@php
+ $h = 'font-display text-base font-semibold text-ink';
+ $p = 'text-sm leading-relaxed text-ink-2';
+ $li = 'text-sm leading-relaxed text-ink-2';
+ $code = 'rounded bg-inset px-1.5 py-0.5 font-mono text-[12px] text-accent-text';
+@endphp
+
+
+
Updates
+
Unter Version & Releases prüft das Panel beim Öffnen automatisch, ob eine neuere Version im Kanal verfügbar ist (Vergleich mit dem neuesten getaggten Release). Ist eines verfügbar, erscheint der Knopf „Jetzt aktualisieren".
+
+ - Per Knopf: „Jetzt aktualisieren" anstoßen. Das Panel ist während des Neubaus ein bis zwei Minuten kurz nicht erreichbar; danach springt die Anzeige selbst auf „Aktuell".
+ - Per SSH: auf dem Host
cd clusev und sudo ./update.sh ausführen.
+
+
Beim Update wird das Image neu gebaut (inkl. npm run build für CSS/JS) und es werden Datenbank-Migrationen angewendet. Stil-Änderungen und Schema-Updates greifen also automatisch. Secrets und die konfigurierte Domain bleiben erhalten.
+
diff --git a/resources/views/livewire/help/content/en/audit.blade.php b/resources/views/livewire/help/content/en/audit.blade.php
new file mode 100644
index 0000000..18d712f
--- /dev/null
+++ b/resources/views/livewire/help/content/en/audit.blade.php
@@ -0,0 +1,15 @@
+@php
+ $h = 'font-display text-base font-semibold text-ink';
+ $p = 'text-sm leading-relaxed text-ink-2';
+ $li = 'text-sm leading-relaxed text-ink-2';
+@endphp
+
+
+
Audit log
+
The Audit log records security- and configuration-relevant actions — who, when, what, from which IP. Every change stays traceable and attributed to a user.
+
+ - Captures, among others: logins, 2FA changes, domain/TLS changes, update triggers, server hardening and SSH actions.
+ - Retention: the keep duration is configurable; older entries are pruned automatically afterwards.
+
+
Note: behind an external proxy the audit log shows the real visitor IP only when TRUSTED_PROXY_CIDR is set (see "Domain, TLS & reverse proxy").
+
diff --git a/resources/views/livewire/help/content/en/email.blade.php b/resources/views/livewire/help/content/en/email.blade.php
new file mode 100644
index 0000000..0f9398b
--- /dev/null
+++ b/resources/views/livewire/help/content/en/email.blade.php
@@ -0,0 +1,15 @@
+@php
+ $h = 'font-display text-base font-semibold text-ink';
+ $p = 'text-sm leading-relaxed text-ink-2';
+ $li = 'text-sm leading-relaxed text-ink-2';
+@endphp
+
+
+
Email (SMTP)
+
Under Settings → Email you configure an SMTP server. This lets the panel send e-mail — primarily the password-reset link from the "Forgot password" screen.
+
+ - Enter host, port, encryption, username/password and the sender address.
+ - Use "Send test email" to verify the configuration right away.
+
+
Without SMTP, recovery still works via the 2FA proof (e-mail + TOTP or a backup code) or via the host console — see "Account recovery".
+
diff --git a/resources/views/livewire/help/content/en/recovery.blade.php b/resources/views/livewire/help/content/en/recovery.blade.php
new file mode 100644
index 0000000..1491d19
--- /dev/null
+++ b/resources/views/livewire/help/content/en/recovery.blade.php
@@ -0,0 +1,24 @@
+@php
+ $h = 'font-display text-base font-semibold text-ink';
+ $p = 'text-sm leading-relaxed text-ink-2';
+ $li = 'text-sm leading-relaxed text-ink-2';
+ $code = 'rounded bg-inset px-1.5 py-0.5 font-mono text-[12px] text-accent-text';
+ $pre = 'overflow-x-auto rounded-md border border-line bg-inset p-3 font-mono text-[11px] leading-relaxed text-ink-2';
+@endphp
+
+
+
Account recovery
+
Several ways back in if you are locked out — from most convenient to last resort:
+
+ - Forgot password: the "Forgot password" screen offers an e-mail reset link (when SMTP is configured, valid 15 min) or a 2FA-proof reset (e-mail + TOTP or a backup code → new password).
+ - Bare-IP access:
http://<server-ip> always stays reachable — in case the domain (DNS/cert/proxy) is currently down. Note: no security key over this path, only TOTP or a backup code (see "Security & 2FA").
+
+
+
+
+
Completely locked out (last resort)
+
Lost password and 2FA, no SMTP? Recover from the host — SSH into the server and run in the project directory:
+
cd clusev
+docker compose -f docker-compose.prod.yml exec app php artisan clusev:reset-admin
+
clusev:reset-admin clears the second factor so you can set a new password on the next login.
+
diff --git a/resources/views/livewire/help/content/en/servers.blade.php b/resources/views/livewire/help/content/en/servers.blade.php
new file mode 100644
index 0000000..15b41d4
--- /dev/null
+++ b/resources/views/livewire/help/content/en/servers.blade.php
@@ -0,0 +1,17 @@
+@php
+ $h = 'font-display text-base font-semibold text-ink';
+ $p = 'text-sm leading-relaxed text-ink-2';
+ $li = 'text-sm leading-relaxed text-ink-2';
+ $code = 'rounded bg-inset px-1.5 py-0.5 font-mono text-[12px] text-accent-text';
+@endphp
+
+
+
Servers & SSH
+
Clusev manages the fleet agentless over SSH — nothing is installed on the target servers. You add servers with host/IP, port and credentials; the dashboard and the server detail page show metrics, services, files and more.
+
+ - Credential vault: SSH passwords/keys are stored encrypted (app key), never in plaintext.
+ - Hardening: on the server detail page — UFW/firewalld rules, fail2ban status, and a one-click "generate an SSH key and safely disable password login" flow.
+ - SSH key provisioning: generates a key pair, installs the public key on the target server and switches the connection to key auth afterwards.
+
+
Every action over SSH is attributed to the acting user in the audit log.
+
diff --git a/resources/views/livewire/help/content/en/sessions.blade.php b/resources/views/livewire/help/content/en/sessions.blade.php
new file mode 100644
index 0000000..9286c89
--- /dev/null
+++ b/resources/views/livewire/help/content/en/sessions.blade.php
@@ -0,0 +1,15 @@
+@php
+ $h = 'font-display text-base font-semibold text-ink';
+ $p = 'text-sm leading-relaxed text-ink-2';
+@endphp
+
+
+
Sessions (Sitzungen)
+
Under Settings → Sessions you see all active sessions of your account (device, browser, IP, last activity). You can end a single session or sign out all others except the current one.
+
A password change automatically invalidates every other session — the active session stays.
+
+
+
+
Multiple administrators
+
Under Settings → Users you add further admin accounts. Every action is attributed to the respective user in the audit log, and you can revoke active sessions per device, per user, or globally.
+
diff --git a/resources/views/livewire/help/content/en/updates.blade.php b/resources/views/livewire/help/content/en/updates.blade.php
new file mode 100644
index 0000000..663fc39
--- /dev/null
+++ b/resources/views/livewire/help/content/en/updates.blade.php
@@ -0,0 +1,16 @@
+@php
+ $h = 'font-display text-base font-semibold text-ink';
+ $p = 'text-sm leading-relaxed text-ink-2';
+ $li = 'text-sm leading-relaxed text-ink-2';
+ $code = 'rounded bg-inset px-1.5 py-0.5 font-mono text-[12px] text-accent-text';
+@endphp
+
+
+
Updates
+
Under Version & Releases the panel checks on open whether a newer release is available in the channel (compared against the newest tagged release). When one is available, the "Update now" button appears.
+
+ - From the button: trigger "Update now". The panel is briefly unreachable for a minute or two during the rebuild; afterwards the card flips to "Current" on its own.
+ - Over SSH: on the host run
cd clusev and sudo ./update.sh.
+
+
An update rebuilds the image (including npm run build for CSS/JS) and applies database migrations. So style changes and schema updates take effect automatically. Secrets and the configured domain are preserved.
+
diff --git a/tests/Feature/HelpPageTest.php b/tests/Feature/HelpPageTest.php
index 9c06098..36b58bd 100644
--- a/tests/Feature/HelpPageTest.php
+++ b/tests/Feature/HelpPageTest.php
@@ -6,6 +6,7 @@ use App\Livewire\Help\Index;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Livewire\Livewire;
+use PHPUnit\Framework\Attributes\DataProvider;
use Tests\TestCase;
class HelpPageTest extends TestCase
@@ -55,4 +56,23 @@ class HelpPageTest extends TestCase
->assertSee('Backup-Code')
->assertSee('TOTP');
}
+
+ #[DataProvider('topicProvider')]
+ public function test_each_topic_renders_its_own_partial(string $topic, string $marker): void
+ {
+ $this->actAsAdmin();
+ Livewire::test(Index::class)->set('topic', $topic)->assertSee($marker);
+ }
+
+ public static function topicProvider(): array
+ {
+ return [
+ ['updates', 'update.sh'],
+ ['servers', 'SSH'],
+ ['sessions', 'Sitzung'],
+ ['email', 'SMTP'],
+ ['audit', 'Audit'],
+ ['recovery', 'clusev:reset-admin'],
+ ];
+ }
}