Files
Student-Management-System-I…/templates/hod/modals/add_routine_modal.html
T
2025-04-22 03:47:31 +05:45

367 lines
15 KiB
HTML

{% load static %}
<!-- Add Routine Modal -->
<div id="addRoutineModal" 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) closeAddRoutineModal();">
<div style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 90%; max-width: 600px; background: white; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1);">
<div style="background-color: #6366f1; color: white; padding: 1rem 1.5rem; 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: 1.125rem; font-weight: 500;">Add Class Routine</h5>
<button style="background: none; border: none; color: white; font-size: 1.5rem; cursor: pointer; line-height: 1; padding: 0.25rem;" onclick="closeAddRoutineModal()">&times;</button>
</div>
<form id="addRoutineForm">
{% csrf_token %}
<div style="padding: 1.5rem;">
<div style="margin-bottom: 1.5rem;">
<label for="periodSelect" style="display: block; margin-bottom: 0.5rem; font-weight: 500; color: #374151;">{% if course.duration_type == 'Semester' %}Semester{% else %}Year{% endif %}</label>
<select id="periodSelect" name="period_select" style="width: 100%; padding: 0.625rem; border: 1px solid #d1d5db; border-radius: 6px; background-color: white; font-size: 0.875rem;" required>
<option value="">Select {% if course.duration_type == 'Semester' %}Semester{% else %}Year{% endif %}</option>
<!-- Options will be populated dynamically via JavaScript -->
</select>
</div>
<!-- Subject list container - subjects will be added here dynamically -->
<div id="subjectsContainer" style="margin-bottom: 1.5rem; max-height: 400px; overflow-y: auto;"></div>
<input type="hidden" id="periodOrYear" name="period_or_year">
</div>
<div style="padding: 1rem 1.5rem; border-top: 1px solid #e5e7eb; background-color: #f9fafb; border-bottom-left-radius: 8px; border-bottom-right-radius: 8px; display: flex; justify-content: flex-end; gap: 0.75rem;">
<button type="button" style="padding: 0.5rem 1rem; border: 1px solid #d1d5db; background-color: white; color: #374151; border-radius: 6px; font-size: 0.875rem; font-weight: 500;" onclick="closeAddRoutineModal()">Cancel</button>
<button type="button" style="padding: 0.5rem 1rem; background-color: #6366f1; color: white; border: none; border-radius: 6px; font-size: 0.875rem; font-weight: 500;" onclick="submitAddRoutineForm()">Save</button>
</div>
</form>
</div>
</div>
<script>
// Store all subject data for use in the form
const allSubjects = [
{% for subject in subjects %}
{
id: {{ subject.id }},
name: "{{ subject.name }}",
period: "{{ subject.period_or_year }}"
},
{% endfor %}
];
function openAddRoutineModal() {
const modal = document.getElementById('addRoutineModal');
if (modal) {
// Reset form
document.getElementById('addRoutineForm').reset();
document.getElementById('subjectsContainer').innerHTML = '';
// Populate period dropdown dynamically
const periodSelect = document.getElementById('periodSelect');
const periodLabel = {% if course.duration_type == 'Semester' %}'Semester'{% else %}'Year'{% endif %};
// Try to get the course data from the page
const courseElement = document.querySelector('#routineSection');
const courseId = courseElement?.getAttribute('data-course-id') ||
window.location.pathname.match(/\/hod\/(\d+)/)?.at(1);
// Default to 3 periods if we can't determine
let totalPeriods = 3;
{% if course.total_periods %}
totalPeriods = {{ course.total_periods }};
{% endif %}
// Clear all options
periodSelect.innerHTML = '';
// Add placeholder option
periodSelect.innerHTML = `<option value="">Select ${periodLabel}</option>`;
// Add options based on total periods
for (let i = 1; i <= totalPeriods; i++) {
periodSelect.innerHTML += `<option value="${i}">${periodLabel} ${i}</option>`;
}
// Setup period selection change listener
periodSelect.onchange = function() {
const selectedPeriod = this.value;
document.getElementById('periodOrYear').value = selectedPeriod;
// Clear existing subjects
const subjectsContainer = document.getElementById('subjectsContainer');
subjectsContainer.innerHTML = '';
if (selectedPeriod) {
// Filter subjects for the selected period
const periodSubjects = allSubjects.filter(subject => subject.period === selectedPeriod);
if (periodSubjects.length === 0) {
subjectsContainer.innerHTML = '<p style="text-align: center; padding: 1rem; color: #6b7280;">No subjects found for this period.</p>';
return;
}
// Create a form section for each subject
periodSubjects.forEach(subject => {
const subjectDiv = document.createElement('div');
subjectDiv.className = 'subject-item';
subjectDiv.style.padding = '1rem';
subjectDiv.style.marginBottom = '1rem';
subjectDiv.style.border = '1px solid #e5e7eb';
subjectDiv.style.borderRadius = '6px';
subjectDiv.style.backgroundColor = 'white';
// Create subject header
const subjectHeader = document.createElement('h4');
subjectHeader.textContent = subject.name;
subjectHeader.style.margin = '0 0 1rem 0';
subjectHeader.style.fontSize = '0.875rem';
subjectHeader.style.fontWeight = '600';
subjectHeader.style.color = '#374151';
subjectDiv.appendChild(subjectHeader);
// Add hidden input for subject ID
const subjectIdInput = document.createElement('input');
subjectIdInput.type = 'hidden';
subjectIdInput.name = `subject_id_${subject.id}`;
subjectIdInput.value = subject.id;
subjectDiv.appendChild(subjectIdInput);
// Create form grid
const formGrid = document.createElement('div');
formGrid.style.display = 'grid';
formGrid.style.gridTemplateColumns = 'repeat(auto-fit, minmax(150px, 1fr))';
formGrid.style.gap = '1rem';
formGrid.style.alignItems = 'end';
// Create teacher dropdown
const teacherDiv = document.createElement('div');
const teacherLabel = document.createElement('label');
teacherLabel.textContent = 'Teacher';
teacherLabel.style.display = 'block';
teacherLabel.style.marginBottom = '0.5rem';
teacherLabel.style.fontSize = '0.875rem';
teacherLabel.style.fontWeight = '500';
teacherLabel.style.color = '#374151';
teacherDiv.appendChild(teacherLabel);
const teacherSelect = document.createElement('select');
teacherSelect.name = `teacher_id_${subject.id}`;
teacherSelect.style.width = '100%';
teacherSelect.style.padding = '0.625rem';
teacherSelect.style.border = '1px solid #d1d5db';
teacherSelect.style.borderRadius = '6px';
teacherSelect.style.backgroundColor = 'white';
teacherSelect.style.fontSize = '0.875rem';
teacherSelect.required = true;
// Add default option
const defaultOption = document.createElement('option');
defaultOption.value = '';
defaultOption.textContent = 'Select Teacher';
teacherSelect.appendChild(defaultOption);
// Add teacher options
{% for teacher in staff %}
const teacherOption_{{ teacher.id }} = document.createElement('option');
teacherOption_{{ teacher.id }}.value = '{{ teacher.id }}';
teacherOption_{{ teacher.id }}.textContent = '{{ teacher.name }}';
teacherSelect.appendChild(teacherOption_{{ teacher.id }});
{% endfor %}
teacherDiv.appendChild(teacherSelect);
formGrid.appendChild(teacherDiv);
// Start time
const startTimeDiv = document.createElement('div');
const startTimeLabel = document.createElement('label');
startTimeLabel.textContent = 'Start Time';
startTimeLabel.style.display = 'block';
startTimeLabel.style.marginBottom = '0.5rem';
startTimeLabel.style.fontSize = '0.875rem';
startTimeLabel.style.fontWeight = '500';
startTimeLabel.style.color = '#374151';
startTimeDiv.appendChild(startTimeLabel);
const startTimeInput = document.createElement('input');
startTimeInput.type = 'time';
startTimeInput.name = `start_time_${subject.id}`;
startTimeInput.style.width = '100%';
startTimeInput.style.padding = '0.625rem';
startTimeInput.style.border = '1px solid #d1d5db';
startTimeInput.style.borderRadius = '6px';
startTimeInput.style.backgroundColor = 'white';
startTimeInput.style.fontSize = '0.875rem';
startTimeInput.required = true;
startTimeDiv.appendChild(startTimeInput);
formGrid.appendChild(startTimeDiv);
// End time
const endTimeDiv = document.createElement('div');
const endTimeLabel = document.createElement('label');
endTimeLabel.textContent = 'End Time';
endTimeLabel.style.display = 'block';
endTimeLabel.style.marginBottom = '0.5rem';
endTimeLabel.style.fontSize = '0.875rem';
endTimeLabel.style.fontWeight = '500';
endTimeLabel.style.color = '#374151';
endTimeDiv.appendChild(endTimeLabel);
const endTimeInput = document.createElement('input');
endTimeInput.type = 'time';
endTimeInput.name = `end_time_${subject.id}`;
endTimeInput.style.width = '100%';
endTimeInput.style.padding = '0.625rem';
endTimeInput.style.border = '1px solid #d1d5db';
endTimeInput.style.borderRadius = '6px';
endTimeInput.style.backgroundColor = 'white';
endTimeInput.style.fontSize = '0.875rem';
endTimeInput.required = true;
endTimeDiv.appendChild(endTimeInput);
formGrid.appendChild(endTimeDiv);
// Add the form grid to the subject div
subjectDiv.appendChild(formGrid);
// Add the subject div to the container
subjectsContainer.appendChild(subjectDiv);
});
}
};
// Show modal
modal.style.display = 'block';
document.body.style.overflow = 'hidden';
}
}
function closeAddRoutineModal() {
const modal = document.getElementById('addRoutineModal');
if (modal) {
modal.style.display = 'none';
document.body.style.overflow = '';
}
}
// Make functions available globally
if (typeof window !== 'undefined') {
window.openAddRoutineModal = openAddRoutineModal;
window.closeAddRoutineModal = closeAddRoutineModal;
}
// Add form submission function
function submitAddRoutineForm() {
const form = document.getElementById('addRoutineForm');
if (!form) {
console.error('Add routine form not found');
return;
}
// Get selected period
const periodSelect = document.getElementById('periodSelect');
const selectedPeriod = periodSelect.value;
if (!selectedPeriod) {
alert('Please select a period');
return;
}
// Get selected subjects
const subjectItems = document.querySelectorAll('.subject-item');
if (subjectItems.length === 0) {
alert('No subjects available for this period');
return;
}
// Check if any item has incomplete data
let hasIncompleteData = false;
subjectItems.forEach(item => {
const teacherSelect = item.querySelector('select');
const startTime = item.querySelector('input[type="time"][name^="start_time_"]');
const endTime = item.querySelector('input[type="time"][name^="end_time_"]');
if (!teacherSelect.value || !startTime.value || !endTime.value) {
hasIncompleteData = true;
}
});
if (hasIncompleteData) {
alert('Please fill in all required fields for each subject');
return;
}
// Prepare requests to be sent
const requests = [];
// Common data
const courseId = document.querySelector('#routineSection')?.getAttribute('data-course-id') ||
window.location.pathname.match(/\/hod\/(\d+)/)?.at(1);
if (!courseId) {
alert('Course ID not found');
return;
}
// Create a request for each subject
subjectItems.forEach(item => {
const subjectId = item.querySelector('input[type="hidden"]').value;
const teacherId = item.querySelector('select').value;
const startTime = item.querySelector('input[name^="start_time_"]').value;
const endTime = item.querySelector('input[name^="end_time_"]').value;
const formData = new FormData();
formData.append('course_id', courseId);
formData.append('subject_id', subjectId);
formData.append('teacher_id', teacherId);
formData.append('start_time', startTime);
formData.append('end_time', endTime);
formData.append('period_or_year', selectedPeriod);
requests.push(
fetch('/app/api/hod/routines/', {
method: 'POST',
body: formData,
headers: {
'X-CSRFToken': document.querySelector('[name=csrfmiddlewaretoken]').value
}
})
);
});
// Send all requests and handle responses
Promise.all(requests.map(p => p.catch(e => e)))
.then(responses => {
const allSuccessful = responses.every(res => !(res instanceof Error) && res.ok);
if (allSuccessful) {
if (typeof window.showMessageModal === 'function') {
window.showMessageModal('Success', 'All routines added successfully');
} else if (typeof window.showToast === 'function') {
window.showToast('success', 'All routines added successfully');
} else {
alert('All routines added successfully');
}
closeAddRoutineModal();
setTimeout(() => {
window.location.reload();
}, 1000);
} else {
if (typeof window.showMessageModal === 'function') {
window.showMessageModal('Error', 'Some routines could not be added');
} else if (typeof window.showToast === 'function') {
window.showToast('error', 'Some routines could not be added');
} else {
alert('Some routines could not be added');
}
}
})
.catch(error => {
console.error('Error adding routines:', error);
alert('Failed to add routines: ' + error.message);
});
}
// Make submission function globally available
if (typeof window !== 'undefined') {
window.submitAddRoutineForm = submitAddRoutineForm;
}
</script>