index.php 3.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. <?php
  2. declare(strict_types=1);
  3. require_once dirname(__DIR__) . '/src/bootstrap.php';
  4. $status = app_monitor_service()->getStatus();
  5. $appName = $status['app']['name'] ?? 'Getraenkeautomat Monitor';
  6. ?>
  7. <!DOCTYPE html>
  8. <html lang="de">
  9. <head>
  10. <meta charset="UTF-8">
  11. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  12. <title><?= htmlspecialchars($appName, ENT_QUOTES) ?></title>
  13. <link rel="stylesheet" href="/styles.css">
  14. </head>
  15. <body>
  16. <div class="page-shell">
  17. <header class="hero">
  18. <div class="hero__copy">
  19. <p class="eyebrow">Fuellstand live im Blick</p>
  20. <h1><?= htmlspecialchars($appName, ENT_QUOTES) ?></h1>
  21. <p class="hero__lede">
  22. Ueberwache Sensorwerte, erkenne Leerstaende fruehzeitig und springe direkt ins Adminpanel, wenn sich Grenzwerte oder Alarmwege aendern sollen.
  23. </p>
  24. </div>
  25. <div class="hero__stats">
  26. <div class="stat-card">
  27. <span>Automaten</span>
  28. <strong data-summary="machine_count"><?= (int) ($status['summary']['machine_count'] ?? 0) ?></strong>
  29. </div>
  30. <div class="stat-card">
  31. <span>Faecher</span>
  32. <strong data-summary="slot_count"><?= (int) ($status['summary']['slot_count'] ?? 0) ?></strong>
  33. </div>
  34. <div class="stat-card stat-card--alert">
  35. <span>Kritisch</span>
  36. <strong data-summary="critical_count"><?= (int) ($status['summary']['critical_count'] ?? 0) ?></strong>
  37. </div>
  38. </div>
  39. <div class="hero__actions">
  40. <a class="button button--primary" href="/admin/">Adminpanel</a>
  41. <a class="button button--ghost" href="/api/v1/status.php" target="_blank" rel="noreferrer">Status JSON</a>
  42. </div>
  43. </header>
  44. <main class="dashboard">
  45. <section class="panel panel--controls">
  46. <div>
  47. <h2>Automatenansicht</h2>
  48. <p>Filtere einzelne Automaten oder beobachte den Gesamtzustand auf einen Blick.</p>
  49. </div>
  50. <div class="chip-row" id="machine-filter"></div>
  51. </section>
  52. <section class="panel">
  53. <div class="panel__header">
  54. <div>
  55. <h2>Fuellstand nach Fach</h2>
  56. <p>Die Karten zeigen Messwert, geschaetzten Bestand und den Alarmstatus pro Sensor.</p>
  57. </div>
  58. <p class="timestamp">Letzte Aktualisierung: <span id="generated-at"><?= htmlspecialchars($status['generated_at'], ENT_QUOTES) ?></span></p>
  59. </div>
  60. <div id="machine-grid" class="machine-grid"></div>
  61. </section>
  62. <section class="panel">
  63. <div class="panel__header">
  64. <div>
  65. <h2>Letzte Alarmereignisse</h2>
  66. <p>Es werden nur Zustandswechsel geloggt, keine wiederholten Daueralarme.</p>
  67. </div>
  68. </div>
  69. <div id="alert-list" class="alert-list"></div>
  70. </section>
  71. </main>
  72. </div>
  73. <script id="initial-status" type="application/json"><?= json_encode($status, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE) ?></script>
  74. <script src="/app.js" defer></script>
  75. </body>
  76. </html>