feat: Implement initial setup functionality with admin elevation and system settings management
This commit is contained in:
@@ -0,0 +1,226 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}LeagueLedger Setup{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="container mx-auto px-4 py-8">
|
||||
<div class="flex justify-center">
|
||||
<div class="w-full max-w-3xl">
|
||||
<div class="bg-white rounded-lg shadow-lg overflow-hidden">
|
||||
<!-- Header -->
|
||||
<div class="bg-irish-green text-white p-4">
|
||||
<h3 class="text-xl font-bold flex items-center">
|
||||
<i class="fas fa-tools mr-2"></i>LeagueLedger Setup
|
||||
</h3>
|
||||
</div>
|
||||
|
||||
<!-- Body -->
|
||||
<div class="p-6">
|
||||
<div class="bg-blue-50 border-l-4 border-blue-400 p-4 mb-6">
|
||||
<div class="flex items-center">
|
||||
<i class="fas fa-info-circle text-blue-500 mr-2"></i>
|
||||
<p>Welcome to the LeagueLedger setup page. This page is only available once during initial setup.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% if setup_completed %}
|
||||
<div class="bg-green-50 border-l-4 border-green-400 p-4 mb-6">
|
||||
<div class="flex items-center">
|
||||
<i class="fas fa-check-circle text-green-500 mr-2"></i>
|
||||
<p><strong>Setup has been completed.</strong> The system has been configured with an administrator.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% if is_admin %}
|
||||
<p class="mb-4">You already have administrator privileges. You can:</p>
|
||||
<div class="flex justify-center">
|
||||
<a href="/admin" class="bg-irish-green hover:bg-opacity-90 text-white font-bold py-2 px-4 rounded flex items-center">
|
||||
<i class="fas fa-cogs mr-2"></i>Go to Admin Dashboard
|
||||
</a>
|
||||
</div>
|
||||
{% else %}
|
||||
<p class="mb-4">This setup has already been completed by another user. Contact an administrator if you need admin access.</p>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
<p class="mb-4">Welcome, <strong>{{ user.username }}</strong>!</p>
|
||||
|
||||
<div class="my-6">
|
||||
<h4 class="text-lg font-bold text-irish-green mb-2">System Setup</h4>
|
||||
<p class="mb-2">
|
||||
You're about to be promoted to administrator. As an administrator, you will be able to:
|
||||
</p>
|
||||
<ul class="list-disc pl-6 mb-4 space-y-1">
|
||||
<li>Access all administrative functions</li>
|
||||
<li>Manage users and teams</li>
|
||||
<li>Generate and manage QR codes</li>
|
||||
<li>Configure system settings</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-center">
|
||||
<button id="elevateBtn" class="bg-golden-ale hover:bg-opacity-90 text-black-stout font-bold py-3 px-6 rounded flex items-center">
|
||||
<i class="fas fa-user-shield mr-2"></i>Make Me Administrator
|
||||
</button>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<!-- Footer -->
|
||||
<div class="bg-gray-50 px-6 py-4 border-t">
|
||||
<div class="flex justify-between items-center">
|
||||
<a href="/" class="border border-gray-300 text-gray-600 hover:bg-gray-100 font-semibold py-2 px-4 rounded flex items-center">
|
||||
<i class="fas fa-home mr-2"></i>Return to Home
|
||||
</a>
|
||||
|
||||
{% if not setup_completed %}
|
||||
<span class="text-gray-500 text-sm flex items-center">
|
||||
<i class="fas fa-info-circle mr-1"></i>
|
||||
This page will be disabled after setup
|
||||
</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Success Modal -->
|
||||
<div id="successModal" class="fixed z-10 inset-0 overflow-y-auto hidden" aria-labelledby="successModalLabel" role="dialog" aria-modal="true">
|
||||
<div class="flex items-center justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0">
|
||||
<!-- Background overlay -->
|
||||
<div class="fixed inset-0 bg-gray-500 bg-opacity-75 transition-opacity" aria-hidden="true"></div>
|
||||
|
||||
<!-- Modal panel -->
|
||||
<div class="inline-block align-bottom bg-white rounded-lg text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg sm:w-full">
|
||||
<div class="bg-green-500 text-white px-4 py-3 sm:px-6">
|
||||
<div class="flex items-center justify-between">
|
||||
<h3 class="text-lg leading-6 font-medium text-white" id="successModalLabel">
|
||||
<i class="fas fa-check-circle mr-2"></i>Setup Complete
|
||||
</h3>
|
||||
<button type="button" class="modalClose text-white hover:text-gray-200">
|
||||
<i class="fas fa-times"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4">
|
||||
<div class="text-center mb-4">
|
||||
<i class="fas fa-user-shield text-green-500 text-5xl"></i>
|
||||
</div>
|
||||
<p class="mb-2">Congratulations! You have been successfully promoted to administrator.</p>
|
||||
<p>You can now access all administrative functions of LeagueLedger.</p>
|
||||
</div>
|
||||
<div class="bg-gray-50 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse">
|
||||
<a href="/admin" class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-irish-green text-base font-medium text-white hover:bg-opacity-90 focus:outline-none sm:ml-3 sm:w-auto sm:text-sm">
|
||||
<i class="fas fa-cogs mr-2"></i>Go to Admin Dashboard
|
||||
</a>
|
||||
<button type="button" class="modalClose mt-3 w-full inline-flex justify-center rounded-md border border-gray-300 shadow-sm px-4 py-2 bg-white text-base font-medium text-gray-700 hover:bg-gray-50 focus:outline-none sm:mt-0 sm:ml-3 sm:w-auto sm:text-sm">
|
||||
Close
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Error Modal -->
|
||||
<div id="errorModal" class="fixed z-10 inset-0 overflow-y-auto hidden" aria-labelledby="errorModalLabel" role="dialog" aria-modal="true">
|
||||
<div class="flex items-center justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0">
|
||||
<!-- Background overlay -->
|
||||
<div class="fixed inset-0 bg-gray-500 bg-opacity-75 transition-opacity" aria-hidden="true"></div>
|
||||
|
||||
<!-- Modal panel -->
|
||||
<div class="inline-block align-bottom bg-white rounded-lg text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg sm:w-full">
|
||||
<div class="bg-red-500 text-white px-4 py-3 sm:px-6">
|
||||
<div class="flex items-center justify-between">
|
||||
<h3 class="text-lg leading-6 font-medium text-white" id="errorModalLabel">
|
||||
<i class="fas fa-exclamation-circle mr-2"></i>Error
|
||||
</h3>
|
||||
<button type="button" class="modalClose text-white hover:text-gray-200">
|
||||
<i class="fas fa-times"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4">
|
||||
<p id="errorMessage" class="text-red-600">An error occurred while processing your request.</p>
|
||||
</div>
|
||||
<div class="bg-gray-50 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse">
|
||||
<button type="button" class="modalClose w-full inline-flex justify-center rounded-md border border-gray-300 shadow-sm px-4 py-2 bg-white text-base font-medium text-gray-700 hover:bg-gray-50 focus:outline-none sm:mt-0 sm:w-auto sm:text-sm">
|
||||
Close
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block extra_scripts %}
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
const elevateBtn = document.getElementById('elevateBtn');
|
||||
const successModal = document.getElementById('successModal');
|
||||
const errorModal = document.getElementById('errorModal');
|
||||
const errorMessage = document.getElementById('errorMessage');
|
||||
const closeButtons = document.querySelectorAll('.modalClose');
|
||||
|
||||
// Close modal function
|
||||
function closeModal(modal) {
|
||||
modal.classList.add('hidden');
|
||||
}
|
||||
|
||||
// Show modal function
|
||||
function showModal(modal) {
|
||||
modal.classList.remove('hidden');
|
||||
}
|
||||
|
||||
// Add event listeners to close buttons
|
||||
closeButtons.forEach(button => {
|
||||
button.addEventListener('click', function() {
|
||||
closeModal(this.closest('.fixed'));
|
||||
});
|
||||
});
|
||||
|
||||
// Process admin elevation
|
||||
if (elevateBtn) {
|
||||
elevateBtn.addEventListener('click', function() {
|
||||
// Disable button to prevent multiple submissions
|
||||
elevateBtn.disabled = true;
|
||||
elevateBtn.innerHTML = '<svg class="animate-spin -ml-1 mr-3 h-5 w-5 text-white" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle><path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path></svg>Processing...';
|
||||
|
||||
// Send AJAX request
|
||||
fetch('/setup/elevate', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
credentials: 'same-origin'
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.success) {
|
||||
// Show success modal
|
||||
showModal(successModal);
|
||||
} else {
|
||||
// Show error modal
|
||||
errorMessage.textContent = data.message || 'An error occurred.';
|
||||
showModal(errorModal);
|
||||
|
||||
// Re-enable button
|
||||
elevateBtn.disabled = false;
|
||||
elevateBtn.innerHTML = '<i class="fas fa-user-shield mr-2"></i>Make Me Administrator';
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error:', error);
|
||||
// Show error modal
|
||||
errorMessage.textContent = 'Network error. Please try again.';
|
||||
showModal(errorModal);
|
||||
|
||||
// Re-enable button
|
||||
elevateBtn.disabled = false;
|
||||
elevateBtn.innerHTML = '<i class="fas fa-user-shield mr-2"></i>Make Me Administrator';
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
Reference in New Issue
Block a user