<?php
$pageTitle = "Student Documents Management";
include_once('includes/header.php');
// Check if admin is logged in
if (!isset($_SESSION['user_id']) || ($_SESSION['role'] !== 'admin' && $_SESSION['role'] !== 'director')) {
header("Location: ../login.php");
exit();
}
?>
<div class="container-fluid py-4">
<div class="d-flex justify-content-between align-items-center mb-4">
<h2 class="mb-0">Student Documents Management</h2>
</div>
<!-- Filters -->
<div class="card mb-4">
<div class="card-body">
<div class="row g-3">
<div class="col-md-4">
<label for="studentFilter" class="form-label">Student</label>
<select class="form-select" id="studentFilter">
<option value="">All Students</option>
<!-- Will be populated via AJAX -->
</select>
</div>
<div class="col-md-4">
<label for="documentTypeFilter" class="form-label">Document Type</label>
<select class="form-select" id="documentTypeFilter">
<option value="">All Document Types</option>
<option value="id_proof">ID Proof</option>
<option value="address_proof">Address Proof</option>
<option value="educational_certificate">Educational Certificate</option>
<option value="photograph">Passport Size Photo</option>
<option value="other">Other</option>
</select>
</div>
<div class="col-md-4">
<label for="statusFilter" class="form-label">Status</label>
<select class="form-select" id="statusFilter">
<option value="">All Statuses</option>
<option value="pending">Pending</option>
<option value="verified">Verified</option>
<option value="rejected">Rejected</option>
</select>
</div>
</div>
</div>
</div>
<!-- Documents Table -->
<div class="card shadow">
<div class="card-header bg-light">
<h5 class="mb-0">Student Documents</h5>
</div>
<div class="card-body">
<div id="loadingIndicator" class="text-center py-5">
<div class="spinner-border text-primary" role="status">
<span class="visually-hidden">Loading...</span>
</div>
<p class="mt-2">Loading documents...</p>
</div>
<div id="noDocumentsMessage" class="alert alert-info text-center" style="display: none;">
<i class="fas fa-info-circle me-2"></i> No student documents found.
</div>
<div class="table-responsive" id="documentsTableContainer" style="display: none;">
<table id="documentsTable" class="table table-striped">
<thead>
<tr>
<th>ID</th>
<th>Student</th>
<th>Document Type</th>
<th>Upload Date</th>
<th>Status</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<!-- Data will be loaded via AJAX -->
</tbody>
</table>
</div>
</div>
</div>
</div>
<!-- Document Preview Modal -->
<div class="modal fade" id="documentPreviewModal" tabindex="-1" aria-hidden="true">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header bg-primary text-white">
<h5 class="modal-title">Document Preview</h5>
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<div class="text-center py-5" id="documentPreviewLoading">
<div class="spinner-border text-primary" role="status">
<span class="visually-hidden">Loading...</span>
</div>
<p class="mt-2">Loading document preview...</p>
</div>
<div id="documentPreviewContent" style="display: none;">
<div class="row mb-3">
<div class="col-md-6">
<h5 id="previewDocumentType">Document</h5>
<p class="text-muted small">Uploaded on <span id="previewDocumentDate"></span></p>
<p>Student: <strong id="previewStudentName"></strong></p>
<p>Email: <span id="previewStudentEmail"></span></p>
</div>
<div class="col-md-6 text-md-end">
<span id="previewDocumentStatus" class="badge bg-warning text-dark">Pending</span>
</div>
</div>
<div class="ratio ratio-16x9 mb-3" id="documentPreviewContainer">
<!-- Document will be displayed here -->
</div>
<div class="card mt-4 mb-0">
<div class="card-header bg-light">
<h6 class="mb-0">Verification Action</h6>
</div>
<div class="card-body">
<form id="verificationForm">
<input type="hidden" id="documentId" name="document_id">
<div class="mb-3">
<label class="form-label">Verification Status</label>
<div class="d-flex">
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="status" id="statusPending" value="pending">
<label class="form-check-label" for="statusPending">Pending</label>
</div>
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="status" id="statusVerified" value="verified">
<label class="form-check-label" for="statusVerified">Verify</label>
</div>
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="status" id="statusRejected" value="rejected">
<label class="form-check-label" for="statusRejected">Reject</label>
</div>
</div>
</div>
<div class="mb-3">
<label for="adminNotes" class="form-label">Admin Notes</label>
<textarea class="form-control" id="adminNotes" name="admin_notes" rows="3" placeholder="Add any notes regarding this document (optional)"></textarea>
</div>
<div class="d-flex justify-content-end">
<button type="submit" class="btn btn-primary" id="saveVerificationBtn">
<i class="fas fa-save me-2"></i> Save Changes
</button>
</div>
</form>
</div>
</div>
</div>
</div>
<div class="modal-footer">
<a href="#" class="btn btn-secondary" id="downloadDocument" download>
<i class="fas fa-download me-2"></i> Download
</a>
<button type="button" class="btn btn-danger" data-bs-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
<script>
$(document).ready(function() {
// Initialize DataTable
const documentsTable = $('#documentsTable').DataTable({
processing: true,
serverSide: false,
ajax: {
url: "ajax/get_all_documents.php",
dataSrc: function(json) {
// Hide loading indicator
$('#loadingIndicator').hide();
if (!json.success) {
$('#noDocumentsMessage').text(json.message || 'Error loading documents').show();
return [];
}
// Check if there are documents
if (json.data && json.data.length > 0) {
$('#documentsTableContainer').show();
$('#noDocumentsMessage').hide();
// Populate student filter
if (json.students) {
let options = '<option value="">All Students</option>';
json.students.forEach(function(student) {
options += `<option value="${student.id}">${student.name}</option>`;
});
$('#studentFilter').html(options);
}
return json.data;
} else {
$('#documentsTableContainer').hide();
$('#noDocumentsMessage').show();
return [];
}
},
error: function() {
$('#loadingIndicator').hide();
$('#noDocumentsMessage').text('Failed to connect to the server. Please try again later.').show();
}
},
columns: [
{ data: "id" },
{ data: "student_name" },
{ data: "document_type_display" },
{ data: "upload_date" },
{
data: "status_badge",
orderable: false
},
{
data: null,
orderable: false,
render: function(data, type, row) {
return `
<button class="btn btn-sm btn-primary view-document" data-id="${row.id}">
<i class="fas fa-eye me-1"></i> View
</button>
`;
}
}
],
order: [[3, 'desc']], // Order by upload date descending
language: {
emptyTable: "No documents found",
zeroRecords: "No matching documents found"
}
});
// Apply filters
$('#studentFilter, #documentTypeFilter, #statusFilter').on('change', function() {
documentsTable.draw();
});
// Custom filtering function
$.fn.dataTable.ext.search.push(function(settings, data, dataIndex) {
const studentFilter = $('#studentFilter').val();
const documentTypeFilter = $('#documentTypeFilter').val();
const statusFilter = $('#statusFilter').val();
// Get the row data
const rowData = documentsTable.row(dataIndex).data();
// Check student filter
if (studentFilter && rowData.user_id != studentFilter) {
return false;
}
// Check document type filter
if (documentTypeFilter && rowData.document_type != documentTypeFilter) {
return false;
}
// Check status filter
if (statusFilter && rowData.status != statusFilter) {
return false;
}
return true;
});
// View document
$(document).on('click', '.view-document', function() {
const documentId = $(this).data('id');
// Reset form
$('#verificationForm')[0].reset();
$('#documentId').val(documentId);
// Show loading and hide content
$('#documentPreviewLoading').show();
$('#documentPreviewContent').hide();
// Show the modal
$('#documentPreviewModal').modal('show');
// Load document details
$.ajax({
url: "ajax/get_document_details.php",
type: "GET",
data: { document_id: documentId },
dataType: "json",
success: function(response) {
if (response.success) {
const document = response.document;
// Set document details
$('#previewDocumentType').text(document.document_type_display);
$('#previewDocumentDate').text(document.upload_date);
$('#previewStudentName').text(document.student_name);
$('#previewStudentEmail').text(document.student_email);
$('#previewDocumentStatus').html(document.status_badge);
// Set download link
$('#downloadDocument').attr('href', `../${document.file_path}`);
// Set form values
$(`input[name="status"][value="${document.status}"]`).prop('checked', true);
$('#adminNotes').val(document.admin_notes);
// Set preview based on file type
const fileExtension = document.file_path.split('.').pop().toLowerCase();
let previewHtml = '';
if (fileExtension === 'pdf') {
previewHtml = `<embed src="../${document.file_path}" type="application/pdf" width="100%" height="100%" />`;
} else if (['jpg', 'jpeg', 'png', 'gif'].includes(fileExtension)) {
previewHtml = `<img src="../${document.file_path}" class="img-fluid" alt="${document.document_type_display}" />`;
} else {
previewHtml = `<div class="alert alert-info">Preview not available for this file type. Please download to view.</div>`;
}
// Update the preview container and show content
$('#documentPreviewContainer').html(previewHtml);
$('#documentPreviewLoading').hide();
$('#documentPreviewContent').show();
} else {
Swal.fire({
title: 'Error',
text: response.message || 'Failed to load document details',
icon: 'error'
});
$('#documentPreviewModal').modal('hide');
}
},
error: function() {
Swal.fire({
title: 'Error',
text: 'Failed to connect to the server',
icon: 'error'
});
$('#documentPreviewModal').modal('hide');
}
});
});
// Verification form submission
$('#verificationForm').on('submit', function(e) {
e.preventDefault();
const documentId = $('#documentId').val();
const status = $('input[name="status"]:checked').val();
const adminNotes = $('#adminNotes').val();
if (!status) {
Swal.fire({
title: 'Warning',
text: 'Please select a verification status',
icon: 'warning'
});
return;
}
// Disable button and show loading
$('#saveVerificationBtn').prop('disabled', true).html('<span class="spinner-border spinner-border-sm me-2" role="status" aria-hidden="true"></span> Saving...');
$.ajax({
url: "ajax/verify_document.php",
type: "POST",
data: {
document_id: documentId,
status: status,
admin_notes: adminNotes
},
dataType: "json",
success: function(response) {
if (response.success) {
Swal.fire({
title: 'Success',
text: 'Document verification status updated successfully',
icon: 'success'
});
// Reload DataTable
documentsTable.ajax.reload();
// Close modal
$('#documentPreviewModal').modal('hide');
} else {
Swal.fire({
title: 'Error',
text: response.message || 'Failed to update verification status',
icon: 'error'
});
}
// Re-enable button
$('#saveVerificationBtn').prop('disabled', false).html('<i class="fas fa-save me-2"></i> Save Changes');
},
error: function() {
Swal.fire({
title: 'Error',
text: 'Failed to connect to the server',
icon: 'error'
});
// Re-enable button
$('#saveVerificationBtn').prop('disabled', false).html('<i class="fas fa-save me-2"></i> Save Changes');
}
});
});
// Refresh button for reloading documents
$('#refreshDocuments').on('click', function() {
$('#loadingIndicator').show();
$('#documentsTableContainer').hide();
$('#noDocumentsMessage').hide();
documentsTable.ajax.reload();
});
});
</script>
<?php include_once('includes/footer.php'); ?>