Files
job-dashboard/ops.html

155 lines
10 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1">
<title>Ops Timeline — Rhino Terminal</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500;700&display=swap" rel="stylesheet">
<style>
*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
:root{--bg:#0d0f14;--surf:#141820;--card:#181c26;--border:#1e2332;
--amber:#ffb000;--amber-bright:#ffd866;--amber-dim:#665500;--amber-faint:#2a2200;
--green:#4caf7d;--red:#ef5350;--cyan:#7ae9ff;--muted:#3a3e4a;
--font:'JetBrains Mono','Fira Code','Cascadia Code',monospace
}
body{font-family:var(--font);background:var(--bg);color:var(--amber);min-height:100vh;padding:16px;line-height:1.7;font-size:14px}
.container{max-width:720px;margin:0 auto}
body::after{content:'';position:fixed;top:0;left:0;width:100%;height:100%;pointer-events:none;background:radial-gradient(ellipse at center,rgba(255,176,0,0.015) 0%,transparent 70%);z-index:999}
.term-bar{border:1px solid var(--amber-faint);border-radius:4px 4px 0 0;background:var(--surf);overflow:hidden;margin-bottom:8px}
.term-title{display:flex;align-items:center;justify-content:space-between;padding:6px 12px;background:var(--card);border-bottom:1px solid var(--amber-faint);font-size:11px;color:var(--amber-dim);user-select:none}
.term-title .dots{display:flex;gap:4px}
.term-title .dots .dot{width:10px;height:10px;border-radius:50%;margin:0}
.dot.r{background:#ff5f56}.dot.y{background:#ffbd2e}.dot.g{background:#27c93f}
.term-title .name{font-size:10px;text-transform:uppercase;letter-spacing:0.8px}
.term-body{padding:18px 16px 14px;min-height:200px}
.prompt-line{display:flex;align-items:center;gap:2px;margin-bottom:2px;font-size:13px;color:var(--amber-dim)}
.prompt-line .ps1{color:var(--amber-bright);font-weight:500}
.prompt-line .ps2{color:var(--muted)}
.sect{margin-bottom:12px}
.sect-head{display:flex;align-items:center;gap:8px;padding:10px 12px;cursor:pointer;user-select:none;border:1px solid var(--border);background:var(--surf);transition:all 0.2s}
.sect-head:hover{border-color:var(--amber-dim)}
.sect-head .arrow{transition:transform 0.25s;font-size:10px;color:var(--amber-dim)}
.sect-head.open .arrow{transform:rotate(90deg)}
.sect-head .label{font-size:11px;font-weight:500;text-transform:uppercase;letter-spacing:0.6px;color:var(--amber-bright)}
.sect-head .badge{font-size:9px;padding:1px 6px;border-radius:3px;margin-left:auto;font-weight:500}
.badge-green{background:rgba(76,175,125,0.15);color:var(--green)}
.badge-amber{background:rgba(255,176,0,0.15);color:var(--amber)}
.badge-cyan{background:rgba(122,233,255,0.15);color:var(--cyan)}
.sect-body{display:none;padding:12px;background:var(--card);border:1px solid var(--border);border-top:none}
.sect-body.open{display:block}
.entry{display:flex;gap:12px;padding:8px 0;border-bottom:1px solid var(--amber-faint)}
.entry:last-child{border:none}
.entry .date{color:var(--amber-dim);font-size:11px;white-space:nowrap;min-width:75px;padding-top:2px}
.entry .desc{color:var(--txt);font-size:12px;line-height:1.6}
.entry .desc .tag{display:inline-block;font-size:9px;padding:0 5px;border-radius:2px;margin-right:4px;font-weight:500}
.tag-add{background:rgba(76,175,125,0.2);color:var(--green)}
.tag-fix{background:rgba(239,83,80,0.2);color:var(--red)}
.tag-chore{background:rgba(122,233,255,0.15);color:var(--cyan)}
.tag-upgrade{background:rgba(255,176,0,0.15);color:var(--amber)}
.status-grid{display:grid;grid-template-columns:1fr 1fr;gap:8px;margin-top:8px}
.status-item{padding:8px 10px;background:var(--surf);border:1px solid var(--border);font-size:11px}
.status-item .key{color:var(--amber-dim)}
.status-item .val{color:var(--amber-bright);margin-top:2px}
.status-item .val.green{color:var(--green)}
.status-item .val.red{color:var(--red)}
.nav-links{display:flex;gap:12px;justify-content:center;padding:16px 0 8px}
.nav-links a{color:var(--amber-dim);text-decoration:none;font-size:11px;letter-spacing:0.4px}
.nav-links a:hover{color:var(--amber-bright)}
.rhino-ascii{text-align:center;padding:12px 0;color:var(--amber-dim);font-size:10px;line-height:1.3;opacity:0.6}
@media(max-width:600px){.status-grid{grid-template-columns:1fr}}
</style>
</head>
<body><div class="container">
<!-- Terminal Bar -->
<div class="term-bar">
<div class="term-title">
<div class="dots"><span class="dot r"></span><span class="dot y"></span><span class="dot g"></span></div>
<span class="name">ops-timeline · v2.0</span>
<span style="font-size:10px;color:var(--amber-dim)">~$ █</span>
</div>
<div class="term-body">
<div class="prompt-line"><span class="ps1">rhino@green-jacket</span><span class="ps2">:</span><span class="ps1">~</span><span class="ps2">$ cat /var/log/deployments</span></div>
<div style="height:8px"></div>
<!-- ======== Changelog ======== -->
<div class="sect">
<div class="sect-head open" onclick="this.classList.toggle('open');this.nextElementSibling.classList.toggle('open')">
<span class="arrow"></span><span class="label">Changelog</span><span class="badge badge-cyan">v2.0</span>
</div>
<div class="sect-body open" id="changelog">
<div class="entry"><span class="date">2026-07-20</span><div class="desc"><span class="tag tag-add">ADD</span> Ops Timeline page at <code>/ops</code></div></div>
<div class="entry"><span class="date">2026-07-20</span><div class="desc"><span class="tag tag-add">ADD</span> Market Intel API + dashboard tab with salary charts</div></div>
<div class="entry"><span class="date">2026-07-20</span><div class="desc"><span class="tag tag-add">ADD</span> Smart Match score column per job row</div></div>
<div class="entry"><span class="date">2026-07-20</span><div class="desc"><span class="tag tag-add">ADD</span> Evening Stand-Down briefing (6:45pm cron)</div></div>
<div class="entry"><span class="date">2026-07-20</span><div class="desc"><span class="tag tag-add">ADD</span> Backend backup to Gitea: Anthony/job-dashboard</div></div>
<div class="entry"><span class="date">2026-07-19</span><div class="desc"><span class="tag tag-add">ADD</span> Cover letter regeneration endpoint + docx export</div></div>
<div class="entry"><span class="date">2026-07-18</span><div class="desc"><span class="tag tag-add">ADD</span> Closing date urgency colours (past/urgent/warning)</div></div>
<div class="entry"><span class="date">2026-07-08</span><div class="desc"><span class="tag tag-chore">FIX</span> Stale job detection, bulk-edit, sorting</div></div>
<div class="entry"><span class="date">2026-07-03</span><div class="desc"><span class="tag tag-add">ADD</span> Initial job tracker dashboard — Notion sync + API</div></div>
</div>
</div>
<!-- ======== System Status ======== -->
<div class="sect">
<div class="sect-head open" onclick="this.classList.toggle('open');this.nextElementSibling.classList.toggle('open')">
<span class="arrow"></span><span class="label">System Status</span><span class="badge badge-green">online</span>
</div>
<div class="sect-body open">
<div class="status-grid">
<div class="status-item"><div class="key">Dashboard Server</div><div class="val green">● Running</div><div class="key" style="margin-top:4px">port 9099</div></div>
<div class="status-item"><div class="key">Notion Sync</div><div class="val green">● Auto-refresh 5min</div><div class="key" style="margin-top:4px">jobs_cache.json</div></div>
<div class="status-item"><div class="key">Evening Stand-Down</div><div class="val green">● Cron active</div><div class="key" style="margin-top:4px">weekdays 18:45 AWST</div></div>
<div class="status-item"><div class="key">Gitea Backup</div><div class="val green">● Pushed</div><div class="key" style="margin-top:4px">Anthony/job-dashboard</div></div>
<div class="status-item"><div class="key">Cover Letter Engine</div><div class="val green">● OmniRoute</div><div class="key" style="margin-top:4px">cover-letter-writer combo</div></div>
<div class="status-item"><div class="key">Market Intel</div><div class="val green">● Live</div><div class="key" style="margin-top:4px">/api/market-intel</div></div>
</div>
</div>
</div>
<!-- ======== Tech Stack ======== -->
<div class="sect">
<div class="sect-head" onclick="this.classList.toggle('open');this.nextElementSibling.classList.toggle('open')">
<span class="arrow"></span><span class="label">Tech Stack</span><span class="badge badge-cyan">built with</span>
</div>
<div class="sect-body">
<div class="status-grid">
<div class="status-item"><div class="key">Runtime</div><div class="val">Python 3 · HTTPServer</div></div>
<div class="status-item"><div class="key">Data</div><div class="val">Notion API · jobs_cache.json</div></div>
<div class="status-item"><div class="key">LLM</div><div class="val">OmniRoute · cover-letter-writer</div></div>
<div class="status-item"><div class="key">Infra</div><div class="val">Hermes CT460 · Tailscale</div></div>
<div class="status-item"><div class="key">Git</div><div class="val">Gitea · Anthony/job-dashboard</div></div>
<div class="status-item"><div class="key">CI</div><div class="val">Belongs to the rhino now</div></div>
</div>
</div>
</div>
<!-- ======== Rhino Footer ======== -->
<div class="nav-links">
<a href="/">Dashboard</a>
<a href="/api/jobs">API</a>
<a href="/evening.html">Evening Briefing</a>
<a href="https://gitea.kangaroo-eel.ts.net/Anthony/job-dashboard" target="_blank">Source</a>
</div>
<div class="rhino-ascii">
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓<br>
┃ The Rhino in the Green Jacket ┃<br>
┃ "Keep the weird underneath the ┃<br>
┃ competent." ┃<br>
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
</div>
</div></div>
</div>
</body>
</html>