maybe good

This commit is contained in:
HotSwapp
2025-08-08 15:55:15 -05:00
parent ab6f163c15
commit b257a06787
80 changed files with 19739 additions and 0 deletions

181
templates/login.html Normal file
View File

@@ -0,0 +1,181 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Login - Delphi Consulting Group Database System</title>
<!-- Bootstrap 5.3 CDN -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.0/font/bootstrap-icons.css" rel="stylesheet">
<!-- Custom CSS -->
<link href="/static/css/main.css" rel="stylesheet">
<link href="/static/css/themes.css" rel="stylesheet">
<link href="/static/css/components.css" rel="stylesheet">
</head>
<body class="login-page">
<div class="container">
<div class="row justify-content-center">
<div class="col-md-6 col-lg-4">
<div class="card login-card shadow-sm mt-5">
<div class="card-body p-5">
<div class="text-center mb-4">
<img src="/static/images/delphi-logo.webp" alt="Delphi Consulting Group" height="60" class="mb-3">
<h2 class="h4 mb-3">Delphi Database System</h2>
<p class="text-muted">Sign in to access the system</p>
</div>
<form id="loginForm" class="login-form" novalidate>
<div class="mb-3">
<label for="username" class="form-label">Username</label>
<div class="input-group">
<span class="input-group-text"><i class="bi bi-person"></i></span>
<input type="text" class="form-control" id="username" name="username" required>
</div>
<div class="invalid-feedback">Please enter your username.</div>
</div>
<div class="mb-4">
<label for="password" class="form-label">Password</label>
<div class="input-group">
<span class="input-group-text"><i class="bi bi-lock"></i></span>
<input type="password" class="form-control" id="password" name="password" required>
</div>
<div class="invalid-feedback">Please enter your password.</div>
</div>
<div class="d-grid">
<button type="submit" class="btn btn-primary" id="loginBtn">
<i class="bi bi-box-arrow-in-right"></i> Sign In
</button>
</div>
</form>
<div class="text-center mt-4">
<small class="text-muted">
Default credentials: admin / admin123
</small>
</div>
</div>
</div>
<!-- System Status -->
<div class="card login-status mt-3">
<div class="card-body text-center py-2">
<small class="text-muted">
<i class="bi bi-shield-check text-success"></i>
Secure connection established
</small>
</div>
</div>
</div>
</div>
</div>
<!-- Bootstrap JS -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
<script>
document.addEventListener('DOMContentLoaded', function() {
// Check if already logged in
const token = localStorage.getItem('auth_token');
if (token) {
window.location.href = '/customers';
return;
}
const loginForm = document.getElementById('loginForm');
const loginBtn = document.getElementById('loginBtn');
loginForm.addEventListener('submit', async function(e) {
e.preventDefault();
// Validate form
if (!loginForm.checkValidity()) {
e.stopPropagation();
loginForm.classList.add('was-validated');
return;
}
const username = document.getElementById('username').value;
const password = document.getElementById('password').value;
// Show loading state
const originalText = loginBtn.innerHTML;
loginBtn.innerHTML = '<span class="spinner-border spinner-border-sm me-2"></span>Signing in...';
loginBtn.disabled = true;
try {
const response = await fetch('/api/auth/login', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
username: username,
password: password
})
});
if (!response.ok) {
const error = await response.json();
throw new Error(error.detail || 'Login failed');
}
const data = await response.json();
// Store token
localStorage.setItem('auth_token', data.access_token);
// Show success message
showAlert('Login successful! Redirecting...', 'success');
// Redirect to customers page
setTimeout(() => {
window.location.href = '/customers';
}, 1000);
} catch (error) {
console.error('Login error:', error);
showAlert('Login failed: ' + error.message, 'danger');
} finally {
// Restore button
loginBtn.innerHTML = originalText;
loginBtn.disabled = false;
}
});
// Focus username field
document.getElementById('username').focus();
});
function showAlert(message, type = 'info') {
// Remove existing alerts
const existingAlerts = document.querySelectorAll('.alert');
existingAlerts.forEach(alert => alert.remove());
// Create new alert
const alertDiv = document.createElement('div');
alertDiv.className = `alert alert-${type} alert-dismissible fade show mt-3`;
alertDiv.innerHTML = `
${message}
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
`;
// Insert before the form
const form = document.getElementById('loginForm');
form.parentNode.insertBefore(alertDiv, form);
// Auto-dismiss success messages
if (type === 'success') {
setTimeout(() => {
if (alertDiv.parentNode) {
alertDiv.remove();
}
}, 5000);
}
}
</script>
</body>
</html>