216 lines
8.3 KiB
HTML
216 lines
8.3 KiB
HTML
<!-- Sidebar Navigation -->
|
|
<nav class="sidebar bg-dark border-end border-secondary position-fixed h-100" style="width: var(--sidebar-width); z-index: 1000;">
|
|
<div class="d-flex flex-column h-100">
|
|
<!-- Sidebar header -->
|
|
<div class="p-3 border-bottom border-secondary">
|
|
<h5 class="text-white mb-0">
|
|
<i class="bi bi-server me-2"></i>
|
|
SMTP Server
|
|
</h5>
|
|
<small class="text-muted">Management Console</small>
|
|
</div>
|
|
|
|
<!-- Navigation menu -->
|
|
<div class="flex-grow-1 overflow-auto">
|
|
<ul class="nav nav-pills flex-column p-3">
|
|
<!-- Dashboard -->
|
|
<li class="nav-item mb-2">
|
|
<a href="{{ url_for('email.dashboard') }}"
|
|
class="nav-link text-white {{ 'active' if request.endpoint == 'email.dashboard' else '' }}">
|
|
<i class="bi bi-speedometer2 me-2"></i>
|
|
Dashboard
|
|
</a>
|
|
</li>
|
|
|
|
<!-- Domains Section -->
|
|
<li class="nav-item mb-2">
|
|
<h6 class="text-muted text-uppercase small mb-2 mt-3">
|
|
<i class="bi bi-globe me-1"></i>
|
|
Email Server Management
|
|
</h6>
|
|
</li>
|
|
|
|
<li class="nav-item mb-1">
|
|
<a href="{{ url_for('email.domains_list') }}"
|
|
class="nav-link text-white {{ 'active' if request.endpoint in ['email.domains_list', 'email.add_domain'] else '' }}">
|
|
<i class="bi bi-list-ul me-2"></i>
|
|
Domains
|
|
<span class="badge bg-secondary ms-auto">{{ domain_count if domain_count is defined else '' }}</span>
|
|
</a>
|
|
</li>
|
|
|
|
<li class="nav-item mb-1">
|
|
<a href="{{ url_for('email.senders_list') }}"
|
|
class="nav-link text-white {{ 'active' if request.endpoint in ['email.senders_list', 'email.add_user'] else '' }}">
|
|
<i class="bi bi-people me-2"></i>
|
|
Allowed Senders
|
|
<span class="badge bg-secondary ms-auto">{{ sender_count if sender_count is defined else '' }}</span>
|
|
</a>
|
|
</li>
|
|
|
|
<li class="nav-item mb-1">
|
|
<a href="{{ url_for('email.ips_list') }}"
|
|
class="nav-link text-white {{ 'active' if request.endpoint in ['email.ips_list', 'email.add_ip'] else '' }}">
|
|
<i class="bi bi-router me-2"></i>
|
|
Whitelisted IPs
|
|
<span class="badge bg-secondary ms-auto">{{ ip_count if ip_count is defined else '' }}</span>
|
|
</a>
|
|
</li>
|
|
|
|
<li class="nav-item mb-1">
|
|
<a href="{{ url_for('email.dkim_list') }}"
|
|
class="nav-link text-white {{ 'active' if request.endpoint == 'email.dkim_list' else '' }}">
|
|
<i class="bi bi-shield-check me-2"></i>
|
|
DKIM Keys
|
|
<span class="badge bg-secondary ms-auto">{{ dkim_count if dkim_count is defined else '' }}</span>
|
|
</a>
|
|
</li>
|
|
|
|
<li class="nav-item mb-1">
|
|
<a href="{{ url_for('email.logs') }}"
|
|
class="nav-link text-white {{ 'active' if request.endpoint == 'email.logs' else '' }}">
|
|
<i class="bi bi-journal-text me-2"></i>
|
|
Emails Log
|
|
</a>
|
|
</li>
|
|
|
|
<!-- Authentication Section -->
|
|
<li class="nav-item mb-2">
|
|
<h6 class="text-muted text-uppercase small mb-2 mt-3">
|
|
<i class="bi bi-shield-lock me-1"></i>
|
|
Authentication
|
|
</h6>
|
|
</li>
|
|
|
|
|
|
<!-- Configuration Section -->
|
|
<li class="nav-item mb-2">
|
|
<h6 class="text-muted text-uppercase small mb-2 mt-3">
|
|
<i class="bi bi-gear me-1"></i>
|
|
Configuration
|
|
</h6>
|
|
</li>
|
|
|
|
<li class="nav-item mb-1">
|
|
<a href="{{ url_for('email.settings') }}"
|
|
class="nav-link text-white {{ 'active' if request.endpoint == 'email.settings' else '' }}">
|
|
<i class="bi bi-sliders me-2"></i>
|
|
Server Settings
|
|
</a>
|
|
</li>
|
|
|
|
<!-- Monitoring Section -->
|
|
<li class="nav-item mb-2">
|
|
<h6 class="text-muted text-uppercase small mb-2 mt-3">
|
|
<i class="bi bi-activity me-1"></i>
|
|
Monitoring
|
|
</h6>
|
|
</li>
|
|
|
|
<li class="nav-item mb-1">
|
|
<a href="{{ url_for('email.logs') }}"
|
|
class="nav-link text-white {{ 'active' if request.endpoint == 'email.logs' else '' }}">
|
|
<i class="bi bi-journal-text me-2"></i>
|
|
Logs & Activity
|
|
</a>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
|
|
<!-- Sidebar footer -->
|
|
<div class="p-3 border-top border-secondary">
|
|
<div class="d-flex align-items-center">
|
|
<div class="flex-grow-1">
|
|
<small class="text-muted d-block">Server Status</small>
|
|
{% set health = check_health() %}
|
|
<small class="{% if health.status == 'healthy' %}text-success{% else %}text-warning{% endif %} status-indicator"
|
|
data-bs-toggle="tooltip"
|
|
data-bs-html="true"
|
|
data-bs-placement="top"
|
|
title="{{ (
|
|
"<div class='text-start'><strong>Service Status:</strong><br>" +
|
|
'SMTP Server: ' + health.services.smtp_server|title + '<br>' +
|
|
'Web Frontend: ' + health.services.web_frontend|title + '<br>' +
|
|
'Database: ' + health.services.database|title + '</div>'
|
|
) | safe }}">
|
|
<i class="bi bi-circle-fill me-1" style="font-size: 0.5rem;"></i>
|
|
{{ health.status|title }}
|
|
</small>
|
|
</div>
|
|
<button class="btn btn-outline-secondary btn-sm" title="Refresh Status" onclick="location.reload()">
|
|
<i class="bi bi-arrow-clockwise"></i>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</nav>
|
|
|
|
<style>
|
|
.sidebar .nav-link {
|
|
border-radius: 0.375rem;
|
|
padding: 0.75rem 1rem;
|
|
margin-bottom: 0.25rem;
|
|
transition: all 0.2s ease;
|
|
}
|
|
|
|
.sidebar .nav-link:hover {
|
|
background-color: rgba(255, 255, 255, 0.1);
|
|
transform: translateX(4px);
|
|
}
|
|
|
|
.sidebar .nav-link.active {
|
|
background-color: #0d6efd;
|
|
color: white !important;
|
|
}
|
|
|
|
.sidebar .nav-link.active:hover {
|
|
background-color: #0b5ed7;
|
|
}
|
|
|
|
.sidebar h6 {
|
|
font-size: 0.75rem;
|
|
font-weight: 600;
|
|
letter-spacing: 0.05em;
|
|
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
|
|
padding-bottom: 0.5rem;
|
|
margin-bottom: 1rem !important;
|
|
}
|
|
|
|
.sidebar .badge {
|
|
font-size: 0.7rem;
|
|
}
|
|
|
|
.status-indicator {
|
|
cursor: pointer;
|
|
}
|
|
|
|
/* Responsive design */
|
|
@media (max-width: 768px) {
|
|
.sidebar {
|
|
transform: translateX(-100%);
|
|
transition: transform 0.3s ease;
|
|
}
|
|
|
|
.sidebar.show {
|
|
transform: translateX(0);
|
|
}
|
|
|
|
.content-area {
|
|
margin-left: 0 !important;
|
|
}
|
|
}
|
|
</style>
|
|
|
|
<script>
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
const tooltipTriggerList = document.querySelectorAll('[data-bs-toggle="tooltip"]');
|
|
tooltipTriggerList.forEach(function(tooltipTriggerEl) {
|
|
new bootstrap.Tooltip(tooltipTriggerEl, {
|
|
html: true,
|
|
placement: 'top',
|
|
trigger: 'hover'
|
|
});
|
|
});
|
|
});
|
|
</script>
|