This commit is contained in:
Flatlogic Bot 2026-02-03 21:54:23 +00:00
parent c6cc41cce3
commit 091645a299
4 changed files with 107 additions and 58 deletions

View File

@ -43,7 +43,10 @@
</div>
<div class="mb-4">
<label class="form-label fw-bold d-block mb-3">Select Labourers</label>
<div class="d-flex justify-content-between align-items-center mb-3">
<label class="form-label fw-bold mb-0">Select Labourers</label>
<a href="{% url 'manage_resources' %}" class="small text-decoration-none text-primary">Manage Resources</a>
</div>
<div class="row">
{% for checkbox in form.workers %}
<div class="col-md-6 col-lg-4 mb-2">

View File

@ -7,10 +7,22 @@
<div class="row mb-4">
<div class="col">
<h1 class="fw-bold text-dark">Manage Resources</h1>
<p class="text-muted">Toggle the active status of workers, projects, and teams. Inactive items will be hidden from selection forms.</p>
<p class="text-muted">Quickly toggle the active status of workers, projects, and teams. Inactive items will be hidden from selection forms.</p>
</div>
</div>
<!-- Feedback Toast -->
<div class="position-fixed bottom-0 end-0 p-3" style="z-index: 11">
<div id="liveToast" class="toast align-items-center text-white bg-success border-0" role="alert" aria-live="assertive" aria-atomic="true">
<div class="d-flex">
<div class="toast-body" id="toastMessage">
Status updated successfully.
</div>
<button type="button" class="btn-close btn-close-white me-2 m-auto" data-bs-dismiss="toast" aria-label="Close"></button>
</div>
</div>
</div>
<!-- Tabs -->
<ul class="nav nav-tabs mb-4" id="resourceTabs" role="tablist">
<li class="nav-item" role="presentation">
@ -37,8 +49,7 @@
<tr>
<th>Name</th>
<th>ID Number</th>
<th>Status</th>
<th class="text-end">Action</th>
<th class="text-end">Active Status</th>
</tr>
</thead>
<tbody>
@ -46,26 +57,18 @@
<tr>
<td>{{ worker.name }}</td>
<td>{{ worker.id_no }}</td>
<td>
{% if worker.is_active %}
<span class="badge bg-success">Active</span>
{% else %}
<span class="badge bg-secondary">Inactive</span>
{% endif %}
</td>
<td class="text-end">
<form method="post" action="{% url 'toggle_resource_status' 'worker' worker.id %}">
{% csrf_token %}
{% if worker.is_active %}
<button type="submit" class="btn btn-sm btn-outline-danger">Deactivate</button>
{% else %}
<button type="submit" class="btn btn-sm btn-outline-success">Activate</button>
{% endif %}
</form>
<div class="form-check form-switch d-flex justify-content-end">
<input class="form-check-input resource-toggle" type="checkbox" role="switch"
id="worker-{{ worker.id }}"
data-model="worker"
data-id="{{ worker.id }}"
{% if worker.is_active %}checked{% endif %}>
</div>
</td>
</tr>
{% empty %}
<tr><td colspan="4" class="text-center text-muted py-4">No workers found.</td></tr>
<tr><td colspan="3" class="text-center text-muted py-4">No workers found.</td></tr>
{% endfor %}
</tbody>
</table>
@ -84,8 +87,7 @@
<tr>
<th>Name</th>
<th>Description</th>
<th>Status</th>
<th class="text-end">Action</th>
<th class="text-end">Active Status</th>
</tr>
</thead>
<tbody>
@ -93,26 +95,18 @@
<tr>
<td>{{ project.name }}</td>
<td>{{ project.description|truncatechars:50 }}</td>
<td>
{% if project.is_active %}
<span class="badge bg-success">Active</span>
{% else %}
<span class="badge bg-secondary">Inactive</span>
{% endif %}
</td>
<td class="text-end">
<form method="post" action="{% url 'toggle_resource_status' 'project' project.id %}">
{% csrf_token %}
{% if project.is_active %}
<button type="submit" class="btn btn-sm btn-outline-danger">Deactivate</button>
{% else %}
<button type="submit" class="btn btn-sm btn-outline-success">Activate</button>
{% endif %}
</form>
<div class="form-check form-switch d-flex justify-content-end">
<input class="form-check-input resource-toggle" type="checkbox" role="switch"
id="project-{{ project.id }}"
data-model="project"
data-id="{{ project.id }}"
{% if project.is_active %}checked{% endif %}>
</div>
</td>
</tr>
{% empty %}
<tr><td colspan="4" class="text-center text-muted py-4">No projects found.</td></tr>
<tr><td colspan="3" class="text-center text-muted py-4">No projects found.</td></tr>
{% endfor %}
</tbody>
</table>
@ -132,8 +126,7 @@
<th>Name</th>
<th>Supervisor</th>
<th>Workers Count</th>
<th>Status</th>
<th class="text-end">Action</th>
<th class="text-end">Active Status</th>
</tr>
</thead>
<tbody>
@ -142,26 +135,18 @@
<td>{{ team.name }}</td>
<td>{{ team.supervisor.username|default:"-" }}</td>
<td>{{ team.workers.count }}</td>
<td>
{% if team.is_active %}
<span class="badge bg-success">Active</span>
{% else %}
<span class="badge bg-secondary">Inactive</span>
{% endif %}
</td>
<td class="text-end">
<form method="post" action="{% url 'toggle_resource_status' 'team' team.id %}">
{% csrf_token %}
{% if team.is_active %}
<button type="submit" class="btn btn-sm btn-outline-danger">Deactivate</button>
{% else %}
<button type="submit" class="btn btn-sm btn-outline-success">Activate</button>
{% endif %}
</form>
<div class="form-check form-switch d-flex justify-content-end">
<input class="form-check-input resource-toggle" type="checkbox" role="switch"
id="team-{{ team.id }}"
data-model="team"
data-id="{{ team.id }}"
{% if team.is_active %}checked{% endif %}>
</div>
</td>
</tr>
{% empty %}
<tr><td colspan="5" class="text-center text-muted py-4">No teams found.</td></tr>
<tr><td colspan="4" class="text-center text-muted py-4">No teams found.</td></tr>
{% endfor %}
</tbody>
</table>
@ -172,4 +157,57 @@
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
const toggles = document.querySelectorAll('.resource-toggle');
const toastEl = document.getElementById('liveToast');
const toast = new bootstrap.Toast(toastEl);
const toastMessage = document.getElementById('toastMessage');
toggles.forEach(toggle => {
toggle.addEventListener('change', function() {
const model = this.dataset.model;
const id = this.dataset.id;
const isChecked = this.checked;
const url = `/manage-resources/toggle/${model}/${id}/`;
fetch(url, {
method: 'POST',
headers: {
'X-CSRFToken': '{{ csrf_token }}',
'X-Requested-With': 'XMLHttpRequest'
}
})
.then(response => {
if (response.ok) {
return response.json();
}
throw new Error('Network response was not ok.');
})
.then(data => {
if (data.success) {
toastMessage.textContent = data.message;
toastEl.classList.remove('bg-danger');
toastEl.classList.add('bg-success');
toast.show();
} else {
// Revert switch if failed
this.checked = !isChecked;
alert('Failed to update status.');
}
})
.catch(error => {
console.error('Error:', error);
// Revert switch on error
this.checked = !isChecked;
toastMessage.textContent = "Error updating status.";
toastEl.classList.remove('bg-success');
toastEl.classList.add('bg-danger');
toast.show();
});
});
});
});
</script>
{% endblock %}

View File

@ -8,6 +8,7 @@ from django.db.models import Sum, Q
from django.core.mail import send_mail
from django.conf import settings
from django.contrib import messages
from django.http import JsonResponse
from .models import Worker, Project, Team, WorkLog, PayrollRecord
from .forms import WorkLogForm
from datetime import timedelta
@ -178,6 +179,13 @@ def toggle_resource_status(request, model_type, pk):
obj.is_active = not obj.is_active
obj.save()
if request.headers.get('x-requested-with') == 'XMLHttpRequest':
return JsonResponse({
'success': True,
'is_active': obj.is_active,
'message': f"{obj.name} is now {'Active' if obj.is_active else 'Inactive'}."
})
return redirect('manage_resources')
def payroll_dashboard(request):