133 lines
6.2 KiB
PHP
133 lines
6.2 KiB
PHP
<!DOCTYPE html>
|
|
<html lang="de">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Status — CluPilot Cloud</title>
|
|
<meta name="description" content="Aktueller Betriebszustand der CluPilot Cloud: Portal, Kundeninstanzen, Bereitstellung und Sicherungen.">
|
|
<meta name="robots" content="noindex">
|
|
<link rel="icon" type="image/svg+xml" href="/favicon.svg">
|
|
|
|
@verbatim
|
|
<style>
|
|
@font-face{font-family:"Plex Sans";src:url("/fonts/ibm-plex-sans-latin-400-normal.woff2") format("woff2");font-weight:400;font-style:normal;font-display:swap}
|
|
@font-face{font-family:"Plex Sans";src:url("/fonts/ibm-plex-sans-latin-500-normal.woff2") format("woff2");font-weight:500;font-style:normal;font-display:swap}
|
|
@font-face{font-family:"Plex Mono";src:url("/fonts/ibm-plex-mono-latin-400-normal.woff2") format("woff2");font-weight:400;font-style:normal;font-display:swap}
|
|
|
|
:root{
|
|
--paper:#f6f6f8; --paper-2:#fafafb; --card:#ffffff;
|
|
--ink:#17171c; --ink-soft:#43434e; --muted:#6e6e7a; --faint:#a39a8c;
|
|
--rule:#e9e9ee; --rule-mid:#dcdce4;
|
|
--accent:#f97316; --accent-text:#b8500a;
|
|
--ok:#2f7d4f; --ok-bg:#eef7f1;
|
|
--warn:#a2600c; --warn-bg:#fdf5e7;
|
|
--bad:#a4372a; --bad-bg:#fdf1ef;
|
|
--unknown:#6c6459; --unknown-bg:#f1eee8;
|
|
--sans:"Plex Sans",-apple-system,BlinkMacSystemFont,sans-serif;
|
|
--mono:"Plex Mono",ui-monospace,monospace;
|
|
--r:16px;
|
|
}
|
|
*{margin:0;padding:0;box-sizing:border-box}
|
|
body{font-family:var(--sans);background:var(--paper);color:var(--ink-soft);font-size:16px;line-height:1.6;-webkit-font-smoothing:antialiased}
|
|
a{color:inherit;text-decoration:none}
|
|
:focus-visible{outline:2px solid var(--accent-text);outline-offset:3px}
|
|
|
|
.wrap{max-width:760px;margin:0 auto;padding:0 clamp(20px,5vw,32px)}
|
|
header{padding:clamp(48px,8vw,80px) 0 0}
|
|
.mark{font-weight:700;font-size:1.12rem;letter-spacing:-.02em;color:var(--ink)}
|
|
.mark i{font-style:normal;color:var(--accent-text)}
|
|
h1{font-weight:700;font-size:clamp(2rem,4.5vw,2.8rem);letter-spacing:-.028em;line-height:1.1;color:var(--ink);margin-top:28px}
|
|
|
|
.overall{
|
|
display:flex;align-items:center;gap:13px;margin-top:22px;padding:16px 20px;
|
|
border:1px solid var(--rule-mid);border-radius:var(--r);background:var(--card);
|
|
}
|
|
.dot{width:10px;height:10px;border-radius:50%;flex:none}
|
|
.overall b{font-weight:500;color:var(--ink)}
|
|
.s-operational .dot{background:var(--ok)} .s-operational b{color:var(--ok)}
|
|
.s-degraded .dot{background:var(--warn)} .s-degraded b{color:var(--warn)}
|
|
.s-down .dot{background:var(--bad)} .s-down b{color:var(--bad)}
|
|
.s-unknown .dot{background:var(--unknown)} .s-unknown b{color:var(--unknown)}
|
|
|
|
.list{margin-top:34px;border:1px solid var(--rule-mid);border-radius:var(--r);background:var(--card);overflow:hidden}
|
|
.row{display:flex;align-items:flex-start;gap:16px;padding:18px 20px;border-bottom:1px solid var(--rule)}
|
|
.row:last-child{border-bottom:0}
|
|
.row .name{flex:1;min-width:0}
|
|
.row .name b{display:block;font-weight:500;color:var(--ink);font-size:.98rem}
|
|
.row .name small{display:block;color:var(--muted);font-size:.85rem;margin-top:2px;line-height:1.5}
|
|
.badge{
|
|
display:inline-flex;align-items:center;gap:8px;flex:none;
|
|
font-family:var(--mono);font-size:.72rem;text-transform:uppercase;letter-spacing:.1em;
|
|
padding:5px 11px;border-radius:99px;border:1px solid transparent;white-space:nowrap;
|
|
}
|
|
.badge.s-operational{background:var(--ok-bg);color:var(--ok);border-color:#c9e4d4}
|
|
.badge.s-degraded{background:var(--warn-bg);color:var(--warn);border-color:#f0dcb4}
|
|
.badge.s-down{background:var(--bad-bg);color:var(--bad);border-color:#f2cdc7}
|
|
.badge.s-unknown{background:var(--unknown-bg);color:var(--unknown);border-color:var(--rule-mid)}
|
|
|
|
.meta{margin-top:20px;font-family:var(--mono);font-size:.74rem;color:var(--muted)}
|
|
.note{margin-top:26px;padding-top:22px;border-top:1px solid var(--rule);font-size:.88rem;color:var(--muted);line-height:1.65}
|
|
.note a{color:var(--accent-text);font-weight:500}
|
|
footer{margin-top:clamp(48px,7vw,72px);padding:24px 0 40px;border-top:1px solid var(--rule)}
|
|
.fo{display:flex;flex-wrap:wrap;gap:12px 22px;font-family:var(--mono);font-size:.73rem;color:var(--muted)}
|
|
.fo .right{margin-left:auto;display:flex;flex-wrap:wrap;gap:18px}
|
|
.fo a:hover{color:var(--ink)}
|
|
@media(max-width:520px){.row{flex-wrap:wrap}.badge{order:-1}}
|
|
</style>
|
|
@endverbatim
|
|
</head>
|
|
<body>
|
|
<div class="wrap">
|
|
<header>
|
|
<a class="mark" href="{{ route('home') }}">Clu<i>Pilot</i> Cloud</a>
|
|
<h1>Betriebsstatus</h1>
|
|
|
|
<div class="overall s-{{ $overall }}">
|
|
<span class="dot" aria-hidden="true"></span>
|
|
<b>{{ __('status.overall.'.$overall) }}</b>
|
|
</div>
|
|
</header>
|
|
|
|
<div class="list">
|
|
@foreach ($components as $c)
|
|
<div class="row">
|
|
<div class="name">
|
|
<b>{{ __('status.component.'.$c['key']) }}</b>
|
|
<small>
|
|
@if ($c['detail'] !== null)
|
|
{{ __('status.detail.'.$c['key'], $c['detail']) }}
|
|
@else
|
|
{{ __('status.about.'.$c['key']) }}
|
|
@endif
|
|
</small>
|
|
</div>
|
|
<span class="badge s-{{ $c['state'] }}">{{ __('status.state.'.$c['state']) }}</span>
|
|
</div>
|
|
@endforeach
|
|
</div>
|
|
|
|
<p class="meta">Stand: {{ $checkedAt->timezone(config('app.timezone'))->format('d.m.Y, H:i') }} Uhr</p>
|
|
|
|
<p class="note">
|
|
Jede Zeile wird bei jedem Aufruf neu gemessen — aus Überwachung, Sicherungsprotokoll und
|
|
Bereitstellungsläufen. Wo gerade nichts gemessen wird, steht „unbekannt“ und nicht „in Betrieb“:
|
|
eine fehlende Messung ist kein Nachweis, dass alles läuft.
|
|
Eine Störung, die Sie hier nicht sehen, melden Sie bitte an
|
|
<a href="mailto:office@clupilot.com">office@clupilot.com</a> — Antwort am selben Werktag.
|
|
</p>
|
|
|
|
<footer>
|
|
<div class="fo">
|
|
<span>© {{ date('Y') }} CluPilot Cloud · Österreich</span>
|
|
<div class="right">
|
|
<a href="{{ route('home') }}">Startseite</a>
|
|
<a href="{{ route('legal.impressum') }}">Impressum</a>
|
|
<a href="{{ route('legal.datenschutz') }}">Datenschutz</a>
|
|
<a href="{{ route('legal.agb') }}">AGB</a>
|
|
</div>
|
|
</div>
|
|
</footer>
|
|
</div>
|
|
</body>
|
|
</html>
|