offene Migrationen public string $appVersion = ''; public bool $hasUpdate = false; // z.B. wenn remote Version > local (optional) // Klassen für Farben (im Blade nur verwenden) public string $domainsBadgeClass = 'bg-emerald-500/20 text-emerald-300'; public string $warningsBadgeClass = 'bg-emerald-500/20 text-emerald-300'; public string $updatesBadgeClass = 'bg-emerald-500/20 text-emerald-300'; public ?string $ipv4 = null; public ?string $ipv6 = null; public function mount(): void { // Domains + Zertifikate (passe an deinen Storage an) $this->domainsCount = Domain::where('is_server', false)->where('is_system', false)->count(); // oder aus Cache/Repo // Beispiel: Domain::select('cert_expires_at','cert_issuer')... // -> hier simple Annahme: im Cache 'domains:certs' liegt [{domain, days_left, type}] $certs = Cache::get('domains:certs', []); // Struktur: [['days_left'=>int,'type'=>'letsencrypt|selfsigned'], ...] $this->certExpiring = collect($certs)->where('days_left', '<=', 30)->count(); // Warnungen $events = Cache::get('events:recent', []); $this->warningsCount = is_array($events) ? min(99, count($events)) : 0; // Updates / Migrations $meta = Cache::get('health:meta', []); $this->pendingMigs = (int)($meta['pending_migs'] ?? 0); $this->appVersion = (string)($meta['app_version'] ?? ''); $this->hasUpdate = $this->pendingMigs > 0; // oder echte Versionprüfung // IPv4 $this->ipv4 = trim(shell_exec("hostname -I | awk '{print $1}'")) ?: '–'; // IPv6 (optional) $this->ipv6 = trim(shell_exec("hostname -I | awk '{print $2}'")) ?: '–'; // Farben berechnen (nur einmal hier) $this->domainsBadgeClass = $this->certExpiring === 0 ? 'bg-emerald-500/20 text-emerald-300' : ($this->certExpiring <= 2 ? 'bg-amber-400/20 text-amber-300' : 'bg-rose-500/20 text-rose-300'); $this->warningsBadgeClass = $this->warningsCount > 0 ? 'bg-rose-500/20 text-rose-300' : 'bg-emerald-500/20 text-emerald-300'; $this->updatesBadgeClass = $this->hasUpdate ? 'bg-amber-400/20 text-amber-300' : 'bg-emerald-500/20 text-emerald-300'; } public function render() { return view('livewire.ui.dashboard.top-bar'); } }