crypto-api-clean-fixed / static /pages /fallback-demo.html
Really-amin's picture
Initial import: cleaned working Crypto Resources API
e530d34 verified
<!DOCTYPE html>
<html lang="fa" dir="rtl">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Fallback API Demo</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
padding: 20px;
min-height: 100vh;
}
.container {
max-width: 1200px;
margin: 0 auto;
}
.card {
background: white;
border-radius: 15px;
padding: 30px;
margin-bottom: 20px;
box-shadow: 0 10px 30px rgba(0,0,0,0.2);
}
h1 {
color: #667eea;
margin-bottom: 10px;
}
.subtitle {
color: #666;
margin-bottom: 30px;
}
.button-group {
display: flex;
gap: 10px;
flex-wrap: wrap;
margin-bottom: 20px;
}
button {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
border: none;
padding: 12px 24px;
border-radius: 8px;
cursor: pointer;
font-size: 14px;
font-weight: bold;
transition: transform 0.2s;
}
button:hover {
transform: translateY(-2px);
}
button:disabled {
opacity: 0.5;
cursor: not-allowed;
}
.stats-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 15px;
margin-bottom: 20px;
}
.stat-box {
background: #f5f5f5;
padding: 15px;
border-radius: 8px;
text-align: center;
}
.stat-value {
font-size: 24px;
font-weight: bold;
color: #667eea;
margin-bottom: 5px;
}
.stat-label {
font-size: 12px;
color: #666;
}
.log-container {
background: #1e1e1e;
color: #00ff00;
padding: 20px;
border-radius: 8px;
font-family: 'Courier New', monospace;
font-size: 13px;
max-height: 400px;
overflow-y: auto;
margin-bottom: 20px;
}
.log-entry {
margin-bottom: 5px;
padding: 5px;
border-left: 3px solid transparent;
}
.log-success {
border-left-color: #00ff00;
color: #00ff00;
}
.log-error {
border-left-color: #ff0000;
color: #ff6b6b;
}
.log-info {
border-left-color: #00bfff;
color: #00bfff;
}
.log-warning {
border-left-color: #ffa500;
color: #ffa500;
}
.endpoints-list {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
gap: 10px;
}
.endpoint-item {
background: #f9f9f9;
padding: 15px;
border-radius: 8px;
border-left: 4px solid #667eea;
}
.endpoint-url {
font-family: monospace;
font-size: 12px;
color: #333;
margin-bottom: 10px;
word-break: break-all;
}
.endpoint-stats {
display: flex;
justify-content: space-between;
font-size: 11px;
color: #666;
}
.result-box {
background: #f9f9f9;
padding: 20px;
border-radius: 8px;
margin-top: 20px;
}
.result-box pre {
background: #1e1e1e;
color: #00ff00;
padding: 15px;
border-radius: 5px;
overflow-x: auto;
font-size: 12px;
}
</style>
</head>
<body>
<div class="container">
<div class="card">
<h1>🔄 Fallback API Client Demo</h1>
<p class="subtitle">سیستم fallback سلسله مراتبی با 10 endpoint پشتیبان</p>
<div class="button-group">
<button onclick="testHealth()">🏥 Test Health</button>
<button onclick="testTopCoins()">💰 Test Top Coins</button>
<button onclick="testTrending()">📈 Test Trending</button>
<button onclick="testSentiment()">😊 Test Sentiment</button>
<button onclick="testNews()">📰 Test News</button>
<button onclick="testResources()">📦 Test Resources</button>
<button onclick="clearLogs()">🗑️ Clear Logs</button>
<button onclick="optimizeEndpoints()">⚡ Optimize</button>
</div>
<div class="stats-grid">
<div class="stat-box">
<div class="stat-value" id="totalRequests">0</div>
<div class="stat-label">کل درخواست‌ها</div>
</div>
<div class="stat-box">
<div class="stat-value" id="successRequests">0</div>
<div class="stat-label">موفق</div>
</div>
<div class="stat-box">
<div class="stat-value" id="failedRequests">0</div>
<div class="stat-label">ناموفق</div>
</div>
<div class="stat-box">
<div class="stat-value" id="successRate">0%</div>
<div class="stat-label">نرخ موفقیت</div>
</div>
<div class="stat-box">
<div class="stat-value" id="cacheSize">0</div>
<div class="stat-label">Cache Size</div>
</div>
</div>
</div>
<div class="card">
<h2>📊 Endpoints Status</h2>
<div class="endpoints-list" id="endpointsList"></div>
</div>
<div class="card">
<h2>📝 Logs</h2>
<div class="log-container" id="logContainer"></div>
</div>
<div class="card" id="resultCard" style="display: none;">
<h2>✅ Result</h2>
<div class="result-box">
<pre id="resultContent"></pre>
</div>
</div>
</div>
<script src="/static/shared/js/fallback-api-client.js"></script>
<script>
// Initialize API
const api = new CryptoAPI();
// Logging
function log(message, type = 'info') {
const container = document.getElementById('logContainer');
const entry = document.createElement('div');
entry.className = `log-entry log-${type}`;
entry.textContent = `[${new Date().toLocaleTimeString('fa-IR')}] ${message}`;
container.appendChild(entry);
container.scrollTop = container.scrollHeight;
}
function clearLogs() {
document.getElementById('logContainer').innerHTML = '';
log('Logs cleared', 'info');
}
// Update stats
function updateStats() {
const stats = api.getStats();
document.getElementById('totalRequests').textContent = stats.totalRequests;
document.getElementById('successRequests').textContent = stats.successfulRequests;
document.getElementById('failedRequests').textContent = stats.failedRequests;
document.getElementById('successRate').textContent = stats.successRate;
document.getElementById('cacheSize').textContent = stats.cacheSize;
// Update endpoints list
const endpointsList = document.getElementById('endpointsList');
endpointsList.innerHTML = '';
api.client.endpoints.forEach((endpoint, index) => {
const endpointStats = stats.endpointStats[endpoint];
const item = document.createElement('div');
item.className = 'endpoint-item';
const successRate = endpointStats.requests > 0
? (endpointStats.successes / endpointStats.requests * 100).toFixed(0)
: 0;
item.innerHTML = `
<div class="endpoint-url">${index + 1}. ${endpoint}</div>
<div class="endpoint-stats">
<span>✅ ${endpointStats.successes}</span>
<span>❌ ${endpointStats.failures}</span>
<span>📊 ${successRate}%</span>
<span>⚡ ${endpointStats.avgResponseTime.toFixed(0)}ms</span>
</div>
`;
endpointsList.appendChild(item);
});
}
// Show result
function showResult(data) {
const resultCard = document.getElementById('resultCard');
const resultContent = document.getElementById('resultContent');
resultContent.textContent = JSON.stringify(data, null, 2);
resultCard.style.display = 'block';
}
// Test functions
async function testHealth() {
log('Testing health endpoint...', 'info');
try {
const result = await api.health();
log('✅ Health check successful', 'success');
showResult(result);
} catch (error) {
log(`❌ Health check failed: ${error.message}`, 'error');
}
updateStats();
}
async function testTopCoins() {
log('Testing top coins endpoint...', 'info');
try {
const result = await api.getTopCoins(10);
log('✅ Top coins fetched successfully', 'success');
showResult(result);
} catch (error) {
log(`❌ Top coins failed: ${error.message}`, 'error');
}
updateStats();
}
async function testTrending() {
log('Testing trending endpoint...', 'info');
try {
const result = await api.getTrending();
log('✅ Trending data fetched successfully', 'success');
showResult(result);
} catch (error) {
log(`❌ Trending failed: ${error.message}`, 'error');
}
updateStats();
}
async function testSentiment() {
log('Testing sentiment endpoint...', 'info');
try {
const result = await api.getGlobalSentiment();
log('✅ Sentiment data fetched successfully', 'success');
showResult(result);
} catch (error) {
log(`❌ Sentiment failed: ${error.message}`, 'error');
}
updateStats();
}
async function testNews() {
log('Testing news endpoint...', 'info');
try {
const result = await api.getNews(10);
log('✅ News fetched successfully', 'success');
showResult(result);
} catch (error) {
log(`❌ News failed: ${error.message}`, 'error');
}
updateStats();
}
async function testResources() {
log('Testing resources endpoint...', 'info');
try {
const result = await api.getResources();
log('✅ Resources fetched successfully', 'success');
showResult(result);
} catch (error) {
log(`❌ Resources failed: ${error.message}`, 'error');
}
updateStats();
}
function optimizeEndpoints() {
log('Optimizing endpoints based on performance...', 'info');
api.optimizeEndpoints();
log('✅ Endpoints optimized', 'success');
updateStats();
}
// Initial update
updateStats();
log('Fallback API Client initialized with 10 endpoints', 'success');
</script>
</body>
</html>