main
html 69 lines 1.89 KB
Raw
1 <html>
2
3 <head>
4 <title>Sync Status</title>
5 <script type="module">
6 import { store } from "/components/sync/sync-store.js";
7 </script>
8
9 <style>
10 .status-icon {
11 display: inline-flex;
12 align-items: center;
13 gap: 0.1rem;
14 }
15
16 .status-icon svg {
17 pointer-events: none;
18 }
19
20 .status-icon > x-extension {
21 display: contents;
22 }
23
24 .pending-ring {
25 animation: pendingPulse 1.2s infinite ease-in-out;
26 }
27
28 @keyframes pendingPulse {
29 0% {
30 stroke-opacity: 1;
31 stroke-width: 3;
32 }
33
34 50% {
35 stroke-opacity: 0.25;
36 stroke-width: 5;
37 }
38
39 100% {
40 stroke-opacity: 1;
41 stroke-width: 3;
42 }
43 }
44 </style>
45 </head>
46
47 <body>
48 <div x-data>
49 <template x-if="$store.sync">
50 <div
51 class="status-icon"
52 x-create="$store.sync.init()"
53 >
54 <svg viewBox="0 0 30 30" width="20" height="20" aria-label="sync status">
55 <circle
56 cx="15" cy="15" r="12" fill="none" stroke="#e40138" stroke-width="3"
57 :class="{ 'pending-ring': $store.sync.mode === 'HANDSHAKE_PENDING' }"
58 :r="['HEALTHY', 'DEGRADED'].includes($store.sync.mode) ? 8 : 12"
59 :fill="$store.sync.mode === 'HEALTHY' ? '#00c340' : $store.sync.mode === 'DEGRADED' ? '#ff6b00' : 'none'"
60 :stroke="$store.sync.mode === 'HANDSHAKE_PENDING' ? '#f0a000' : $store.sync.mode === 'DISCONNECTED' ? '#e40138' : 'none'"
61 />
62 </svg>
63 <x-extension id="sync-status-end"></x-extension>
64 </div>
65 </template>
66 </div>
67 </body>
68
69 </html>