- Drop the embedded 20-contact RAW_DATA sample; the logbook now comes only from data/k5bss-log.json - Show a banner and table message when the log fails to load, and display "—" for the header stats - Skip building the dashboard when there is no data (it crashed on an empty log) and guard the activity chart redraw on resize - Compute the QSO count from the log instead of hardcoding it Co-Authored-By: Claude Opus 5.5 <[email protected]>
223 lines
8.7 KiB
HTML
Executable File
223 lines
8.7 KiB
HTML
Executable File
<!DOCTYPE html>
|
||
<html lang="en">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||
<meta name="referrer" content="strict-origin-when-cross-origin">
|
||
<meta http-equiv="Content-Security-Policy" content="default-src 'none'; script-src 'self' 'unsafe-inline' https://static.cloudflareinsights.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; font-src 'self' https://fonts.gstatic.com; img-src 'self' data:; connect-src 'self' https://cloudflareinsights.com; frame-src 'none'; object-src 'none'; base-uri 'self'; form-action 'none'; upgrade-insecure-requests">
|
||
<title>K5BSS — Justin Frasier · Ham Radio Station</title>
|
||
<link rel="sitemap" type="application/xml" href="/sitemap.xml">
|
||
<link rel="icon" type="image/svg+xml" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'%3E%3Crect width='32' height='32' rx='4' fill='%230f1218'/%3E%3Ctext x='3' y='11' font-family='IBM Plex Mono,Courier New,monospace' font-size='6' fill='%234a5568'%3E~$%3C/text%3E%3Ctext x='2' y='27' font-family='IBM Plex Mono,Courier New,monospace' font-size='19' font-weight='600' fill='%2322c55e'%3Ejf%3C/text%3E%3C/svg%3E">
|
||
<link rel="icon" type="image/x-icon" href="/favicon.ico">
|
||
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
|
||
<link rel="icon" type="image/png" sizes="64x64" href="/favicon-64x64.png">
|
||
<link rel="icon" type="image/png" sizes="256x256" href="/favicon-256x256.png">
|
||
<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=Share+Tech+Mono&family=Orbitron:wght@400;700;900&family=Barlow:wght@300;400;600&display=swap" rel="stylesheet">
|
||
<link rel="stylesheet" href="css/k5bss-style.css">
|
||
</head>
|
||
<body>
|
||
|
||
<header>
|
||
<div class="header-inner">
|
||
<div class="callsign-block">
|
||
<div>
|
||
<div class="callsign">K5BSS</div>
|
||
<div class="op-name">JUSTIN A FRASIER · BOSSIER CITY, LA · EM32</div>
|
||
</div>
|
||
</div>
|
||
<div class="header-status">
|
||
<div class="status-item">
|
||
<span class="status-val" id="stat-qso">—</span>
|
||
<span class="status-lbl">QSOs Logged</span>
|
||
</div>
|
||
<div class="status-item">
|
||
<span class="status-val" id="stat-dxcc">—</span>
|
||
<span class="status-lbl">Countries</span>
|
||
</div>
|
||
<div class="status-item">
|
||
<span class="status-val" id="stat-states">—</span>
|
||
<span class="status-lbl">States</span>
|
||
</div>
|
||
<div class="online-badge">
|
||
<span class="pulse-dot"></span>
|
||
STATION ONLINE
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</header>
|
||
|
||
<nav>
|
||
<div class="nav-inner">
|
||
<button class="nav-btn active" onclick="showSection('dashboard', this)">◈ DASHBOARD</button>
|
||
<button class="nav-btn" onclick="showSection('logbook', this)">▤ LOGBOOK</button>
|
||
<button class="nav-btn" onclick="showSection('about', this)">◉ ABOUT</button>
|
||
</div>
|
||
</nav>
|
||
|
||
<main>
|
||
|
||
<div class="log-error" id="log-error" role="alert" hidden>
|
||
⚠ LOG UNAVAILABLE — The logbook could not be loaded. Try again later.
|
||
</div>
|
||
|
||
<!-- DASHBOARD -->
|
||
<div id="section-dashboard" class="section active">
|
||
<div class="dash-grid">
|
||
|
||
<div class="card amber" id="card-modes">
|
||
<div class="card-title">▶ Modes</div>
|
||
<div class="bar-chart" id="modes-chart"></div>
|
||
</div>
|
||
|
||
<div class="card blue" id="card-bands">
|
||
<div class="card-title">▶ Bands</div>
|
||
<div class="bar-chart" id="bands-chart"></div>
|
||
</div>
|
||
|
||
<div class="card cyan" id="card-countries">
|
||
<div class="card-title">▶ Top Countries</div>
|
||
<div class="country-list" id="countries-list"></div>
|
||
</div>
|
||
|
||
<div class="card green activity-card">
|
||
<div class="card-title">▶ QSO Activity by Month</div>
|
||
<canvas id="activityCanvas"></canvas>
|
||
</div>
|
||
|
||
</div>
|
||
</div>
|
||
|
||
<!-- LOGBOOK -->
|
||
<div id="section-logbook" class="section">
|
||
<div class="log-controls">
|
||
<input class="search-input" id="search-input" type="text" placeholder="Search callsign, name, country, QTH..." oninput="applyFilters()">
|
||
<select class="filter-select" id="filter-band" onchange="applyFilters()">
|
||
<option value="">All Bands</option>
|
||
</select>
|
||
<select class="filter-select" id="filter-mode" onchange="applyFilters()">
|
||
<option value="">All Modes</option>
|
||
</select>
|
||
<select class="filter-select" id="filter-lotw" onchange="applyFilters()">
|
||
<option value="">LoTW: All</option>
|
||
<option value="Y">LoTW: Confirmed</option>
|
||
<option value="N">LoTW: Not Confirmed</option>
|
||
</select>
|
||
<span class="log-meta" id="log-meta">Loading...</span>
|
||
</div>
|
||
<div class="table-wrap">
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
<th onclick="sortTable('call')">Call</th>
|
||
<th onclick="sortTable('name')">Name</th>
|
||
<th onclick="sortTable('date')">Date</th>
|
||
<th onclick="sortTable('time')">Time (UTC)</th>
|
||
<th onclick="sortTable('band')">Band</th>
|
||
<th onclick="sortTable('mode')">Mode</th>
|
||
<th onclick="sortTable('rst_sent')">RST S/R</th>
|
||
<th onclick="sortTable('country')">Country</th>
|
||
<th onclick="sortTable('dist')">Dist (mi)</th>
|
||
<th onclick="sortTable('lotw')">LoTW</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody id="log-tbody">
|
||
<tr><td colspan="10"><div class="loading"><div class="spinner"></div>Loading logbook...</div></td></tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
<div class="pagination" id="pagination"></div>
|
||
</div>
|
||
|
||
<!-- ABOUT -->
|
||
<div id="section-about" class="section">
|
||
<div class="about-grid">
|
||
<div class="card green">
|
||
<div class="card-title">▶ Station Info</div>
|
||
<div class="info-block">
|
||
<div class="info-label">Call Sign</div>
|
||
<div class="info-value">K5BSS</div>
|
||
</div>
|
||
<div class="info-block">
|
||
<div class="info-label">Operator</div>
|
||
<div class="info-value">Justin A Frasier</div>
|
||
</div>
|
||
<div class="info-block">
|
||
<div class="info-label">Location</div>
|
||
<div class="info-value">Bossier City, Louisiana</div>
|
||
</div>
|
||
<div class="info-block">
|
||
<div class="info-label">Grid Square</div>
|
||
<div class="info-value">EM32</div>
|
||
</div>
|
||
<div class="info-block">
|
||
<div class="info-label">County</div>
|
||
<div class="info-value">Bossier County, LA</div>
|
||
</div>
|
||
<div class="info-block">
|
||
<div class="info-label">CQ Zone / ITU Zone</div>
|
||
<div class="info-value">5 / 6</div>
|
||
</div>
|
||
<div class="info-block">
|
||
<div class="info-label">QRZ Profile</div>
|
||
<div class="info-value"><a href="https://www.qrz.com/db/K5BSS" target="_blank">qrz.com/db/K5BSS ↗</a></div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="card blue">
|
||
<div class="card-title">▶ Operating Preferences</div>
|
||
<div class="info-block">
|
||
<div class="info-label">Primary Modes</div>
|
||
<div class="tag-list">
|
||
<span class="tag">FT8</span>
|
||
<span class="tag">FT4</span>
|
||
<span class="tag">DIG</span>
|
||
<span class="tag">USB/SSB</span>
|
||
<span class="tag">RTTY</span>
|
||
</div>
|
||
</div>
|
||
<div class="info-block">
|
||
<div class="info-label">Primary Bands</div>
|
||
<div class="tag-list">
|
||
<span class="tag">20m</span>
|
||
<span class="tag">40m</span>
|
||
<span class="tag">80m</span>
|
||
<span class="tag">30m</span>
|
||
<span class="tag">17m</span>
|
||
<span class="tag">15m</span>
|
||
</div>
|
||
</div>
|
||
<div class="info-block">
|
||
<div class="info-label">Logging Software</div>
|
||
<div class="info-value">QRZ Logbook</div>
|
||
</div>
|
||
<div class="info-block">
|
||
<div class="info-label">LoTW / eQSL</div>
|
||
<div class="info-value">Active on both</div>
|
||
</div>
|
||
<div class="info-block">
|
||
<div class="info-label">Log Period</div>
|
||
<div class="info-value">Jan 2021 – May 2023</div>
|
||
</div>
|
||
<div class="info-block">
|
||
<div class="info-label">Total QSOs</div>
|
||
<div class="info-value" style="color:var(--green);font-size:1.5rem;font-family:var(--font-display)">2,112</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
</main>
|
||
|
||
<footer>
|
||
<span>K5BSS</span> · JUSTIN A FRASIER · BOSSIER CITY, LA ·
|
||
GRID EM32 · CQ5 · ALL TIMES UTC ·
|
||
LOGBOOK GENERATED FROM ADIF EXPORT
|
||
</footer>
|
||
|
||
<script src="js/k5bss.js"></script>
|
||
</body>
|
||
</html>
|