<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Hammerwork Dashboard</title>
<link rel="stylesheet" href="/static/dashboard.css">
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
</head>
<body>
<div class="dashboard">
<header class="header">
<div class="header-content">
<h1>🔨 Hammerwork Dashboard</h1>
<div class="header-actions">
<span id="connectionStatus" class="status-indicator">Connected</span>
<button id="refreshBtn" class="btn btn-secondary">Refresh</button>
</div>
</div>
</header>
<main class="main-content">
<section class="overview-section">
<h2>System Overview</h2>
<div class="cards-grid">
<div class="card metric-card">
<div class="card-header">
<h3>Total Jobs</h3>
<span class="card-icon">📊</span>
</div>
<div class="card-value" id="totalJobs">-</div>
<div class="card-subtitle">All time</div>
</div>
<div class="card metric-card">
<div class="card-header">
<h3>Pending</h3>
<span class="card-icon">⏳</span>
</div>
<div class="card-value" id="pendingJobs">-</div>
<div class="card-subtitle">Waiting to process</div>
</div>
<div class="card metric-card">
<div class="card-header">
<h3>Running</h3>
<span class="card-icon">⚡</span>
</div>
<div class="card-value" id="runningJobs">-</div>
<div class="card-subtitle">Currently processing</div>
</div>
<div class="card metric-card">
<div class="card-header">
<h3>Error Rate</h3>
<span class="card-icon">🚨</span>
</div>
<div class="card-value" id="errorRate">-</div>
<div class="card-subtitle">Last 24 hours</div>
</div>
<div class="card metric-card">
<div class="card-header">
<h3>Throughput</h3>
<span class="card-icon">📈</span>
</div>
<div class="card-value" id="throughput">-</div>
<div class="card-subtitle">Jobs per minute</div>
</div>
<div class="card metric-card">
<div class="card-header">
<h3>Avg. Processing</h3>
<span class="card-icon">⏱️</span>
</div>
<div class="card-value" id="avgProcessing">-</div>
<div class="card-subtitle">Milliseconds</div>
</div>
</div>
</section>
<section class="charts-section">
<div class="charts-grid">
<div class="card chart-card">
<div class="card-header">
<h3>Job Throughput</h3>
<select id="throughputPeriod" class="period-selector">
<option value="1h">Last Hour</option>
<option value="24h" selected>Last 24 Hours</option>
<option value="7d">Last 7 Days</option>
</select>
</div>
<div class="chart-container">
<canvas id="throughputChart"></canvas>
</div>
</div>
<div class="card chart-card">
<div class="card-header">
<h3>Queue Status</h3>
</div>
<div class="chart-container">
<canvas id="queueStatusChart"></canvas>
</div>
</div>
</div>
</section>
<section class="queues-section">
<div class="section-header">
<h2>Queues</h2>
<div class="section-actions">
<input type="text" id="queueSearch" placeholder="Search queues..." class="search-input">
<button id="addQueueBtn" class="btn btn-primary">+ Add Job</button>
</div>
</div>
<div class="card">
<div class="table-container">
<table class="data-table" id="queuesTable">
<thead>
<tr>
<th>Queue Name</th>
<th>Status</th>
<th>Pending</th>
<th>Running</th>
<th>Completed</th>
<th>Failed</th>
<th>Throughput</th>
<th>Error Rate</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<tr class="loading-row">
<td colspan="9">Loading queues...</td>
</tr>
</tbody>
</table>
</div>
</div>
</section>
<section class="jobs-section">
<div class="section-header">
<h2>Recent Jobs</h2>
<div class="section-actions">
<select id="jobStatusFilter" class="filter-select">
<option value="">All Statuses</option>
<option value="pending">Pending</option>
<option value="running">Running</option>
<option value="completed">Completed</option>
<option value="failed">Failed</option>
<option value="dead">Dead</option>
</select>
<select id="jobQueueFilter" class="filter-select">
<option value="">All Queues</option>
</select>
</div>
</div>
<div class="card">
<div class="table-container">
<table class="data-table" id="jobsTable">
<thead>
<tr>
<th>Job ID</th>
<th>Queue</th>
<th>Status</th>
<th>Priority</th>
<th>Attempts</th>
<th>Created</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<tr class="loading-row">
<td colspan="7">Loading jobs...</td>
</tr>
</tbody>
</table>
</div>
</div>
</section>
<section class="archive-section">
<div class="section-header">
<h2>Job Archive</h2>
<div class="section-actions">
<select id="archiveReasonFilter" class="filter-select">
<option value="">All Reasons</option>
<option value="automatic">Automatic</option>
<option value="manual">Manual</option>
<option value="compliance">Compliance</option>
<option value="maintenance">Maintenance</option>
</select>
<select id="archiveQueueFilter" class="filter-select">
<option value="">All Queues</option>
</select>
<button id="archiveJobsBtn" class="btn btn-primary">Archive Jobs</button>
<button id="archiveStatsBtn" class="btn btn-secondary">View Stats</button>
</div>
</div>
<div class="archive-stats-grid">
<div class="card metric-card">
<div class="card-header">
<h3>Total Archived</h3>
<span class="card-icon">🗄️</span>
</div>
<div class="card-value" id="totalArchived">-</div>
<div class="card-subtitle">All time</div>
</div>
<div class="card metric-card">
<div class="card-header">
<h3>Storage Saved</h3>
<span class="card-icon">💾</span>
</div>
<div class="card-value" id="storageSaved">-</div>
<div class="card-subtitle">Compression ratio</div>
</div>
<div class="card metric-card">
<div class="card-header">
<h3>Last Archive</h3>
<span class="card-icon">📅</span>
</div>
<div class="card-value" id="lastArchive">-</div>
<div class="card-subtitle">Most recent operation</div>
</div>
</div>
<div class="card">
<div class="table-container">
<table class="data-table" id="archivedJobsTable">
<thead>
<tr>
<th>Job ID</th>
<th>Queue</th>
<th>Original Status</th>
<th>Archived At</th>
<th>Reason</th>
<th>Size</th>
<th>Compressed</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<tr class="loading-row">
<td colspan="8">Loading archived jobs...</td>
</tr>
</tbody>
</table>
</div>
<div class="pagination-controls">
<button id="archivePrevPage" class="btn btn-secondary" disabled>Previous</button>
<span id="archivePageInfo">Page 1 of 1</span>
<button id="archiveNextPage" class="btn btn-secondary" disabled>Next</button>
</div>
</div>
</section>
</main>
</div>
<div id="jobModal" class="modal">
<div class="modal-content">
<div class="modal-header">
<h3>Job Details</h3>
<button class="modal-close">×</button>
</div>
<div class="modal-body">
<div id="jobDetails"></div>
</div>
<div class="modal-footer">
<button id="retryJobBtn" class="btn btn-primary">Retry Job</button>
<button id="deleteJobBtn" class="btn btn-danger">Delete Job</button>
<button class="btn btn-secondary modal-close">Close</button>
</div>
</div>
</div>
<div id="addJobModal" class="modal">
<div class="modal-content">
<div class="modal-header">
<h3>Add New Job</h3>
<button class="modal-close">×</button>
</div>
<div class="modal-body">
<form id="addJobForm">
<div class="form-group">
<label for="jobQueue">Queue Name</label>
<input type="text" id="jobQueue" required>
</div>
<div class="form-group">
<label for="jobPriority">Priority</label>
<select id="jobPriority">
<option value="background">Background</option>
<option value="low">Low</option>
<option value="normal" selected>Normal</option>
<option value="high">High</option>
<option value="critical">Critical</option>
</select>
</div>
<div class="form-group">
<label for="jobPayload">Payload (JSON)</label>
<textarea id="jobPayload" rows="6" placeholder='{"key": "value"}'></textarea>
</div>
<div class="form-group">
<label for="jobScheduledAt">Scheduled At (optional)</label>
<input type="datetime-local" id="jobScheduledAt">
</div>
</form>
</div>
<div class="modal-footer">
<button id="submitJobBtn" class="btn btn-primary">Add Job</button>
<button class="btn btn-secondary modal-close">Cancel</button>
</div>
</div>
</div>
<div id="archiveModal" class="modal">
<div class="modal-content">
<div class="modal-header">
<h3>Archive Jobs</h3>
<button class="modal-close">×</button>
</div>
<div class="modal-body">
<form id="archiveForm">
<div class="form-group">
<label for="archiveQueue">Queue (optional)</label>
<select id="archiveQueue">
<option value="">All Queues</option>
</select>
</div>
<div class="form-group">
<label for="archiveReason">Reason</label>
<select id="archiveReason" required>
<option value="manual">Manual</option>
<option value="automatic">Automatic</option>
<option value="compliance">Compliance</option>
<option value="maintenance">Maintenance</option>
</select>
</div>
<div class="form-group">
<label for="archivedBy">Archived By</label>
<input type="text" id="archivedBy" placeholder="admin">
</div>
<div class="form-group">
<label>
<input type="checkbox" id="archiveDryRun" checked> Dry Run (preview only)
</label>
</div>
<div class="form-group">
<h4>Archive Policy</h4>
<div class="policy-settings">
<label>
<input type="number" id="completedAfterDays" min="1" value="7">
Archive completed jobs after (days)
</label>
<label>
<input type="number" id="failedAfterDays" min="1" value="30">
Archive failed jobs after (days)
</label>
<label>
<input type="number" id="deadAfterDays" min="1" value="14">
Archive dead jobs after (days)
</label>
<label>
<input type="checkbox" id="compressPayloads" checked>
Compress payloads
</label>
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button id="submitArchiveBtn" class="btn btn-primary">Archive Jobs</button>
<button class="btn btn-secondary modal-close">Cancel</button>
</div>
</div>
</div>
<div id="archiveStatsModal" class="modal">
<div class="modal-content large">
<div class="modal-header">
<h3>Archive Statistics</h3>
<button class="modal-close">×</button>
</div>
<div class="modal-body">
<div id="archiveStatsContent">
<div class="stats-grid">
<div class="stat-item">
<h4>Jobs Archived</h4>
<span id="statsJobsArchived">-</span>
</div>
<div class="stat-item">
<h4>Jobs Purged</h4>
<span id="statsJobsPurged">-</span>
</div>
<div class="stat-item">
<h4>Bytes Archived</h4>
<span id="statsBytesArchived">-</span>
</div>
<div class="stat-item">
<h4>Compression Ratio</h4>
<span id="statsCompressionRatio">-</span>
</div>
<div class="stat-item">
<h4>Last Operation</h4>
<span id="statsLastRun">-</span>
</div>
<div class="stat-item">
<h4>Operation Duration</h4>
<span id="statsOperationDuration">-</span>
</div>
</div>
<div class="recent-operations">
<h4>Recent Operations</h4>
<div id="recentOperationsList">
<p>Loading recent operations...</p>
</div>
</div>
</div>
</div>
<div class="modal-footer">
<button id="purgeOldBtn" class="btn btn-warning">Purge Old Archives</button>
<button class="btn btn-secondary modal-close">Close</button>
</div>
</div>
</div>
<div id="restoreJobModal" class="modal">
<div class="modal-content">
<div class="modal-header">
<h3>Restore Archived Job</h3>
<button class="modal-close">×</button>
</div>
<div class="modal-body">
<p>Are you sure you want to restore this job back to the pending queue?</p>
<div id="restoreJobDetails"></div>
<form id="restoreForm">
<div class="form-group">
<label for="restoreReason">Reason (optional)</label>
<input type="text" id="restoreReason" placeholder="Data recovery, reprocessing needed, etc.">
</div>
<div class="form-group">
<label for="restoredBy">Restored By</label>
<input type="text" id="restoredBy" placeholder="admin">
</div>
</form>
</div>
<div class="modal-footer">
<button id="confirmRestoreBtn" class="btn btn-primary">Restore Job</button>
<button class="btn btn-secondary modal-close">Cancel</button>
</div>
</div>
</div>
<script src="/static/dashboard.js"></script>
</body>
</html>