453 lines
20 KiB
PHP
453 lines
20 KiB
PHP
@extends('layouts.app')
|
|
|
|
@section('content')
|
|
<div class="container py-4">
|
|
<div class="row">
|
|
<div class="col-12">
|
|
<div class="card shadow-sm">
|
|
<div class="card-header d-flex justify-content-between align-items-center">
|
|
<h3 class="page-title m-0">
|
|
<i class="fas fa-list-alt me-2 text-primary"></i>All Responses
|
|
</h3>
|
|
@if(auth()->user()->role->name === 'Admin')
|
|
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#missingProofsModal">
|
|
<i class="fas fa-search me-1"></i> Check Missing Proofs
|
|
</button>
|
|
@endif
|
|
</div>
|
|
<div class="card-body">
|
|
<!-- Filter Controls -->
|
|
<div class="row mb-4">
|
|
<div class="col-md-4">
|
|
<div class="input-group">
|
|
<span class="input-group-text bg-light">Department</span>
|
|
<select id="department-filter" class="form-select">
|
|
<option value="">All Departments</option>
|
|
@foreach($departments as $department)
|
|
<option value="{{ $department->id }}">{{ $department->name }}</option>
|
|
@endforeach
|
|
</select>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-md-4">
|
|
<div class="input-group">
|
|
<span class="input-group-text bg-light">Category</span>
|
|
<select id="category-filter" class="form-select">
|
|
<option value="">All Categories</option>
|
|
<!-- Category options would be populated dynamically -->
|
|
</select>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<div class="input-group">
|
|
<span class="input-group-text bg-light">Date Range</span>
|
|
<input type="date" id="date-from" class="form-control">
|
|
<span class="input-group-text bg-light">to</span>
|
|
<input type="date" id="date-to" class="form-control">
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Table -->
|
|
<div class="table-responsive">
|
|
<table id="responses-table" class="table table-striped table-hover">
|
|
<thead>
|
|
<tr>
|
|
<th>ID</th>
|
|
<th>Title</th>
|
|
<th>Organising Institute</th>
|
|
<th>Address</th>
|
|
<th>Department</th>
|
|
<th>Faculty</th>
|
|
<th>Start Date</th>
|
|
<th>End Date</th>
|
|
<th>Days</th>
|
|
<th>Activity Type</th>
|
|
<th>Category</th>
|
|
<th>Level</th>
|
|
<th>Actions</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<!-- Data will be loaded via AJAX -->
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Missing Proofs Modal -->
|
|
@if(auth()->user()->role->name === 'Admin')
|
|
<div class="modal fade" id="missingProofsModal" tabindex="-1" aria-labelledby="missingProofsModalLabel" aria-hidden="true">
|
|
<div class="modal-dialog modal-dialog-centered">
|
|
<div class="modal-content">
|
|
<div class="modal-header bg-light">
|
|
<h5 class="modal-title" id="missingProofsModalLabel">
|
|
<i class="fas fa-check-square me-2 text-primary"></i>Select Categories to Check
|
|
</h5>
|
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
|
</div>
|
|
<form id="missingProofsForm" action="{{ route('missing-proofs.check') }}" method="POST">
|
|
@csrf
|
|
<div class="modal-body">
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
<div class="form-check mb-3">
|
|
<input class="form-check-input" type="checkbox" name="categories[]" value="activities_attended" id="checkActivitiesAttended">
|
|
<label class="form-check-label" for="checkActivitiesAttended">
|
|
1. Activities Attended
|
|
</label>
|
|
</div>
|
|
<div class="form-check mb-3">
|
|
<input class="form-check-input" type="checkbox" name="categories[]" value="activities_organised" id="checkActivitiesOrganised">
|
|
<label class="form-check-label" for="checkActivitiesOrganised">
|
|
2. Activities Organised
|
|
</label>
|
|
</div>
|
|
<div class="form-check mb-3">
|
|
<input class="form-check-input" type="checkbox" name="categories[]" value="iv_organised" id="checkIVOrganised">
|
|
<label class="form-check-label" for="checkIVOrganised">
|
|
3. IV Organised
|
|
</label>
|
|
</div>
|
|
<div class="form-check mb-3">
|
|
<input class="form-check-input" type="checkbox" name="categories[]" value="publications" id="checkPublications">
|
|
<label class="form-check-label" for="checkPublications">
|
|
4. Publications
|
|
</label>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="form-check mb-3">
|
|
<input class="form-check-input" type="checkbox" name="categories[]" value="books_published" id="checkBooksPublished">
|
|
<label class="form-check-label" for="checkBooksPublished">
|
|
5. Books Published
|
|
</label>
|
|
</div>
|
|
<div class="form-check mb-3">
|
|
<input class="form-check-input" type="checkbox" name="categories[]" value="external_engagement" id="checkExternalEngagement">
|
|
<label class="form-check-label" for="checkExternalEngagement">
|
|
6. External Engagement
|
|
</label>
|
|
</div>
|
|
<div class="form-check mb-3">
|
|
<input class="form-check-input" type="checkbox" name="categories[]" value="online_courses" id="checkOnlineCourses">
|
|
<label class="form-check-label" for="checkOnlineCourses">
|
|
7. Online Courses
|
|
</label>
|
|
</div>
|
|
<div class="form-check mb-3">
|
|
<input class="form-check-input" type="checkbox" name="categories[]" value="patents_copyrights" id="checkPatentsCopyrights">
|
|
<label class="form-check-label" for="checkPatentsCopyrights">
|
|
8. Patents/Copyrights
|
|
</label>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="form-check mb-2">
|
|
<input class="form-check-input" type="checkbox" id="selectAll">
|
|
<label class="form-check-label" for="selectAll">
|
|
<strong>Select All Categories</strong>
|
|
</label>
|
|
</div>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-outline-secondary" data-bs-dismiss="modal">
|
|
<i class="fas fa-times me-1"></i>Close
|
|
</button>
|
|
<button type="submit" class="btn btn-primary">
|
|
<i class="fas fa-paper-plane me-1"></i>Send Email
|
|
</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
@endif
|
|
|
|
@endsection
|
|
|
|
@section('scripts')
|
|
<script src="https://kit.fontawesome.com/a076d05399.js" crossorigin="anonymous"></script>
|
|
<script>
|
|
$(document).ready(function() {
|
|
// Handle "Select All" checkbox
|
|
$('#selectAll').change(function() {
|
|
const isChecked = $(this).prop('checked');
|
|
$('input[name="categories[]"]').prop('checked', isChecked);
|
|
});
|
|
|
|
// Update "Select All" when individual checkboxes change
|
|
$('input[name="categories[]"]').change(function() {
|
|
const totalCheckboxes = $('input[name="categories[]"]').length;
|
|
const checkedCheckboxes = $('input[name="categories[]"]:checked').length;
|
|
$('#selectAll').prop('checked', totalCheckboxes === checkedCheckboxes);
|
|
});
|
|
|
|
|
|
// Form validation for the modal
|
|
const form = document.getElementById('missingProofsForm');
|
|
if (form) {
|
|
form.addEventListener('submit', function(e) {
|
|
const checkboxes = form.querySelectorAll('input[type="checkbox"]:checked');
|
|
|
|
if (checkboxes.length === 0) {
|
|
e.preventDefault();
|
|
alert('Please select at least one category before sending emails.');
|
|
}
|
|
});
|
|
}
|
|
|
|
const sheetName = "Responses Report";
|
|
|
|
var initAjaxRoute = function(route) {
|
|
table = $("#responses-table").DataTable({
|
|
fnDestroy: true,
|
|
processing: true,
|
|
serverSide: true,
|
|
responsive: true,
|
|
ajax: {
|
|
url: route,
|
|
data: function(d) {
|
|
d.department = $('#department-filter').val();
|
|
d.category = $('#category-filter').val();
|
|
d.dateFrom = $('#date-from').val();
|
|
d.dateTo = $('#date-to').val();
|
|
}
|
|
},
|
|
columns: [{
|
|
data: 'id',
|
|
name: 'id',
|
|
searchable: false
|
|
},
|
|
{
|
|
data: 'title',
|
|
name: 'title',
|
|
orderable: false
|
|
},
|
|
{
|
|
data: 'organising_institute',
|
|
name: 'organising_institute',
|
|
orderable: false
|
|
},
|
|
{
|
|
data: 'address',
|
|
name: 'address',
|
|
orderable: false
|
|
},
|
|
{
|
|
data: 'department_name',
|
|
name: 'department_name',
|
|
orderable: false,
|
|
searchable: false
|
|
|
|
},
|
|
{
|
|
data: 'user_name',
|
|
name: 'user_name',
|
|
orderable: false
|
|
},
|
|
{
|
|
data: 'start_date',
|
|
name: 'start_date',
|
|
orderable: false
|
|
},
|
|
// { data: 'start_time', name: 'start_time', orderable: false },
|
|
{
|
|
data: 'end_date',
|
|
name: 'end_date',
|
|
orderable: false
|
|
},
|
|
// { data: 'end_time', name: 'end_time', orderable: false },
|
|
{
|
|
data: 'num_days',
|
|
name: 'num_days',
|
|
orderable: false
|
|
},
|
|
{
|
|
data: 'activity_type',
|
|
name: 'activity_type',
|
|
orderable: false
|
|
},
|
|
{
|
|
data: 'category',
|
|
name: 'category',
|
|
orderable: false,
|
|
searchable: false
|
|
},
|
|
{
|
|
data: 'level',
|
|
name: 'level',
|
|
orderable: false
|
|
},
|
|
{
|
|
data: 'action',
|
|
name: 'proof',
|
|
orderable: false,
|
|
searchable: false
|
|
}
|
|
],
|
|
columnDefs: [{
|
|
targets: '_all',
|
|
className: 'text-center wrap-text'
|
|
},
|
|
{
|
|
targets: 12,
|
|
render: function(data, type, row) {
|
|
return '<div class="btn-group" role="group">' +
|
|
data +
|
|
'</div>';
|
|
}
|
|
}
|
|
],
|
|
dom: '<"d-flex justify-content-between align-items-center mb-3"<"d-flex align-items-center"l><"d-flex"f<"ms-2"B>>>rtip',
|
|
buttons: [{
|
|
extend: 'copy',
|
|
text: '<i class="fas fa-copy me-1"></i> Copy',
|
|
className: 'btn btn-sm btn-outline-white',
|
|
title: sheetName,
|
|
exportOptions: exportOptions()
|
|
},
|
|
{
|
|
extend: 'csv',
|
|
text: '<i class="fas fa-file-csv me-1"></i> CSV',
|
|
className: 'btn btn-sm btn-outline-white',
|
|
title: sheetName,
|
|
exportOptions: exportOptions()
|
|
},
|
|
{
|
|
extend: 'excel',
|
|
text: '<i class="fas fa-file-excel me-1"></i> Excel',
|
|
className: 'btn btn-sm btn-outline-white',
|
|
title: sheetName,
|
|
exportOptions: exportOptions()
|
|
},
|
|
{
|
|
extend: 'pdf',
|
|
text: '<i class="fas fa-file-pdf me-1"></i> PDF',
|
|
className: 'btn btn-sm btn-outline-white',
|
|
title: sheetName,
|
|
exportOptions: exportOptions()
|
|
},
|
|
{
|
|
extend: 'print',
|
|
text: '<i class="fas fa-print me-1"></i> Print',
|
|
className: 'btn btn-sm btn-outline-white',
|
|
title: sheetName,
|
|
exportOptions: exportOptions()
|
|
}
|
|
],
|
|
language: {
|
|
search: "<i class='fas fa-search'></i> _INPUT_",
|
|
searchPlaceholder: "Search records...",
|
|
lengthMenu: "<i class='fas fa-list me-1'></i> _MENU_ records per page",
|
|
info: "Showing _START_ to _END_ of _TOTAL_ entries",
|
|
paginate: {
|
|
first: "<i class='fas fa-angle-double-left'></i>",
|
|
last: "<i class='fas fa-angle-double-right'></i>",
|
|
next: "<i class='fas fa-angle-right'></i>",
|
|
previous: "<i class='fas fa-angle-left'></i>"
|
|
}
|
|
}
|
|
});
|
|
|
|
// Apply filters when they change
|
|
$('#department-filter, #category-filter, #date-from, #date-to').change(function() {
|
|
table.ajax.reload();
|
|
});
|
|
};
|
|
|
|
// Delete button handler
|
|
$('#responses-table').on('click', '.delete-btn', function() {
|
|
if (confirm('Are you sure you want to delete this record?')) {
|
|
const id = $(this).data('id');
|
|
const url = $(this).data('url');
|
|
|
|
$.ajax({
|
|
url: url,
|
|
type: 'DELETE',
|
|
data: {
|
|
"_token": "{{ csrf_token() }}"
|
|
},
|
|
success: function(result) {
|
|
table.ajax.reload();
|
|
showToast('Record deleted successfully', 'success');
|
|
},
|
|
error: function(error) {
|
|
console.error(error);
|
|
showToast('Error deleting record', 'danger');
|
|
}
|
|
});
|
|
}
|
|
});
|
|
|
|
function exportOptions() {
|
|
return {
|
|
columns: ':visible',
|
|
format: {
|
|
body: function(data, row, column, node) {
|
|
if ($(node).find('select').length) {
|
|
return $(node).find("select option:selected").text();
|
|
}
|
|
return $(node).text();
|
|
}
|
|
}
|
|
};
|
|
}
|
|
|
|
// Toast notification function
|
|
function showToast(message, type) {
|
|
const toastContainer = document.createElement('div');
|
|
toastContainer.className = 'position-fixed bottom-0 start-0 p-3';
|
|
toastContainer.style.zIndex = '1050';
|
|
|
|
const toastEl = document.createElement('div');
|
|
toastEl.className = `toast align-items-center text-white bg-${type} border-0`;
|
|
toastEl.setAttribute('role', 'alert');
|
|
toastEl.setAttribute('aria-live', 'assertive');
|
|
toastEl.setAttribute('aria-atomic', 'true');
|
|
|
|
toastEl.innerHTML = `
|
|
<div class="d-flex">
|
|
<div class="toast-body">
|
|
${message}
|
|
</div>
|
|
<button type="button" class="btn-close btn-close-white me-2 m-auto" data-bs-dismiss="toast" aria-label="Close"></button>
|
|
</div>
|
|
`;
|
|
|
|
toastContainer.appendChild(toastEl);
|
|
document.body.appendChild(toastContainer);
|
|
|
|
const toast = new bootstrap.Toast(toastEl, {
|
|
autohide: true,
|
|
delay: 3000
|
|
});
|
|
|
|
toast.show();
|
|
|
|
toastEl.addEventListener('hidden.bs.toast', function() {
|
|
document.body.removeChild(toastContainer);
|
|
});
|
|
}
|
|
|
|
// Set the appropriate data route based on user role
|
|
const userRole = "{{ auth()->user()->role->name }}";
|
|
let dataRoute = "{{ route('admin.ActivitiesAttendedResponses.data') }}";
|
|
|
|
if (userRole === 'Coordinator') {
|
|
dataRoute = "{{ route('coordinator.ActivitiesAttendedResponses.data') }}";
|
|
}
|
|
if (userRole === 'Faculty') {
|
|
dataRoute = "{{ route('faculty.ActivitiesAttendedResponses.data') }}";
|
|
}
|
|
|
|
// Initialize the data table
|
|
initAjaxRoute(dataRoute);
|
|
});
|
|
</script>
|
|
@endsection |