245 lines
12 KiB
HTML
245 lines
12 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="en">
|
||
<head>
|
||
<meta charset="UTF-8" />
|
||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||
<title>Swap Station – Logs</title>
|
||
|
||
<script src="https://cdn.socket.io/4.7.5/socket.io.min.js"></script>
|
||
|
||
<script src="js/auth-guard.js"></script>
|
||
|
||
<!-- Font + Tailwind -->
|
||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700;800&display=swap" rel="stylesheet">
|
||
|
||
<script src="https://cdn.jsdelivr.net/npm/flatpickr"></script>
|
||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/flatpickr/dist/flatpickr.min.css">
|
||
|
||
<script src="https://cdn.tailwindcss.com"></script>
|
||
<script>
|
||
tailwind.config = {
|
||
theme: {
|
||
extend: {
|
||
fontFamily: { sans: ["Inter","ui-sans-serif","system-ui"] },
|
||
keyframes: { pulseDot: { "0%,100%": { transform:"scale(1)", opacity:1 }, "50%": { transform:"scale(1.2)", opacity:.7 } } },
|
||
animation: { pulseDot: "pulseDot 1.2s ease-in-out infinite" }
|
||
}
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style>
|
||
:root { color-scheme: dark; }
|
||
html, body { height: 100%; }
|
||
body { background:#0a0a0a; }
|
||
|
||
/* subtle background glow */
|
||
.bg-glow::before,
|
||
.bg-glow::after {
|
||
content:""; position:fixed; pointer-events:none; z-index:-1; border-radius:9999px; filter: blur(64px);
|
||
}
|
||
.bg-glow::before { width:34rem; height:34rem; left:-8rem; top:-8rem; background: rgba(16,185,129,.12); }
|
||
.bg-glow::after { width:36rem; height:36rem; right:-10rem; bottom:-10rem; background: rgba(56,189,248,.10); }
|
||
|
||
.badge { font-size:12px; font-weight:800; padding:.35rem .6rem; border-radius:.6rem; border:1px solid; display:inline-flex; align-items:center; gap:.4rem; }
|
||
.chip{display:inline-flex;align-items:center;gap:.4rem;padding:.4rem .5rem;border-radius:.4rem;
|
||
font-size:10px;font-weight:800;letter-spacing:.02em;text-transform:uppercase;border:1px solid}
|
||
.chip-emerald{background:rgba(16,185,129,.15);color:#a7f3d0;border-color:rgba(16,185,129,.35)}
|
||
.chip-rose{background:rgba(244,63,94,.16);color:#fecaca;border-color:rgba(244,63,94,.35)}
|
||
.chip-amber{background:rgba(245,158,11,.18);color:#fde68a;border-color:rgba(245,158,11,.40)}
|
||
.chip-sky{background:rgba(56,189,248,.15);color:#bae6fd;border-color:rgba(56,189,248,.35)}
|
||
.chip-slate{background:rgba(148,163,184,.12);color:#cbd5e1;border-color:rgba(148,163,184,.30)}
|
||
|
||
.cham_chip{display:inline-flex;align-items:center;gap:.4rem;padding:.4rem .5rem;border-radius:.4rem;
|
||
font-size:10px;font-weight:800;letter-spacing:.02em;text-transform:uppercase;border:1px solid}
|
||
.cham_chip-emerald{background:rgba(16,185,129,.15);color:#a7f3d0;border-color:rgba(16,185,129,.35)}
|
||
.cham_chip-rose{background:rgba(244,63,94,.16);color:#fecaca;border-color:rgba(244,63,94,.35)}
|
||
.cham_chip-amber{background:rgba(245,158,11,.18);color:#fde68a;border-color:rgba(245,158,11,.40)}
|
||
.cham_chip-sky{background:rgba(56,189,248,.15);color:#bae6fd;border-color:rgba(56,189,248,.35)}
|
||
.cham_chip-slate{background:rgba(148,163,184,.12);color:#cbd5e1;border-color:rgba(148,163,184,.30)}
|
||
|
||
.glass { background: rgba(30,41,59,.45); border: 1px solid rgba(255,255,255,.10); border-radius: .9rem; backdrop-filter: saturate(150%) blur(12px); }
|
||
.btn { font-weight:800; font-size:12px; padding:.5rem .7rem; border-radius:.6rem; border:1px solid rgba(255,255,255,.12); background:rgba(255,255,255,.06); transition:.18s; }
|
||
.btn:hover { border-color: rgba(16,185,129,.45); background: rgba(16,185,129,.10); }
|
||
.btn-danger { border-color: rgba(244,63,94,.35); background: rgba(244,63,94,.14); color: #fecaca; }
|
||
.btn-danger:hover { background: rgba(244,63,94,.22); }
|
||
.btn-ghost { border-color: rgba(255,255,255,.10); background: rgba(255,255,255,.05); }
|
||
.badge { font-size:12px; font-weight:800; padding:.35rem .6rem; border-radius:.6rem; border:1px solid; display:inline-flex; align-items:center; gap:.4rem; }
|
||
.textarea {
|
||
width:100%; height:100%; background: linear-gradient(180deg, rgba(2,6,23,.55), rgba(2,6,23,.35));
|
||
border:1px dashed rgba(255,255,255,.14); border-radius:.75rem; padding:1rem; color:#d1d5db;
|
||
font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size:12px; resize:none; outline:none;
|
||
}
|
||
</style>
|
||
</head>
|
||
<body class="min-h-screen text-gray-100 bg-glow">
|
||
|
||
<!-- STATUS BAR + TABS -->
|
||
<header class="relative z-10 border-b border-white/10 bg-black/20 backdrop-blur">
|
||
<div class="mx-auto max-w-7.5xl px-3 sm:px-4 py-2 grid grid-cols-[auto_1fr_auto] items-center gap-2">
|
||
<div class="flex items-center gap-2 sm:gap-3">
|
||
<a href="./station_selection.html"
|
||
class="h-9 w-9 flex items-center justify-center rounded-full bg-white/5 hover:bg-white/10 transition"
|
||
title="Back">
|
||
<svg class="w-5 h-5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
||
<path stroke-linecap="round" stroke-linejoin="round" d="M15 19l-7-7 7-7"/>
|
||
</svg>
|
||
</a>
|
||
<div class="flex flex-col leading-tight">
|
||
<div id="station-name" class="text-base sm:text-lg font-extrabold tracking-tight">
|
||
Loading...
|
||
</div>
|
||
<div id="station-location" class="text-xs sm:text-sm text-slate-100">
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="flex items-center justify-center scale-100">
|
||
<img src="./assets/vec_logo.png" alt="VECMOCON"
|
||
class="h-7 w-auto opacity-90" onerror="this.style.display='none'"/>
|
||
</div>
|
||
|
||
<div class="flex items-center flex-wrap justify-end gap-1.5 sm:gap-2">
|
||
|
||
<span class="badge border-white/10 bg-white/5 text-slate-200">
|
||
<span>Product ID:</span>
|
||
<span id="product-id" class="font-semibold">—</span>
|
||
</span>
|
||
|
||
<span class="badge border-white/10 bg-white/5 text-slate-200">
|
||
<span>Station ID:</span>
|
||
<span id="device-id" class="font-semibold">—</span>
|
||
</span>
|
||
|
||
<!-- <span class="badge border-white/10 bg-white/5 text-slate-200">
|
||
<span>Device ID:</span>
|
||
<span id="device-id">—</span>
|
||
</span> -->
|
||
|
||
<span class="badge border-white/10 bg-white/5 text-slate-200">
|
||
<svg class="w-2.5 h-2.5 opacity-90" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8">
|
||
<circle cx="12" cy="12" r="9"></circle><path d="M12 7v5l3 3"></path>
|
||
</svg>
|
||
<span id="last-update-status">Waiting...</span>
|
||
</span>
|
||
|
||
<span id="connection-status-chip" class="cham_chip cham_chip-amber" title="Connection to backend">
|
||
<span class="h-2 w-2 rounded-full bg-amber-400"></span> Connecting...
|
||
</span>
|
||
|
||
<button id="station-reset-btn" class="btn btn-danger !p-2" title="Station Reset">
|
||
<svg class="w-3.5 h-3.5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round">
|
||
<path d="M18.36 6.64a9 9 0 1 1-12.73 0"/><line x1="12" y1="2" x2="12" y2="12"/>
|
||
</svg>
|
||
</button>
|
||
|
||
<!-- <span id="backup-power-chip" class="cham_chip cham_chip-slate" title="Station power source" style="display: none;">On Backup</span> -->
|
||
|
||
<div class="hidden sm:block w-px h-5 bg-white/10"></div>
|
||
|
||
<button id="refreshBtn" class="btn btn-ghost !p-2">
|
||
<svg class="w-3.5 h-3.5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2">
|
||
<path d="M21 12a9 9 0 10-3.5 7.1M21 12h-4m4 0l-2.5-2.5"></path>
|
||
</svg>
|
||
</button>
|
||
|
||
<button id="downloadBtn" class="btn btn-ghost !p-2">
|
||
<svg class="w-3.5 h-3.5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2">
|
||
<path d="M12 3v12m0 0l4-4m-4 4l-4-4"></path><path d="M5 21h14"></path>
|
||
</svg>
|
||
</button>
|
||
|
||
<button id="logout-btn" class="btn btn-danger !p-2">
|
||
<svg class="w-3.5 h-3.5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2">
|
||
<path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4"></path>
|
||
<path d="M16 17l5-5-5-5"></path><path d="M21 12H9"></path>
|
||
</svg>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Tabs -->
|
||
<div class="border-t border-white/10 bg-black/10">
|
||
<nav class="mx-auto max-w-7.5xl px-3 sm:px-4 flex">
|
||
<a href="./dashboard.html" class="px-4 py-2 text-sm text-gray-400 hover:text-gray-200 hover:border-b-2 hover:border-white/30 font-semibold">Main</a>
|
||
<a href="./logs.html" class="px-4 py-2 text-sm font-semibold border-b-2 border-emerald-400/70 text-white">Logs</a>
|
||
<a href="./analytics.html" class="px-4 py-2 text-sm text-gray-400 hover:text-gray-200 hover:border-b-2 hover:border-white/30 font-semibold">Analytics</a>
|
||
</nav>
|
||
</div>
|
||
</header>
|
||
|
||
<!-- BODY -->
|
||
<main class="relative z-10 mx-auto max-w-7.5xl px-3 sm:px-4 py-4 flex flex-col gap-4">
|
||
<!-- Top row: Device badge + hint -->
|
||
|
||
<!-- <section class="flex items-center gap-2 mb-4">
|
||
<label for="log-date-picker" class="text-sm font-bold text-gray-300">Select Date:</label>
|
||
<input id="log-date-picker" type="text" placeholder="Select a date" class="rounded-md bg-white/5 border border-white/10 px-2 py-1.5 text-sm outline-none focus:ring-2 focus:ring-emerald-500/60">
|
||
</section> -->
|
||
|
||
<section class="flex flex-wrap items-center gap-4 mb-4">
|
||
<div class="flex items-center gap-2">
|
||
<label for="log-count" class="text-sm font-bold text-gray-300">Log Count:</label>
|
||
<input id="log-count" type="number" value="50" min="10" max="500" class="w-20 rounded-md bg-white/5 border border-white/10 px-2 py-1.5 text-sm outline-none">
|
||
</div>
|
||
|
||
<div class="ml-auto flex items-center gap-2">
|
||
<input id="from-date" type="text" placeholder="Start Date" class="rounded-md bg-white/5 border border-white/10 px-2 py-1.5 text-sm outline-none">
|
||
<span class="text-gray-500">to</span>
|
||
<input id="to-date" type="text" placeholder="End Date" class="rounded-md bg-white/5 border border-white/10 px-2 py-1.5 text-sm outline-none">
|
||
<button id="apply-filters-btn" class="btn">Apply</button>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- Logs panels -->
|
||
<div class="grid grid-cols-1 lg:grid-cols-2 gap-4 min-h-[18rem]">
|
||
<!-- Request -->
|
||
<section class="glass p-4 flex flex-col min-h-[34rem]">
|
||
<div class="flex items-center justify-between">
|
||
<div>
|
||
<h2 class="text-base sm:text-lg font-extrabold">RPC Request</h2>
|
||
</div>
|
||
<div class="flex items-center gap-2">
|
||
<button id="clear-req" class="btn btn-danger">Clear</button>
|
||
</div>
|
||
</div>
|
||
<div class="mt-3 flex-1">
|
||
<textarea id="request-log-area" class="textarea" readonly></textarea>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- Events -->
|
||
<section class="glass p-4 flex flex-col min-h-[34rem]">
|
||
<div class="flex items-center justify-between">
|
||
<div>
|
||
<h2 class="text-base sm:text-lg font-extrabold">Events</h2>
|
||
</div>
|
||
<div class="flex items-center gap-2">
|
||
<button id="clear-evt" class="btn btn-danger">Clear</button>
|
||
</div>
|
||
</div>
|
||
<div class="mt-3 flex-1">
|
||
<textarea id="event-log-area" class="textarea" readonly></textarea>
|
||
</div>
|
||
</section>
|
||
</div>
|
||
|
||
<!-- Footer actions -->
|
||
<div class="flex justify-end">
|
||
<button id="clear-all" class="btn btn-danger inline-flex items-center gap-1">
|
||
<svg class="w-4 h-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8">
|
||
<path d="M3 6h18"></path><path d="M19 6l-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6"></path>
|
||
<path d="M10 11v6"></path><path d="M14 11v6"></path>
|
||
</svg>
|
||
Clear All Logs
|
||
</button>
|
||
</div>
|
||
</main>
|
||
|
||
<script src="./js/common-header.js"></script>
|
||
<script src="./js/logs.js"></script>
|
||
</body>
|
||
</html>
|