Delete templates directory

This commit is contained in:
DJObleezy 2025-04-09 11:43:14 -07:00 committed by GitHub
parent d374bc3ba1
commit 4845f42fa4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 0 additions and 1468 deletions

View File

@ -1,73 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{% block title %}Ocean.xyz Pool Mining Dashboard{% endblock %}</title>
<!-- Common fonts -->
<link href="https://fonts.googleapis.com/css2?family=Orbitron:wght@400;700&family=VT323&display=swap" rel="stylesheet">
<!-- Font Awesome -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" crossorigin="anonymous" referrerpolicy="no-referrer" />
<!-- Bootstrap -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<!-- Common CSS -->
<link rel="stylesheet" href="/static/css/common.css">
<!-- Page-specific CSS -->
{% block css %}{% endblock %}
</head>
<body>
<div class="container-fluid">
<!-- Connection status indicator -->
<div id="connectionStatus"></div>
<!-- Top right link -->
<a href="https://x.com/DJObleezy" id="topRightLink" target="_blank" rel="noopener noreferrer">Made by @DJO₿leezy</a>
<h1 class="text-center">
<a href="/" style="text-decoration:none; color:inherit;">
{% block header %}Ocean.xyz Pool Mining Dashboard v 0.3{% endblock %}
</a>
</h1>
{% block last_updated %}
<p class="text-center" id="lastUpdated" style="color: #f7931a"><strong>Last Updated:</strong> {{ current_time }}<span id="terminal-cursor"></span></p>
{% endblock %}
{% block navigation %}
<div class="navigation-links">
<a href="/dashboard" class="nav-link {% block dashboard_active %}{% endblock %}">Dashboard</a>
<a href="/workers" class="nav-link {% block workers_active %}{% endblock %}">Workers</a>
<a href="/blocks" class="nav-link {% block blocks_active %}{% endblock %}">Blocks</a>
<a href="/notifications" class="nav-link {% block notifications_active %}{% endblock %}">
Notifications
<span id="nav-unread-badge" class="nav-badge"></span>
</a>
</div>
{% endblock %}
<!-- Main content area -->
{% block content %}{% endblock %}
<!-- Hidden Congrats Message -->
{% block congrats_message %}
<div id="congratsMessage" style="display:none; position: fixed; top: 20px; left: 50%; transform: translateX(-50%); z-index: 1000; background: #f7931a; color: #000; padding: 10px; border-radius: 5px; box-shadow: 0 0 15px rgba(247, 147, 26, 0.7);"></div>
{% endblock %}
</div>
<!-- External JavaScript libraries -->
<script src="https://code.jquery.com/jquery-3.7.0.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-annotation@1.1.0"></script>
<!-- Page-specific JavaScript -->
{% block javascript %}{% endblock %}
<!-- Bitcoin Progress Bar -->
<script src="/static/js/BitcoinProgressBar.js"></script>
</body>
</html>

View File

@ -1,94 +0,0 @@
{% extends "base.html" %}
{% block title %}Blocks - Ocean.xyz Mining Dashboard{% endblock %}
{% block css %}
<link rel="stylesheet" href="/static/css/blocks.css">
{% endblock %}
{% block header %}Blockchain Monitor{% endblock %}
{% block blocks_active %}active{% endblock %}
{% block content %}
<!-- Latest block stats -->
<div class="row mb-2 equal-height">
<div class="col-12">
<div class="card">
<div class="card-header">Latest Block Stats</div>
<div class="card-body">
<div class="latest-block-stats">
<div class="stat-item">
<strong>Block Height:</strong>
<span id="latest-height" class="metric-value white">Loading...</span>
</div>
<div class="stat-item">
<strong>Time:</strong>
<span id="latest-time" class="metric-value blue">Loading...</span>
</div>
<div class="stat-item">
<strong>Transactions:</strong>
<span id="latest-tx-count" class="metric-value white">Loading...</span>
</div>
<div class="stat-item">
<strong>Size:</strong>
<span id="latest-size" class="metric-value white">Loading...</span>
</div>
<div class="stat-item">
<strong>Difficulty:</strong>
<span id="latest-difficulty" class="metric-value yellow">Loading...</span>
</div>
<div class="stat-item">
<strong>Mining Pool:</strong>
<span id="latest-pool" class="metric-value green">Loading...</span>
</div>
<div class="stat-item">
<strong>Avg Fee Rate:</strong>
<span id="latest-fee-rate" class="metric-value yellow">Loading...</span>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Blocks grid -->
<div class="row">
<div class="col-12">
<div class="card">
<div class="card-header">Recent Bitcoin Blocks</div>
<div class="card-body">
<div class="blocks-container">
<div id="blocks-grid" class="blocks-grid">
<!-- Blocks will be generated here via JavaScript -->
<div class="loader">
<span class="loader-text">Connecting to mempool.space API<span class="terminal-cursor"></span></span>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Block details modal -->
<div id="block-modal" class="block-modal">
<div class="block-modal-content">
<div class="block-modal-header">
<span class="block-modal-title">Block Details</span>
<span class="block-modal-close">&times;</span>
</div>
<div class="block-modal-body">
<div id="block-details">
<!-- Block details will be displayed here -->
</div>
</div>
</div>
</div>
{% endblock %}
{% block javascript %}
<script src="/static/js/blocks.js"></script>
<script src="/static/js/block-animation.js"></script>
{% endblock %}

View File

@ -1,713 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Ocean.xyz Pool Miner - Initializing...</title>
<link href="https://fonts.googleapis.com/css2?family=VT323&display=swap" rel="stylesheet">
<link rel="stylesheet" href="/static/css/boot.css">
<style>
/* Added styles for configuration form */
#config-form {
display: none;
margin-top: 20px;
background-color: rgba(0, 0, 0, 0.7);
border: 1px solid #f7931a;
padding: 15px;
max-width: 600px;
margin-left: auto;
margin-right: auto;
box-shadow: 0 0 10px rgba(247, 147, 26, 0.5);
}
.config-title {
color: #f7931a;
font-size: 22px;
text-align: center;
margin-bottom: 15px;
text-shadow: 0 0 8px rgba(247, 147, 26, 0.8);
}
.form-group {
margin-bottom: 15px;
}
.form-group label {
display: block;
margin-bottom: 5px;
color: #f7931a;
}
.form-group input {
width: 100%;
background-color: #111;
border: 1px solid #f7931a;
padding: 8px;
color: white;
font-family: 'VT323', monospace;
font-size: 18px;
}
.form-group input:focus {
outline: none;
box-shadow: 0 0 5px #f7931a;
}
.form-actions {
display: flex;
justify-content: space-between;
margin-top: 20px;
}
.btn {
background-color: #f7931a;
border: none;
color: black;
padding: 8px 15px;
font-family: 'VT323', monospace;
font-size: 18px;
cursor: pointer;
min-width: 120px;
text-align: center;
}
.btn:hover {
background-color: #ffa642;
}
.btn-secondary {
background-color: #333;
color: #f7931a;
}
.btn-secondary:hover {
background-color: #444;
}
/* Make skip button more mobile-friendly */
#skip-button {
position: fixed;
bottom: 20px;
right: 20px;
z-index: 1000;
padding: 12px 20px;
font-size: 18px;
border-radius: 8px;
}
@media (max-width: 768px) {
#skip-button {
bottom: 10px;
right: 10px;
padding: 15px 25px;
font-size: 20px; /* Larger font size for better tap targets */
border-radius: 10px;
width: auto;
}
.form-actions {
flex-direction: column;
gap: 10px;
}
.btn {
width: 100%;
padding: 12px;
font-size: 20px;
}
}
/* Tooltip styles */
.tooltip {
position: relative;
display: inline-block;
margin-left: 5px;
cursor: help;
}
.tooltip .tooltip-text {
visibility: hidden;
width: 200px;
background-color: #000;
color: #fff;
text-align: center;
border: 1px solid #f7931a;
padding: 5px;
position: absolute;
z-index: 1;
bottom: 125%;
left: 50%;
margin-left: -100px;
opacity: 0;
transition: opacity 0.3s;
font-size: 14px;
}
.tooltip:hover .tooltip-text {
visibility: visible;
opacity: 1;
}
/* Form success/error message */
#form-message {
margin-top: 10px;
padding: 8px;
text-align: center;
display: none;
}
.message-success {
background-color: rgba(50, 205, 50, 0.2);
border: 1px solid #32CD32;
color: #32CD32;
}
.message-error {
background-color: rgba(255, 0, 0, 0.2);
border: 1px solid #ff0000;
color: #ff0000;
}
</style>
</head>
<body>
<button id="skip-button">SKIP</button>
<div id="debug-info"></div>
<div id="loading-message">Loading mining data...</div>
<div id="bitcoin-logo">
██████╗ ████████╗ ██████╗ ██████╗ ███████╗
██╔══██╗╚══██╔══╝██╔════╝ ██╔═══██╗██╔════╝
██████╔╝ ██║ ██║ ██║ ██║███████╗
██╔══██╗ ██║ ██║ ██║ ██║╚════██║
██████╔╝ ██║ ╚██████╗ ╚██████╔╝███████║
╚═════╝ ╚═╝ ╚═════╝ ╚═════╝ ╚══════╝
v.21
</div>
<div id="terminal">
<div id="terminal-content">
<span id="output"></span><span class="cursor"></span>
<span id="prompt-container">
<span id="prompt-text">
Initialize mining dashboard? [Y/N]:
<span class="prompt-cursor"></span>
<input type="text" id="user-input" maxlength="1" autocomplete="off" spellcheck="false" autofocus style="font-size: 16px; font-weight: bold;">
</span>
</span>
</div>
</div>
<!-- Configuration Form -->
<div id="config-form">
<div class="config-title">MINING CONFIGURATION</div>
<div class="form-group">
<label for="wallet-address">
Bitcoin Wallet Address
<span class="tooltip">
?
<span class="tooltip-text">Your Ocean.xyz pool mining address</span>
</span>
</label>
<input type="text" id="wallet-address" placeholder="bc1..." value="">
</div>
<div class="form-group">
<label for="power-cost">
Power Cost ($/kWh)
<span class="tooltip">
?
<span class="tooltip-text">Your electricity cost per kilowatt-hour</span>
</span>
</label>
<input type="number" id="power-cost" step="0.01" min="0" placeholder="0.12" value="">
</div>
<div class="form-group">
<label for="power-usage">
Power Usage (Watts)
<span class="tooltip">
?
<span class="tooltip-text">Total power consumption of your mining equipment</span>
</span>
</label>
<input type="number" id="power-usage" step="1" min="0" placeholder="3450" value="">
</div>
<div id="form-message"></div>
<div class="form-actions">
<button class="btn btn-secondary" id="use-defaults">Use Defaults</button>
<button class="btn" id="save-config">Save & Continue</button>
</div>
</div>
<script>
// Debug logging
function updateDebug(message) {
document.getElementById('debug-info').textContent = message;
console.log(message);
}
// Format numbers with commas
function numberWithCommas(x) {
if (x == null) return "N/A";
return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}
// Global variables
let bootMessages = [];
let dashboardData = null;
let outputElement = document.getElementById('output');
const bitcoinLogo = document.getElementById('bitcoin-logo');
const skipButton = document.getElementById('skip-button');
const loadingMessage = document.getElementById('loading-message');
const promptContainer = document.getElementById('prompt-container');
const userInput = document.getElementById('user-input');
const configForm = document.getElementById('config-form');
let messageIndex = 0;
let timeoutId = null;
let waitingForUserInput = false;
let bootComplete = false;
let configLoaded = false;
let currentConfig = {
wallet: "yourwallethere",
power_cost: 0.0,
power_usage: 0.0
};
// Replace the current loadConfig function with this improved version
function loadConfig() {
// Always make a fresh request to get the latest config
fetch('/api/config?nocache=' + new Date().getTime()) // Add cache-busting parameter
.then(response => {
if (!response.ok) {
throw new Error('Failed to load configuration: ' + response.statusText);
}
return response.json();
})
.then(data => {
console.log("Loaded configuration:", data);
currentConfig = data;
// After loading, always update the form fields with the latest values
document.getElementById('wallet-address').value = currentConfig.wallet || "";
document.getElementById('power-cost').value = currentConfig.power_cost || "";
document.getElementById('power-usage').value = currentConfig.power_usage || "";
configLoaded = true;
})
.catch(err => {
console.error("Error loading config:", err);
// Use default values if loading fails
currentConfig = {
wallet: "yourwallethere",
power_cost: 0.0,
power_usage: 0.0
};
// Still update the form with default values
document.getElementById('wallet-address').value = currentConfig.wallet || "";
document.getElementById('power-cost').value = currentConfig.power_cost || "";
document.getElementById('power-usage').value = currentConfig.power_usage || "";
});
}
// Also update the save button event handler to reload the config after saving
document.getElementById('save-config').addEventListener('click', function () {
const messageElement = document.getElementById('form-message');
messageElement.style.display = 'block';
saveConfig()
.then(data => {
console.log("Configuration saved:", data);
messageElement.textContent = "Configuration saved successfully!";
messageElement.className = "message-success";
// Update currentConfig with the saved values
currentConfig = data.config || data;
setTimeout(redirectToDashboard, 1000);
})
.catch(error => {
console.error("Error saving configuration:", error);
messageElement.textContent = "Error saving configuration. Please try again.";
messageElement.className = "message-error";
});
});
// Save configuration
function saveConfig() {
const wallet = document.getElementById('wallet-address').value.trim();
const powerCost = parseFloat(document.getElementById('power-cost').value) || 0;
const powerUsage = parseFloat(document.getElementById('power-usage').value) || 0;
const updatedConfig = {
wallet: wallet || currentConfig.wallet,
power_cost: powerCost,
power_usage: powerUsage
};
return fetch('/api/config', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(updatedConfig)
})
.then(response => {
if (!response.ok) {
throw new Error('Failed to save configuration');
}
return response.json();
});
}
// Safety timeout: redirect after 60 seconds if boot not complete
window.addEventListener('load', function () {
setTimeout(function () {
if (!bootComplete && !waitingForUserInput) {
console.warn("Safety timeout reached - redirecting to dashboard");
redirectToDashboard();
}
}, 60000);
});
// Configuration form event listeners
document.getElementById('save-config').addEventListener('click', function () {
const messageElement = document.getElementById('form-message');
messageElement.style.display = 'block';
saveConfig()
.then(data => {
console.log("Configuration saved:", data);
messageElement.textContent = "Configuration saved successfully!";
messageElement.className = "message-success";
setTimeout(redirectToDashboard, 1000);
})
.catch(error => {
console.error("Error saving configuration:", error);
messageElement.textContent = "Error saving configuration. Please try again.";
messageElement.className = "message-error";
});
});
// Replace the current Use Defaults button event listener with this fixed version
document.getElementById('use-defaults').addEventListener('click', function () {
console.log("Use Defaults button clicked");
// Always use the hardcoded default values, not the currentConfig
const defaultWallet = "yourwallethere";
const defaultPowerCost = 0.0;
const defaultPowerUsage = 0.0;
console.log("Setting to default values");
// Apply the hardcoded default values to the form fields
document.getElementById('wallet-address').value = defaultWallet;
document.getElementById('power-cost').value = defaultPowerCost;
document.getElementById('power-usage').value = defaultPowerUsage;
// Show visual feedback that the button was clicked
const btn = document.getElementById('use-defaults');
const originalText = btn.textContent;
btn.textContent = "Defaults Applied";
btn.style.backgroundColor = "#32CD32";
// Reset the button after a short delay
setTimeout(function () {
btn.textContent = originalText;
btn.style.backgroundColor = "";
}, 1500);
});
// Redirect to dashboard
function redirectToDashboard() {
updateDebug("Boot sequence complete, redirecting...");
const baseUrl = window.location.origin;
window.location.href = baseUrl + "/dashboard";
}
// Fade in Bitcoin logo
document.addEventListener('DOMContentLoaded', function () {
setTimeout(function () {
bitcoinLogo.style.visibility = 'visible';
setTimeout(function () {
bitcoinLogo.style.opacity = '1';
}, 100);
}, 500);
// Load configuration
loadConfig();
});
// Post-confirmation messages with retro typing effect
function showPostConfirmationMessages(response) {
try {
outputElement = document.getElementById('output');
if (!outputElement) {
setTimeout(redirectToDashboard, 1000);
return;
}
// Configuration form will be shown after boot sequence
if (response.toUpperCase() === 'Y') {
const yesMessages = [
{ text: "INITIALIZING DASHBOARD...\n", html: true, delay: 400 },
{ text: "Connecting to real-time data feeds...", speed: 20, delay: 300 },
{ text: "<span class='green'>CONNECTED</span>\n", html: true, delay: 400 },
{ text: "Loading blockchain validators...", speed: 15, delay: 300 },
{ text: "<span class='green'>COMPLETE</span>\n", html: true, delay: 400 },
{ text: "Starting TX fee calculation module...", speed: 15, delay: 400 },
{ text: "<span class='green'>ACTIVE</span>\n", html: true, delay: 400 },
{ text: "Verifying BTC-USD exchange rates...", speed: 15, delay: 200 },
{ text: "<span class='green'>CURRENT RATE CONFIRMED</span>\n", html: true, delay: 300 },
{ text: "Calibrating hashrate telemetry...", speed: 15, delay: 200 },
{ text: "<span class='green'>CALIBRATED</span>\n", html: true, delay: 200 },
{ text: "Loading mining configuration...", speed: 15, delay: 200 },
{ text: "<span class='green'>LOADED</span>\n", html: true, delay: 300 },
{ text: "Preparing configuration interface...", speed: 15, delay: 800 },
{ text: "<span class='green'>READY</span>\n", html: true, delay: 500 },
{ text: "\nPlease configure your mining setup or use the default values:\n", html: true, delay: 800, showConfigForm: true }
];
let msgIndex = 0;
function processNextMessage() {
if (msgIndex >= yesMessages.length) {
return;
}
const currentMessage = yesMessages[msgIndex];
if (currentMessage.showConfigForm) {
msgIndex++;
// Show configuration form
document.getElementById('config-form').style.display = 'block';
return;
}
if (currentMessage.html) {
outputElement.innerHTML += currentMessage.text;
msgIndex++;
setTimeout(processNextMessage, currentMessage.delay || 300);
} else {
let charIndex = 0;
function typeCharacter() {
if (charIndex < currentMessage.text.length) {
outputElement.innerHTML += currentMessage.text.charAt(charIndex);
charIndex++;
setTimeout(typeCharacter, currentMessage.speed || 20);
} else {
msgIndex++;
setTimeout(processNextMessage, currentMessage.delay || 300);
}
}
typeCharacter();
}
}
setTimeout(processNextMessage, 500);
} else {
// If user selects 'N', just redirect to dashboard
outputElement.innerHTML += "N\n\nDASHBOARD INITIALIZATION ABORTED.\n";
outputElement.innerHTML += "\nUsing default configuration values.\n";
setTimeout(redirectToDashboard, 2000);
}
} catch (err) {
setTimeout(redirectToDashboard, 1000);
}
}
// Handle Y/N prompt input
userInput.addEventListener('keydown', function (e) {
if (waitingForUserInput && e.key === 'Enter') {
e.preventDefault();
const response = userInput.value.toUpperCase();
if (response === 'Y' || response === 'N') {
promptContainer.style.display = 'none';
waitingForUserInput = false;
outputElement.innerHTML += response + "\n";
userInput.value = '';
showPostConfirmationMessages(response);
}
}
});
// Show the prompt
function showUserPrompt() {
promptContainer.style.display = 'inline';
waitingForUserInput = true;
document.querySelector('.cursor').style.display = 'none';
userInput.focus();
}
// Disable truncation so all text is visible
function manageTerminalContent() { }
// Retro typing effect for boot messages
function typeBootMessages() {
try {
if (!outputElement) {
outputElement = document.getElementById('output');
if (!outputElement) {
skipButton.click();
return;
}
}
if (messageIndex >= bootMessages.length) { return; }
const currentMessage = bootMessages[messageIndex];
if (currentMessage.showPrompt) {
messageIndex++;
showUserPrompt();
return;
}
if (currentMessage.html) {
outputElement.innerHTML += currentMessage.text;
messageIndex++;
timeoutId = setTimeout(typeBootMessages, currentMessage.delay || 300);
return;
}
if (!currentMessage.typingIndex) { currentMessage.typingIndex = 0; }
if (currentMessage.typingIndex < currentMessage.text.length) {
outputElement.innerHTML += currentMessage.text.charAt(currentMessage.typingIndex);
currentMessage.typingIndex++;
timeoutId = setTimeout(typeBootMessages, currentMessage.speed || 15);
} else {
messageIndex++;
timeoutId = setTimeout(typeBootMessages, currentMessage.delay || 300);
}
} catch (err) {
messageIndex++;
timeoutId = setTimeout(typeBootMessages, 500);
}
}
// Skip button: reveal configuration form only
skipButton.addEventListener('click', function () {
clearTimeout(timeoutId);
// Optionally, clear boot messages or hide elements related to boot sequence
outputElement.innerHTML = "";
// Hide any loading or prompt messages
loadingMessage.style.display = 'none';
promptContainer.style.display = 'none';
// Show the configuration form
configForm.style.display = 'block';
});
// Start the typing animation (hides loading message)
function startTyping() {
loadingMessage.style.display = 'none';
setTimeout(typeBootMessages, 150);
}
// Fallback messages (used immediately)
function setupFallbackMessages() {
bootMessages = [
{ text: "BITCOIN OS - MINING SYSTEM - v21.000.000\n", speed: 25, delay: 300 },
{ text: "Copyright (c) 2009-2025 Satoshi Nakamoto\n", speed: 20, delay: 250 },
{ text: "All rights reserved.\n\n", speed: 25, delay: 300 },
{ text: "INITIALIZING SYSTEM...\n", speed: 25, delay: 300 },
{ text: "HARDWARE: ", speed: 25, delay: 100 },
{ text: "<span class='green'>OK</span>\n", html: true, delay: 300 },
{ text: "NETWORK: ", speed: 25, delay: 100 },
{ text: "<span class='green'>OK</span>\n", html: true, delay: 300 },
{ text: "BLOCKCHAIN: ", speed: 25, delay: 100 },
{ text: "<span class='green'>SYNCHRONIZED</span>\n", html: true, delay: 300 },
{ text: "MINING RIG: ", speed: 25, delay: 100 },
{ text: "<span class='green'>ONLINE</span>\n", html: true, delay: 300 },
{ text: "\nSystem ready. ", speed: 25, delay: 400 },
{ showPrompt: true, delay: 0 }
];
startTyping();
}
// Initialize with fallback, then try live data
setupFallbackMessages();
updateDebug("Fetching dashboard data...");
fetch('/api/metrics')
.then(response => {
if (!response.ok) { throw new Error(`HTTP error! Status: ${response.status}`); }
return response.json();
})
.then(data => {
dashboardData = data;
clearTimeout(timeoutId);
messageIndex = 0;
outputElement = document.getElementById('output');
outputElement.innerHTML = "";
bootMessages = [
{ text: "BITCOIN OS - MINING CONTROL SYSTEM - v21.000.000\n", speed: 25, delay: 300 },
{ text: "Copyright (c) 2009-2025 Satoshi Nakamoto & The Bitcoin Core Developers\n", speed: 20, delay: 250 },
{ text: "All rights reserved.\n\n", speed: 25, delay: 300 },
{ text: "INITIALIZING SHA-256 MINING SUBSYSTEMS...\n", speed: 25, delay: 400 },
{ text: "ASIC CLUSTER STATUS: ", speed: 15, delay: 100 },
{ text: "<span class='green'>ONLINE</span>\n", html: true, delay: 300 },
{ text: "CHIP TEMPERATURE: ", speed: 15, delay: 100 },
{ text: "<span class='green'>62°C - WITHIN OPTIMAL RANGE</span>\n", html: true, delay: 300 },
{ text: "COOLING SYSTEMS: ", speed: 15, delay: 100 },
{ text: "<span class='green'>OPERATIONAL</span>\n", html: true, delay: 300 },
{ text: "POWER SUPPLY HEALTH: ", speed: 15, delay: 100 },
{ text: "<span class='green'>98.7% - NOMINAL</span>\n", html: true, delay: 300 },
{ text: "\nCONNECTING TO BITCOIN NETWORK...\n", speed: 20, delay: 400 },
{ text: "BLOCKCHAIN SYNC STATUS: ", speed: 15, delay: 100 },
{ text: "<span class='green'>SYNCHRONIZED</span>\n", html: true, delay: 300 },
{ text: "DIFFICULTY ADJUSTMENT: ", speed: 15, delay: 100 },
{ text: "<span class='yellow'>CALCULATED</span>\n", html: true, delay: 300 },
{ text: "MEMPOOL MONITORING: ", speed: 15, delay: 100 },
{ text: "<span class='green'>ACTIVE</span>\n", html: true, delay: 300 },
{ text: "\nESTABLISHING POOL CONNECTION...\n", speed: 20, delay: 300 },
{ text: "CONNECTING TO OCEAN.XYZ...\n", speed: 20, delay: 300 },
{ text: "STRATUM PROTOCOL v2: ", speed: 15, delay: 100 },
{ text: "<span class='green'>INITIALIZED</span>\n", html: true, delay: 300 },
{ text: "POOL HASHRATE: ", speed: 15, delay: 100 },
{ text: "<span class='green'>VERIFIED</span>\n", html: true, delay: 300 },
{ text: "WORKER AUTHENTICATION: ", speed: 15, delay: 100 },
{ text: "<span class='green'>SUCCESSFUL</span>\n", html: true, delay: 300 },
{ text: "\nINITIALIZING METRICS COLLECTORS...\n", speed: 20, delay: 300 },
{ text: "HASHRATE MONITOR: ", speed: 15, delay: 100 },
{ text: "<span class='green'>ACTIVE</span>\n", html: true, delay: 300 },
{ text: "EARNINGS CALCULATOR: ", speed: 15, delay: 100 },
{ text: "<span class='green'>CALIBRATED</span>\n", html: true, delay: 300 },
{ text: "POWER USAGE TRACKING: ", speed: 15, delay: 100 },
{ text: "<span class='green'>ENABLED</span>\n", html: true, delay: 300 },
{ text: "PAYOUT THRESHOLD MONITOR: ", speed: 15, delay: 100 },
{ text: "<span class='green'>ACTIVE</span>\n", html: true, delay: 300 },
{ text: "\nCURRENT NETWORK METRICS DETECTED\n", speed: 20, delay: 300 },
{ text: "BTC PRICE: ", speed: 20, delay: 100 },
{ text: "<span class='yellow'>$" + numberWithCommas((data.btc_price || 0).toFixed(2)) + "</span>\n", html: true, delay: 300 },
{ text: "NETWORK DIFFICULTY: ", speed: 20, delay: 100 },
{ text: "<span class='white'>" + numberWithCommas(Math.round(data.difficulty || 0)) + "</span>\n", html: true, delay: 300 },
{ text: "NETWORK HASHRATE: ", speed: 20, delay: 100 },
{ text: "<span class='white'>" + (data.network_hashrate ? numberWithCommas(Math.round(data.network_hashrate)) : "N/A") + " EH/s</span>\n", html: true, delay: 300 },
{ text: "BLOCK HEIGHT: ", speed: 20, delay: 100 },
{ text: "<span class='white'>" + numberWithCommas(data.block_number || "N/A") + "</span>\n", html: true, delay: 300 },
{ text: "\nMINER PERFORMANCE DATA\n", speed: 20, delay: 300 },
{ text: "CURRENT HASHRATE: ", speed: 20, delay: 100 },
{ text: "<span class='yellow'>" + (data.hashrate_60sec || "N/A") + " " + (data.hashrate_60sec_unit || "TH/s") + "</span>\n", html: true, delay: 300 },
{ text: "24HR AVG HASHRATE: ", speed: 20, delay: 100 },
{ text: "<span class='yellow'>" + (data.hashrate_24hr || "N/A") + " " + (data.hashrate_24hr_unit || "TH/s") + "</span>\n", html: true, delay: 300 },
{ text: "ACTIVE WORKERS: ", speed: 20, delay: 100 },
{ text: "<span class='yellow'>" + (data.workers_hashing || "0") + "</span>\n", html: true, delay: 300 },
{ text: "\nFINANCIAL CALCULATIONS\n", speed: 20, delay: 300 },
{ text: "DAILY MINING REVENUE: ", speed: 20, delay: 100 },
{ text: "<span class='green'>$" + numberWithCommas((data.daily_revenue || 0).toFixed(2)) + "</span>\n", html: true, delay: 300 },
{ text: "DAILY POWER COST: ", speed: 20, delay: 100 },
{ text: "<span class='red'>$" + numberWithCommas((data.daily_power_cost || 0).toFixed(2)) + "</span>\n", html: true, delay: 300 },
{ text: "DAILY PROFIT: ", speed: 20, delay: 100 },
{ text: "<span class='green'>$" + numberWithCommas((data.daily_profit_usd || 0).toFixed(2)) + "</span>\n", html: true, delay: 300 },
{ text: "PROJECTED MONTHLY PROFIT: ", speed: 20, delay: 100 },
{ text: "<span class='green'>$" + numberWithCommas((data.monthly_profit_usd || 0).toFixed(2)) + "</span>\n", html: true, delay: 300 },
{ text: "DAILY SATOSHI YIELD: ", speed: 20, delay: 100 },
{ text: "<span class='yellow'>" + numberWithCommas(data.daily_mined_sats || 0) + " sats</span>\n", html: true, delay: 300 },
{ text: "UNPAID EARNINGS: ", speed: 20, delay: 100 },
{ text: "<span class='green'>" + (data.unpaid_earnings || "0") + " BTC</span>\n", html: true, delay: 300 },
{ text: "ESTIMATED TIME TO PAYOUT: ", speed: 20, delay: 100 },
{ text: "<span class='yellow'>" + (data.est_time_to_payout || "Unknown") + "</span>\n", html: true, delay: 300 },
{ text: "\n", speed: 25, delay: 100 },
{ text: "<span class='green'>ALL MINING PROCESSES OPERATIONAL</span>\n", html: true, delay: 400 },
{ text: "\nInitialize mining dashboard? ", speed: 25, delay: 400 },
{ showPrompt: true, delay: 0 }
];
startTyping();
})
.catch(error => {
updateDebug(`Error fetching dashboard data: ${error.message}`);
});
</script>
</body>
</html>

View File

@ -1,363 +0,0 @@
{% extends "base.html" %}
{% block title %}Ocean.xyz Pool Mining Dashboard v 0.3{% endblock %}
{% block css %}
<link rel="stylesheet" href="/static/css/dashboard.css">
{% endblock %}
{% block dashboard_active %}active{% endblock %}
{% block content %}
<!-- Graph Container -->
<div id="graphContainer" class="mb-2">
<canvas id="trendGraph" style="width: 100%; height: 100%; position: relative; z-index: 2;"></canvas>
</div>
<!-- Miner Status -->
<div class="row mb-2 equal-height">
<div class="col-12">
<div class="card">
<div class="card-header">Miner Status</div>
<div class="card-body">
<p>
<strong>Status:</strong>
<span id="miner_status" class="metric-value">
{% if metrics and metrics.workers_hashing and metrics.workers_hashing > 0 %}
<span class="status-green">ONLINE</span> <span class="online-dot"></span>
{% else %}
<span class="status-red">OFFLINE</span> <span class="offline-dot"></span>
{% endif %}
</span>
</p>
<p>
<strong>Workers Hashing:</strong>
<span id="workers_hashing" class="metric-value">{{ metrics.workers_hashing or 0 }}</span>
<span id="indicator_workers_hashing"></span>
</p>
<p>
<strong>Last Share:</strong>
<span id="last_share" class="metric-value">{{ metrics.total_last_share or "N/A" }}</span>
</p>
</div>
</div>
</div>
</div>
<!-- Pool Hashrates and Bitcoin Network Stats -->
<div class="row equal-height">
<div class="col-md-6">
<div class="card">
<div class="card-header">Pool Hashrates</div>
<div class="card-body">
<p>
<strong>Pool Total Hashrate:</strong>
<span id="pool_total_hashrate" class="metric-value white">
{% if metrics and metrics.pool_total_hashrate and metrics.pool_total_hashrate_unit %}
{{ metrics.pool_total_hashrate }} {{ metrics.pool_total_hashrate_unit[:-2]|upper ~ metrics.pool_total_hashrate_unit[-2:] }}
{% else %}
N/A
{% endif %}
</span>
<span id="indicator_pool_total_hashrate"></span>
</p>
<hr>
<p>
<strong>24hr Avg Hashrate:</strong>
<span id="hashrate_24hr" class="metric-value white">
{% if metrics and metrics.hashrate_24hr %}
{{ metrics.hashrate_24hr }}
{% if metrics.hashrate_24hr_unit %}
{{ metrics.hashrate_24hr_unit[:-2]|upper ~ metrics.hashrate_24hr_unit[-2:] }}
{% else %}
TH/s
{% endif %}
{% else %}
N/A
{% endif %}
</span>
<span id="indicator_hashrate_24hr"></span>
</p>
<p>
<strong>3hr Avg Hashrate:</strong>
<span id="hashrate_3hr" class="metric-value white">
{% if metrics and metrics.hashrate_3hr %}
{{ metrics.hashrate_3hr }}
{% if metrics.hashrate_3hr_unit %}
{{ metrics.hashrate_3hr_unit[:-2]|upper ~ metrics.hashrate_3hr_unit[-2:] }}
{% else %}
TH/s
{% endif %}
{% else %}
N/A
{% endif %}
</span>
<span id="indicator_hashrate_3hr"></span>
</p>
<p>
<strong>10min Avg Hashrate:</strong>
<span id="hashrate_10min" class="metric-value white">
{% if metrics and metrics.hashrate_10min %}
{{ metrics.hashrate_10min }}
{% if metrics.hashrate_10min_unit %}
{{ metrics.hashrate_10min_unit[:-2]|upper ~ metrics.hashrate_10min_unit[-2:] }}
{% else %}
TH/s
{% endif %}
{% else %}
N/A
{% endif %}
</span>
<span id="indicator_hashrate_10min"></span>
</p>
<p>
<strong>60sec Avg Hashrate:</strong>
<span id="hashrate_60sec" class="metric-value white">
{% if metrics and metrics.hashrate_60sec %}
{{ metrics.hashrate_60sec }}
{% if metrics.hashrate_60sec_unit %}
{{ metrics.hashrate_60sec_unit[:-2]|upper ~ metrics.hashrate_60sec_unit[-2:] }}
{% else %}
TH/s
{% endif %}
{% else %}
N/A
{% endif %}
</span>
<span id="indicator_hashrate_60sec"></span>
</p>
</div>
</div>
</div>
<div class="col-md-6">
<div class="card">
<div class="card-header">Bitcoin Network Stats</div>
<div class="card-body">
<p>
<strong>Block Number:</strong>
<span id="block_number" class="metric-value white">
{% if metrics and metrics.block_number %}
{{ metrics.block_number|commafy }}
{% else %}
N/A
{% endif %}
</span>
<span id="indicator_block_number"></span>
</p>
<p>
<strong>BTC Price:</strong>
<span id="btc_price" class="metric-value yellow">
{% if metrics and metrics.btc_price %}
${{ "%.2f"|format(metrics.btc_price) }}
{% else %}
$0.00
{% endif %}
</span>
<span id="indicator_btc_price"></span>
</p>
<p>
<strong>Network Hashrate:</strong>
<span id="network_hashrate" class="metric-value white">
{% if metrics and metrics.network_hashrate %}
{{ metrics.network_hashrate|round|commafy }} EH/s
{% else %}
N/A
{% endif %}
</span>
<span id="indicator_network_hashrate"></span>
</p>
<p>
<strong>Difficulty:</strong>
<span id="difficulty" class="metric-value white">
{% if metrics and metrics.difficulty %}
{{ metrics.difficulty|round|commafy }}
{% else %}
N/A
{% endif %}
</span>
<span id="indicator_difficulty"></span>
</p>
</div>
</div>
</div>
</div>
<!-- Satoshi and USD Metrics -->
<div class="row equal-height">
<div class="col-md-6">
<div class="card">
<div class="card-header">Satoshi Metrics</div>
<div class="card-body">
<p>
<strong>Daily Mined (Net):</strong>
<span id="daily_mined_sats" class="metric-value yellow">
{% if metrics and metrics.daily_mined_sats %}
{{ metrics.daily_mined_sats|commafy }} sats
{% else %}
0 sats
{% endif %}
</span>
<span id="indicator_daily_mined_sats"></span>
</p>
<p>
<strong>Monthly Mined (Net):</strong>
<span id="monthly_mined_sats" class="metric-value yellow">
{% if metrics and metrics.monthly_mined_sats %}
{{ metrics.monthly_mined_sats|commafy }} sats
{% else %}
0 sats
{% endif %}
</span>
<span id="indicator_monthly_mined_sats"></span>
</p>
<p>
<strong>Est. Earnings/Day:</strong>
<span id="estimated_earnings_per_day_sats" class="metric-value yellow">
{% if metrics and metrics.estimated_earnings_per_day_sats %}
{{ metrics.estimated_earnings_per_day_sats|commafy }} sats
{% else %}
0 sats
{% endif %}
</span>
<span id="indicator_estimated_earnings_per_day_sats"></span>
</p>
<p>
<strong>Est. Earnings/Block:</strong>
<span id="estimated_earnings_next_block_sats" class="metric-value yellow">
{% if metrics and metrics.estimated_earnings_next_block_sats %}
{{ metrics.estimated_earnings_next_block_sats|commafy }} sats
{% else %}
0 sats
{% endif %}
</span>
<span id="indicator_estimated_earnings_next_block_sats"></span>
</p>
<p>
<strong>Est. Rewards in Window:</strong>
<span id="estimated_rewards_in_window_sats" class="metric-value yellow">
{% if metrics and metrics.estimated_rewards_in_window_sats %}
{{ metrics.estimated_rewards_in_window_sats|commafy }} sats
{% else %}
0 sats
{% endif %}
</span>
<span id="indicator_estimated_rewards_in_window_sats"></span>
</p>
</div>
</div>
</div>
<div class="col-md-6">
<div class="card">
<div class="card-header">USD Metrics</div>
<div class="card-body">
<p>
<strong>Daily Revenue:</strong>
<span id="daily_revenue" class="metric-value green">
{% if metrics and metrics.daily_revenue is defined and metrics.daily_revenue is not none %}
${{ "%.2f"|format(metrics.daily_revenue) }}
{% else %}
$0.00
{% endif %}
</span>
<span id="indicator_daily_revenue"></span>
</p>
<p>
<strong>Daily Power Cost:</strong>
<span id="daily_power_cost" class="metric-value red">
{% if metrics and metrics.daily_power_cost is defined and metrics.daily_power_cost is not none %}
${{ "%.2f"|format(metrics.daily_power_cost) }}
{% else %}
$0.00
{% endif %}
</span>
<span id="indicator_daily_power_cost"></span>
</p>
<p>
<strong>Daily Profit (USD):</strong>
<span id="daily_profit_usd" class="metric-value green">
{% if metrics and metrics.daily_profit_usd is defined and metrics.daily_profit_usd is not none %}
${{ "%.2f"|format(metrics.daily_profit_usd) }}
{% else %}
$0.00
{% endif %}
</span>
<span id="indicator_daily_profit_usd"></span>
</p>
<p>
<strong>Monthly Profit (USD):</strong>
<span id="monthly_profit_usd" class="metric-value green">
{% if metrics and metrics.monthly_profit_usd is defined and metrics.monthly_profit_usd is not none %}
${{ "%.2f"|format(metrics.monthly_profit_usd) }}
{% else %}
$0.00
{% endif %}
</span>
<span id="indicator_monthly_profit_usd"></span>
</p>
</div>
</div>
</div>
</div>
<!-- Payout & Misc -->
<div class="row">
<div class="col-12">
<div class="card" id="payoutMiscCard">
<div class="card-header">Payout &amp; Misc</div>
<div class="card-body">
<p>
<strong>Unpaid Earnings:</strong>
<span id="unpaid_earnings" class="metric-value green">
{% if metrics and metrics.unpaid_earnings %}
{{ metrics.unpaid_earnings }} BTC
{% else %}
0 BTC
{% endif %}
</span>
<span id="indicator_unpaid_earnings"></span>
</p>
<p>
<strong>Last Block:</strong>
<span id="last_block_height" class="metric-value white">
{{ metrics.last_block_height if metrics and metrics.last_block_height else "N/A" }}
</span>
<span id="last_block_time" class="metric-value blue">
{{ metrics.last_block_time if metrics and metrics.last_block_time else "N/A" }}
</span>
<span class="green">
{% if metrics and metrics.last_block_earnings %}
+{{ metrics.last_block_earnings|int|commafy }} sats
{% else %}
+0 sats
{% endif %}
</span>
<span id="indicator_last_block"></span>
</p>
<p>
<strong>Est. Time to Payout:</strong>
<span id="est_time_to_payout" class="metric-value yellow">
{{ metrics.est_time_to_payout if metrics and metrics.est_time_to_payout else "N/A" }}
</span>
<span id="indicator_est_time_to_payout"></span>
</p>
<p>
<strong>Blocks Found:</strong>
<span id="blocks_found" class="metric-value white">
{{ metrics.blocks_found if metrics and metrics.blocks_found else "0" }}
</span>
<span id="indicator_blocks_found"></span>
</p>
</div>
</div>
</div>
</div>
{% endblock %}
{% block javascript %}
<!-- External JavaScript file with our application logic -->
<script src="/static/js/main.js"></script>
{% endblock %}

View File

@ -1,22 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Error - Mining Dashboard</title>
<!-- Include both Orbitron and VT323 fonts -->
<link href="https://fonts.googleapis.com/css2?family=Orbitron:wght@400;700&family=VT323&display=swap" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="/static/css/error.css">
</head>
<body>
<div class="container">
<div class="error-container">
<h1>ERROR</h1>
<div class="error-code">CODE: SYS_EXCEPTION_0x45</div>
<p>{{ message }}<span class="terminal-cursor"></span></p>
<a href="/" class="btn btn-primary">Return to Dashboard</a>
</div>
</div>
</body>
</html>

View File

@ -1,94 +0,0 @@
{% extends "base.html" %}
{% block title %}Notifications - Ocean.xyz Mining Dashboard{% endblock %}
{% block css %}
<link rel="stylesheet" href="/static/css/notifications.css">
{% endblock %}
{% block header %}Notification Center{% endblock %}
{% block notifications_active %}active{% endblock %}
{% block content %}
<!-- Notification Controls -->
<div class="row mb-2">
<div class="col-12">
<div class="card">
<div class="card-header">Notification Controls</div>
<div class="card-body">
<div class="notification-controls">
<div class="filter-buttons">
<button class="filter-button active" data-filter="all">All</button>
<button class="filter-button" data-filter="hashrate">Hashrate</button>
<button class="filter-button" data-filter="block">Blocks</button>
<button class="filter-button" data-filter="worker">Workers</button>
<button class="filter-button" data-filter="earnings">Earnings</button>
<button class="filter-button" data-filter="system">System</button>
</div>
<div class="notification-actions">
<button id="mark-all-read" class="action-button">Mark All as Read</button>
<button id="clear-read" class="action-button">Clear Read Notifications</button>
<button id="clear-all" class="action-button danger">Clear All</button>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Notifications List -->
<div class="row">
<div class="col-12">
<div class="card">
<div class="card-header">
<span>Notifications</span>
<span id="unread-badge" class="unread-badge">0</span>
</div>
<div class="card-body">
<div id="notifications-container">
<!-- Notifications will be populated here by JavaScript -->
<div class="loading-message">Loading notifications<span class="terminal-cursor"></span></div>
</div>
<!-- Pagination -->
<div class="pagination-controls">
<button id="load-more" class="load-more-button">Load More</button>
</div>
</div>
</div>
</div>
</div>
<!-- Empty State Template (hidden) -->
<div id="empty-template" style="display:none;">
<div class="empty-state">
<i class="fas fa-bell-slash"></i>
<p>No notifications to display</p>
</div>
</div>
<!-- Notification Template (hidden) -->
<div id="notification-template" style="display:none;">
<div class="notification-item" data-id="">
<div class="notification-icon">
<i class="fas"></i>
</div>
<div class="notification-content">
<div class="notification-message"></div>
<div class="notification-meta">
<span class="notification-time"></span>
<span class="notification-category"></span>
</div>
</div>
<div class="notification-actions">
<button class="mark-read-button"><i class="fas fa-check"></i></button>
<button class="delete-button"><i class="fas fa-trash"></i></button>
</div>
</div>
</div>
{% endblock %}
{% block javascript %}
<script src="/static/js/notifications.js"></script>
{% endblock %}

View File

@ -1,109 +0,0 @@
{% extends "base.html" %}
{% block title %}Workers Overview - Ocean.xyz Pool Mining Dashboard{% endblock %}
{% block css %}
<link rel="stylesheet" href="/static/css/workers.css">
{% endblock %}
{% block header %}Workers Overview{% endblock %}
{% block workers_active %}active{% endblock %}
{% block content %}
<!-- Summary statistics -->
<div class="row mb-3">
<div class="col-md-12">
<div class="card">
<div class="card-header">Miner Summary</div>
<div class="card-body">
<div class="summary-stats">
<div class="summary-stat">
<div class="worker-ring" style="--online-percent: {{ workers_online / workers_total if workers_total > 0 else 0 }}">
<div class="worker-ring-inner">
<span id="workers-count">{{ workers_total }}</span>
</div>
</div>
<div class="summary-stat-label">Workers</div>
<div>
<span class="green-glow" id="workers-online">{{ workers_online }}</span> /
<span class="red-glow" id="workers-offline">{{ workers_offline }}</span>
</div>
</div>
<div class="summary-stat">
<div class="summary-stat-value white-glow" id="total-hashrate">
{% if total_hashrate is defined %}
{{ "%.1f"|format(total_hashrate) }} {{ hashrate_unit }}
{% else %}
N/A
{% endif %}
</div>
<div class="summary-stat-label">Total Hashrate</div>
<div class="mini-chart">
<canvas id="total-hashrate-chart"></canvas>
</div>
</div>
<div class="summary-stat">
<div class="summary-stat-value green-glow" id="total-earnings">
{% if total_earnings is defined %}
{{ "%.8f"|format(total_earnings) }} BTC
{% else %}
N/A
{% endif %}
</div>
<div class="summary-stat-label">Unpaid Earnings</div>
</div>
<div class="summary-stat">
<div class="summary-stat-value yellow-glow" id="daily-sats">
{% if daily_sats is defined %}
{{ daily_sats|commafy }} sats
{% else %}
N/A
{% endif %}
</div>
<div class="summary-stat-label">Daily Sats</div>
</div>
<div class="summary-stat">
<div class="summary-stat-value white-glow" id="avg-acceptance-rate">
{% if avg_acceptance_rate is defined %}
{{ "%.2f"|format(avg_acceptance_rate) }}%
{% else %}
N/A
{% endif %}
</div>
<div class="summary-stat-label">Acceptance Rate</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Controls bar -->
<div class="controls-bar">
<input type="text" class="search-box" id="worker-search" placeholder="Search workers...">
<div class="filter-buttons">
<button class="filter-button active" data-filter="all">All Workers</button>
<button class="filter-button" data-filter="online">Online</button>
<button class="filter-button" data-filter="offline">Offline</button>
<button class="filter-button" data-filter="asic">ASIC</button>
<button class="filter-button" data-filter="bitaxe">Bitaxe</button>
</div>
</div>
<!-- Workers grid -->
<div class="worker-grid" id="worker-grid">
<!-- Worker cards will be generated here via JavaScript -->
<div id="loader" class="text-center p-5" style="display:none;">
<i class="fas fa-spinner fa-spin"></i> Loading worker data...
</div>
</div>
{% endblock %}
{% block javascript %}
<script src="/static/js/workers.js"></script>
{% endblock %}