parent
09117fe1e9
commit
dd3f413e6a
|
|
@ -2,96 +2,350 @@
|
|||
|
||||
namespace App\Livewire\Ui\System;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Livewire\Component;
|
||||
use Illuminate\Support\Str;
|
||||
use Carbon\Carbon;
|
||||
|
||||
class BackupStatusCard extends Component
|
||||
{
|
||||
public string $lastAt = '–';
|
||||
public string $lastSize = '–';
|
||||
public string $lastDuration = '–';
|
||||
public string $statusText = 'unbekannt';
|
||||
public string $statusColor = 'text-white/60 border-white/20 bg-white/5';
|
||||
// Anzeige-Felder (nur Ausgabe im Blade)
|
||||
public ?string $lastAt = null; // "27.10.2025 18:27:35"
|
||||
public ?string $lastSize = null; // "93.0 MB"
|
||||
public ?string $lastDuration = null; // "11s" / "2m 03s"
|
||||
public ?bool $ok = null;
|
||||
|
||||
public string $progressText = '';
|
||||
public string $progressPercent = '0';
|
||||
public string $progressVisibleClass = 'hidden'; // <- Sichtbarkeit
|
||||
// Progress (nur wenn state=running)
|
||||
public bool $running = false;
|
||||
public int $percent = 0;
|
||||
public ?string $step = null; // z.B. "compress"
|
||||
|
||||
protected string $statusFile = '/var/lib/mailwolt/backup.status';
|
||||
|
||||
public function mount(): void { $this->load(); }
|
||||
public function render() { return view('livewire.ui.system.backup-status-card'); }
|
||||
public function refresh(): void { $this->load(true); }
|
||||
public function mount(): void
|
||||
{
|
||||
$this->load();
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
return view('livewire.ui.system.backup-status-card');
|
||||
}
|
||||
|
||||
public function refresh(): void
|
||||
{
|
||||
$this->load(true);
|
||||
}
|
||||
|
||||
public function runNow(): void
|
||||
{
|
||||
// asynchron starten (sudoers vorausgesetzt)
|
||||
@shell_exec('nohup sudo -n /usr/local/sbin/mailwolt-backup >/dev/null 2>&1 &');
|
||||
// UI sofort auf "läuft" setzen
|
||||
$this->progressText = 'Vorbereitung läuft...';
|
||||
$this->progressPercent = '1';
|
||||
$this->progressVisibleClass = 'block';
|
||||
|
||||
// Sofort UI auf „läuft“ setzen – Poll holt Echtstatus
|
||||
$this->running = true;
|
||||
$this->percent = 1;
|
||||
$this->step = 'start';
|
||||
}
|
||||
|
||||
protected function load(bool $force = false): void
|
||||
private function load(bool $force = false): void
|
||||
{
|
||||
$kv = [];
|
||||
if (is_file($this->statusFile)) {
|
||||
foreach (@file($this->statusFile, FILE_IGNORE_NEW_LINES) ?: [] as $ln) {
|
||||
$p = strpos($ln, '='); if ($p !== false) $kv[substr($ln,0,$p)] = substr($ln,$p+1);
|
||||
}
|
||||
}
|
||||
$state = $this->readStatus();
|
||||
|
||||
$state = $kv['state'] ?? null; // running | done | failed
|
||||
$step = $kv['step'] ?? null;
|
||||
$percent = isset($kv['percent']) ? (int)$kv['percent'] : 0;
|
||||
$ok = isset($kv['ok']) ? ((int)$kv['ok'] === 1) : null;
|
||||
// Progress
|
||||
$this->running = ($state['state'] ?? null) === 'running';
|
||||
$this->percent = (int)($state['percent'] ?? 0);
|
||||
$this->step = $state['step'] ?? null;
|
||||
|
||||
// Anzeigeformatierungen wie gehabt …
|
||||
// (deine bestehenden formatBytes/formatDuration/Timezone-Logik)
|
||||
// Abschlusswerte
|
||||
$fin = $state['finished_at'] ?? $state['start_at'] ?? null;
|
||||
$this->lastAt = $fin ? $this->fmtDate($fin) : null;
|
||||
|
||||
$this->progressPercent = (string)max(0, min(100, $percent));
|
||||
$this->progressText = $this->mapStep($step);
|
||||
$sizeB = isset($state['size']) ? (int)$state['size'] : null;
|
||||
$this->lastSize = $sizeB !== null ? $this->fmtBytes($sizeB) : null;
|
||||
|
||||
// Sichtbarkeit steuern – KEINE Blade-Logik nötig
|
||||
if ($state === 'running') {
|
||||
$this->progressVisibleClass = 'block';
|
||||
} else {
|
||||
// bei done/failed: Balken verstecken und auf 100% / finalen Text setzen
|
||||
$this->progressVisibleClass = 'hidden';
|
||||
if ($percent >= 100 || $step === 'done') {
|
||||
$this->progressPercent = '100';
|
||||
$this->progressText = 'Backup abgeschlossen.';
|
||||
}
|
||||
}
|
||||
$durS = isset($state['duration']) ? (int)$state['duration'] : null;
|
||||
$this->lastDuration = $durS !== null ? $this->fmtDuration($durS) : null;
|
||||
|
||||
// Status-Badge (wie gehabt)
|
||||
if ($ok === true) {
|
||||
$this->statusText = 'erfolgreich';
|
||||
$this->statusColor = 'text-emerald-300 border-emerald-400/30 bg-emerald-500/10';
|
||||
} elseif ($ok === false) {
|
||||
$this->statusText = 'fehlgeschlagen';
|
||||
$this->statusColor = 'text-rose-300 border-rose-400/30 bg-rose-500/10';
|
||||
} else {
|
||||
$this->statusText = 'unbekannt';
|
||||
$this->statusColor = 'text-white/60 border-white/20 bg-white/5';
|
||||
$this->ok = isset($state['ok']) ? ((string)$state['ok'] === '1') : null;
|
||||
|
||||
// Wenn fertig → Balken aus
|
||||
if (!$this->running) {
|
||||
$this->percent = 0;
|
||||
$this->step = null;
|
||||
}
|
||||
}
|
||||
|
||||
private function mapStep(?string $step): string
|
||||
private function readStatus(): array
|
||||
{
|
||||
return match($step) {
|
||||
'mysqldump' => 'Datenbank wird gesichert...',
|
||||
'maildir' => 'Mail-Verzeichnis wird archiviert...',
|
||||
'app' => 'Anwendungsdaten werden gesichert...',
|
||||
'configs' => 'Konfigurationen werden gesichert...',
|
||||
'compress' => 'Backup wird komprimiert...',
|
||||
'retention' => 'Alte Backups werden gelöscht...',
|
||||
'done' => 'Backup abgeschlossen.',
|
||||
default => 'Vorbereitung läuft...',
|
||||
};
|
||||
if (!is_readable($this->statusFile)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$out = [];
|
||||
foreach (@file($this->statusFile, FILE_IGNORE_NEW_LINES) ?: [] as $line) {
|
||||
if (!str_contains($line, '=')) continue;
|
||||
[$k, $v] = array_map('trim', explode('=', $line, 2));
|
||||
// nur erwartete Keys
|
||||
if (in_array($k, ['state', 'pid', 'start_at', 'finished_at', 'step', 'percent', 'size', 'duration', 'ok'], true)) {
|
||||
$out[$k] = $v;
|
||||
}
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
|
||||
private function fmtDate(string $iso): string
|
||||
{
|
||||
// in App-Zeitzone anzeigen
|
||||
$tz = config('app.timezone', 'UTC');
|
||||
try {
|
||||
return Carbon::parse($iso)->setTimezone($tz)->format('d.m.Y H:i:s');
|
||||
} catch (\Throwable) {
|
||||
return $iso;
|
||||
}
|
||||
}
|
||||
|
||||
private function fmtBytes(int $bytes): string
|
||||
{
|
||||
$u = ['B', 'KB', 'MB', 'GB', 'TB'];
|
||||
$i = 0;
|
||||
$n = (float)$bytes;
|
||||
while ($n >= 1024 && $i < count($u) - 1) {
|
||||
$n /= 1024;
|
||||
$i++;
|
||||
}
|
||||
return number_format($n, ($i <= 1 ? 0 : 1), ',', '.') . ' ' . $u[$i];
|
||||
}
|
||||
|
||||
private function fmtDuration(int $sec): string
|
||||
{
|
||||
if ($sec < 60) return $sec . 's';
|
||||
$m = intdiv($sec, 60);
|
||||
$s = $sec % 60;
|
||||
return sprintf('%dm %02ds', $m, $s);
|
||||
}
|
||||
}
|
||||
|
||||
//namespace App\Livewire\Ui\System;
|
||||
//
|
||||
//use Illuminate\Support\Str;
|
||||
//use Livewire\Component;
|
||||
//use Carbon\Carbon;
|
||||
//
|
||||
//class BackupStatusCard extends Component
|
||||
//{
|
||||
// // Anzeige-Felder (fertig formatiert)
|
||||
// public ?string $lastAt = null;
|
||||
// public ?string $lastSize = null;
|
||||
// public ?string $lastDuration = null;
|
||||
// public ?bool $ok = null;
|
||||
//
|
||||
// // Laufstatus für Progress (nur zur Sichtbarkeit)
|
||||
// public bool $running = false;
|
||||
// public int $percent = 0;
|
||||
// public string $progressText = '';
|
||||
//
|
||||
// protected string $statusFile = '/var/lib/mailwolt/backup.status';
|
||||
//
|
||||
// public function mount(): void
|
||||
// {
|
||||
// $this->load();
|
||||
// }
|
||||
//
|
||||
// public function render()
|
||||
// {
|
||||
// return view('livewire.ui.system.backup-status-card');
|
||||
// }
|
||||
//
|
||||
// public function refresh(): void
|
||||
// {
|
||||
// $this->load(true);
|
||||
// }
|
||||
//
|
||||
// public function runNow(): void
|
||||
// {
|
||||
// // asynchron starten – sudoers wie bereits gesetzt
|
||||
// @shell_exec('nohup sudo -n /usr/local/sbin/mailwolt-backup >/dev/null 2>&1 &');
|
||||
// // UI direkt "laufend" schalten; echte Werte kommen über Poll
|
||||
// $this->running = true;
|
||||
// $this->percent = 1;
|
||||
// $this->progressText = 'Backup gestartet …';
|
||||
// }
|
||||
//
|
||||
// protected function load(bool $force = false): void
|
||||
// {
|
||||
// $s = $this->readStatus();
|
||||
//
|
||||
// // Progress
|
||||
// $state = $s['state'] ?? null;
|
||||
// $this->running = in_array($state, ['running'], true);
|
||||
// $this->percent = (int)($s['percent'] ?? 0);
|
||||
// $step = $s['step'] ?? '';
|
||||
// $this->progressText = $this->mapStepText($step, $state);
|
||||
//
|
||||
// // Abschlusswerte
|
||||
// $finishedAt = $s['finished_at'] ?? ($state === 'done' ? ($s['start_at'] ?? null) : null);
|
||||
// $sizeBytes = isset($s['size']) ? (int)$s['size'] : null;
|
||||
// $durSec = isset($s['duration']) ? (int)$s['duration'] : null;
|
||||
// $okStr = $s['ok'] ?? null;
|
||||
//
|
||||
// $this->lastAt = $finishedAt ? $this->fmtDate($finishedAt) : null;
|
||||
// $this->lastSize = $sizeBytes !== null ? $this->fmtBytes($sizeBytes) : null;
|
||||
// $this->lastDuration = $durSec !== null ? $this->fmtDuration($durSec) : null;
|
||||
// $this->ok = $okStr !== null ? ($okStr === '1' || $okStr === 'true') : null;
|
||||
// }
|
||||
//
|
||||
// protected function readStatus(): array
|
||||
// {
|
||||
// if (!is_readable($this->statusFile)) {
|
||||
// return [];
|
||||
// }
|
||||
// $lines = @file($this->statusFile, FILE_IGNORE_NEW_LINES) ?: [];
|
||||
// $out = [];
|
||||
// foreach ($lines as $ln) {
|
||||
// if (!str_contains($ln, '=')) continue;
|
||||
// [$k, $v] = array_map('trim', explode('=', $ln, 2));
|
||||
// $out[$k] = $v;
|
||||
// }
|
||||
// return $out;
|
||||
// }
|
||||
//
|
||||
// private function mapStepText(string $step, ?string $state): string
|
||||
// {
|
||||
// if ($state === 'done') return 'Backup abgeschlossen.';
|
||||
// if ($state === 'failed') return 'Backup fehlgeschlagen.';
|
||||
// return match ($step) {
|
||||
// 'start' => 'Backup wird vorbereitet …',
|
||||
// 'mysqldump' => 'Datenbank wird gesichert …',
|
||||
// 'maildir' => 'Maildir wird gesichert …',
|
||||
// 'app' => 'Applikation wird gesichert …',
|
||||
// 'configs' => 'Konfigurationen werden gesichert …',
|
||||
// 'compress' => 'Archiv wird komprimiert …',
|
||||
// 'retention' => 'Alte Backups werden aufgeräumt …',
|
||||
// default => $step ? Str::headline($step) . ' …' : 'Backup läuft …',
|
||||
// };
|
||||
// }
|
||||
//
|
||||
// private function fmtDate(string $iso): string
|
||||
// {
|
||||
// return Carbon::parse($iso)->timezone(config('app.timezone', 'Europe/Berlin'))->format('d.m.Y H:i:s');
|
||||
// }
|
||||
//
|
||||
// private function fmtBytes(int $b): string
|
||||
// {
|
||||
// $units = ['B', 'KB', 'MB', 'GB', 'TB'];
|
||||
// $i = 0;
|
||||
// $val = $b;
|
||||
// while ($val >= 1024 && $i < count($units) - 1) {
|
||||
// $val /= 1024;
|
||||
// $i++;
|
||||
// }
|
||||
// return number_format($val, $val >= 10 ? 0 : ($val >= 1 ? 1 : 0)) . ' ' . $units[$i];
|
||||
// }
|
||||
//
|
||||
// private function fmtDuration(int $s): string
|
||||
// {
|
||||
// if ($s < 60) return $s . 's';
|
||||
// $m = intdiv($s, 60);
|
||||
// $r = $s % 60;
|
||||
// if ($m < 60) return sprintf('%dm %02ds', $m, $r);
|
||||
// $h = intdiv($m, 60);
|
||||
// $m = $m % 60;
|
||||
// return sprintf('%dh %02dm', $h, $m);
|
||||
// }
|
||||
//}
|
||||
|
||||
//namespace App\Livewire\Ui\System;
|
||||
//
|
||||
//use Carbon\Carbon;
|
||||
//use Livewire\Component;
|
||||
//
|
||||
//class BackupStatusCard extends Component
|
||||
//{
|
||||
// public string $lastAt = '–';
|
||||
// public string $lastSize = '–';
|
||||
// public string $lastDuration = '–';
|
||||
// public string $statusText = 'unbekannt';
|
||||
// public string $statusColor = 'text-white/60 border-white/20 bg-white/5';
|
||||
//
|
||||
// public string $progressText = '';
|
||||
// public string $progressPercent = '0';
|
||||
// public string $progressVisibleClass = 'hidden'; // <- Sichtbarkeit
|
||||
//
|
||||
// protected string $statusFile = '/var/lib/mailwolt/backup.status';
|
||||
//
|
||||
// public function mount(): void { $this->load(); }
|
||||
// public function render() { return view('livewire.ui.system.backup-status-card'); }
|
||||
// public function refresh(): void { $this->load(true); }
|
||||
//
|
||||
// public function runNow(): void
|
||||
// {
|
||||
// @shell_exec('nohup sudo -n /usr/local/sbin/mailwolt-backup >/dev/null 2>&1 &');
|
||||
// // UI sofort auf "läuft" setzen
|
||||
// $this->progressText = 'Vorbereitung läuft...';
|
||||
// $this->progressPercent = '1';
|
||||
// $this->progressVisibleClass = 'block';
|
||||
// }
|
||||
//
|
||||
// protected function load(bool $force = false): void
|
||||
// {
|
||||
// $kv = [];
|
||||
// if (is_file($this->statusFile)) {
|
||||
// foreach (@file($this->statusFile, FILE_IGNORE_NEW_LINES) ?: [] as $ln) {
|
||||
// $p = strpos($ln, '='); if ($p !== false) $kv[substr($ln,0,$p)] = substr($ln,$p+1);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// $state = $kv['state'] ?? null; // running | done | failed
|
||||
// $step = $kv['step'] ?? null;
|
||||
// $percent = isset($kv['percent']) ? (int)$kv['percent'] : 0;
|
||||
// $ok = isset($kv['ok']) ? ((int)$kv['ok'] === 1) : null;
|
||||
//
|
||||
// // Anzeigeformatierungen wie gehabt …
|
||||
// // (deine bestehenden formatBytes/formatDuration/Timezone-Logik)
|
||||
//
|
||||
// $this->progressPercent = (string)max(0, min(100, $percent));
|
||||
// $this->progressText = $this->mapStep($step);
|
||||
//
|
||||
// // Sichtbarkeit steuern – KEINE Blade-Logik nötig
|
||||
// if ($state === 'running') {
|
||||
// $this->progressVisibleClass = 'block';
|
||||
// } else {
|
||||
// // bei done/failed: Balken verstecken und auf 100% / finalen Text setzen
|
||||
// $this->progressVisibleClass = 'hidden';
|
||||
// if ($percent >= 100 || $step === 'done') {
|
||||
// $this->progressPercent = '100';
|
||||
// $this->progressText = 'Backup abgeschlossen.';
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // Status-Badge (wie gehabt)
|
||||
// if ($ok === true) {
|
||||
// $this->statusText = 'erfolgreich';
|
||||
// $this->statusColor = 'text-emerald-300 border-emerald-400/30 bg-emerald-500/10';
|
||||
// } elseif ($ok === false) {
|
||||
// $this->statusText = 'fehlgeschlagen';
|
||||
// $this->statusColor = 'text-rose-300 border-rose-400/30 bg-rose-500/10';
|
||||
// } else {
|
||||
// $this->statusText = 'unbekannt';
|
||||
// $this->statusColor = 'text-white/60 border-white/20 bg-white/5';
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// private function mapStep(?string $step): string
|
||||
// {
|
||||
// return match($step) {
|
||||
// 'mysqldump' => 'Datenbank wird gesichert...',
|
||||
// 'maildir' => 'Mail-Verzeichnis wird archiviert...',
|
||||
// 'app' => 'Anwendungsdaten werden gesichert...',
|
||||
// 'configs' => 'Konfigurationen werden gesichert...',
|
||||
// 'compress' => 'Backup wird komprimiert...',
|
||||
// 'retention' => 'Alte Backups werden gelöscht...',
|
||||
// 'done' => 'Backup abgeschlossen.',
|
||||
// default => 'Vorbereitung läuft...',
|
||||
// };
|
||||
// }
|
||||
//}
|
||||
|
||||
//
|
||||
//class BackupStatusCard extends Component
|
||||
//{
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<div wire:key="backup-card" wire:poll.2s="refresh"
|
||||
class="glass-card p-4 rounded-2xl border border-white/10 bg-white/5">
|
||||
<div class="glass-card p-4 rounded-2xl border border-white/10 bg-white/5"
|
||||
wire:poll.2s="refresh">
|
||||
|
||||
<div class="flex items-center justify-between mb-2">
|
||||
<div class="inline-flex items-center gap-2 bg-white/5 border border-white/10 px-2.5 py-1 rounded-full">
|
||||
|
|
@ -12,30 +12,108 @@
|
|||
</button>
|
||||
</div>
|
||||
|
||||
{{-- Fortschritt (sichtbar nur während run) --}}
|
||||
<div class="mb-3 {{ $progressVisibleClass }}">
|
||||
<div class="flex items-center justify-between mb-1 text-xs text-white/70">
|
||||
<span>{{ $progressText }}</span>
|
||||
<span>{{ $progressPercent }}%</span>
|
||||
@if($running)
|
||||
<div class="text-white/70 mb-2">
|
||||
{{ $step === 'compress' ? 'Komprimiere …' : ($step === 'mysqldump' ? 'Datenbank exportieren …' : 'Backup läuft …') }}
|
||||
<span class="float-right text-white/70">{{ $percent }}%</span>
|
||||
</div>
|
||||
<div class="w-full h-2 rounded bg-white/10 overflow-hidden">
|
||||
<div class="h-2 bg-white/40" style="width: {{ $progressPercent }}%"></div>
|
||||
<div class="w-full h-2 rounded-full bg-white/10 overflow-hidden mb-3">
|
||||
<div class="h-2 bg-white/40" style="width: {{ $percent }}%"></div>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
{{-- Infos --}}
|
||||
<div class="space-y-1 text-sm">
|
||||
<div class="text-white/70">Letztes Backup: <span class="text-white/90">{{ $lastAt }}</span></div>
|
||||
<div class="text-white/70">Größe: <span class="text-white/90">{{ $lastSize }}</span></div>
|
||||
<div class="text-white/70">Dauer: <span class="text-white/90">{{ $lastDuration }}</span></div>
|
||||
<div class="text-white/70">
|
||||
Letztes Backup: <span class="text-white/90">{{ $lastAt ?? '–' }}</span>
|
||||
</div>
|
||||
<div class="text-white/70">
|
||||
Größe: <span class="text-white/90">{{ $lastSize ?? '–' }}</span>
|
||||
</div>
|
||||
<div class="text-white/70">
|
||||
Dauer: <span class="text-white/90">{{ $lastDuration ?? '–' }}</span>
|
||||
</div>
|
||||
<div>
|
||||
<span class="px-2 py-0.5 rounded-full border text-xs {{ $statusColor }}">
|
||||
{{ $statusText }}
|
||||
</span>
|
||||
<span class="px-2 py-0.5 rounded-full border text-xs
|
||||
{{ $ok === true ? 'text-emerald-300 border-emerald-400/30 bg-emerald-500/10'
|
||||
: ($ok === false ? 'text-rose-300 border-rose-400/30 bg-rose-500/10'
|
||||
: 'text-white/60 border-white/20 bg-white/5') }}">
|
||||
{{ $ok === null ? 'unbekannt' : ($ok ? 'erfolgreich' : 'fehlgeschlagen') }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{--<div class="glass-card p-4 rounded-2xl border border-white/10 bg-white/5" wire:poll.2s="refresh">--}}
|
||||
{{-- <div class="flex items-center justify-between mb-2">--}}
|
||||
{{-- <div class="inline-flex items-center gap-2 bg-white/5 border border-white/10 px-2.5 py-1 rounded-full">--}}
|
||||
{{-- <i class="ph ph-archive-box text-white/70 text-[13px]"></i>--}}
|
||||
{{-- <span class="text-[11px] uppercase text-white/70">Backups</span>--}}
|
||||
{{-- </div>--}}
|
||||
{{-- <button wire:click="runNow" class="px-2 py-1 text-xs rounded-lg border border-white/10 bg-white/5 hover:border-white/20">--}}
|
||||
{{-- Jetzt sichern--}}
|
||||
{{-- </button>--}}
|
||||
{{-- </div>--}}
|
||||
|
||||
{{-- @if($running)--}}
|
||||
{{-- <div class="text-white/70 mb-2">{{ $progressText }}</div>--}}
|
||||
{{-- <div class="w-full h-2 rounded-full bg-white/10 overflow-hidden mb-4">--}}
|
||||
{{-- <div class="h-2 bg-white/40" style="width: {{ $percent }}%"></div>--}}
|
||||
{{-- </div>--}}
|
||||
{{-- @endif--}}
|
||||
|
||||
{{-- <div class="space-y-1 text-sm">--}}
|
||||
{{-- <div class="text-white/70">Letztes Backup: <span class="text-white/90">{{ $lastAt ?? '–' }}</span></div>--}}
|
||||
{{-- <div class="text-white/70">Größe: <span class="text-white/90">{{ $lastSize ?? '–' }}</span></div>--}}
|
||||
{{-- <div class="text-white/70">Dauer: <span class="text-white/90">{{ $lastDuration ?? '–' }}</span></div>--}}
|
||||
{{-- <div>--}}
|
||||
{{-- <span class="px-2 py-0.5 rounded-full border text-xs--}}
|
||||
{{-- {{ $ok === true ? 'text-emerald-300 border-emerald-400/30 bg-emerald-500/10'--}}
|
||||
{{-- : ($ok === false ? 'text-rose-300 border-rose-400/30 bg-rose-500/10'--}}
|
||||
{{-- : 'text-white/60 border-white/20 bg-white/5') }}">--}}
|
||||
{{-- {{ $ok === null ? 'unbekannt' : ($ok ? 'erfolgreich' : 'fehlgeschlagen') }}--}}
|
||||
{{-- </span>--}}
|
||||
{{-- </div>--}}
|
||||
{{-- </div>--}}
|
||||
{{--</div>--}}
|
||||
|
||||
{{--<div wire:key="backup-card" wire:poll.2s="refresh"--}}
|
||||
{{-- class="glass-card p-4 rounded-2xl border border-white/10 bg-white/5">--}}
|
||||
|
||||
{{-- <div class="flex items-center justify-between mb-2">--}}
|
||||
{{-- <div class="inline-flex items-center gap-2 bg-white/5 border border-white/10 px-2.5 py-1 rounded-full">--}}
|
||||
{{-- <i class="ph ph-archive-box text-white/70 text-[13px]"></i>--}}
|
||||
{{-- <span class="text-[11px] uppercase text-white/70">Backups</span>--}}
|
||||
{{-- </div>--}}
|
||||
{{-- <button wire:click="runNow"--}}
|
||||
{{-- class="px-2 py-1 text-xs rounded-lg border border-white/10 bg-white/5 hover:border-white/20">--}}
|
||||
{{-- Jetzt sichern--}}
|
||||
{{-- </button>--}}
|
||||
{{-- </div>--}}
|
||||
|
||||
{{-- --}}{{-- Fortschritt (sichtbar nur während run) --}}
|
||||
{{-- <div class="mb-3 {{ $progressVisibleClass }}">--}}
|
||||
{{-- <div class="flex items-center justify-between mb-1 text-xs text-white/70">--}}
|
||||
{{-- <span>{{ $progressText }}</span>--}}
|
||||
{{-- <span>{{ $progressPercent }}%</span>--}}
|
||||
{{-- </div>--}}
|
||||
{{-- <div class="w-full h-2 rounded bg-white/10 overflow-hidden">--}}
|
||||
{{-- <div class="h-2 bg-white/40" style="width: {{ $progressPercent }}%"></div>--}}
|
||||
{{-- </div>--}}
|
||||
{{-- </div>--}}
|
||||
|
||||
{{-- --}}{{-- Infos --}}
|
||||
{{-- <div class="space-y-1 text-sm">--}}
|
||||
{{-- <div class="text-white/70">Letztes Backup: <span class="text-white/90">{{ $lastAt }}</span></div>--}}
|
||||
{{-- <div class="text-white/70">Größe: <span class="text-white/90">{{ $lastSize }}</span></div>--}}
|
||||
{{-- <div class="text-white/70">Dauer: <span class="text-white/90">{{ $lastDuration }}</span></div>--}}
|
||||
{{-- <div>--}}
|
||||
{{-- <span class="px-2 py-0.5 rounded-full border text-xs {{ $statusColor }}">--}}
|
||||
{{-- {{ $statusText }}--}}
|
||||
{{-- </span>--}}
|
||||
{{-- </div>--}}
|
||||
{{-- </div>--}}
|
||||
{{--</div>--}}
|
||||
|
||||
{{--<div--}}
|
||||
{{-- wire:key="backup-card"--}}
|
||||
{{-- @if($running) wire:poll.1s="refresh" @endif--}}
|
||||
|
|
|
|||
Loading…
Reference in New Issue