Files
Student-Management-System-I…/templates/subject_files.html
T
2025-04-03 16:30:28 +05:45

327 lines
14 KiB
HTML

{% extends 'base.html' %}
{% load static %}
{% block content %}
<!-- Add CSRF token to the page -->
{% csrf_token %}
<div class="container-fluid py-4">
<!-- Welcome Section -->
{% include 'components/welcome_section.html' with user=teacher %}
<!-- Subject Files Content -->
<div class="content-section active">
<div class="content-card">
<div class="d-flex justify-content-between align-items-center mb-4">
<div>
<h3 class="text-xl font-semibold mb-0">
<i class="fas fa-book me-2"></i>Manage Subject Materials
</h3>
<a href="{% url 'teacherDashboard' %}#subjectsSection" class="btn btn-sm btn-link text-decoration-none ps-0" id="backToSubjectsBtn">
<i class="fas fa-arrow-left me-1"></i> Back to Subjects
</a>
</div>
<button class="btn btn-primary" onclick="openUploadModal()">
<i class="fas fa-file-upload me-1"></i> Upload New Material
</button>
</div>
{% if subjects %}
<div class="row">
{% for subject in subjects %}
<div class="col-md-6 col-lg-4 mb-4">
<div class="card border-0 shadow-sm h-100">
<div class="card-header bg-light py-3">
<h5 class="card-title mb-0">{{ subject.name }}</h5>
<p class="text-muted mb-0 small">{{ subject.course }} - {{ subject.semester_or_year }}</p>
</div>
<div class="card-body">
<p class="text-muted small mb-3">
<i class="fas fa-file me-1"></i> {{ subject.files_count }} file(s) available
</p>
{% if subject.files %}
<div class="list-group">
{% for file in subject.files %}
<div class="list-group-item list-group-item-action {% if file.file_type == 'syllabus' %}bg-light{% endif %}">
<div class="d-flex w-100 justify-content-between align-items-start">
<div>
<h6 class="mb-1">
{% if file.file_type == 'syllabus' %}
<i class="fas fa-file-pdf text-danger me-2"></i>
{% else %}
<i class="fas fa-file-alt text-primary me-2"></i>
{% endif %}
{{ file.title }}
</h6>
<p class="mb-1 small">
{% if file.description %}{{ file.description }}{% endif %}
</p>
<small class="text-muted">
{% if file.file_type == 'syllabus' %}
<span class="badge bg-info">Syllabus</span>
{% else %}
<span class="badge bg-primary">Study Material</span>
{% endif %}
{% if file.uploaded_at %}
<span class="ms-1">Uploaded {{ file.uploaded_at|timesince }} ago</span>
{% endif %}
{% if file.uploaded_by %}
<span class="ms-1">by {{ file.uploaded_by }}</span>
{% endif %}
</small>
</div>
<div class="d-flex flex-column align-items-end">
<a href="{{ file.file_url }}" class="btn btn-sm btn-outline-primary mb-1" target="_blank">
<i class="fas fa-download me-1"></i> Download
</a>
{% if file.file_type == 'syllabus' %}
<a href="{{ file.file_url }}" class="btn btn-sm btn-outline-secondary" target="_blank">
<i class="fas fa-eye me-1"></i> View Syllabus
</a>
{% else %}
<button class="btn btn-sm btn-outline-danger" onclick="deleteFile('{{ file.id }}')">
<i class="fas fa-trash"></i>
</button>
{% endif %}
</div>
</div>
</div>
{% endfor %}
</div>
{% else %}
<div class="alert alert-info">
<i class="fas fa-info-circle me-2"></i>No files available for this subject.
</div>
{% endif %}
<div class="mt-3">
<button class="btn btn-sm btn-primary w-100" onclick="openUploadModal('{{ subject.id }}')">
<i class="fas fa-file-upload me-1"></i> Upload to {{ subject.name }}
</button>
</div>
</div>
</div>
</div>
{% endfor %}
</div>
{% else %}
<div class="alert alert-info">
<i class="fas fa-info-circle me-2"></i>You don't have any subjects assigned.
</div>
{% endif %}
</div>
</div>
</div>
<!-- Upload File Modal -->
<div id="uploadFileModal" style="display: none; position: fixed; top: 0; left: 0; right: 0; bottom: 0; background-color: rgba(0,0,0,0.5); z-index: 10000;" onclick="if(event.target === this) closeUploadModal();">
<div style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 90%; max-width: 600px; background-color: white; border-radius: 8px; box-shadow: 0 2px 10px rgba(0,0,0,0.2);">
<div style="background-color: #3F51B5; color: white; padding: 15px; border-top-left-radius: 8px; border-top-right-radius: 8px; display: flex; justify-content: space-between; align-items: center;">
<h5 style="margin: 0; font-size: 18px;">Upload Study Material</h5>
<button style="background: none; border: none; color: white; font-size: 24px; cursor: pointer; line-height: 24px;" onclick="closeUploadModal()">&times;</button>
</div>
<div style="padding: 20px;">
<form id="uploadFileForm" method="post" action="/app/manage-subject-files/" enctype="multipart/form-data">
{% csrf_token %}
<div class="mb-3">
<label for="subject_id" class="form-label">Subject</label>
<select class="form-select" id="subject_id" name="subject_id" required>
<option value="">Select a subject</option>
{% for subject in subjects %}
<option value="{{ subject.id }}">{{ subject.name }} ({{ subject.course }})</option>
{% endfor %}
</select>
</div>
<div class="mb-3">
<label for="title" class="form-label">Title</label>
<input type="text" class="form-control" id="title" name="title" required placeholder="e.g. Chapter 1 Notes">
</div>
<div class="mb-3">
<label for="description" class="form-label">Description (Optional)</label>
<textarea class="form-control" id="description" name="description" rows="2" placeholder="Brief description of the material"></textarea>
</div>
<div class="mb-3">
<label for="file" class="form-label">File</label>
<input type="file" class="form-control" id="file" name="file" required>
<div class="form-text">Upload PDF, DOCX, PPT or other study materials. Max file size: 10MB</div>
</div>
<div id="uploadResponse" style="display: none;" class="alert mb-3"></div>
<div class="d-flex justify-content-end">
<button type="button" class="btn btn-secondary me-2" onclick="closeUploadModal()">Cancel</button>
<button type="submit" class="btn btn-primary">
<i class="fas fa-upload me-1"></i> Upload
</button>
</div>
</form>
</div>
</div>
</div>
<!-- Confirmation Modal -->
<div id="confirmationModal" style="display: none; position: fixed; top: 0; left: 0; right: 0; bottom: 0; background-color: rgba(0,0,0,0.5); z-index: 10000;" onclick="if(event.target === this) closeConfirmationModal();">
<div style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 90%; max-width: 400px; background-color: white; border-radius: 8px; box-shadow: 0 2px 10px rgba(0,0,0,0.2);">
<div style="background-color: #f44336; color: white; padding: 15px; border-top-left-radius: 8px; border-top-right-radius: 8px; display: flex; justify-content: space-between; align-items: center;">
<h5 style="margin: 0; font-size: 18px;">Confirm Deletion</h5>
<button style="background: none; border: none; color: white; font-size: 24px; cursor: pointer; line-height: 24px;" onclick="closeConfirmationModal()">&times;</button>
</div>
<div style="padding: 20px;">
<p class="mb-4">Are you sure you want to delete this file? This action cannot be undone.</p>
<div class="d-flex justify-content-end">
<button type="button" class="btn btn-secondary me-2" onclick="closeConfirmationModal()">Cancel</button>
<button type="button" class="btn btn-danger" id="confirmDeleteBtn">
<i class="fas fa-trash me-1"></i> Delete
</button>
</div>
</div>
</div>
</div>
<!-- Bottom Navigation -->
{% include 'components/bottom_nav.html' with user=teacher %}
<script>
// Modal Functions
function openUploadModal(subjectId = '') {
const modal = document.getElementById('uploadFileModal');
const subjectSelect = document.getElementById('subject_id');
const responseDiv = document.getElementById('uploadResponse');
// Reset the form
document.getElementById('uploadFileForm').reset();
responseDiv.style.display = 'none';
// If a subject ID was provided, pre-select it
if (subjectId) {
subjectSelect.value = subjectId;
}
modal.style.display = 'block';
document.body.style.overflow = 'hidden';
}
function closeUploadModal() {
document.getElementById('uploadFileModal').style.display = 'none';
document.body.style.overflow = '';
}
let fileIdToDelete = null;
function deleteFile(fileId) {
fileIdToDelete = fileId;
document.getElementById('confirmationModal').style.display = 'block';
document.body.style.overflow = 'hidden';
}
function closeConfirmationModal() {
document.getElementById('confirmationModal').style.display = 'none';
document.body.style.overflow = '';
fileIdToDelete = null;
}
// Form Submission and AJAX Functions
document.addEventListener('DOMContentLoaded', function() {
// File upload form submission
const uploadForm = document.getElementById('uploadFileForm');
uploadForm.addEventListener('submit', function(e) {
e.preventDefault();
const formData = new FormData(uploadForm);
const submitBtn = uploadForm.querySelector('button[type="submit"]');
const responseDiv = document.getElementById('uploadResponse');
// Disable the submit button and show loading state
submitBtn.disabled = true;
submitBtn.innerHTML = '<i class="fas fa-spinner fa-spin me-1"></i> Uploading...';
fetch('/app/manage-subject-files/', {
method: 'POST',
body: formData,
credentials: 'same-origin',
})
.then(response => response.json())
.then(data => {
responseDiv.style.display = 'block';
if (data.success) {
responseDiv.className = 'alert alert-success mb-3';
responseDiv.innerHTML = '<i class="fas fa-check-circle me-1"></i> ' + data.message;
// Reload the page after a short delay to show the new file
setTimeout(() => {
window.location.reload();
}, 1500);
} else {
responseDiv.className = 'alert alert-danger mb-3';
responseDiv.innerHTML = '<i class="fas fa-exclamation-circle me-1"></i> ' + data.message;
}
})
.catch(error => {
responseDiv.style.display = 'block';
responseDiv.className = 'alert alert-danger mb-3';
responseDiv.innerHTML = '<i class="fas fa-exclamation-circle me-1"></i> An error occurred while uploading the file.';
console.error('Error:', error);
})
.finally(() => {
// Re-enable the submit button
submitBtn.disabled = false;
submitBtn.innerHTML = '<i class="fas fa-upload me-1"></i> Upload';
});
});
// Delete file confirmation
const confirmDeleteBtn = document.getElementById('confirmDeleteBtn');
confirmDeleteBtn.addEventListener('click', function() {
if (!fileIdToDelete) return;
// Disable the button and show loading state
confirmDeleteBtn.disabled = true;
confirmDeleteBtn.innerHTML = '<i class="fas fa-spinner fa-spin me-1"></i> Deleting...';
const formData = new FormData();
formData.append('file_id', fileIdToDelete);
formData.append('csrfmiddlewaretoken', document.querySelector('[name=csrfmiddlewaretoken]').value);
fetch('/app/delete-subject-file/', {
method: 'POST',
body: formData,
credentials: 'same-origin',
})
.then(response => response.json())
.then(data => {
if (data.success) {
// Close the modal and reload the page to show the updated list
closeConfirmationModal();
window.location.reload();
} else {
alert('Error: ' + data.message);
closeConfirmationModal();
}
})
.catch(error => {
console.error('Error:', error);
alert('An error occurred while deleting the file.');
closeConfirmationModal();
});
});
});
// Ensure back button properly navigates to subjects section
document.addEventListener('DOMContentLoaded', function() {
const backBtn = document.getElementById('backToSubjectsBtn');
if (backBtn) {
backBtn.addEventListener('click', function(e) {
// Store in sessionStorage that we should activate subjects section
sessionStorage.setItem('activateSection', 'subjectsSection');
});
}
});
</script>
{% endblock %}