← back to Handbag Auth Nextjs
auction-viewer/analytics-demo.html
357 lines
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>LUXVAULT Analytics Demo</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
padding: 20px;
}
.container {
max-width: 1400px;
margin: 0 auto;
}
.header {
background: white;
border-radius: 16px;
padding: 40px;
margin-bottom: 30px;
box-shadow: 0 10px 40px rgba(0,0,0,0.1);
text-align: center;
}
.header h1 {
color: #667eea;
font-size: 3em;
margin-bottom: 10px;
}
.header p {
color: #666;
font-size: 1.2em;
}
.grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(350px, 1fr));
gap: 20px;
margin-bottom: 30px;
}
.card {
background: white;
border-radius: 12px;
padding: 30px;
box-shadow: 0 5px 20px rgba(0,0,0,0.1);
transition: transform 0.3s, box-shadow 0.3s;
cursor: pointer;
}
.card:hover {
transform: translateY(-5px);
box-shadow: 0 10px 30px rgba(0,0,0,0.15);
}
.card-icon {
width: 50px;
height: 50px;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
border-radius: 12px;
display: flex;
align-items: center;
justify-content: center;
font-size: 24px;
margin-bottom: 20px;
}
.card h3 {
color: #333;
font-size: 1.5em;
margin-bottom: 10px;
}
.card p {
color: #666;
line-height: 1.6;
margin-bottom: 15px;
}
.card-url {
font-family: 'Courier New', monospace;
background: #f5f5f5;
padding: 10px;
border-radius: 6px;
font-size: 0.9em;
word-break: break-all;
color: #667eea;
}
.test-btn {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
border: none;
padding: 12px 24px;
border-radius: 8px;
font-size: 1em;
cursor: pointer;
margin-top: 15px;
width: 100%;
transition: opacity 0.3s;
}
.test-btn:hover {
opacity: 0.9;
}
.result-area {
margin-top: 15px;
padding: 15px;
background: #f9f9f9;
border-radius: 6px;
display: none;
max-height: 300px;
overflow-y: auto;
}
.result-area pre {
font-size: 0.85em;
color: #333;
white-space: pre-wrap;
}
.stats {
background: white;
border-radius: 12px;
padding: 30px;
box-shadow: 0 5px 20px rgba(0,0,0,0.1);
text-align: center;
}
.stats-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 20px;
margin-top: 20px;
}
.stat-item {
padding: 20px;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
border-radius: 12px;
color: white;
}
.stat-value {
font-size: 2.5em;
font-weight: bold;
margin-bottom: 5px;
}
.stat-label {
font-size: 1em;
opacity: 0.9;
}
@media (max-width: 768px) {
.header h1 {
font-size: 2em;
}
.grid {
grid-template-columns: 1fr;
}
}
</style>
</head>
<body>
<div class="container">
<div class="header">
<h1>🧠 LUXVAULT Analytics Engine</h1>
<p>Advanced Data Science & Predictive Analytics for Luxury Auctions</p>
</div>
<div class="stats">
<h2>System Overview</h2>
<div class="stats-grid">
<div class="stat-item">
<div class="stat-value">10</div>
<div class="stat-label">Analytics Endpoints</div>
</div>
<div class="stat-item">
<div class="stat-value">2,250</div>
<div class="stat-label">Auctions Analyzed</div>
</div>
<div class="stat-item">
<div class="stat-value">22</div>
<div class="stat-label">Luxury Brands</div>
</div>
<div class="stat-item">
<div class="stat-value">100%</div>
<div class="stat-label">Uptime</div>
</div>
</div>
</div>
<div class="grid">
<!-- Deal Scores -->
<div class="card">
<div class="card-icon">🏆</div>
<h3>Deal Scores</h3>
<p>Proprietary algorithm ranks auctions by savings, price point, urgency, and historical performance.</p>
<div class="card-url">/api/insights/deal-scores</div>
<button class="test-btn" onclick="testEndpoint('deal-scores', this)">Test Endpoint</button>
<div class="result-area"></div>
</div>
<!-- Price Trends -->
<div class="card">
<div class="card-icon">📈</div>
<h3>Price Trends</h3>
<p>Analyze price trends by brand over time with direction indicators and monthly statistics.</p>
<div class="card-url">/api/insights/trends</div>
<button class="test-btn" onclick="testEndpoint('trends', this)">Test Endpoint</button>
<div class="result-area"></div>
</div>
<!-- Anomalies -->
<div class="card">
<div class="card-icon">🎯</div>
<h3>Price Anomalies</h3>
<p>Statistical outlier detection using z-score analysis finds rare items and exceptional deals.</p>
<div class="card-url">/api/insights/anomalies</div>
<button class="test-btn" onclick="testEndpoint('anomalies', this)">Test Endpoint</button>
<div class="result-area"></div>
</div>
<!-- Predictions -->
<div class="card">
<div class="card-icon">🔮</div>
<h3>Price Predictions</h3>
<p>Forecast final auction prices using historical data and median ratio analysis.</p>
<div class="card-url">/api/insights/predict/:id</div>
<button class="test-btn" onclick="testPrediction(this)">Test Endpoint</button>
<div class="result-area"></div>
</div>
<!-- Recommendations -->
<div class="card">
<div class="card-icon">💡</div>
<h3>Recommendations</h3>
<p>Personalized auction recommendations with budget filtering and deal reasoning.</p>
<div class="card-url">/api/insights/recommendations</div>
<button class="test-btn" onclick="testEndpoint('recommendations?budget=5000', this)">Test Endpoint</button>
<div class="result-area"></div>
</div>
<!-- Market Insights -->
<div class="card">
<div class="card-icon">📊</div>
<h3>Market Insights</h3>
<p>Comprehensive market overview with summary statistics and top value brands.</p>
<div class="card-url">/api/insights/market</div>
<button class="test-btn" onclick="testEndpoint('market', this)">Test Endpoint</button>
<div class="result-area"></div>
</div>
<!-- Brand Analytics -->
<div class="card">
<div class="card-icon">👜</div>
<h3>Brand Analytics</h3>
<p>Deep-dive into specific brands with statistics, recent auctions, and price history.</p>
<div class="card-url">/api/insights/brand/:brand</div>
<button class="test-btn" onclick="testBrand(this)">Test Endpoint</button>
<div class="result-area"></div>
</div>
<!-- Time Series -->
<div class="card">
<div class="card-icon">📉</div>
<h3>Time Series</h3>
<p>Historical data optimized for Chart.js visualization with customizable intervals.</p>
<div class="card-url">/api/insights/time-series</div>
<button class="test-btn" onclick="testEndpoint('time-series?interval=month', this)">Test Endpoint</button>
<div class="result-area"></div>
</div>
<!-- Brand Comparison -->
<div class="card">
<div class="card-icon">⚖️</div>
<h3>Brand Comparison</h3>
<p>Comparative analysis across all brands with pricing metrics and deal counts.</p>
<div class="card-url">/api/insights/compare-brands</div>
<button class="test-btn" onclick="testEndpoint('compare-brands', this)">Test Endpoint</button>
<div class="result-area"></div>
</div>
<!-- Velocity -->
<div class="card">
<div class="card-icon">⚡</div>
<h3>Auction Velocity</h3>
<p>Track auctions ending soon by brand for time-sensitive opportunities.</p>
<div class="card-url">/api/insights/velocity</div>
<button class="test-btn" onclick="testEndpoint('velocity', this)">Test Endpoint</button>
<div class="result-area"></div>
</div>
</div>
</div>
<script>
async function testEndpoint(endpoint, button) {
const resultArea = button.nextElementSibling;
resultArea.style.display = 'block';
resultArea.innerHTML = '<pre>Loading...</pre>';
try {
const response = await fetch(`/api/insights/${endpoint}`);
const data = await response.json();
// Format nicely
let displayData = data;
if (data.data && Array.isArray(data.data)) {
displayData = {
success: data.success,
count: data.count,
sample: data.data.slice(0, 2), // Show first 2 items
note: `Showing 2 of ${data.count} results`
};
}
resultArea.innerHTML = `<pre>${JSON.stringify(displayData, null, 2)}</pre>`;
} catch (error) {
resultArea.innerHTML = `<pre style="color: red;">Error: ${error.message}</pre>`;
}
}
async function testPrediction(button) {
// Get a sample auction ID first
const response = await fetch('/api/auctions?limit=1');
const data = await response.json();
const auctionId = data.data[0]?.auction_id;
if (auctionId) {
testEndpoint(`predict/${auctionId}`, button);
} else {
const resultArea = button.nextElementSibling;
resultArea.style.display = 'block';
resultArea.innerHTML = '<pre style="color: red;">No auction data available</pre>';
}
}
async function testBrand(button) {
testEndpoint('brand/Hermes%20Birkin', button);
}
</script>
</body>
</html>