mailwolt/resources/views/livewire/ui/system/modal/backup-progress-modal.blade...

159 lines
8.5 KiB
PHP

<div class="mw-modal-frame" wire:poll.2s>
@php
$isRestore = !empty($restoreToken);
if ($isRestore) {
$rs = $this->restoreStatus;
$status = $rs['status'] ?? 'queued';
$log = $rs['log'] ?? '';
} else {
$job = $this->job;
$status = $job?->status ?? 'queued';
$log = $job?->log_excerpt ?: ($job?->error ?? '');
}
$done = in_array($status, ['ok','failed','canceled']);
$elapsed = 0;
if (!$isRestore && ($job?->started_at ?? null)) {
$elapsed = $done && ($job->finished_at ?? null)
? $job->started_at->diffInSeconds($job->finished_at)
: now()->diffInSeconds($job->started_at);
}
$elapsedFmt = $elapsed >= 60
? floor($elapsed/60) . ' min ' . ($elapsed % 60) . 's'
: $elapsed . 's';
@endphp
<div class="mw-modal-head">
<div style="display:flex;align-items:center;gap:7px">
<span class="mbx-badge-mute">{{ $isRestore ? 'Restore' : 'Backup' }}</span>
<span style="font-size:12px;color:var(--mw-t3)"> {{ $isRestore ? 'Wiederherstellung' : 'Sicherung' }}</span>
</div>
@if($done)
<button wire:click="close" class="mw-modal-close">
<svg width="13" height="13" viewBox="0 0 13 13" fill="none"><path d="M1 1l11 11M12 1L1 12" stroke="currentColor" stroke-width="1.4" stroke-linecap="round"/></svg>
</button>
@endif
</div>
<div class="mw-modal-body" style="display:flex;flex-direction:column;gap:16px">
{{-- Status-Zeile --}}
<div style="display:flex;align-items:center;gap:12px;padding:14px 16px;background:var(--mw-bg4);border:1px solid var(--mw-b2);border-radius:8px">
@if($status === 'queued')
<div class="bpm-spin" style="color:var(--mw-t4)">
<svg width="20" height="20" viewBox="0 0 24 24" fill="none"><circle cx="12" cy="12" r="9" stroke="currentColor" stroke-width="2" stroke-dasharray="28 14" stroke-linecap="round"/></svg>
</div>
<div>
<div style="font-size:13px;font-weight:500;color:var(--mw-t2)">Warteschlange…</div>
<div style="font-size:11.5px;color:var(--mw-t4);margin-top:2px">Prozess wird gestartet</div>
</div>
@elseif($status === 'running')
<div class="bpm-spin" style="color:var(--mw-v2)">
<svg width="20" height="20" viewBox="0 0 24 24" fill="none"><circle cx="12" cy="12" r="9" stroke="currentColor" stroke-width="2" stroke-dasharray="28 14" stroke-linecap="round"/></svg>
</div>
<div style="flex:1">
<div style="font-size:13px;font-weight:500;color:var(--mw-t2)">
{{ $isRestore ? 'Wiederherstellung läuft…' : 'Sicherung läuft…' }}
</div>
@if(!$isRestore && $elapsed > 0)
<div style="font-size:11.5px;color:var(--mw-t4);margin-top:2px">Verstrichene Zeit: {{ $elapsedFmt }}</div>
@endif
</div>
@elseif($status === 'ok')
<div style="width:32px;height:32px;border-radius:50%;background:rgba(34,197,94,.12);border:1px solid rgba(34,197,94,.25);display:flex;align-items:center;justify-content:center;flex-shrink:0">
<svg width="14" height="14" viewBox="0 0 14 14" fill="none"><path d="M2.5 7l3.5 3.5 5.5-6" stroke="#22c55e" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/></svg>
</div>
<div style="flex:1">
<div style="font-size:13px;font-weight:500;color:#22c55e">
{{ $isRestore ? 'Wiederherstellung erfolgreich' : 'Backup erfolgreich' }}
</div>
@if(!$isRestore)
<div style="font-size:11.5px;color:var(--mw-t4);margin-top:2px">
Dauer: {{ $elapsedFmt }}
@if($job?->size_bytes > 0)
&nbsp;·&nbsp;
@php $u=['B','KB','MB','GB']; $i=0; $v=(float)$job->size_bytes;
while($v>=1024&&$i<3){$v/=1024;$i++;} echo number_format($v,$i<=1?0:1).' '.$u[$i]; @endphp
@endif
</div>
@endif
</div>
@elseif($status === 'failed')
<div style="width:32px;height:32px;border-radius:50%;background:rgba(239,68,68,.1);border:1px solid rgba(239,68,68,.2);display:flex;align-items:center;justify-content:center;flex-shrink:0">
<svg width="14" height="14" viewBox="0 0 14 14" fill="none"><path d="M2 2l10 10M12 2L2 12" stroke="#ef4444" stroke-width="1.6" stroke-linecap="round"/></svg>
</div>
<div style="flex:1">
<div style="font-size:13px;font-weight:500;color:#ef4444">
{{ $isRestore ? 'Wiederherstellung fehlgeschlagen' : 'Backup fehlgeschlagen' }}
</div>
@if(!$isRestore)
<div style="font-size:11.5px;color:var(--mw-t4);margin-top:2px">Dauer: {{ $elapsedFmt }}</div>
@endif
</div>
@endif
</div>
{{-- Fortschrittsbalken --}}
@if(!$done)
<div style="height:3px;background:var(--mw-bg4);border-radius:2px;overflow:hidden">
<div class="bpm-progress" style="height:100%;border-radius:2px;background:linear-gradient(90deg,#7c3aed,#a78bfa)"></div>
</div>
@endif
{{-- Log --}}
@if($log)
<div>
<div style="font-size:11px;color:var(--mw-t4);margin-bottom:5px;text-transform:uppercase;letter-spacing:.05em">Ausgabe</div>
<pre style="font-family:monospace;font-size:11px;color:var(--mw-t3);background:var(--mw-bg4);border:1px solid var(--mw-b2);border-radius:6px;padding:10px 12px;overflow-y:auto;max-height:160px;white-space:pre-wrap;word-break:break-all;margin:0">{{ $log }}</pre>
</div>
@endif
{{-- Hinweis --}}
@if(!$done)
<div style="display:flex;gap:8px;padding:9px 12px;background:var(--mw-bg4);border:1px solid var(--mw-b2);border-radius:7px;font-size:11.5px;color:var(--mw-t4)">
<svg width="12" height="12" viewBox="0 0 13 13" fill="none" style="flex-shrink:0;margin-top:1px"><circle cx="6.5" cy="6.5" r="5.5" stroke="currentColor" stroke-width="1.2"/><path d="M6.5 6v3.5" stroke="currentColor" stroke-width="1.3" stroke-linecap="round"/><circle cx="6.5" cy="4" r=".7" fill="currentColor"/></svg>
{{ $isRestore ? 'Die Wiederherstellung läuft im Hintergrund weiter.' : 'Du kannst dieses Fenster schließen — das Backup läuft im Hintergrund weiter.' }}
</div>
@endif
@if($isRestore && $status === 'ok')
<div style="display:flex;gap:8px;padding:9px 12px;background:rgba(34,197,94,.07);border:1px solid rgba(34,197,94,.2);border-radius:7px;font-size:11.5px;color:#22c55e">
<svg width="12" height="12" viewBox="0 0 14 14" fill="none" style="flex-shrink:0;margin-top:1px"><path d="M2.5 7l3.5 3.5 5.5-6" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/></svg>
Seite neu laden um die wiederhergestellten Daten zu sehen.
</div>
@endif
</div>
<div class="mw-modal-foot" style="justify-content:space-between">
@if(!$isRestore)
<a href="{{ route('ui.system.backups') }}" class="mbx-btn-mute" style="font-size:12px;padding:5px 12px;text-decoration:none">Verlauf</a>
@else
<div></div>
@endif
<div style="display:flex;gap:8px">
<button wire:click="close" class="{{ $done ? 'mbx-btn-primary' : 'mbx-btn-mute' }}" style="font-size:12px;padding:5px 14px">
{{ $done ? 'Schließen' : 'Im Hintergrund weiterlaufen' }}
</button>
@if($isRestore && $status === 'ok')
<button onclick="location.reload()" class="mbx-btn-primary" style="font-size:12px;padding:5px 14px">
Seite neu laden
</button>
@endif
</div>
</div>
<style>
@keyframes bpm-spin { to { transform: rotate(360deg); } }
.bpm-spin { animation: bpm-spin 1s linear infinite; display:flex; }
@keyframes bpm-slide { 0%{transform:translateX(-100%)} 100%{transform:translateX(400%)} }
.bpm-progress { width:30%;animation:bpm-slide 1.6s ease-in-out infinite; }
</style>
</div>