secubox-openwrt/package/secubox/luci-app-haproxy/htdocs/luci-static/resources/haproxy/dashboard.css
CyberMind-FR f3fd676ad1 feat(haproxy): Add HAProxy load balancer packages for OpenWrt
- Add secubox-app-haproxy: LXC-containerized HAProxy service
  - Alpine Linux container with HAProxy
  - Multi-certificate SSL/TLS termination with SNI routing
  - ACME/Let's Encrypt auto-renewal
  - Virtual hosts management
  - Backend health checks and load balancing

- Add luci-app-haproxy: Full LuCI web interface
  - Overview dashboard with service status
  - Virtual hosts management with SSL options
  - Backends and servers configuration
  - SSL certificate management (ACME + import)
  - ACLs and URL-based routing rules
  - Statistics dashboard and logs
  - Settings for ports, timeouts, ACME

- Update luci-app-secubox-portal:
  - Add Services category with HAProxy, HexoJS, PicoBrew,
    Tor Shield, Jellyfin, Home Assistant, AdGuard Home, Nextcloud
  - Make portal dynamic - only shows installed apps
  - Add empty state UI for sections with no apps
  - Remove 404 errors for uninstalled apps

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-23 20:09:32 +01:00

316 lines
5.5 KiB
CSS

/* HAProxy Dashboard Styles */
.haproxy-dashboard {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
gap: 1rem;
margin-bottom: 1.5rem;
}
.haproxy-card {
background: var(--background-color-high, #fff);
border: 1px solid var(--border-color-medium, #ddd);
border-radius: 8px;
padding: 1.25rem;
box-shadow: 0 2px 4px rgba(0,0,0,0.05);
}
.haproxy-card h3 {
margin: 0 0 1rem 0;
font-size: 1rem;
color: var(--text-color-medium, #666);
font-weight: 500;
}
.haproxy-card .stat-value {
font-size: 2rem;
font-weight: 700;
color: var(--text-color-high, #333);
}
.haproxy-card .stat-label {
font-size: 0.875rem;
color: var(--text-color-medium, #666);
margin-top: 0.25rem;
}
.haproxy-status {
display: flex;
align-items: center;
gap: 0.5rem;
}
.haproxy-status-indicator {
width: 12px;
height: 12px;
border-radius: 50%;
flex-shrink: 0;
}
.haproxy-status-indicator.running {
background: #22c55e;
box-shadow: 0 0 8px rgba(34, 197, 94, 0.5);
}
.haproxy-status-indicator.stopped {
background: #ef4444;
}
.haproxy-status-indicator.unknown {
background: #f59e0b;
}
.haproxy-actions {
display: flex;
gap: 0.5rem;
flex-wrap: wrap;
margin-top: 1rem;
}
.haproxy-actions .cbi-button {
padding: 0.5rem 1rem;
}
/* Vhost table styles */
.haproxy-vhosts-table {
width: 100%;
border-collapse: collapse;
margin-top: 1rem;
}
.haproxy-vhosts-table th,
.haproxy-vhosts-table td {
padding: 0.75rem;
text-align: left;
border-bottom: 1px solid var(--border-color-low, #eee);
}
.haproxy-vhosts-table th {
font-weight: 600;
color: var(--text-color-medium, #666);
background: var(--background-color-low, #f9f9f9);
}
.haproxy-vhosts-table tr:hover td {
background: var(--background-color-low, #f9f9f9);
}
.haproxy-badge {
display: inline-block;
padding: 0.25rem 0.5rem;
border-radius: 4px;
font-size: 0.75rem;
font-weight: 500;
}
.haproxy-badge.ssl {
background: #dbeafe;
color: #1d4ed8;
}
.haproxy-badge.acme {
background: #dcfce7;
color: #166534;
}
.haproxy-badge.enabled {
background: #dcfce7;
color: #166534;
}
.haproxy-badge.disabled {
background: #fee2e2;
color: #991b1b;
}
/* Backend cards */
.haproxy-backends-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
gap: 1rem;
margin-top: 1rem;
}
.haproxy-backend-card {
background: var(--background-color-high, #fff);
border: 1px solid var(--border-color-medium, #ddd);
border-radius: 8px;
overflow: hidden;
}
.haproxy-backend-header {
padding: 1rem;
background: var(--background-color-low, #f9f9f9);
border-bottom: 1px solid var(--border-color-low, #eee);
display: flex;
justify-content: space-between;
align-items: center;
}
.haproxy-backend-header h4 {
margin: 0;
font-size: 1rem;
}
.haproxy-backend-servers {
padding: 0.5rem 0;
}
.haproxy-server-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 0.75rem 1rem;
border-bottom: 1px solid var(--border-color-low, #eee);
}
.haproxy-server-item:last-child {
border-bottom: none;
}
.haproxy-server-info {
display: flex;
flex-direction: column;
}
.haproxy-server-name {
font-weight: 500;
}
.haproxy-server-address {
font-size: 0.875rem;
color: var(--text-color-medium, #666);
font-family: monospace;
}
.haproxy-server-status {
display: flex;
align-items: center;
gap: 0.5rem;
}
.haproxy-server-weight {
font-size: 0.75rem;
background: var(--background-color-low, #f5f5f5);
padding: 0.25rem 0.5rem;
border-radius: 4px;
}
/* Certificate list */
.haproxy-cert-list {
margin-top: 1rem;
}
.haproxy-cert-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 1rem;
background: var(--background-color-high, #fff);
border: 1px solid var(--border-color-medium, #ddd);
border-radius: 8px;
margin-bottom: 0.5rem;
}
.haproxy-cert-domain {
font-weight: 500;
font-family: monospace;
}
.haproxy-cert-type {
font-size: 0.875rem;
color: var(--text-color-medium, #666);
}
/* Form sections */
.haproxy-form-section {
background: var(--background-color-high, #fff);
border: 1px solid var(--border-color-medium, #ddd);
border-radius: 8px;
padding: 1.5rem;
margin-bottom: 1rem;
}
.haproxy-form-section h3 {
margin: 0 0 1rem 0;
padding-bottom: 0.5rem;
border-bottom: 1px solid var(--border-color-low, #eee);
}
/* Stats iframe */
.haproxy-stats-frame {
width: 100%;
height: 600px;
border: 1px solid var(--border-color-medium, #ddd);
border-radius: 8px;
}
/* Logs viewer */
.haproxy-logs {
background: #1e1e1e;
color: #d4d4d4;
font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
font-size: 0.8125rem;
line-height: 1.5;
padding: 1rem;
border-radius: 8px;
max-height: 400px;
overflow: auto;
white-space: pre-wrap;
word-wrap: break-word;
}
/* Modal styles */
.haproxy-modal {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.5);
display: flex;
align-items: center;
justify-content: center;
z-index: 1000;
}
.haproxy-modal-content {
background: var(--background-color-high, #fff);
border-radius: 8px;
padding: 1.5rem;
max-width: 500px;
width: 90%;
max-height: 80vh;
overflow-y: auto;
}
.haproxy-modal-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 1rem;
}
.haproxy-modal-header h3 {
margin: 0;
}
.haproxy-modal-close {
background: none;
border: none;
font-size: 1.5rem;
cursor: pointer;
color: var(--text-color-medium, #666);
}
/* Responsive adjustments */
@media (max-width: 768px) {
.haproxy-dashboard {
grid-template-columns: 1fr;
}
.haproxy-backends-grid {
grid-template-columns: 1fr;
}
}