← back to Watches
public/index.html
113 lines
<!DOCTYPE html>
<html lang="en">
<head>
<script>
// Credential-safe fetch guard (fleet drop-in) — if this page is opened with
// credentials in the URL (a saved bookmark / Chrome-remembered basic-auth:
// https://user:pass@host/…), the browser poisons document.baseURI, so any
// relative or root-relative fetch('/api/…') throws "Request cannot be constructed
// from a URL that includes credentials" and callers silently fall to an empty
// state. Resolve every non-absolute request URL against the credential-free
// location instead of baseURI. Placed first so it wraps window.fetch before any
// app script runs. Ref: creds-in-url-fetch-guard-fleet-pattern.
(function () {
var _fetch = window.fetch.bind(window);
var cleanBase = function () { return location.origin + location.pathname; };
window.fetch = function (input, init) {
try {
if (typeof input === 'string' && !/^[a-z]+:\/\//i.test(input) && input.indexOf('//') !== 0) {
input = new URL(input, cleanBase()).href;
} else if (input instanceof Request && !/^[a-z]+:\/\//i.test(input.url)) {
input = new Request(new URL(input.url, cleanBase()).href, input);
}
} catch (_) { /* fall through to native */ }
return _fetch(input, init);
};
})();
</script>
<link rel="icon" type="image/svg+xml" href="/favicon.svg">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Omega Watch Price History</title>
<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@300;400;500;600;700&display=swap" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<div class="container">
<header>
<h1>Omega Watch Price History</h1>
<p class="subtitle">Complete Historical Price Tracking for All Omega Models</p>
</header>
<div class="stats-grid" id="statsGrid">
<div class="stat-card">
<div class="stat-value" id="totalModels">--</div>
<div class="stat-label">Total Models</div>
</div>
<div class="stat-card">
<div class="stat-value" id="avgPrice">--</div>
<div class="stat-label">Avg. Current Price</div>
</div>
<div class="stat-card">
<div class="stat-value" id="topAppreciation">--</div>
<div class="stat-label">Top Appreciation</div>
</div>
<div class="stat-card">
<div class="stat-value" id="dataPoints">--</div>
<div class="stat-label">Price Data Points</div>
</div>
</div>
<div class="controls">
<div class="search-box">
<input type="text" id="searchInput" placeholder="Search watches...">
</div>
<div class="filter-buttons">
<button class="filter-btn active" data-collection="all">All</button>
<button class="filter-btn" data-collection="Speedmaster">Speedmaster</button>
<button class="filter-btn" data-collection="Seamaster">Seamaster</button>
<button class="filter-btn" data-collection="Constellation">Constellation</button>
<button class="filter-btn" data-collection="De Ville">De Ville</button>
</div>
</div>
<div class="main-content">
<div class="watches-panel">
<h2>Select Watches to Compare</h2>
<div class="watches-list" id="watchesList">
<!-- Watches will be loaded here -->
</div>
</div>
<div class="chart-panel">
<div class="chart-header">
<h2>Price History Chart</h2>
<div class="chart-controls">
<button id="clearChart" class="btn-secondary">Clear All</button>
<button id="exportData" class="btn-secondary">Export Data</button>
</div>
</div>
<div class="chart-container">
<canvas id="priceChart"></canvas>
</div>
<div id="selectedWatches" class="selected-watches">
<!-- Selected watches will appear here -->
</div>
</div>
</div>
<div class="top-appreciating">
<h2>Top Appreciating Models</h2>
<div id="topAppreciatingList" class="appreciation-list">
<!-- Top appreciating watches will be loaded here -->
</div>
</div>
</div>
<script src="app.js"></script>
</body>
</html>