← 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>