207 lines
9.2 KiB
PHTML
Executable File
207 lines
9.2 KiB
PHTML
Executable File
</div>
|
|
<div class="site-footer mt-auto">
|
|
<!-- Footer Content -->
|
|
<div class="row">
|
|
<div id="footer" class="col-xs-12">
|
|
<p class="m-0">George Wilkinson @2024</p>
|
|
<p class="m-0">Powered by Bootstrap</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Bootstrap core JavaScript
|
|
================================================== -->
|
|
<!-- Placed at the end of the document so the pages load faster -->
|
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
|
|
|
|
<!-- Application JavaScript -->
|
|
<!-- Note: auth.js is already included in the header -->
|
|
<!-- Note: facilityData.js is already included in the header -->
|
|
<script src="/public/js/comments.js"></script>
|
|
|
|
<!-- initialise components -->
|
|
<script>
|
|
// Only run initialization if not already done
|
|
if (!window.initializationComplete) {
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
// initialise auth service
|
|
const loginButton = document.querySelector('[data-bs-toggle="modal"]');
|
|
const loginModal = document.getElementById('loginModal');
|
|
|
|
// initialise all modals
|
|
try {
|
|
const modalElements = document.querySelectorAll('.modal');
|
|
modalElements.forEach(modalElement => {
|
|
if (modalElement) {
|
|
const modalInstance = new bootstrap.Modal(modalElement, {
|
|
backdrop: true,
|
|
keyboard: true,
|
|
focus: true
|
|
});
|
|
|
|
// Add click handler for modal triggers
|
|
const triggers = document.querySelectorAll(`[data-bs-target="#${modalElement.id}"]`);
|
|
triggers.forEach(trigger => {
|
|
trigger.addEventListener('click', (e) => {
|
|
e.preventDefault();
|
|
modalInstance.show();
|
|
});
|
|
});
|
|
}
|
|
});
|
|
} catch (error) {
|
|
console.error('Error initializing modals:', error);
|
|
}
|
|
|
|
// initialise CommentsManager
|
|
CommentsManager.state.isDomReady = true;
|
|
if (window.auth) {
|
|
CommentsManager.state.isAuthReady = true;
|
|
CommentsManager.checkinitialise();
|
|
} else {
|
|
window.addEventListener('authReady', () => {
|
|
console.log('auth is now ready');
|
|
CommentsManager.state.isAuthReady = true;
|
|
CommentsManager.checkinitialise();
|
|
});
|
|
}
|
|
|
|
// initialise auth form handlers
|
|
const loginForm = document.querySelector('#loginModal form');
|
|
const loginError = document.querySelector('#loginError');
|
|
const captchaContainer = document.querySelector('.captcha-container');
|
|
|
|
if (loginForm) {
|
|
// Show CAPTCHA if needed
|
|
if (auth.needsCaptcha() && captchaContainer) {
|
|
captchaContainer.style.display = 'flex';
|
|
}
|
|
|
|
// Add login form handler
|
|
loginForm.addEventListener('submit', async function(e) {
|
|
e.preventDefault();
|
|
|
|
// Get form data
|
|
const username = document.getElementById('username').value;
|
|
const password = document.getElementById('password').value;
|
|
const captchaInput = document.getElementById('captchaInput')?.value;
|
|
|
|
// Clear previous error
|
|
if (loginError) {
|
|
loginError.style.display = 'none';
|
|
loginError.textContent = '';
|
|
}
|
|
|
|
// Show loading spinner in submit button
|
|
const submitButton = this.querySelector('button[type="submit"]');
|
|
const originalButtonContent = submitButton.innerHTML;
|
|
submitButton.disabled = true;
|
|
submitButton.innerHTML = `
|
|
<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span>
|
|
<span class="ms-2">Logging in...</span>
|
|
`;
|
|
|
|
// Record start time for minimum spinner display
|
|
const startTime = Date.now();
|
|
|
|
try {
|
|
// Attempt login
|
|
const result = await auth.login({
|
|
username: username,
|
|
password: password,
|
|
captchaInput: captchaInput
|
|
});
|
|
|
|
// Calculate elapsed time and wait if needed to show spinner for at least 500ms
|
|
const elapsedTime = Date.now() - startTime;
|
|
const minSpinnerTime = 500; // 500ms minimum spinner display time
|
|
|
|
if (elapsedTime < minSpinnerTime) {
|
|
await new Promise(resolve => setTimeout(resolve, minSpinnerTime - elapsedTime));
|
|
}
|
|
|
|
if (result.success) {
|
|
// Show success message in button
|
|
submitButton.classList.remove('btn-success');
|
|
submitButton.classList.add('btn-success');
|
|
submitButton.innerHTML = `
|
|
<i class="bi bi-check-circle me-2"></i>Login successful
|
|
`;
|
|
|
|
// Wait a moment before closing modal and reloading
|
|
setTimeout(() => {
|
|
// Close modal
|
|
const modal = bootstrap.Modal.getInstance(document.getElementById('loginModal'));
|
|
if (modal) {
|
|
modal.hide();
|
|
}
|
|
|
|
// Reload page to update UI
|
|
window.location.reload();
|
|
}, 500);
|
|
} else {
|
|
// Show error
|
|
if (loginError) {
|
|
loginError.textContent = result.error || 'Login failed';
|
|
loginError.style.display = 'block';
|
|
}
|
|
|
|
// Show CAPTCHA if needed
|
|
if (auth.needsCaptcha() && captchaContainer) {
|
|
captchaContainer.style.display = 'flex';
|
|
// Generate new CAPTCHA if needed
|
|
if (result.captcha) {
|
|
document.getElementById('captchaCode').value = result.captcha;
|
|
}
|
|
}
|
|
|
|
// Reset button
|
|
submitButton.disabled = false;
|
|
submitButton.innerHTML = originalButtonContent;
|
|
}
|
|
} catch (error) {
|
|
console.error('Login error:', error);
|
|
if (loginError) {
|
|
loginError.textContent = error.message || 'An error occurred during login';
|
|
loginError.style.display = 'block';
|
|
}
|
|
|
|
// Reset button
|
|
submitButton.disabled = false;
|
|
submitButton.innerHTML = originalButtonContent;
|
|
}
|
|
});
|
|
}
|
|
|
|
// Handle logout button
|
|
const logoutButton = document.querySelector('button[name="logoutButton"]');
|
|
if (logoutButton) {
|
|
logoutButton.addEventListener('click', async (e) => {
|
|
e.preventDefault();
|
|
await auth.logout();
|
|
});
|
|
}
|
|
|
|
// Validate token if authenticated
|
|
if (auth.isAuthenticated()) {
|
|
auth.validateToken().then(valid => {
|
|
if (!valid) {
|
|
if (!localStorage.getItem('validationAttempted')) {
|
|
localStorage.setItem('validationAttempted', 'true');
|
|
window.location.reload();
|
|
} else {
|
|
localStorage.removeItem('validationAttempted');
|
|
}
|
|
} else {
|
|
localStorage.removeItem('validationAttempted');
|
|
}
|
|
});
|
|
}
|
|
|
|
// Mark initialization as complete
|
|
window.initializationComplete = true;
|
|
});
|
|
}
|
|
</script>
|
|
</body>
|
|
</html> |