anycoder-ebe8fc62 / index.html
Re2906's picture
Upload folder using huggingface_hub
d3c0da4 verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Firely Server Deployment Dashboard</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<style>
:root {
--primary: #4a90e2;
--primary-dark: #357abd;
--secondary: #50c878;
--danger: #e74c3c;
--warning: #f39c12;
--dark: #2c3e50;
--darker: #1a252f;
--light: #ecf0f1;
--white: #ffffff;
--gray: #95a5a6;
--success: #27ae60;
--info: #3498db;
--border-radius: 12px;
--transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
--shadow: 0 10px 40px rgba(0, 0, 0, 0.1);
--shadow-lg: 0 20px 60px rgba(0, 0, 0, 0.15);
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
color: var(--dark);
position: relative;
}
body::before {
content: '';
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1440 320"><path fill="%23ffffff" fill-opacity="0.05" d="M0,96L48,112C96,128,192,160,288,165.3C384,171,480,149,576,138.7C672,128,768,128,864,138.7C960,149,1056,171,1152,165.3C1248,160,1344,128,1392,112L1440,96L1440,320L1392,320C1344,320,1248,320,1152,320C1056,320,960,320,864,320C768,320,672,320,576,320C480,320,384,320,288,320C192,320,96,320,48,320L0,320Z"></path></svg>') no-repeat bottom;
background-size: cover;
pointer-events: none;
z-index: -1;
}
.container {
max-width: 1400px;
margin: 0 auto;
padding: 20px;
}
header {
background: rgba(255, 255, 255, 0.95);
backdrop-filter: blur(10px);
border-radius: var(--border-radius);
padding: 30px;
margin-bottom: 30px;
box-shadow: var(--shadow);
animation: slideDown 0.5s ease-out;
}
@keyframes slideDown {
from {
opacity: 0;
transform: translateY(-20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.header-content {
display: flex;
justify-content: space-between;
align-items: center;
flex-wrap: wrap;
gap: 20px;
}
.logo {
display: flex;
align-items: center;
gap: 15px;
}
.logo i {
font-size: 2.5rem;
color: var(--primary);
animation: pulse 2s infinite;
}
@keyframes pulse {
0%, 100% { transform: scale(1); }
50% { transform: scale(1.05); }
}
.logo h1 {
font-size: 1.8rem;
background: linear-gradient(135deg, var(--primary), var(--secondary));
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
.status-indicators {
display: flex;
gap: 20px;
align-items: center;
}
.status-badge {
display: flex;
align-items: center;
gap: 8px;
padding: 8px 16px;
background: var(--white);
border-radius: 20px;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
transition: var(--transition);
}
.status-badge:hover {
transform: translateY(-2px);
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
}
.status-dot {
width: 10px;
height: 10px;
border-radius: 50%;
animation: blink 2s infinite;
}
.status-dot.online { background: var(--success); }
.status-dot.offline { background: var(--danger); }
.status-dot.warning { background: var(--warning); }
@keyframes blink {
0%, 100% { opacity: 1; }
50% { opacity: 0.5; }
}
.main-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 20px;
margin-bottom: 30px;
}
.card {
background: rgba(255, 255, 255, 0.95);
backdrop-filter: blur(10px);
border-radius: var(--border-radius);
padding: 25px;
box-shadow: var(--shadow);
transition: var(--transition);
animation: fadeInUp 0.5s ease-out forwards;
opacity: 0;
}
.card:nth-child(1) { animation-delay: 0.1s; }
.card:nth-child(2) { animation-delay: 0.2s; }
.card:nth-child(3) { animation-delay: 0.3s; }
.card:nth-child(4) { animation-delay: 0.4s; }
@keyframes fadeInUp {
from {
opacity: 0;
transform: translateY(20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.card:hover {
transform: translateY(-5px);
box-shadow: var(--shadow-lg);
}
.card-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
padding-bottom: 15px;
border-bottom: 2px solid var(--light);
}
.card-title {
font-size: 1.2rem;
font-weight: 600;
color: var(--dark);
display: flex;
align-items: center;
gap: 10px;
}
.card-title i {
color: var(--primary);
}
.metric-value {
font-size: 2rem;
font-weight: bold;
color: var(--primary);
margin: 10px 0;
}
.metric-label {
color: var(--gray);
font-size: 0.9rem;
}
.progress-bar {
width: 100%;
height: 8px;
background: var(--light);
border-radius: 4px;
overflow: hidden;
margin: 10px 0;
}
.progress-fill {
height: 100%;
background: linear-gradient(90deg, var(--primary), var(--secondary));
border-radius: 4px;
transition: width 0.5s ease-out;
}
.deployment-form {
background: rgba(255, 255, 255, 0.95);
backdrop-filter: blur(10px);
border-radius: var(--border-radius);
padding: 30px;
box-shadow: var(--shadow);
margin-bottom: 30px;
}
.form-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 20px;
margin-bottom: 20px;
}
.form-group {
display: flex;
flex-direction: column;
}
.form-label {
font-weight: 600;
margin-bottom: 8px;
color: var(--dark);
display: flex;
align-items: center;
gap: 5px;
}
.form-label i {
font-size: 0.9rem;
color: var(--gray);
}
.form-control {
padding: 12px 15px;
border: 2px solid var(--light);
border-radius: 8px;
font-size: 1rem;
transition: var(--transition);
background: var(--white);
}
.form-control:focus {
outline: none;
border-color: var(--primary);
box-shadow: 0 0 0 3px rgba(74, 144, 226, 0.1);
}
.form-control.error {
border-color: var(--danger);
}
.error-message {
color: var(--danger);
font-size: 0.85rem;
margin-top: 5px;
display: none;
}
.btn {
padding: 12px 24px;
border: none;
border-radius: 8px;
font-size: 1rem;
font-weight: 600;
cursor: pointer;
transition: var(--transition);
display: inline-flex;
align-items: center;
gap: 8px;
}
.btn-primary {
background: linear-gradient(135deg, var(--primary), var(--primary-dark));
color: var(--white);
}
.btn-primary:hover {
transform: translateY(-2px);
box-shadow: 0 10px 20px rgba(74, 144, 226, 0.3);
}
.btn-success {
background: linear-gradient(135deg, var(--success), #229954);
color: var(--white);
}
.btn-danger {
background: linear-gradient(135deg, var(--danger), #c0392b);
color: var(--white);
}
.btn:disabled {
opacity: 0.5;
cursor: not-allowed;
}
.tabs {
display: flex;
gap: 10px;
margin-bottom: 20px;
border-bottom: 2px solid var(--light);
overflow-x: auto;
}
.tab {
padding: 12px 20px;
background: transparent;
border: none;
border-bottom: 3px solid transparent;
color: var(--gray);
font-weight: 600;
cursor: pointer;
transition: var(--transition);
white-space: nowrap;
}
.tab:hover {
color: var(--primary);
}
.tab.active {
color: var(--primary);
border-bottom-color: var(--primary);
}
.tab-content {
display: none;
animation: fadeIn 0.3s ease-out;
}
.tab-content.active {
display: block;
}
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
.log-viewer {
background: var(--darker);
color: var(--light);
padding: 20px;
border-radius: 8px;
font-family: 'Courier New', monospace;
font-size: 0.9rem;
max-height: 400px;
overflow-y: auto;
margin-top: 20px;
}
.log-entry {
margin-bottom: 5px;
padding: 5px;
border-radius: 4px;
transition: var(--transition);
}
.log-entry:hover {
background: rgba(255, 255, 255, 0.05);
}
.log-timestamp {
color: var(--gray);
margin-right: 10px;
}
.log-level {
padding: 2px 6px;
border-radius: 4px;
font-size: 0.8rem;
font-weight: bold;
margin-right: 10px;
}
.log-level.info { background: var(--info); }
.log-level.success { background: var(--success); }
.log-level.warning { background: var(--warning); }
.log-level.error { background: var(--danger); }
.health-check {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 15px;
margin-top: 20px;
}
.health-item {
padding: 15px;
background: var(--light);
border-radius: 8px;
display: flex;
align-items: center;
gap: 10px;
transition: var(--transition);
}
.health-item:hover {
transform: translateX(5px);
}
.health-icon {
font-size: 1.5rem;
}
.health-icon.healthy { color: var(--success); }
.health-icon.unhealthy { color: var(--danger); }
.health-icon.checking { color: var(--warning); }
.modal {
display: none;
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.5);
backdrop-filter: blur(5px);
z-index: 1000;
animation: fadeIn 0.3s ease-out;
}
.modal.active {
display: flex;
align-items: center;
justify-content: center;
}
.modal-content {
background: var(--white);
border-radius: var(--border-radius);
padding: 30px;
max-width: 500px;
width: 90%;
max-height: 90vh;
overflow-y: auto;
animation: slideUp 0.3s ease-out;
}
@keyframes slideUp {
from {
opacity: 0;
transform: translateY(20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.modal-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
}
.modal-title {
font-size: 1.5rem;
font-weight: bold;
}
.modal-close {
background: none;
border: none;
font-size: 1.5rem;
cursor: pointer;
color: var(--gray);
transition: var(--transition);
}
.modal-close:hover {
color: var(--danger);
}
.spinner {
border: 3px solid var(--light);
border-top: 3px solid var(--primary);
border-radius: 50%;
width: 40px;
height: 40px;
animation: spin 1s linear infinite;
margin: 20px auto;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
.toast {
position: fixed;
bottom: 20px;
right: 20px;
padding: 15px 20px;
background: var(--white);
border-radius: 8px;
box-shadow: var(--shadow);
display: flex;
align-items: center;
gap: 10px;
transform: translateX(400px);
transition: transform 0.3s ease-out;
z-index: 2000;
}
.toast.show {
transform: translateX(0);
}
.toast.success { border-left: 4px solid var(--success); }
.toast.error { border-left: 4px solid var(--danger); }
.toast.warning { border-left: 4px solid var(--warning); }
.toast.info { border-left: 4px solid var(--info); }
.chart-container {
position: relative;
height: 300px;
margin-top: 20px;
}
.environment-selector {
display: flex;
gap: 10px;
margin-bottom: 20px;
}
.env-btn {
padding: 10px 20px;
border: 2px solid var(--light);
background: var(--white);
border-radius: 8px;
cursor: pointer;
transition: var(--transition);
font-weight: 600;
}
.env-btn:hover {
border-color: var(--primary);
transform: translateY(-2px);
}
.env-btn.active {
background: var(--primary);
color: var(--white);
border-color: var(--primary);
}
.secret-input {
position: relative;
}
.secret-toggle {
position: absolute;
right: 10px;
top: 50%;
transform: translateY(-50%);
background: none;
border: none;
color: var(--gray);
cursor: pointer;
}
.deployment-history {
margin-top: 20px;
}
.history-item {
padding: 15px;
background: var(--light);
border-radius: 8px;
margin-bottom: 10px;
display: flex;
justify-content: space-between;
align-items: center;
transition: var(--transition);
}
.history-item:hover {
background: #e8ecef;
transform: translateX(5px);
}
.history-status {
padding: 4px 12px;
border-radius: 20px;
font-size: 0.85rem;
font-weight: 600;
}
.history-status.success {
background: var(--success);
color: var(--white);
}
.history-status.failed {
background: var(--danger);
color: var(--white);
}
.history-status.running {
background: var(--warning);
color: var(--white);
}
@media (max-width: 768px) {
.container {
padding: 10px;
}
.header-content {
flex-direction: column;
text-align: center;
}
.status-indicators {
flex-wrap: wrap;
justify-content: center;
}
.form-grid {
grid-template-columns: 1fr;
}
.tabs {
flex-wrap: nowrap;
overflow-x: scroll;
}
.modal-content {
padding: 20px;
}
}
.footer {
text-align: center;
padding: 20px;
color: var(--white);
margin-top: 40px;
}
.footer a {
color: var(--white);
text-decoration: none;
font-weight: 600;
transition: var(--transition);
}
.footer a:hover {
text-decoration: underline;
}
</style>
</head>
<body>
<div class="container">
<header>
<div class="header-content">
<div class="logo">
<i class="fas fa-server"></i>
<h1>Firely Server Deployment Dashboard</h1>
</div>
<div class="status-indicators">
<div class="status-badge">
<span class="status-dot online"></span>
<span>Docker: Online</span>
</div>
<div class="status-badge">
<span class="status-dot online"></span>
<span>Environment: <span id="currentEnv">Dev</span></span>
</div>
<div class="status-badge">
<i class="fas fa-clock"></i>
<span id="currentTime"></span>
</div>
</div>
</div>
</header>
<div class="main-grid">
<div class="card">
<div class="card-header">
<div class="card-title">
<i class="fas fa-rocket"></i>
Deployments
</div>
<span class="metric-value" id="deploymentCount">0</span>
</div>
<div class="metric-label">Total Deployments</div>
<div class="progress-bar">
<div class="progress-fill" style="width: 75%"></div>
</div>
<div class="metric-label" style="margin-top: 10px;">Success Rate: 75%</div>
</div>
<div class="card">
<div class="card-header">
<div class="card-title">
<i class="fas fa-heartbeat"></i>
Health Status
</div>
<i class="fas fa-check-circle" style="color: var(--success);"></i>
</div>
<div class="metric-value">100%</div>
<div class="metric-label">Services Healthy</div>
<div class="health-check">
<div class="health-item">
<i class="fas fa-database health-icon healthy"></i>
<span>Database</span>
</div>
<div class="health-item">
<i class="fas fa-network-wired health-icon healthy"></i>
<span>API</span>
</div>
</div>
</div>
<div class="card">
<div class="card-header">
<div class="card-title">
<i class="fas fa-memory"></i>
Resource Usage
</div>
<i class="fas fa-chart-line" style="color: var(--info);"></i>
</div>
<div class="metric-value">2.4 GB</div>
<div class="metric-label">Memory Used</div>
<div class="progress-bar">
<div class="progress-fill" style="width: 60%"></div>
</div>
<div class="metric-label" style="margin-top: 10px;">CPU: 45%</div>
</div>
<div class="card">
<div class="card-header">
<div class="card-title">
<i class="fas fa-shield-alt"></i>
Security
</div>
<i class="fas fa-lock" style="color: var(--success);"></i>
</div>
<div class="metric-value">Enabled</div>
<div class="metric-label">HTTPS Active</div>
<div class="progress-bar">
<div class="progress-fill" style="width: 100%; background: var(--success)"></div>
</div>
<div class="metric-label" style="margin-top: 10px;">Certificate Valid</div>
</div>
</div>
<div class="deployment-form">
<div class="card-header">
<div class="card-title">
<i class="fas fa-cogs"></i>
Deployment Configuration
</div>
</div>
<div class="environment-selector">
<button class="env-btn active" data-env="Dev">
<i class="fas fa-flask"></i> Development
</button>
<button class="env-btn" data-env="Test">
<i class="fas fa-vial"></i> Testing
</button>
<button class="env-btn" data-env="Prod">
<i class="fas fa-industry"></i> Production
</button>
</div>
<form id="deploymentForm">
<div class="form-grid">
<div class="form-group">
<label class="form-label">
<i class="fas fa-file-contract"></i>
License File Path
</label>
<input type="text" class="form-control" id="licensePath"
placeholder="./config/licenses/firely-dev.lic" required>
<span class="error-message">License file is required</span>
</div>
<div class="form-group">
<label class="form-label">
<i class="fas fa-folder"></i>
Configuration Path
</label>
<input type="text" class="form-control" id="configPath"
placeholder="./config/dev" required>
<span class="error-message">Configuration path is required</span>
</div>
<div class="form-group">
<label class="form-label">
<i class="fas fa-plug"></i>
HTTP Port
</label>
<input type="number" class="form-control" id="httpPort"
value="8080" min="1" max="65535" required>
<span class="error-message">Valid port required</span>
</div>
<div class="form-group">
<label class="form-label">
<i class="fas fa-lock"></i>
HTTPS Port
</label>
<input type="number" class="form-control" id="httpsPort"
value="8443" min="1" max="65535" required>
<span class="error-message">Valid port required</span>
</div>
<div class="form-group">
<label class="form-label">
<i class="fas fa-fingerprint"></i>
Certificate Thumbprint
</label>
<input type="text" class="form-control" id="certThumbprint"
placeholder="Required for Production">
<span class="error-message">Certificate thumbprint required for Production</span>
</div>
<div class="form-group">
<label class="form-label">
<i class="fas fa-key"></i>
Database Password Secret
</label>
<div class="secret-input">
<input type="password" class="form-control" id="dbPasswordSecret"
placeholder="Secret name or value">
<button type="button" class="secret-toggle" onclick="toggleSecret('dbPasswordSecret')">
<i class="fas fa-eye"></i>
</button>
</div>
</div>
<div class="form-group">
<label class="form-label">
<i class="fas fa-user-shield"></i>
Auth Authority Secret
</label>
<div class="secret-input">
<input type="password" class="form-control" id="authAuthoritySecret"
placeholder="Secret name or URL">
<button type="button" class="secret-toggle" onclick="toggleSecret('authAuthoritySecret')">
<i class="fas fa-eye"></i>
</button>
</div>
</div>
<div class="form-group">
<label class="form-label">
<i class="fas fa-users"></i>
Auth Audience Secret
</label>
<div class="secret-input">
<input type="password" class="form-control" id="authAudienceSecret"
placeholder="Secret name or value">
<button type="button" class="secret-toggle" onclick="toggleSecret('authAudienceSecret')">
<i class="fas fa-eye"></i>
</button>
</div>
</div>
</div>
<div class="form-group" style="flex-direction: row; gap: 20px; margin-top: 20px;">
<label style="display: flex; align-items: center; gap: 8px;">
<input type="checkbox" id="withMonitoring">
<span>Enable Monitoring Stack (Prometheus, Grafana)</span>
</label>
<label style="display: flex; align-items: center; gap: 8px;">
<input type="checkbox" id="withSecurity">
<span>Enable Enhanced Security</span>
</label>
<label style="display: flex; align-items: center; gap: 8px;">
<input type="checkbox" id="forceDeploy">
<span>Force Deployment (overwrite)</span>
</label>
</div>
<div style="display: flex; gap: 10px; margin-top: 20px;">
<button type="submit" class="btn btn-primary">
<i class="fas fa-rocket"></i>
Deploy Firely Server
</button>
<button type="button" class="btn btn-success" onclick="validateConfiguration()">
<i class="fas fa-check"></i>
Validate Configuration
</button>
<button type="button" class="btn btn-danger" onclick="resetForm()">
<i class="fas fa-undo"></i>
Reset
</button>
</div>
</form>
</div>
<div class="card">
<div class="card-header">
<div class="card-title">
<i class="fas fa-tasks"></i>
Deployment Operations
</div>
</div>
<div class="tabs">
<button class="tab active" onclick="switchTab('logs')">
<i class="fas fa-file-alt"></i> Logs
</button>
<button class="tab" onclick="switchTab('monitoring')">
<i class="fas fa-chart-bar"></i> Monitoring
</button>
<button class="tab" onclick="switchTab('health')">
<i class="fas fa-heartbeat"></i> Health Checks
</button>
<button class="tab" onclick="switchTab('history')">
<i class="fas fa-history"></i> History
</button>
</div>
<div id="logs" class="tab-content active">
<div class="log-viewer" id="logViewer">
<div class="log-entry">
<span class="log-timestamp">2024-01-15 10:30:45</span>
<span class="log-level info">INFO</span>
<span>Initializing Firely Server Deployment Dashboard...</span>
</div>
<div class="log-entry">
<span class="log-timestamp">2024-01-15 10:30:46</span>
<span class="log-level success">SUCCESS</span>
<span>Docker daemon connected successfully</span>
</div>
<div class="log-entry">
<span class="log-timestamp">2024-01-15 10:30:47</span>
<span class="log-level info">INFO</span>
<span>Loading environment configuration for Dev</span>
</div>
<div class="log-entry">
<span class="log-timestamp">2024-01-15 10:30:48</span>
<span class="log-level success">SUCCESS</span>
<span>All dependencies verified and ready</span>
</div>
</div>
</div>
<div id="monitoring" class="tab-content">
<div class="chart-container">
<canvas id="performanceChart"></canvas>
</div>
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 15px; margin-top: 20px;">
<div class="health-item">
<i class="fas fa-tachometer-alt" style="color: var(--info);"></i>
<div>
<div>Response Time</div>
<strong>45ms</strong>
</div>
</div>
<div class="health-item">
<i class="fas fa-exchange-alt" style="color: var(--success);"></i>
<div>
<div>Requests/sec</div>
<strong>234</strong>
</div>
</div>
<div class="health-item">
<i class="fas fa-hdd" style="color: var(--warning);"></i>
<div>
<div>Disk Usage</div>
<strong>67%</strong>
</div>
</div>
<div class="health-item">
<i class="fas fa-network-wired" style="color: var(--primary);"></i>
<div>
<div>Network I/O</div>
<strong>12 MB/s</strong>
</div>
</div>
</div>
</div>
<div id="health" class="tab-content">
<div class="health-check">
<div class="health-item">
<i class="fas fa-database health-icon healthy"></i>
<div>
<div>PostgreSQL</div>
<strong>Healthy</strong>
</div>
</div>
<div class="health-item">
<i class="fas fa-server health-icon healthy"></i>
<div>
<div>Firely Server</div>
<strong>Running</strong>
</div>
</div>
<div class="health-item">
<i class="fas fa-chart-line health-icon healthy"></i>
<div>
<div>Prometheus</div>
<strong>Active</strong>
</div>
</div>
<div class="health-item">
<i class="fas fa-chart-pie health-icon healthy"></i>
<div>
<div>Grafana</div>
<strong>Available</strong>
</div>
</div>
<div class="health-item">
<i class="fas fa-lock health-icon healthy"></i>
<div>
<div>SSL Certificate</div>
<strong>Valid</strong>
</div>
</div>
<div class="health-item">
<i class="fas fa-memory health-icon checking"></i>
<div>
<div>Memory Check</div>
<strong>Checking...</strong>
</div>
</div>
</div>
</div>
<div id="history" class="tab-content">
<div class="deployment-history" id="deploymentHistory">
<div class="history-item">
<div>
<strong>Deployment #1234</strong>
<div style="color: var(--gray); font-size: 0.9rem;">
Environment: Prod | Time: 2024-01-15 09:15:30
</div>
</div>
<span class="history-status success">Success</span>
</div>
<div class="history-item">
<div>
<strong>Deployment #1233</strong>
<div style="color: var(--gray); font-size: 0.9rem;">
Environment: Test | Time: 2024-01-15 08:45:12
</div>
</div>
<span class="history-status success">Success</span>
</div>
<div class="history-item">
<div>
<strong>Deployment #1232</strong>
<div style="color: var(--gray); font-size: 0.9