You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

243 lines
7.3 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="robots" content="noindex, nofollow">
<meta name="referrer" content="no-referrer">
<!-- Security headers -->
<meta http-equiv="Content-Security-Policy"
content="default-src 'self';
img-src 'self' data:;
style-src 'self' 'unsafe-inline';
script-src 'self' 'unsafe-inline';
font-src 'self' data:;
connect-src 'self';">
<meta http-equiv="X-Content-Type-Options" content="nosniff">
<meta http-equiv="X-Frame-Options" content="DENY">
<title>TorGuard WireGuard Manager</title>
<!-- Bootstrap CSS and Icons (Local) -->
<link href="{{ url_for('static', filename='css/bootstrap.min.css') }}" rel="stylesheet">
<link href="{{ url_for('static', filename='css/bootstrap-icons.css') }}" rel="stylesheet">
<!-- Custom Styles -->
<style>
:root {
--primary-color: #0d6efd;
--danger-color: #dc3545;
--success-color: #198754;
}
body {
background-color: #f8f9fa;
min-height: 100vh;
display: flex;
flex-direction: column;
}
.container {
max-width: 800px;
flex: 1;
}
.logo {
max-width: 300px;
margin: 2rem 0;
height: auto;
}
.status-badge {
font-size: 1.1rem;
padding: 0.5rem 1rem;
transition: all 0.3s ease;
}
.form-container {
background: #ffffff;
padding: 2rem;
border-radius: 10px;
box-shadow: 0 0 20px rgba(0,0,0,0.1);
margin-bottom: 2rem;
}
.btn {
transition: all 0.2s ease;
}
.btn:hover {
transform: translateY(-1px);
}
.alert {
border-radius: 8px;
margin-bottom: 1rem;
}
.alert-info {
background-color: #cff4fc;
border-color: #b6effb;
}
.alert-danger {
background-color: #f8d7da;
border-color: #f5c2c7;
}
.alert-success {
background-color: #d1e7dd;
border-color: #badbcc;
}
/* Loading spinner */
.spinner-overlay {
display: none;
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.5);
z-index: 9999;
justify-content: center;
align-items: center;
}
.spinner-container {
background: white;
padding: 2rem;
border-radius: 10px;
text-align: center;
}
/* Responsive adjustments */
@media (max-width: 768px) {
.form-container {
padding: 1.5rem;
}
.logo {
max-width: 250px;
}
}
@media (max-width: 576px) {
.form-container {
padding: 1rem;
}
.logo {
max-width: 200px;
}
}
/* Footer */
.footer {
margin-top: auto;
padding: 1rem 0;
text-align: center;
font-size: 0.875rem;
color: #6c757d;
}
</style>
</head>
<body>
<!-- Loading Spinner -->
<div class="spinner-overlay" id="loadingSpinner">
<div class="spinner-container">
<div class="spinner-border text-primary mb-2" role="status">
<span class="visually-hidden">Loading...</span>
</div>
<div>Please wait...</div>
</div>
</div>
<div class="container py-4">
<!-- Header Section -->
{% if session.authenticated %}
<div class="d-flex justify-content-between align-items-center mb-4">
<div>
<span class="text-muted">Welcome, {{ session.username }}</span>
</div>
<div>
<a href="{{ url_for('logout') }}" class="btn btn-outline-danger">
<i class="bi bi-box-arrow-right"></i> Logout
</a>
</div>
</div>
{% endif %}
<!-- Logo Section -->
<div class="text-center">
<img src="{{ url_for('static', filename='logo.png') }}"
alt="TorGuard Logo"
class="logo"
onerror="this.onerror=null; this.src='data:image/svg+xml,<svg xmlns=\'http://www.w3.org/2000/svg\' viewBox=\'0 0 100 40\'><rect width=\'100\' height=\'40\' fill=\'%23f8f9fa\'/><text x=\'50\' y=\'20\' text-anchor=\'middle\' alignment-baseline=\'middle\' font-family=\'Arial\' font-size=\'16\'>TorGuard</text></svg>';">
</div>
<!-- Flash Messages -->
{% with messages = get_flashed_messages(with_categories=true) %}
{% if messages %}
{% for category, message in messages %}
<div class="alert alert-{{ category if category != 'message' else 'info' }} alert-dismissible fade show" role="alert">
{{ message }}
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
</div>
{% endfor %}
{% endif %}
{% endwith %}
<!-- Main Content -->
{% block content %}{% endblock %}
</div>
<!-- Footer -->
<footer class="footer">
<div class="container">
<p class="mb-0">TorGuard WireGuard Manager</p>
{% if session.authenticated %}
<small>Connected to: {{ request.host }}</small>
{% endif %}
</div>
</footer>
<!-- JavaScript Dependencies (Local) -->
<script src="{{ url_for('static', filename='js/bootstrap.bundle.min.js') }}"></script>
<!-- Common JavaScript -->
<script>
// Show loading spinner on form submissions
document.addEventListener('DOMContentLoaded', function() {
const forms = document.querySelectorAll('form');
const spinner = document.getElementById('loadingSpinner');
forms.forEach(form => {
form.addEventListener('submit', function() {
if (this.checkValidity()) {
spinner.style.display = 'flex';
}
});
});
// Hide alerts after 5 seconds
const alerts = document.querySelectorAll('.alert');
alerts.forEach(alert => {
setTimeout(() => {
const bsAlert = new bootstrap.Alert(alert);
bsAlert.close();
}, 5000);
});
});
// Prevent form resubmission on refresh
if (window.history.replaceState) {
window.history.replaceState(null, null, window.location.href);
}
</script>
</body>
</html>