ver 7.1
This commit is contained in:
parent
c6cc41cce3
commit
091645a299
Binary file not shown.
@ -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">
|
||||
|
||||
@ -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>
|
||||
{% endblock %}
|
||||
|
||||
<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 %}
|
||||
@ -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):
|
||||
@ -294,4 +302,4 @@ def payslip_detail(request, pk):
|
||||
'record': record,
|
||||
'logs': logs,
|
||||
}
|
||||
return render(request, 'core/payslip.html', context)
|
||||
return render(request, 'core/payslip.html', context)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user