first commit

This commit is contained in:
2026-01-16 22:20:18 +03:00
commit 5d437e5e28
56 changed files with 4463 additions and 0 deletions

View File

@@ -0,0 +1,199 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{% block title %}Bitcoin Monitor{% endblock %}</title>
<style>
/* Gruvbox color scheme matching dashboard */
:root {
--bg-primary: #282828;
--bg-secondary: #3c3836;
--bg-tertiary: #504945;
--text-primary: #ebdbb2;
--text-secondary: #d5c4a1;
--accent-red: #cc241d;
--accent-yellow: #d79921;
--accent-blue: #458588;
--accent-green: #98971a;
--accent-purple: #b16286;
}
body {
font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace, Arial, sans-serif;
line-height: 1.6;
color: #333333;
max-width: 600px;
margin: 0 auto;
padding: 20px;
background: #f5f5f5;
}
.email-container {
background: white;
border-radius: 12px;
overflow: hidden;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}
.email-header {
background: var(--bg-primary);
color: var(--text-primary);
padding: 25px;
text-align: center;
}
.email-header h1 {
margin: 0;
font-size: 24px;
font-weight: bold;
}
.email-header .subtitle {
color: var(--text-secondary);
margin-top: 8px;
font-size: 14px;
}
.email-body {
padding: 25px;
}
.alert-banner {
padding: 15px;
border-radius: 8px;
margin-bottom: 25px;
font-weight: bold;
text-align: center;
}
.alert-dip { background: #f8d7da; color: #721c24; border-left: 5px solid var(--accent-red); }
.alert-peak { background: #fff3cd; color: #856404; border-left: 5px solid var(--accent-yellow); }
.alert-system { background: #cce5ff; color: #004085; border-left: 5px solid var(--accent-blue); }
.alert-digest { background: #d4edda; color: #155724; border-left: 5px solid var(--accent-green); }
.metric-card {
background: #f8f9fa;
border-radius: 8px;
padding: 20px;
margin-bottom: 20px;
border-left: 4px solid var(--accent-purple);
}
.metric-value {
font-size: 28px;
font-weight: bold;
color: var(--accent-purple);
margin: 10px 0;
}
.metric-label {
color: #6c757d;
font-size: 14px;
text-transform: uppercase;
letter-spacing: 1px;
}
.stats-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
gap: 15px;
margin: 25px 0;
}
.stat-item {
text-align: center;
padding: 15px;
background: #e9ecef;
border-radius: 6px;
}
.stat-value {
font-size: 20px;
font-weight: bold;
color: var(--bg-primary);
}
.stat-label {
font-size: 12px;
color: #6c757d;
margin-top: 5px;
}
.action-button {
display: inline-block;
background: var(--accent-blue);
color: white;
padding: 12px 24px;
text-decoration: none;
border-radius: 6px;
font-weight: bold;
margin: 15px 0;
}
.recommendation {
background: #e8f4fd;
border-left: 4px solid var(--accent-blue);
padding: 15px;
margin: 20px 0;
border-radius: 0 6px 6px 0;
}
.footer {
background: var(--bg-secondary);
color: var(--text-secondary);
padding: 20px;
text-align: center;
font-size: 12px;
line-height: 1.5;
}
.footer a {
color: var(--accent-purple);
text-decoration: none;
}
.unsubscribe-link {
color: #6c757d !important;
font-size: 11px;
margin-top: 10px;
display: inline-block;
}
@media (max-width: 600px) {
body { padding: 10px; }
.email-body { padding: 15px; }
.stats-grid { grid-template-columns: 1fr; }
.metric-value { font-size: 24px; }
}
</style>
</head>
<body>
<div class="email-container">
<div class="email-header">
<h1>₿ Bitcoin Monitor</h1>
<div class="subtitle">Real-time Bitcoin Price Monitoring</div>
</div>
<div class="email-body">
{% block content %}{% endblock %}
</div>
<div class="footer">
<p>This email was sent by Bitcoin Monitor System.</p>
<p>
<a href="{{ dashboard_url }}">View Dashboard</a> |
<a href="{{ admin_url }}">Admin Panel</a>
</p>
<p>
<a href="{{ unsubscribe_url }}" class="unsubscribe-link">
Unsubscribe or manage preferences
</a>
</p>
<p style="margin-top: 15px; color: #999; font-size: 11px;">
Bitcoin Monitor &copy; {% now "Y" %} • Automated notifications
</p>
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,100 @@
{% extends "emails/base.html" %}
{% block title %}Daily Digest - Bitcoin Monitor{% endblock %}
{% block content %}
<div class="alert-banner alert-digest">
📊 DAILY DIGEST: {{ date|date:"F d, Y" }}
</div>
<div style="text-align: center; margin-bottom: 30px;">
<h2 style="color: #343a40; margin-bottom: 5px;">24-Hour Summary</h2>
<p style="color: #6c757d; margin-top: 0;">{{ summary_period }}</p>
</div>
<div class="metric-card">
<div class="metric-label">Market Status</div>
<div class="metric-value" style="color:
{% if market_status == 'dip' %}#dc3545
{% elif market_status == 'peak' %}#ffc107
{% else %}#28a745{% endif %};">
{{ market_status|upper }}
</div>
<div style="color: #6c757d; font-size: 14px;">
{% if market_status == 'dip' %}Price below yearly average
{% elif market_status == 'peak' %}Price above yearly average
{% else %}Price within normal range{% endif %}
</div>
</div>
<div class="stats-grid">
<div class="stat-item">
<div class="stat-value">${{ current_price|floatformat:2 }}</div>
<div class="stat-label">Current Price</div>
</div>
<div class="stat-item">
<div class="stat-value">${{ daily_high|floatformat:2 }}</div>
<div class="stat-label">24h High</div>
</div>
<div class="stat-item">
<div class="stat-value">${{ daily_low|floatformat:2 }}</div>
<div class="stat-label">24h Low</div>
</div>
<div class="stat-item">
<div class="stat-value">{{ daily_change|floatformat:1 }}%</div>
<div class="stat-label">24h Change</div>
</div>
</div>
<div style="margin: 30px 0;">
<h3 style="color: #343a40; margin-bottom: 15px;">📈 Market Activity</h3>
<div style="background: #f8f9fa; padding: 15px; border-radius: 6px; margin-bottom: 15px;">
<div style="display: flex; justify-content: space-between; margin-bottom: 10px;">
<span style="color: #6c757d;">Events Today:</span>
<span style="font-weight: bold;">{{ events_count }}</span>
</div>
<div style="display: flex; justify-content: space-between; margin-bottom: 10px;">
<span style="color: #6c757d;">Price Fetches:</span>
<span style="font-weight: bold;">{{ price_fetches }}</span>
</div>
<div style="display: flex; justify-content: space-between;">
<span style="color: #6c757d;">System Uptime:</span>
<span style="font-weight: bold;">{{ uptime_percentage|floatformat:1 }}%</span>
</div>
</div>
{% if events_today %}
<div style="background: #e8f4fd; padding: 15px; border-radius: 6px; margin-top: 15px;">
<h4 style="margin-top: 0; color: #004085;">⚠️ Events Today</h4>
<ul style="margin-bottom: 0; padding-left: 20px;">
{% for event in events_today %}
<li>
<strong>{{ event.type|title }}</strong> at
${{ event.price|floatformat:2 }} ({{ event.time|time:"H:i" }})
</li>
{% endfor %}
</ul>
</div>
{% endif %}
</div>
{% if market_insight %}
<div class="recommendation">
<h4 style="margin-top: 0; color: #004085;">📋 Market Insight</h4>
<p style="margin-bottom: 0;">{{ market_insight }}</p>
</div>
{% endif %}
<div style="margin-top: 30px; padding: 15px; background: #f8f9fa; border-radius: 8px; text-align: center;">
<p style="margin: 0; color: #6c757d;">
Next digest: Tomorrow at 08:00 UTC
</p>
</div>
<div style="text-align: center; margin: 30px 0;">
<a href="{{ dashboard_url }}" class="action-button">
View Full Dashboard
</a>
</div>
{% endblock %}

View File

@@ -0,0 +1,83 @@
{% extends "emails/base.html" %}
{% block title %}{{ alert_type }} Alert - Bitcoin Monitor{% endblock %}
{% block content %}
<div class="alert-banner alert-{{ alert_type }}">
{% if alert_type == 'dip' %}
🚨 DIP DETECTED: Price is {{ percent_change|floatformat:1 }}% below average
{% elif alert_type == 'peak' %}
⚡ PEAK DETECTED: Price is {{ percent_change|floatformat:1 }}% above average
{% else %}
MARKET EVENT DETECTED
{% endif %}
</div>
<div class="metric-card">
<div class="metric-label">Current Bitcoin Price</div>
<div class="metric-value">${{ current_price|floatformat:2 }}</div>
<div style="color: #6c757d; font-size: 14px;">
{% if alert_type == 'dip' %}📉 Below threshold{% else %}📈 Above threshold{% endif %}
</div>
</div>
<div class="stats-grid">
<div class="stat-item">
<div class="stat-value">{{ threshold_percent }}%</div>
<div class="stat-label">Threshold</div>
</div>
<div class="stat-item">
<div class="stat-value">${{ yearly_average|floatformat:2 }}</div>
<div class="stat-label">Yearly Average</div>
</div>
<div class="stat-item">
<div class="stat-value">${{ lower_threshold|floatformat:2 }}</div>
<div class="stat-label">Lower Bound</div>
</div>
<div class="stat-item">
<div class="stat-value">${{ upper_threshold|floatformat:2 }}</div>
<div class="stat-label">Upper Bound</div>
</div>
</div>
<div style="margin: 25px 0; padding: 20px; background: #f8f9fa; border-radius: 8px;">
<h3 style="margin-top: 0; color: #343a40;">Event Details</h3>
<table style="width: 100%; border-collapse: collapse;">
<tr>
<td style="padding: 8px 0; border-bottom: 1px solid #dee2e6; color: #6c757d;">Event Type:</td>
<td style="padding: 8px 0; border-bottom: 1px solid #dee2e6; font-weight: bold; text-align: right;">
{{ alert_type|upper }}
</td>
</tr>
<tr>
<td style="padding: 8px 0; border-bottom: 1px solid #dee2e6; color: #6c757d;">Detected At:</td>
<td style="padding: 8px 0; border-bottom: 1px solid #dee2e6; text-align: right;">
{{ detected_at|date:"M d, Y H:i" }} UTC
</td>
</tr>
<tr>
<td style="padding: 8px 0; border-bottom: 1px solid #dee2e6; color: #6c757d;">Price Deviation:</td>
<td style="padding: 8px 0; border-bottom: 1px solid #dee2e6; text-align: right; font-weight: bold;">
{{ percent_change|floatformat:1 }}%
</td>
</tr>
<tr>
<td style="padding: 8px 0; color: #6c757d;">Previous Status:</td>
<td style="padding: 8px 0; text-align: right;">{{ previous_status|default:"N/A"|title }}</td>
</tr>
</table>
</div>
{% if recommendation %}
<div class="recommendation">
<h4 style="margin-top: 0; color: #004085;">💡 Recommendation</h4>
<p style="margin-bottom: 0;">{{ recommendation }}</p>
</div>
{% endif %}
<div style="text-align: center; margin: 30px 0;">
<a href="{{ dashboard_url }}" class="action-button">
View Live Dashboard
</a>
</div>
{% endblock %}

View File

@@ -0,0 +1,52 @@
{% extends "emails/base.html" %}
{% block title %}System Alert - Bitcoin Monitor{% endblock %}
{% block content %}
<div class="alert-banner alert-system">
⚠️ SYSTEM ALERT: {{ alert_title }}
</div>
<div style="margin: 25px 0;">
<h3 style="color: #343a40; margin-top: 0;">Issue Details</h3>
<div style="background: #f8f9fa; padding: 15px; border-radius: 6px; border-left: 4px solid #dc3545;">
<p style="margin: 0; white-space: pre-wrap; font-family: monospace; font-size: 13px;">
{{ alert_message }}
</p>
</div>
</div>
<div class="stats-grid">
<div class="stat-item">
<div class="stat-value">{{ affected_component }}</div>
<div class="stat-label">Affected Component</div>
</div>
<div class="stat-item">
<div class="stat-value">{{ severity|upper }}</div>
<div class="stat-label">Severity</div>
</div>
<div class="stat-item">
<div class="stat-value">{{ occurred_at|date:"H:i" }}</div>
<div class="stat-label">Time (UTC)</div>
</div>
<div class="stat-item">
<div class="stat-value">{{ error_code|default:"N/A" }}</div>
<div class="stat-label">Error Code</div>
</div>
</div>
<div style="margin: 25px 0; padding: 20px; background: #fff3cd; border-radius: 8px; border-left: 4px solid #ffc107;">
<h4 style="margin-top: 0; color: #856404;">🛠️ Troubleshooting Steps</h4>
<ul style="margin-bottom: 0; padding-left: 20px;">
{% for step in troubleshooting_steps %}
<li>{{ step }}</li>
{% endfor %}
</ul>
</div>
<div style="text-align: center; margin: 30px 0;">
<a href="{{ admin_url }}" class="action-button" style="background: #6c757d;">
Go to Admin Panel
</a>
</div>
{% endblock %}

View File

@@ -0,0 +1,108 @@
<!DOCTYPE html>
<html>
<head>
<title>Analysis Results</title>
<style>
body {
font-family: Arial, sans-serif;
max-width: 1200px;
margin: 0 auto;
padding: 20px;
background: #f8f9fa;
}
.container {
background: white;
padding: 30px;
border-radius: 10px;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
}
.header {
background: linear-gradient(135deg, #4e54c8 0%, #8f94fb 100%);
color: white;
padding: 20px;
border-radius: 8px;
margin-bottom: 30px;
}
.success {
background: #d4edda;
color: #155724;
padding: 15px;
border-radius: 5px;
margin: 20px 0;
border: 1px solid #c3e6cb;
}
.analysis-card {
border: 1px solid #dee2e6;
border-radius: 8px;
padding: 20px;
margin: 15px 0;
background: #f8f9fa;
}
.status-dip { border-left: 5px solid #dc3545; }
.status-peak { border-left: 5px solid #ffc107; }
.status-neutral { border-left: 5px solid #28a745; }
.btn {
display: inline-block;
padding: 10px 20px;
background: #007bff;
color: white;
text-decoration: none;
border-radius: 5px;
margin-right: 10px;
margin-top: 20px;
}
.btn:hover {
background: #0056b3;
}
.btn-secondary {
background: #6c757d;
}
.btn-secondary:hover {
background: #545b62;
}
</style>
</head>
<body>
<div class="container">
<div class="header">
<h1>✓ Analysis Complete</h1>
<p>Market analysis has been successfully executed</p>
</div>
<div class="success">
<h3>{{ message }}</h3>
</div>
<h2>Analysis Results</h2>
{% for analysis in analyses %}
<div class="analysis-card status-{{ analysis.status }}">
<h3>{{ analysis.period|title }} Analysis</h3>
<p><strong>Status:</strong>
<span style="font-weight: bold;
{% if analysis.status == 'dip' %}color: #dc3545;
{% elif analysis.status == 'peak' %}color: #ffc107;
{% else %}color: #28a745;{% endif %}">
{{ analysis.status|upper }}
</span>
</p>
<p><strong>Current Price:</strong> ${{ analysis.current_price }}</p>
<p><strong>Average Price:</strong> ${{ analysis.average_price }}</p>
<p><strong>Threshold:</strong> {{ analysis.threshold_percent }}%</p>
<p><strong>Range:</strong> ${{ analysis.lower_threshold }} - ${{ analysis.upper_threshold }}</p>
{% if analysis.is_event %}
<p><strong>⚠️ Event Detected:</strong> {{ analysis.event_type|title }}</p>
{% endif %}
<p><small>Analyzed at: {{ analysis.timestamp }}</small></p>
</div>
{% endfor %}
<div style="margin-top: 30px;">
<a href="{% url 'view_analysis' %}" class="btn">View All Analyses</a>
<a href="/" class="btn btn-secondary">Back to Dashboard</a>
<a href="/admin/monitor/marketanalysis/" class="btn btn-secondary">Admin Panel</a>
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,294 @@
<!DOCTYPE html>
<!-- Add this script to use API -->
<script>
// Fetch status from API
function fetchApiStatus() {
fetch('/api/status/')
.then(response => response.json())
.then(data => {
// Update status display
document.getElementById('current-price').textContent =
`$${data.current_price.toFixed(2)}`;
document.getElementById('current-status').textContent =
data.current_status.toUpperCase();
document.getElementById('current-status').className =
`status-${data.current_status}`;
// Update stats
document.getElementById('yearly-avg').textContent =
`$${data.yearly_average.toFixed(2)}`;
document.getElementById('yearly-min').textContent =
`$${data.yearly_min.toFixed(2)}`;
document.getElementById('yearly-max').textContent =
`$${data.yearly_max.toFixed(2)}`;
// Show/hide stale warnings
const staleWarning = document.getElementById('stale-warning');
if (data.stale_yearly || data.stale_hourly) {
staleWarning.style.display = 'block';
} else {
staleWarning.style.display = 'none';
}
})
.catch(error => {
console.error('Error fetching status:', error);
});
}
// Fetch events from API
function fetchApiEvents() {
fetch('/api/events/?limit=5')
.then(response => response.json())
.then(data => {
const eventsList = document.getElementById('events-list');
eventsList.innerHTML = '';
data.forEach(event => {
const li = document.createElement('li');
li.innerHTML = `
<strong>${event.event_type.replace('_', ' ').toUpperCase()}</strong>
at $${event.current_price.toFixed(2)}
(${new Date(event.timestamp).toLocaleTimeString()})
`;
eventsList.appendChild(li);
});
});
}
// Auto-refresh API data every 30 seconds
setInterval(() => {
fetchApiStatus();
fetchApiEvents();
}, 30000);
// Initial load
fetchApiStatus();
fetchApiEvents();
</script>
<html>
<head>
<title>Bitcoin Price Monitor</title>
<style>
body {
font-family: Arial, sans-serif;
max-width: 1200px;
margin: 0 auto;
padding: 20px;
background: #f8f9fa;
}
.container {
background: white;
padding: 30px;
border-radius: 10px;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
}
.header {
background: linear-gradient(135deg, #f7931a 0%, #8b4513 100%);
color: white;
padding: 20px;
border-radius: 8px;
margin-bottom: 30px;
}
.stats-card {
background: #e9ecef;
padding: 20px;
border-radius: 8px;
margin-bottom: 30px;
}
{% if analysis %}
<div style="background: #e8f4fd; padding: 15px; border-radius: 8px; margin: 20px 0; border-left: 4px solid #007bff;">
<h3>Latest Analysis</h3>
<p><strong>Status:</strong>
<span style="font-weight: bold;
{% if analysis.status == 'dip' %}color: #dc3545;
{% elif analysis.status == 'peak' %}color: #ffc107;
{% else %}color: #28a745;{% endif %}">
{{ analysis.status|upper }}
</span>
</p>
<p><strong>Average (Hourly):</strong> ${{ analysis.average_price|floatformat:2 }}</p>
<p><strong>Threshold:</strong> ±{{ analysis.threshold_percent }}%</p>
{% if analysis.is_event %}
<p style="color: #dc3545; font-weight: bold;">
{{ analysis.event_type|title }} event detected!
</p>
{% endif %}
<a href="{% url 'view_analysis' %}" style="color: #007bff; text-decoration: none;">View detailed analysis </a>
</div>
{% endif %}
.price-table {
width: 100%;
border-collapse: collapse;
margin-top: 20px;
}
.price-table th {
background: #343a40;
color: white;
padding: 12px;
text-align: left;
}
.price-table td {
padding: 12px;
border-bottom: 1px solid #dee2e6;
}
.price-table tr:hover {
background: #f8f9fa;
}
.btn {
background: #28a745;
color: white;
border: none;
padding: 10px 20px;
border-radius: 5px;
cursor: pointer;
font-size: 16px;
margin-right: 10px;
}
.btn:hover {
background: #218838;
}
.btn-fetch {
background: #007bff;
}
.btn-fetch:hover {
background: #0056b3;
}
.btn-admin {
background: #6c757d;
}
.btn-admin:hover {
background: #545b62;
}
.success {
color: #28a745;
padding: 10px;
background: #d4edda;
border-radius: 5px;
margin: 10px 0;
}
.error {
color: #dc3545;
padding: 10px;
background: #f8d7da;
border-radius: 5px;
margin: 10px 0;
}
</style>
</head>
<body>
<div class="container">
<div class="header">
<h1>₿ Bitcoin Price Monitor</h1>
<p>Real-time Bitcoin price tracking and historical data</p>
</div>
<div class="stats-card">
<h2>Current Status</h2>
<p><strong>Latest Price:</strong> ${{ stats.latest_price }}</p>
<p><strong>Last Updated:</strong> {{ stats.latest_time }}</p>
<p><strong>Total Records:</strong> {{ stats.total_records }}</p>
<div>
<button class="btn btn-fetch" onclick="fetchPrice()">
Fetch Current Price
</button>
<button class="btn" onclick="location.reload()">
Refresh Data
</button>
<a href="/admin/monitor/bitcoinprice/" class="btn btn-admin">
Admin Panel
</a>
<a href="{% url 'run_analysis' %}" class="btn" style="background: #28a745;">
Run Analysis
</a>
<a href="{% url 'view_analysis' %}" class="btn" style="background: #17a2b8;">
View Analysis
</a>
</div>
<div id="message"></div>
</div>
<h2>Recent Prices (Last 10)</h2>
{% if prices %}
<table class="price-table">
<thead>
<tr>
<th>Timestamp</th>
<th>Price (USD)</th>
<th>Volume</th>
<th>Market Cap</th>
</tr>
</thead>
<tbody>
{% for price in prices %}
<tr>
<td>{{ price.timestamp }}</td>
<td>${{ price.price_usd }}</td>
<td>{% if price.volume %}${{ price.volume }}{% else %}-{% endif %}</td>
<td>{% if price.market_cap %}${{ price.market_cap }}{% else %}-{% endif %}</td>
</tr>
{% endfor %}
</tbody>
</table>
{% else %}
<p>No price data available yet. Click "Fetch Current Price" to get started!</p>
{% endif %}
</div>
<div id="api-status-display" style="margin: 20px 0; padding: 15px; background: #f8f9fa; border-radius: 5px;">
<h3>API Status</h3>
<p><strong>Current Price:</strong> <span id="current-price">Loading...</span></p>
<p><strong>Status:</strong> <span id="current-status" class="status-neutral">Loading...</span></p>
<p><strong>Yearly Average:</strong> <span id="yearly-avg">Loading...</span></p>
<div id="stale-warning" style="display: none; color: #dc3545; padding: 10px; background: #f8d7da; border-radius: 5px;">
⚠️ Data may be stale. Last fetch was more than 1 hour ago.
</div>
</div>
<div style="margin: 20px 0;">
<h3>Recent Events</h3>
<ul id="events-list">
<li>Loading events...</li>
</ul>
</div>
<style>
.status-dip { color: #dc3545; font-weight: bold; }
.status-peak { color: #ffc107; font-weight: bold; }
.status-neutral { color: #28a745; font-weight: bold; }
</style>
<script>
function fetchPrice() {
const messageDiv = document.getElementById('message');
messageDiv.innerHTML = '<p>Fetching current price...</p>';
messageDiv.className = '';
fetch('/fetch-price/')
.then(response => response.json())
.then(data => {
if (data.success) {
messageDiv.innerHTML = `<p class="success">${data.message}</p>`;
// Reload the page after 2 seconds to show new data
setTimeout(() => {
location.reload();
}, 2000);
} else {
messageDiv.innerHTML = `<p class="error">${data.message}</p>`;
}
})
.catch(error => {
messageDiv.innerHTML = `<p class="error">Error: ${error}</p>`;
});
}
// Auto-refresh every 30 seconds
setInterval(() => {
const currentTime = new Date().toLocaleTimeString();
console.log(`Auto-refreshing at ${currentTime}`);
fetchPrice();
}, 30000);
</script>
</body>
</html>

View File

@@ -0,0 +1,195 @@
<!DOCTYPE html>
<html>
<head>
<title>Market Analysis</title>
<style>
body {
font-family: Arial, sans-serif;
max-width: 1400px;
margin: 0 auto;
padding: 20px;
background: #f8f9fa;
}
.container {
background: white;
padding: 30px;
border-radius: 10px;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
}
.header {
background: linear-gradient(135deg, #4e54c8 0%, #8f94fb 100%);
color: white;
padding: 20px;
border-radius: 8px;
margin-bottom: 30px;
}
.summary-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 20px;
margin: 30px 0;
}
.summary-card {
border: 1px solid #dee2e6;
border-radius: 8px;
padding: 20px;
background: white;
box-shadow: 0 2px 4px rgba(0,0,0,0.05);
}
.summary-card h3 {
margin-top: 0;
color: #495057;
border-bottom: 2px solid #e9ecef;
padding-bottom: 10px;
}
.status-badge {
display: inline-block;
padding: 5px 10px;
border-radius: 20px;
font-size: 12px;
font-weight: bold;
margin-left: 10px;
}
.status-dip { background: #dc3545; color: white; }
.status-peak { background: #ffc107; color: #212529; }
.status-neutral { background: #28a745; color: white; }
.analysis-table {
width: 100%;
border-collapse: collapse;
margin: 30px 0;
}
.analysis-table th {
background: #343a40;
color: white;
padding: 12px;
text-align: left;
}
.analysis-table td {
padding: 12px;
border-bottom: 1px solid #dee2e6;
}
.analysis-table tr:hover {
background: #f8f9fa;
}
.btn {
display: inline-block;
padding: 10px 20px;
background: #007bff;
color: white;
text-decoration: none;
border-radius: 5px;
margin-right: 10px;
margin-bottom: 20px;
}
.btn:hover {
background: #0056b3;
}
.btn-run {
background: #28a745;
}
.btn-run:hover {
background: #218838;
}
.btn-secondary {
background: #6c757d;
}
.btn-secondary:hover {
background: #545b62;
}
.no-data {
text-align: center;
padding: 40px;
color: #6c757d;
}
</style>
</head>
<body>
<div class="container">
<div class="header">
<h1>📊 Market Analysis Dashboard</h1>
<p>Comprehensive Bitcoin market analysis across different time periods</p>
</div>
<div>
<a href="{% url 'run_analysis' %}" class="btn btn-run">Run New Analysis</a>
<a href="/" class="btn">Back to Dashboard</a>
<a href="/admin/monitor/marketanalysis/" class="btn btn-secondary">Admin Panel</a>
</div>
<h2>Latest Analysis Summary</h2>
{% if summary %}
<div class="summary-grid">
{% for period, data in summary.items %}
<div class="summary-card">
<h3>{{ period|title }} Analysis
<span class="status-badge status-{{ data.status }}">
{{ data.status|upper }}
</span>
</h3>
<p><strong>Current Price:</strong> ${{ data.current_price|floatformat:2 }}</p>
<p><strong>Average Price:</strong> ${{ data.average_price|floatformat:2 }}</p>
<p><strong>Threshold:</strong> {{ data.threshold_percent }}%</p>
{% if data.is_event %}
<p><strong>⚠️ Event Active</strong></p>
{% endif %}
</div>
{% endfor %}
</div>
{% else %}
<div class="no-data">
<h3>No analysis data available</h3>
<p>Click "Run New Analysis" to generate your first analysis report.</p>
</div>
{% endif %}
<h2>Recent Analyses</h2>
{% if all_analyses %}
<table class="analysis-table">
<thead>
<tr>
<th>Time</th>
<th>Period</th>
<th>Status</th>
<th>Current Price</th>
<th>Average Price</th>
<th>Threshold</th>
<th>Event</th>
</tr>
</thead>
<tbody>
{% for analysis in all_analyses %}
<tr>
<td>{{ analysis.timestamp|date:"M d, H:i" }}</td>
<td>{{ analysis.period }}</td>
<td>
<span class="status-badge status-{{ analysis.status }}">
{{ analysis.status|upper }}
</span>
</td>
<td>${{ analysis.current_price|floatformat:2 }}</td>
<td>${{ analysis.average_price|floatformat:2 }}</td>
<td>{{ analysis.threshold_percent }}%</td>
<td>
{% if analysis.is_event %}
<span style="color: #dc3545;">{{ analysis.event_type|title }}</span>
{% else %}
-
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% else %}
<div class="no-data">
<p>No analysis records found. Run an analysis to see results here.</p>
</div>
{% endif %}
</div>
</body>
</html>