← back to Watches
add-real-price-data.html
263 lines
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Add Real Price Data - Omega Watch Price History</title>
<script src="https://cdn.tailwindcss.com"></script>
</head>
<body class="bg-slate-900 text-slate-100 p-8">
<div class="max-w-4xl mx-auto">
<h1 class="text-3xl font-bold text-red-500 mb-2">⚠️ Add REAL Price Data</h1>
<p class="text-slate-400 mb-8">Enter actual auction results, dealer sales, or verified market prices with source URLs</p>
<div class="bg-slate-800 rounded-lg p-6 border border-slate-700 mb-6">
<h2 class="text-xl font-bold mb-4">Select Watch</h2>
<select id="watchSelect" class="w-full bg-slate-700 text-white p-3 rounded-lg border border-slate-600">
<option value="">Loading watches...</option>
</select>
</div>
<div class="bg-slate-800 rounded-lg p-6 border border-slate-700 mb-6">
<h2 class="text-xl font-bold mb-4">Add Price Entry</h2>
<div class="grid grid-cols-2 gap-4 mb-4">
<div>
<label class="block text-sm font-medium mb-2">Year *</label>
<input type="number" id="year" min="1940" max="2024"
class="w-full bg-slate-700 text-white p-3 rounded-lg border border-slate-600"
placeholder="2023">
</div>
<div>
<label class="block text-sm font-medium mb-2">Price (USD) *</label>
<input type="number" id="price" min="0" step="100"
class="w-full bg-slate-700 text-white p-3 rounded-lg border border-slate-600"
placeholder="15000">
</div>
</div>
<div class="grid grid-cols-2 gap-4 mb-4">
<div>
<label class="block text-sm font-medium mb-2">Condition *</label>
<select id="condition" class="w-full bg-slate-700 text-white p-3 rounded-lg border border-slate-600">
<option value="new">New</option>
<option value="mint">Mint</option>
<option value="excellent">Excellent</option>
<option value="very good">Very Good</option>
<option value="good">Good</option>
<option value="fair">Fair</option>
<option value="vintage">Vintage</option>
</select>
</div>
<div>
<label class="block text-sm font-medium mb-2">Source Type *</label>
<select id="sourceType" class="w-full bg-slate-700 text-white p-3 rounded-lg border border-slate-600">
<option value="auction">Auction Sale</option>
<option value="dealer">Dealer Price</option>
<option value="retail">Retail/MSRP</option>
<option value="private">Private Sale</option>
</select>
</div>
</div>
<div class="mb-4">
<label class="block text-sm font-medium mb-2">Source Description *</label>
<input type="text" id="sourceDesc"
class="w-full bg-slate-700 text-white p-3 rounded-lg border border-slate-600"
placeholder="Sotheby's Important Watches May 2023 Lot 234">
</div>
<div class="mb-4">
<label class="block text-sm font-medium mb-2">Source URL (REQUIRED for verification) *</label>
<input type="url" id="sourceUrl"
class="w-full bg-slate-700 text-white p-3 rounded-lg border border-slate-600"
placeholder="https://www.sothebys.com/en/buy/auction/2023/important-watches/lot-234">
<p class="text-xs text-slate-400 mt-1">Must be a direct link to the auction lot, product page, or archived listing</p>
</div>
<div class="mb-4">
<label class="block text-sm font-medium mb-2">Additional Notes (Optional)</label>
<textarea id="notes" rows="3"
class="w-full bg-slate-700 text-white p-3 rounded-lg border border-slate-600"
placeholder="Full set with box and papers, unpolished case, service history included"></textarea>
</div>
<button onclick="addPriceEntry()"
class="w-full bg-green-600 hover:bg-green-700 text-white font-bold py-3 px-6 rounded-lg transition">
✓ Add Verified Price Entry
</button>
</div>
<div id="currentData" class="bg-slate-800 rounded-lg p-6 border border-slate-700">
<h2 class="text-xl font-bold mb-4">Current Price History</h2>
<div id="priceList" class="text-slate-400">Select a watch to view current data</div>
</div>
<div class="mt-6 bg-yellow-900 border border-yellow-700 text-yellow-100 p-4 rounded-lg">
<h3 class="font-bold mb-2">⚠️ Data Quality Requirements</h3>
<ul class="text-sm space-y-1 ml-4 list-disc">
<li>Every price MUST have a verifiable source URL</li>
<li>NO estimates or calculations allowed</li>
<li>Only actual sales, auctions, or dealer listings</li>
<li>URLs must link to EXACT lot/product, not category pages</li>
<li>Auction results preferred (Sotheby's, Christie's, Phillips)</li>
</ul>
</div>
</div>
<script>
let watches = [];
let selectedWatch = null;
// Load watches
fetch('/api/watches')
.then(r => r.json())
.then(data => {
watches = data.watches || data;
const select = document.getElementById('watchSelect');
select.innerHTML = '<option value="">Select a watch...</option>' +
watches.map((w, i) =>
`<option value="${i}">${w.model} (${w.reference})</option>`
).join('');
});
document.getElementById('watchSelect').addEventListener('change', (e) => {
if (e.target.value === '') return;
selectedWatch = watches[e.target.value];
displayCurrentData();
});
function displayCurrentData() {
const priceHistory = selectedWatch.priceHistory || [];
const list = document.getElementById('priceList');
if (priceHistory.length === 0) {
list.innerHTML = '<p class="text-yellow-500">⚠️ No price data yet - all entries will be NEW REAL DATA</p>';
return;
}
list.innerHTML = `
<div class="overflow-x-auto">
<table class="w-full text-left text-sm">
<thead class="border-b border-slate-700">
<tr>
<th class="pb-2">Year</th>
<th class="pb-2">Price</th>
<th class="pb-2">Condition</th>
<th class="pb-2">Source</th>
<th class="pb-2">Verified</th>
</tr>
</thead>
<tbody class="divide-y divide-slate-700">
${priceHistory.map(p => `
<tr class="${!p.source.includes('http') ? 'bg-red-900/20' : ''}">
<td class="py-2">${p.year}</td>
<td class="py-2">$${p.price.toLocaleString()}</td>
<td class="py-2">${p.condition}</td>
<td class="py-2 text-xs">${p.source}</td>
<td class="py-2">
${p.source.includes('http')
? '<span class="text-green-400">✓ URL</span>'
: '<span class="text-red-400">✗ No URL</span>'}
</td>
</tr>
`).join('')}
</tbody>
</table>
<p class="text-xs text-slate-400 mt-4">
Red rows = Estimated/calculated data (SHOULD BE REPLACED)
</p>
</div>
`;
}
function addPriceEntry() {
if (!selectedWatch) {
alert('Please select a watch first');
return;
}
const year = document.getElementById('year').value;
const price = document.getElementById('price').value;
const condition = document.getElementById('condition').value;
const sourceType = document.getElementById('sourceType').value;
const sourceDesc = document.getElementById('sourceDesc').value;
const sourceUrl = document.getElementById('sourceUrl').value;
const notes = document.getElementById('notes').value;
// Validation
if (!year || !price || !sourceDesc || !sourceUrl) {
alert('Please fill in all required fields (Year, Price, Source Description, Source URL)');
return;
}
if (!sourceUrl.startsWith('http')) {
alert('Source URL must be a valid HTTP/HTTPS link');
return;
}
// Create new price entry
const newEntry = {
year: parseInt(year),
price: parseFloat(price),
condition: condition,
source: `${sourceDesc} ${sourceUrl}`,
sourceType: sourceType,
sourceUrl: sourceUrl,
notes: notes || undefined,
addedAt: new Date().toISOString()
};
// Add to watch
if (!selectedWatch.priceHistory) {
selectedWatch.priceHistory = [];
}
selectedWatch.priceHistory.push(newEntry);
// Sort by year
selectedWatch.priceHistory.sort((a, b) => a.year - b.year);
// Display success
alert(`✓ Added: ${year} - $${parseFloat(price).toLocaleString()} from ${sourceDesc}\n\nNOTE: This is in-memory only. To save permanently, export the data.`);
// Update display
displayCurrentData();
// Clear form
document.getElementById('year').value = '';
document.getElementById('price').value = '';
document.getElementById('sourceDesc').value = '';
document.getElementById('sourceUrl').value = '';
document.getElementById('notes').value = '';
// Show export button
showExportButton();
}
function showExportButton() {
if (document.getElementById('exportBtn')) return;
const btn = document.createElement('button');
btn.id = 'exportBtn';
btn.className = 'fixed bottom-8 right-8 bg-blue-600 hover:bg-blue-700 text-white font-bold py-4 px-6 rounded-lg shadow-lg';
btn.innerHTML = '💾 Export Updated Data (JSON)';
btn.onclick = exportData;
document.body.appendChild(btn);
}
function exportData() {
const json = JSON.stringify(watches, null, 2);
const blob = new Blob([json], { type: 'application/json' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = `watches-updated-${new Date().toISOString().split('T')[0]}.json`;
a.click();
URL.revokeObjectURL(url);
alert('✓ Data exported! Replace /root/Projects/watches/data/watches.json with this file.');
}
</script>
</body>
</html>