huh new thing
This commit is contained in:
1 parent
0975a125c7
commit
9a842c12bf
29 files changed
+2771
-255
No files matched your search
+30
-140
@@ -16,168 +16,58 @@ from app.models import (
|
||||
)
|
||||
# Register your models here.
|
||||
|
||||
admin.site.register(FeedbackStudent)
|
||||
admin.site.register(FeedbackTeacher)
|
||||
admin.site.register(LeaveReportStudent)
|
||||
admin.site.register(LeaveReportTeacher)
|
||||
|
||||
@admin.register(LeaveReportStudent)
|
||||
class LeaveReportStudentAdmin(admin.ModelAdmin):
|
||||
def changelist_view(self, request, extra_context=None):
|
||||
return redirect(reverse("student_leave_view"))
|
||||
|
||||
|
||||
@admin.register(LeaveReportTeacher)
|
||||
class LeaveReportTeacherAdmin(admin.ModelAdmin):
|
||||
def changelist_view(self, request, extra_context=None):
|
||||
return redirect(reverse("teacher_leave_view"))
|
||||
|
||||
|
||||
@admin.register(FeedbackTeacher)
|
||||
class FeedbackTeacherAdmin(admin.ModelAdmin):
|
||||
def changelist_view(self, request, extra_context=None):
|
||||
return redirect(reverse("teacher_feedback"))
|
||||
|
||||
|
||||
@admin.register(FeedbackStudent)
|
||||
class FeedbackStudentAdmin(admin.ModelAdmin):
|
||||
def changelist_view(self, request, extra_context=None):
|
||||
return redirect(reverse("student_feedback_message"))
|
||||
|
||||
|
||||
@admin.register(AcademicYear)
|
||||
class AcademicYearAdmin(admin.ModelAdmin):
|
||||
list_display = ("id", "start_date", "created_at", "updated_at")
|
||||
|
||||
def changelist_view(self, request, extra_context=None):
|
||||
return redirect(reverse("manage_academicyear"))
|
||||
|
||||
|
||||
@admin.register(Attendance)
|
||||
class AttendanceAdmin(admin.ModelAdmin):
|
||||
list_display = ("subject_id", "attendance_date", "created_at", "updated_at")
|
||||
def changelist_view(self, request, extra_context=None):
|
||||
return redirect(reverse("admin_view_attendance"))
|
||||
|
||||
|
||||
@admin.register(AttendanceReport)
|
||||
class AttendanceReportAdmin(admin.ModelAdmin):
|
||||
list_display = ("student_id", "attendance_id", "status", "created_at", "updated_at")
|
||||
pass
|
||||
|
||||
|
||||
@admin.register(Student)
|
||||
class StudentAdmin(admin.ModelAdmin):
|
||||
list_display = (
|
||||
"id",
|
||||
"first_name",
|
||||
"middle_name",
|
||||
"last_name",
|
||||
"username",
|
||||
"email",
|
||||
"phone",
|
||||
"dob",
|
||||
"gender",
|
||||
"address",
|
||||
"father_name",
|
||||
"mother_name",
|
||||
"parents_number",
|
||||
"father_occupation",
|
||||
"guardian_name",
|
||||
"relationship_with_student",
|
||||
)
|
||||
search_fields = (
|
||||
"first_name",
|
||||
"middle_name",
|
||||
"last_name",
|
||||
"email",
|
||||
"phone",
|
||||
"father_name",
|
||||
"mother_name",
|
||||
"guardian_name",
|
||||
)
|
||||
list_filter = (
|
||||
"gender",
|
||||
"father_occupation",
|
||||
"mother_occupation",
|
||||
"relationship_with_student",
|
||||
)
|
||||
list_editable = ("phone", "email", "gender", "address")
|
||||
date_hierarchy = "dob"
|
||||
fieldsets = (
|
||||
(
|
||||
"Personal Information",
|
||||
{
|
||||
"fields": (
|
||||
"first_name",
|
||||
"middle_name",
|
||||
"last_name",
|
||||
"dob",
|
||||
"gender",
|
||||
"address",
|
||||
)
|
||||
},
|
||||
),
|
||||
("Contact Information", {"fields": ("username", "password", "phone", "email")}),
|
||||
(
|
||||
"Parent Details",
|
||||
{
|
||||
"fields": (
|
||||
"father_name",
|
||||
"mother_name",
|
||||
"parents_number",
|
||||
"father_occupation",
|
||||
"mother_occupation",
|
||||
)
|
||||
},
|
||||
),
|
||||
(
|
||||
"Guardian Details",
|
||||
{
|
||||
"fields": (
|
||||
"guardian_name",
|
||||
"guardian_number",
|
||||
"relationship_with_student",
|
||||
)
|
||||
},
|
||||
),
|
||||
("Timestamps", {"fields": ("created_at", "updated_at")}),
|
||||
)
|
||||
readonly_fields = ("created_at", "updated_at")
|
||||
def changelist_view(self, request, extra_context=None):
|
||||
return redirect(reverse("manage_student"))
|
||||
|
||||
|
||||
@admin.register(Teacher)
|
||||
class TeacherAdmin(admin.ModelAdmin):
|
||||
list_display = (
|
||||
"id",
|
||||
"first_name",
|
||||
"middle_name",
|
||||
"last_name",
|
||||
"username",
|
||||
"email",
|
||||
"phone",
|
||||
"gender",
|
||||
"qualification",
|
||||
"specialization_on",
|
||||
"marital_status",
|
||||
"date_of_joining",
|
||||
"created_at",
|
||||
"updated_at",
|
||||
)
|
||||
search_fields = (
|
||||
"first_name",
|
||||
"middle_name",
|
||||
"last_name",
|
||||
"email",
|
||||
"phone",
|
||||
"username",
|
||||
"specialization_on",
|
||||
)
|
||||
list_filter = (
|
||||
"gender",
|
||||
"qualification",
|
||||
"marital_status",
|
||||
"date_of_joining",
|
||||
)
|
||||
list_editable = ("phone", "email", "gender", "marital_status")
|
||||
date_hierarchy = "date_of_joining"
|
||||
fieldsets = (
|
||||
(
|
||||
"Personal Information",
|
||||
{
|
||||
"fields": (
|
||||
"first_name",
|
||||
"middle_name",
|
||||
"last_name",
|
||||
"dob",
|
||||
"gender",
|
||||
"marital_status",
|
||||
"address",
|
||||
)
|
||||
},
|
||||
),
|
||||
("Contact Information", {"fields": ("username", "password", "phone", "email")}),
|
||||
(
|
||||
"Professional Details",
|
||||
{"fields": ("qualification", "specialization_on", "date_of_joining")},
|
||||
),
|
||||
("Timestamps", {"fields": ("created_at", "updated_at")}),
|
||||
)
|
||||
readonly_fields = ("created_at", "updated_at")
|
||||
def changelist_view(self, request, extra_context=None):
|
||||
return redirect(reverse("manage_teacher"))
|
||||
|
||||
|
||||
@admin.register(Course)
|
||||
|
||||
+446
-63
@@ -17,6 +17,8 @@ from app.models import (
|
||||
Attendance,
|
||||
AttendanceReport,
|
||||
AcademicYear,
|
||||
FeedbackStudent,
|
||||
FeedbackTeacher,
|
||||
)
|
||||
from django.contrib.auth.decorators import login_required, user_passes_test
|
||||
from app.forms import SubjectForm
|
||||
@@ -27,7 +29,6 @@ admin_site = site
|
||||
@login_required
|
||||
@user_passes_test(lambda u: u.is_superuser)
|
||||
def admin_home(request):
|
||||
admin_site = site
|
||||
student_count1 = Student.objects.all().count()
|
||||
teacher_count = Teacher.objects.all().count()
|
||||
subject_count = Subject.objects.all().count()
|
||||
@@ -43,48 +44,50 @@ def admin_home(request):
|
||||
subject_count_list.append(subjects)
|
||||
student_count_list_in_course.append(students)
|
||||
|
||||
subjects_all = Subject.objects.all()
|
||||
subject_list = []
|
||||
student_count_list_in_subject = []
|
||||
for subject in subjects_all:
|
||||
course = subject.course
|
||||
student_count = Student.objects.filter(course_id=course.id).count()
|
||||
subject_list.append(subject.name)
|
||||
student_count_list_in_subject.append(student_count)
|
||||
# subjects_all = Subject.objects.all()
|
||||
# subject_list = []
|
||||
# student_count_list_in_subject = []
|
||||
# for subject in subjects_all:
|
||||
# course = subject.course
|
||||
# student_count = Student.objects.filter(course_id=course.id).count()
|
||||
# subject_list.append(subject.name)
|
||||
# student_count_list_in_subject.append(student_count)
|
||||
|
||||
teacher = Teacher.objects.all()
|
||||
attendance_present_list_teacher = []
|
||||
attendance_absent_list_teacher = []
|
||||
teacher_name_list = []
|
||||
for teacher in teacher:
|
||||
subject_ids = Subject.objects.filter(teacher_id=teacher.id)
|
||||
attendance = Attendance.objects.filter(
|
||||
subject_id__in=subject_ids,
|
||||
).count()
|
||||
leaves = LeaveReportTeacher.objects.filter(
|
||||
teacher_id=teacher.id, leave_status=1
|
||||
).count()
|
||||
attendance_present_list_teacher.append(attendance)
|
||||
attendance_absent_list_teacher.append(leaves)
|
||||
teacher_name_list.append(teacher.first_name)
|
||||
# teacher = Teacher.objects.all()
|
||||
# attendance_present_list_teacher = []
|
||||
# attendance_absent_list_teacher = []
|
||||
# teacher_name_list = []
|
||||
# for teacher in teacher:
|
||||
# subject_ids = Subject.objects.filter(teacher=teacher).values_list(
|
||||
# "id", flat=True
|
||||
# )
|
||||
# attendance = Attendance.objects.filter(
|
||||
# subject_id__in=subject_ids,
|
||||
# ).count()
|
||||
# leaves = LeaveReportTeacher.objects.filter(
|
||||
# teacher_id=teacher.id, leave_status=1
|
||||
# ).count()
|
||||
# attendance_present_list_teacher.append(attendance)
|
||||
# attendance_absent_list_teacher.append(leaves)
|
||||
# teacher_name_list.append(teacher.first_name)
|
||||
|
||||
students_all = Student.objects.all()
|
||||
attendance_present_list_student = []
|
||||
attendance_absent_list_student = []
|
||||
student_name_list = []
|
||||
for student in students_all:
|
||||
attendance = AttendanceReport.objects.filter(
|
||||
student_id=student.id, status=True
|
||||
).count()
|
||||
absent = AttendanceReport.objects.filter(
|
||||
student_id=student.id, status=False
|
||||
).count()
|
||||
leaves = LeaveReportStudent.objects.filter(
|
||||
student_id=student.id, leave_status=1
|
||||
).count()
|
||||
attendance_present_list_student.append(attendance)
|
||||
attendance_absent_list_student.append(leaves + absent)
|
||||
student_name_list.append(student.admin.username)
|
||||
# students_all = Student.objects.all()
|
||||
# attendance_present_list_student = []
|
||||
# attendance_absent_list_student = []
|
||||
# student_name_list = []
|
||||
# for student in students_all:
|
||||
# attendance = AttendanceReport.objects.filter(
|
||||
# student_id=student.id, status=True
|
||||
# ).count()
|
||||
# absent = AttendanceReport.objects.filter(
|
||||
# student_id=student.id, status=False
|
||||
# ).count()
|
||||
# leaves = LeaveReportStudent.objects.filter(
|
||||
# student_id=student.id, leave_status=1
|
||||
# ).count()
|
||||
# attendance_present_list_student.append(attendance)
|
||||
# attendance_absent_list_student.append(leaves + absent)
|
||||
# student_name_list.append(student.username)
|
||||
|
||||
context = {
|
||||
**admin_site.each_context(request),
|
||||
@@ -93,17 +96,17 @@ def admin_home(request):
|
||||
"teacher_count": teacher_count,
|
||||
"subject_count": subject_count,
|
||||
"course_count": course_count,
|
||||
"course_name_list": course_name_list,
|
||||
# "course_name_list": course_name_list,
|
||||
"subject_count_list": subject_count_list,
|
||||
"student_count_list_in_course": student_count_list_in_course,
|
||||
"student_count_list_in_subject": student_count_list_in_subject,
|
||||
"subject_list": subject_list,
|
||||
"teacher_name_list": teacher_name_list,
|
||||
"attendance_present_list_teacher": attendance_present_list_teacher,
|
||||
"attendance_absent_list_teacher": attendance_absent_list_teacher,
|
||||
"student_name_list": student_name_list,
|
||||
"attendance_present_list_student": attendance_present_list_student,
|
||||
"attendance_absent_list_student": attendance_absent_list_student,
|
||||
# "student_count_list_in_course": student_count_list_in_course,
|
||||
# "student_count_list_in_subject": student_count_list_in_subject,
|
||||
# "subject_list": subject_list,
|
||||
# "teacher_name_list": teacher_name_list,
|
||||
# "attendance_present_list_teacher": attendance_present_list_teacher,
|
||||
# "attendance_absent_list_teacher": attendance_absent_list_teacher,
|
||||
# "student_name_list": student_name_list,
|
||||
# "attendance_present_list_student": attendance_present_list_student,
|
||||
# "attendance_absent_list_student": attendance_absent_list_student,
|
||||
"opts": Student._meta,
|
||||
}
|
||||
return render(request, "hod/dashboard.html", context)
|
||||
@@ -146,7 +149,6 @@ def add_course(request):
|
||||
|
||||
|
||||
def manage_course(request):
|
||||
admin_site = site
|
||||
courses = Course.objects.all()
|
||||
context = {
|
||||
**admin_site.each_context(request),
|
||||
@@ -183,10 +185,12 @@ def edit_course(request, course_id):
|
||||
|
||||
except Exception as e:
|
||||
messages.error(request, f"Error updating course: {str(e)}")
|
||||
|
||||
return render(
|
||||
request, "hod/edit_course.html", {"course": course, "title": "Edit Course"}
|
||||
)
|
||||
context = {
|
||||
**admin_site.each_context(request),
|
||||
"title": "Edit Course",
|
||||
"course": course,
|
||||
}
|
||||
return render(request, "hod/edit_course.html", context)
|
||||
|
||||
|
||||
def delete_course(request, course_id):
|
||||
@@ -201,7 +205,6 @@ def delete_course(request, course_id):
|
||||
|
||||
|
||||
def add_academicyear(request):
|
||||
admin_site = site
|
||||
if request.method == "POST":
|
||||
start_date = request.POST.get("start_date")
|
||||
academic_year = AcademicYear.objects.create(start_date=start_date)
|
||||
@@ -210,6 +213,7 @@ def add_academicyear(request):
|
||||
context = {
|
||||
**admin_site.each_context(request),
|
||||
"title": "Add Academic Year",
|
||||
# "academic_year": academic_year,
|
||||
"opts": AcademicYear._meta,
|
||||
}
|
||||
return render(request, "hod/add_academicyear.html", context)
|
||||
@@ -217,7 +221,6 @@ def add_academicyear(request):
|
||||
|
||||
def edit_academicyear(request, pk):
|
||||
academic_year = get_object_or_404(AcademicYear, pk=pk)
|
||||
admin_site = site
|
||||
if request.method == "POST":
|
||||
start_date = request.POST.get("start_date")
|
||||
|
||||
@@ -233,13 +236,10 @@ def edit_academicyear(request, pk):
|
||||
"title": "Edit Academic Year",
|
||||
"opts": AcademicYear._meta,
|
||||
}
|
||||
return render(
|
||||
request, "hod/edit_academicyear.html", {"academic_year": academic_year}
|
||||
)
|
||||
return render(request, "hod/edit_academicyear.html", context)
|
||||
|
||||
|
||||
def manage_academicyear(request):
|
||||
admin_site = site
|
||||
context = {
|
||||
**admin_site.each_context(request),
|
||||
"academic_years": AcademicYear.objects.all(),
|
||||
@@ -315,7 +315,7 @@ def edit_subject(request, pk):
|
||||
form = SubjectForm(request.POST, instance=subject)
|
||||
if form.is_valid():
|
||||
form.save()
|
||||
return redirect("manage_subjects")
|
||||
return redirect("manage_subject")
|
||||
else:
|
||||
form = SubjectForm(instance=subject)
|
||||
context = {
|
||||
@@ -339,3 +339,386 @@ def delete_subject(request, subject_id):
|
||||
messages.error(request, "Failed to Delete Subject.")
|
||||
return redirect("manage_subject")
|
||||
|
||||
|
||||
def manage_student(request):
|
||||
search_query = request.GET.get("search", "")
|
||||
students = Student.objects.all()
|
||||
|
||||
if search_query:
|
||||
students = (
|
||||
students.filter(first_name__icontains=search_query)
|
||||
| students.filter(last_name__icontains=search_query)
|
||||
| students.filter(email__icontains=search_query)
|
||||
)
|
||||
|
||||
context = {
|
||||
**admin_site.each_context(request),
|
||||
"title": "Manage Students",
|
||||
"students": students,
|
||||
"search_query": search_query,
|
||||
}
|
||||
return render(request, "hod/manage_student.html", context)
|
||||
|
||||
|
||||
def add_student(request):
|
||||
courses = Course.objects.all()
|
||||
academic_years = AcademicYear.objects.all()
|
||||
occupation_choices = dict(Student.occupation_choice)
|
||||
relationship_choices = dict(Student.relationship_choice)
|
||||
|
||||
if request.method == "POST":
|
||||
first_name = request.POST.get("first_name")
|
||||
middle_name = request.POST.get("middle_name")
|
||||
last_name = request.POST.get("last_name")
|
||||
email = request.POST.get("email")
|
||||
phone = request.POST.get("phone")
|
||||
dob = request.POST.get("dob")
|
||||
gender = request.POST.get("gender")
|
||||
course_id = request.POST.get("course")
|
||||
academic_year_id = request.POST.get("academic_year")
|
||||
address = request.POST.get("address")
|
||||
father_name = request.POST.get("father_name")
|
||||
father_occupation = request.POST.get("father_occupation")
|
||||
mother_name = request.POST.get("mother_name")
|
||||
mother_occupation = request.POST.get("mother_occupation")
|
||||
guardian_name = request.POST.get("guardian_name")
|
||||
guardian_number = request.POST.get("guardian_number")
|
||||
parents_number = request.POST.get("parents_number")
|
||||
relationship_with_student = request.POST.get("relationship_with_student")
|
||||
|
||||
try:
|
||||
course = get_object_or_404(Course, id=course_id)
|
||||
academic_year = get_object_or_404(AcademicYear, id=academic_year_id)
|
||||
|
||||
Student.objects.create(
|
||||
first_name=first_name,
|
||||
middle_name=middle_name,
|
||||
last_name=last_name,
|
||||
email=email,
|
||||
phone=phone,
|
||||
dob=dob,
|
||||
gender=gender,
|
||||
course=course,
|
||||
academic_year=academic_year,
|
||||
address=address,
|
||||
father_name=father_name,
|
||||
father_occupation=father_occupation,
|
||||
mother_name=mother_name,
|
||||
mother_occupation=mother_occupation,
|
||||
guardian_name=guardian_name,
|
||||
guardian_number=guardian_number,
|
||||
parents_number=parents_number,
|
||||
relationship_with_student=relationship_with_student,
|
||||
)
|
||||
messages.success(request, "Student added successfully!")
|
||||
return redirect("manage_student")
|
||||
except Exception as e:
|
||||
messages.error(request, f"Error adding student: {e}")
|
||||
|
||||
context = {
|
||||
**admin_site.each_context(request),
|
||||
"title": "Add Student",
|
||||
"courses": courses,
|
||||
"academic_years": academic_years,
|
||||
"occupation_choices": occupation_choices.items(),
|
||||
"relationship_choices": relationship_choices.items(),
|
||||
}
|
||||
return render(request, "hod/add_student.html", context)
|
||||
|
||||
|
||||
def edit_student(request, student_id):
|
||||
student = get_object_or_404(Student, id=student_id)
|
||||
courses = Course.objects.all()
|
||||
academic_years = AcademicYear.objects.all()
|
||||
occupation_choices = dict(Student.occupation_choice)
|
||||
relationship_choices = dict(Student.relationship_choice)
|
||||
|
||||
if request.method == "POST":
|
||||
student.first_name = request.POST.get("first_name")
|
||||
student.middle_name = request.POST.get("middle_name")
|
||||
student.last_name = request.POST.get("last_name")
|
||||
student.email = request.POST.get("email")
|
||||
student.phone = request.POST.get("phone")
|
||||
student.dob = request.POST.get("dob")
|
||||
student.gender = request.POST.get("gender")
|
||||
student.course = get_object_or_404(Course, id=request.POST.get("course"))
|
||||
student.academic_year = get_object_or_404(
|
||||
AcademicYear, id=request.POST.get("academic_year")
|
||||
)
|
||||
student.father_occupation = request.POST.get("father_occupation")
|
||||
student.relationship_with_student = request.POST.get(
|
||||
"relationship_with_student"
|
||||
)
|
||||
|
||||
try:
|
||||
student.save()
|
||||
messages.success(request, "Student updated successfully!")
|
||||
return redirect("manage_student")
|
||||
except Exception as e:
|
||||
messages.error(request, f"Error updating student: {e}")
|
||||
|
||||
context = {
|
||||
**admin_site.each_context(request),
|
||||
"title": "Edit Student",
|
||||
"student": student,
|
||||
"courses": courses,
|
||||
"academic_years": academic_years,
|
||||
"occupation_choices": occupation_choices.items(),
|
||||
"relationship_choices": relationship_choices.items(),
|
||||
}
|
||||
return render(request, "hod/edit_student.html", context)
|
||||
|
||||
|
||||
def delete_student(request, student_id):
|
||||
student = get_object_or_404(Student, id=student_id)
|
||||
student.delete()
|
||||
messages.success(request, "Student deleted successfully!")
|
||||
return redirect("manage_student")
|
||||
|
||||
|
||||
def manage_teacher(request):
|
||||
teachers = Teacher.objects.all()
|
||||
context = {
|
||||
**admin_site.each_context(request),
|
||||
"title": "Manage Teachers",
|
||||
"teachers": teachers,
|
||||
}
|
||||
return render(request, "hod/manage_teacher.html", context)
|
||||
|
||||
|
||||
def add_teacher(request):
|
||||
if request.method == "POST":
|
||||
try:
|
||||
Teacher.objects.create(
|
||||
first_name=request.POST.get("first_name"),
|
||||
middle_name=request.POST.get("middle_name"),
|
||||
last_name=request.POST.get("last_name"),
|
||||
email=request.POST.get("email"),
|
||||
phone=request.POST.get("phone"),
|
||||
dob=request.POST.get("dob"),
|
||||
gender=request.POST.get("gender"),
|
||||
address=request.POST.get("address"),
|
||||
# username=request.POST.get("username"),
|
||||
# password=request.POST.get("password"),
|
||||
qualification=request.POST.get("qualification"),
|
||||
specialization_on=request.POST.get("specialization_on"),
|
||||
marital_status=request.POST.get("marital_status"),
|
||||
date_of_joining=request.POST.get("date_of_joining"),
|
||||
)
|
||||
messages.success(request, "Teacher added successfully!")
|
||||
return redirect("manage_teacher")
|
||||
except Exception as e:
|
||||
messages.error(request, f"Error adding teacher: {e}")
|
||||
|
||||
context = {
|
||||
**admin_site.each_context(request),
|
||||
"title": "Add Teacher",
|
||||
"qualification_choices": dict(Teacher.qualification_choice).items(),
|
||||
"marital_status_choices": dict(Teacher.marital_status_choice).items(),
|
||||
}
|
||||
return render(request, "hod/add_teacher.html", context)
|
||||
|
||||
|
||||
def edit_teacher(request, teacher_id):
|
||||
teacher = get_object_or_404(Teacher, id=teacher_id)
|
||||
|
||||
if request.method == "POST":
|
||||
try:
|
||||
teacher.first_name = request.POST.get("first_name")
|
||||
teacher.middle_name = request.POST.get("middle_name")
|
||||
teacher.last_name = request.POST.get("last_name")
|
||||
teacher.email = request.POST.get("email")
|
||||
teacher.phone = request.POST.get("phone")
|
||||
teacher.dob = request.POST.get("dob")
|
||||
teacher.gender = request.POST.get("gender")
|
||||
teacher.address = request.POST.get("address")
|
||||
teacher.qualification = request.POST.get("qualification")
|
||||
teacher.specialization_on = request.POST.get("specialization_on")
|
||||
teacher.marital_status = request.POST.get("marital_status")
|
||||
teacher.date_of_joining = request.POST.get("date_of_joining")
|
||||
teacher.save()
|
||||
|
||||
messages.success(request, "Teacher updated successfully!")
|
||||
return redirect("manage_teacher")
|
||||
except Exception as e:
|
||||
messages.error(request, f"Error updating teacher: {e}")
|
||||
|
||||
context = {
|
||||
**admin_site.each_context(request),
|
||||
"title": "Edit Teacher",
|
||||
"teacher": teacher,
|
||||
"qualification_choices": dict(Teacher.qualification_choice).items(),
|
||||
"marital_status_choices": dict(Teacher.marital_status_choice).items(),
|
||||
}
|
||||
return render(request, "hod/edit_teacher.html", context)
|
||||
|
||||
|
||||
def delete_teacher(request, teacher_id):
|
||||
teacher = get_object_or_404(Teacher, id=teacher_id)
|
||||
teacher.delete()
|
||||
messages.success(request, "Teacher deleted successfully!")
|
||||
return redirect("manage_teacher")
|
||||
|
||||
|
||||
def student_feedback_message(request):
|
||||
feedbacks = FeedbackStudent.objects.all()
|
||||
context = {
|
||||
**admin_site.each_context(request),
|
||||
"title": "Student's Feedback",
|
||||
"feedbacks": feedbacks,
|
||||
}
|
||||
return render(request, "hod/student_feedback.html", context)
|
||||
|
||||
|
||||
@csrf_exempt
|
||||
def student_feedback_message_reply(request):
|
||||
feedback_id = request.POST.get("id")
|
||||
feedback_reply = request.POST.get("reply")
|
||||
|
||||
try:
|
||||
feedback = FeedbackStudent.objects.get(id=feedback_id)
|
||||
feedback.feedback_reply = feedback_reply
|
||||
feedback.save()
|
||||
return HttpResponse("True")
|
||||
|
||||
except:
|
||||
return HttpResponse("False")
|
||||
|
||||
|
||||
def teacher_feedback(request):
|
||||
feedbacks = FeedbackTeacher.objects.all()
|
||||
context = {
|
||||
**admin_site.each_context(request),
|
||||
"title": "Staff's Feedback",
|
||||
"feedbacks": feedbacks,
|
||||
}
|
||||
return render(request, "hod/teacher_feedback.html", context)
|
||||
|
||||
|
||||
@csrf_exempt
|
||||
def teacher_feedback_replied(request):
|
||||
feedback_id = request.POST.get("id")
|
||||
feedback_message = request.POST.get("message")
|
||||
|
||||
try:
|
||||
feedback = FeedbackTeacher.objects.get(id=feedback_id)
|
||||
feedback.feedback_reply = feedback_message
|
||||
feedback.save()
|
||||
return HttpResponse("True")
|
||||
except Exception:
|
||||
return HttpResponse("False")
|
||||
|
||||
|
||||
def student_leave_view(request):
|
||||
leaves = LeaveReportStudent.objects.all()
|
||||
context = {
|
||||
**admin_site.each_context(request),
|
||||
"title": "Student Application",
|
||||
"leaves": leaves,
|
||||
}
|
||||
return render(request, "hod/student_leave_view.html", context)
|
||||
|
||||
|
||||
def student_leave_approve(request, leave_id):
|
||||
leave = LeaveReportStudent.objects.get(id=leave_id)
|
||||
leave.leave_status = 1
|
||||
leave.save()
|
||||
return HttpResponseRedirect(reverse("student_leave_view"))
|
||||
|
||||
|
||||
def student_leave_reject(request, leave_id):
|
||||
leave = LeaveReportStudent.objects.get(id=leave_id)
|
||||
leave.leave_status = 2
|
||||
leave.save()
|
||||
return HttpResponseRedirect(reverse("student_leave_view"))
|
||||
|
||||
|
||||
def teacher_leave_view(request):
|
||||
leaves = LeaveReportTeacher.objects.all()
|
||||
context = {
|
||||
**admin_site.each_context(request),
|
||||
"title": "Teacher Application",
|
||||
"leaves": leaves,
|
||||
}
|
||||
return render(request, "hod/teacher_leave_view.html", context)
|
||||
|
||||
|
||||
def teacher_leave_approve(request, leave_id):
|
||||
leave = LeaveReportTeacher.objects.get(id=leave_id)
|
||||
leave.leave_status = 1
|
||||
leave.save()
|
||||
return HttpResponseRedirect(reverse("teacher_leave_view"))
|
||||
|
||||
|
||||
def teacher_leave_reject(request, leave_id):
|
||||
leave = LeaveReportTeacher.objects.get(id=leave_id)
|
||||
leave.leave_status = 2
|
||||
leave.save()
|
||||
return HttpResponseRedirect(reverse("teacher_leave_view"))
|
||||
|
||||
|
||||
def admin_view_attendance(request):
|
||||
subjects = Subject.objects.all()
|
||||
academic_years = AcademicYear.objects.all()
|
||||
context = {
|
||||
**admin_site.each_context(request),
|
||||
"subjects": subjects,
|
||||
"academic_years": academic_years,
|
||||
}
|
||||
return render(request, "hod/view_attendance.html", context)
|
||||
|
||||
|
||||
@csrf_exempt
|
||||
def admin_get_attendance_dates(request):
|
||||
# Getting Values from Ajax POST 'Fetch Student'
|
||||
subject_id = request.POST.get("subject")
|
||||
academic_year = request.POST.get("academic_year_id")
|
||||
|
||||
# Students enroll to Course, Course has Subjects
|
||||
# Getting all data from subject model based on subject_id
|
||||
subject_model = Subject.objects.get(id=subject_id)
|
||||
|
||||
academic_model = AcademicYear.objects.get(id=academic_year)
|
||||
|
||||
# students = Students.objects.filter(course_id=subject_model.course_id, session_year_id=session_model)
|
||||
attendance = Attendance.objects.filter(
|
||||
subject_id=subject_model, academic_year_id=academic_model
|
||||
)
|
||||
|
||||
# Only Passing Student Id and Student Name Only
|
||||
list_data = []
|
||||
|
||||
for attendance_single in attendance:
|
||||
data_small = {
|
||||
"id": attendance_single.id,
|
||||
"attendance_date": str(attendance_single.attendance_date),
|
||||
"academic_year_id": attendance_single.academic_year_id.id,
|
||||
}
|
||||
list_data.append(data_small)
|
||||
|
||||
return JsonResponse(
|
||||
json.dumps(list_data), content_type="application/json", safe=False
|
||||
)
|
||||
|
||||
|
||||
@csrf_exempt
|
||||
def admin_get_attendance_student(request):
|
||||
# Getting Values from Ajax POST 'Fetch Student'
|
||||
attendance_date = request.POST.get("attendance_date")
|
||||
attendance = Attendance.objects.get(id=attendance_date)
|
||||
|
||||
attendance_data = AttendanceReport.objects.filter(attendance_id=attendance)
|
||||
# Only Passing Student Id and Student Name Only
|
||||
list_data = []
|
||||
|
||||
for student in attendance_data:
|
||||
data_small = {
|
||||
"id": student.student_id.id,
|
||||
"name": student.student_id.first_name + " " + student.student_id.last_name,
|
||||
"status": student.status,
|
||||
}
|
||||
list_data.append(data_small)
|
||||
|
||||
return JsonResponse(
|
||||
json.dumps(list_data), content_type="application/json", safe=False
|
||||
)
|
||||
+2
-2
@@ -2,5 +2,5 @@ from django.apps import AppConfig
|
||||
|
||||
|
||||
class AppConfig(AppConfig):
|
||||
default_auto_field = 'django.db.models.BigAutoField'
|
||||
name = 'app'
|
||||
default_auto_field = "django.db.models.BigAutoField"
|
||||
name = "app"
|
||||
@@ -0,0 +1,29 @@
|
||||
# Generated by Django 5.1.5 on 2025-01-18 06:51
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("app", "0008_alter_leavereportstudent_leave_date_and_more"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RemoveField(
|
||||
model_name="student",
|
||||
name="password",
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name="student",
|
||||
name="username",
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name="teacher",
|
||||
name="password",
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name="teacher",
|
||||
name="username",
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,18 @@
|
||||
# Generated by Django 5.1.5 on 2025-01-18 07:59
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("app", "0009_remove_student_password_remove_student_username_and_more"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name="feedbackstudent",
|
||||
name="feedback_reply",
|
||||
field=models.TextField(blank=True, null=True),
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,23 @@
|
||||
# Generated by Django 5.1.5 on 2025-01-18 09:04
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("app", "0010_alter_feedbackstudent_feedback_reply"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RenameField(
|
||||
model_name="feedbackteacher",
|
||||
old_name="staff_id",
|
||||
new_name="teacher_id",
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="feedbackteacher",
|
||||
name="feedback_reply",
|
||||
field=models.TextField(blank=True, null=True),
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,18 @@
|
||||
# Generated by Django 5.1.5 on 2025-01-18 09:48
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("app", "0011_rename_staff_id_feedbackteacher_teacher_id_and_more"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RenameField(
|
||||
model_name="attendance",
|
||||
old_name="academic_year",
|
||||
new_name="academic_year_id",
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,72 @@
|
||||
# Generated by Django 5.1.5 on 2025-01-18 10:24
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("app", "0012_rename_academic_year_attendance_academic_year_id"),
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name="student",
|
||||
name="fcm_token",
|
||||
field=models.TextField(default=""),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="student",
|
||||
name="password",
|
||||
field=models.CharField(default="1", max_length=255),
|
||||
preserve_default=False,
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="student",
|
||||
name="user",
|
||||
field=models.OneToOneField(
|
||||
default="1",
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
related_name="student",
|
||||
to=settings.AUTH_USER_MODEL,
|
||||
),
|
||||
preserve_default=False,
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="student",
|
||||
name="username",
|
||||
field=models.CharField(default="1", max_length=255),
|
||||
preserve_default=False,
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="teacher",
|
||||
name="fcm_token",
|
||||
field=models.TextField(default=""),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="teacher",
|
||||
name="password",
|
||||
field=models.CharField(default="1", max_length=255),
|
||||
preserve_default=False,
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="teacher",
|
||||
name="user",
|
||||
field=models.OneToOneField(
|
||||
default="1",
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
related_name="teacher",
|
||||
to=settings.AUTH_USER_MODEL,
|
||||
),
|
||||
preserve_default=False,
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="teacher",
|
||||
name="username",
|
||||
field=models.CharField(default="1", max_length=255),
|
||||
preserve_default=False,
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,29 @@
|
||||
# Generated by Django 5.1.5 on 2025-01-18 10:39
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("app", "0013_student_fcm_token_student_password_student_user_and_more"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RemoveField(
|
||||
model_name="student",
|
||||
name="user",
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name="student",
|
||||
name="username",
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name="teacher",
|
||||
name="user",
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name="teacher",
|
||||
name="username",
|
||||
),
|
||||
]
|
||||
+7
-7
@@ -1,6 +1,6 @@
|
||||
from django.db import models
|
||||
from django.core.validators import RegexValidator, ValidationError
|
||||
|
||||
from django.contrib.auth.models import User
|
||||
# Create your models here.
|
||||
|
||||
|
||||
@@ -15,8 +15,8 @@ class Student(models.Model):
|
||||
academic_year = models.ForeignKey(
|
||||
"AcademicYear", on_delete=models.CASCADE, related_name="students"
|
||||
)
|
||||
username = models.CharField(max_length=255)
|
||||
password = models.CharField(max_length=255)
|
||||
fcm_token = models.TextField(default="")
|
||||
phone = models.CharField(
|
||||
max_length=10, validators=[RegexValidator(r"^\+?1?\d{9,15}$")]
|
||||
)
|
||||
@@ -80,7 +80,7 @@ class Teacher(models.Model):
|
||||
dob = models.DateField()
|
||||
gender = models.CharField(max_length=1, choices=[("M", "Male"), ("F", "Female")])
|
||||
address = models.CharField(max_length=255)
|
||||
username = models.CharField(max_length=255)
|
||||
fcm_token = models.TextField(default="")
|
||||
password = models.CharField(max_length=255)
|
||||
qualification_choice = (
|
||||
("SLC", "SLC"),
|
||||
@@ -181,8 +181,8 @@ class Attendance(models.Model): # Subject Attendance
|
||||
id = models.AutoField(primary_key=True)
|
||||
subject_id = models.ForeignKey(Subject, on_delete=models.DO_NOTHING)
|
||||
attendance_date = models.DateField()
|
||||
academic_year_id = models.ForeignKey(AcademicYear, on_delete=models.CASCADE)
|
||||
created_at = models.DateTimeField(auto_now_add=True)
|
||||
academic_year = models.ForeignKey(AcademicYear, on_delete=models.CASCADE)
|
||||
updated_at = models.DateTimeField(auto_now=True)
|
||||
|
||||
|
||||
@@ -219,15 +219,15 @@ class FeedbackStudent(models.Model):
|
||||
id = models.AutoField(primary_key=True)
|
||||
student_id = models.ForeignKey(Student, on_delete=models.CASCADE)
|
||||
feedback = models.TextField()
|
||||
feedback_reply = models.TextField()
|
||||
feedback_reply = models.TextField(blank=True, null=True)
|
||||
created_at = models.DateTimeField(auto_now_add=True)
|
||||
updated_at = models.DateTimeField(auto_now=True)
|
||||
|
||||
|
||||
class FeedbackTeacher(models.Model):
|
||||
id = models.AutoField(primary_key=True)
|
||||
staff_id = models.ForeignKey(Teacher, on_delete=models.CASCADE)
|
||||
teacher_id = models.ForeignKey(Teacher, on_delete=models.CASCADE)
|
||||
feedback = models.TextField()
|
||||
feedback_reply = models.TextField()
|
||||
feedback_reply = models.TextField(blank=True, null=True)
|
||||
created_at = models.DateTimeField(auto_now_add=True)
|
||||
updated_at = models.DateTimeField(auto_now=True)
|
||||
@@ -0,0 +1,163 @@
|
||||
from django.contrib.auth.decorators import login_required
|
||||
|
||||
from django.shortcuts import render
|
||||
|
||||
|
||||
@login_required
|
||||
def student_dashboard(request):
|
||||
return render(request, "student/dashboard.html") # Student-specific page
|
||||
|
||||
|
||||
# @login_required
|
||||
# @student_required
|
||||
# def student_view_attendance(request):
|
||||
# student = Student.objects.get(admin=request.user.id)
|
||||
# course = student.course_id
|
||||
# subjects = Subject.objects.filter(course_id=course)
|
||||
# student = Student.objects.get(admin=user)
|
||||
# student_notifcation = Student.objects.get(admin=request.user.id)
|
||||
# notifications = NotificationStudent.objects.filter(
|
||||
# student_id=student_notifcation.id
|
||||
# )
|
||||
# return render(
|
||||
# request,
|
||||
# "student_template/student_view_attendance.html",
|
||||
# {"subjects": subjects, "student": student, "notifications": notifications},
|
||||
# )
|
||||
#
|
||||
#
|
||||
# @login_required
|
||||
# @student_required
|
||||
# def student_view_attendance_post(request):
|
||||
# subject_id = request.POST.get("subject")
|
||||
# start_date = request.POST.get("start_date")
|
||||
# end_date = request.POST.get("end_date")
|
||||
#
|
||||
# start_data_parse = datetime.datetime.strptime(start_date, "%Y-%m-%d").date()
|
||||
# end_data_parse = datetime.datetime.strptime(end_date, "%Y-%m-%d").date()
|
||||
# subject_obj = Subjects.objects.get(id=subject_id)
|
||||
# user_object = CustomUser.objects.get(id=request.user.id)
|
||||
# stud_obj = Students.objects.get(admin=user_object)
|
||||
# user = CustomUser.objects.get(id=request.user.id)
|
||||
# student = Students.objects.get(admin=user)
|
||||
# student_notifcation = Students.objects.get(admin=request.user.id)
|
||||
# notifications = NotificationStudent.objects.filter(
|
||||
# student_id=student_notifcation.id
|
||||
# )
|
||||
#
|
||||
# attendance = Attendance.objects.filter(
|
||||
# attendance_date__range=(start_data_parse, end_data_parse),
|
||||
# subject_id=subject_obj,
|
||||
# )
|
||||
# attendance_reports = AttendanceReport.objects.filter(
|
||||
# attendance_id__in=attendance, student_id=stud_obj
|
||||
# )
|
||||
# return render(
|
||||
# request,
|
||||
# "student_template/student_attendance_data.html",
|
||||
# {
|
||||
# "attendance_reports": attendance_reports,
|
||||
# "student": student,
|
||||
# "notifications": notifications,
|
||||
# },
|
||||
# )
|
||||
#
|
||||
#
|
||||
# @login_required
|
||||
# @student_required
|
||||
# def student_apply_leave(request):
|
||||
# student_obj = Student.objects.get(admin=request.user.id)
|
||||
# leave_data = LeaveReportStudent.objects.filter(student_id=student_obj)
|
||||
# user = CustomUser.objects.get(id=request.user.id)
|
||||
# student = Student.objects.get(admin=user)
|
||||
# student_notifcation = Student.objects.get(admin=request.user.id)
|
||||
# notifications = NotificationStudent.objects.filter(
|
||||
# student_id=student_notifcation.id
|
||||
# )
|
||||
# return render(
|
||||
# request,
|
||||
# "student/apply_leave.html",
|
||||
# {"leave_data": leave_data, "student": student, "notifications": notifications},
|
||||
# )
|
||||
#
|
||||
#
|
||||
# @login_required
|
||||
# @student_required
|
||||
# def student_apply_leave_save(request):
|
||||
# if request.method != "POST":
|
||||
# return HttpResponseRedirect(reverse("student_apply_leave"))
|
||||
# else:
|
||||
# leave_start_date = request.POST.get("leave_start_date")
|
||||
# leave_end_date = request.POST.get("leave_end_date")
|
||||
# leave_date = request.POST.get("leave_date")
|
||||
# leave_msg = request.POST.get("leave_msg")
|
||||
#
|
||||
# student_obj = Student.objects.get(admin=request.user.id)
|
||||
# try:
|
||||
# leave_report = LeaveReportStudent(
|
||||
# student_id=student_obj,
|
||||
# leave_start_date=leave_start_date,
|
||||
# leave_end_date=leave_end_date,
|
||||
# leave_message=leave_msg,
|
||||
# leave_status=0,
|
||||
# )
|
||||
# leave_report.save()
|
||||
# messages.success(request, "Successfully Applied for Leave")
|
||||
# return HttpResponseRedirect(reverse("student_apply_leave"))
|
||||
# except:
|
||||
# messages.error(request, "Failed To Apply for Leave")
|
||||
# return HttpResponseRedirect(reverse("student_apply_leave"))
|
||||
#
|
||||
#
|
||||
# @login_required
|
||||
# @student_required
|
||||
# def student_feedback(request):
|
||||
# staff_id = Student.objects.get(admin=request.user.id)
|
||||
# feedback_data = FeedBackStudent.objects.filter(student_id=staff_id)
|
||||
# student = Student.objects.get(admin=user)
|
||||
# student_notifcation = Student.objects.get(admin=request.user.id)
|
||||
# notifications = NotificationStudent.objects.filter(
|
||||
# student_id=student_notifcation.id
|
||||
# )
|
||||
# return render(
|
||||
# request,
|
||||
# "student_template/student_feedback.html",
|
||||
# {
|
||||
# "feedback_data": feedback_data,
|
||||
# "student": student,
|
||||
# "notifications": notifications,
|
||||
# },
|
||||
# )
|
||||
#
|
||||
#
|
||||
# @login_required
|
||||
# @student_required
|
||||
# def student_feedback_save(request):
|
||||
# if request.method != "POST":
|
||||
# return HttpResponseRedirect(reverse("student_feedback"))
|
||||
# else:
|
||||
# feedback_msg = request.POST.get("feedback_msg")
|
||||
#
|
||||
# student_obj = Student.objects.get(admin=request.user.id)
|
||||
# try:
|
||||
# feedback = FeedBackStudent(
|
||||
# student_id=student_obj, feedback=feedback_msg, feedback_reply=""
|
||||
# )
|
||||
# feedback.save()
|
||||
# messages.success(request, "Feedback submitted for review")
|
||||
# return HttpResponseRedirect(reverse("student_feedback"))
|
||||
# except:
|
||||
# messages.error(request, "Could not Submit")
|
||||
# return HttpResponseRedirect(reverse("student_feedback"))
|
||||
#
|
||||
#
|
||||
# @csrf_exempt
|
||||
# def student_fcmtoken_save(request):
|
||||
# token = request.POST.get("token")
|
||||
# try:
|
||||
# student = Student.objects.get(admin=request.user.id)
|
||||
# student.fcm_token = token
|
||||
# student.save()
|
||||
# return HttpResponse("True")
|
||||
# except:
|
||||
# return HttpResponse("False")
|
||||
@@ -0,0 +1,7 @@
|
||||
from django.shortcuts import render
|
||||
from django.contrib.auth.decorators import login_required
|
||||
|
||||
|
||||
@login_required
|
||||
def teacher_dashboard(request):
|
||||
return render(request, "teacher/dashboard.html")
|
||||
+90
-2
@@ -1,5 +1,5 @@
|
||||
from django.urls import path
|
||||
from app import adminViews
|
||||
from app import adminViews, studentViews, teacherViews
|
||||
|
||||
urlpatterns = [
|
||||
path("dashboard/", adminViews.admin_home, name="dashboard"),
|
||||
@@ -29,5 +29,93 @@ urlpatterns = [
|
||||
path(
|
||||
"delete_subject/<subject_id>/", adminViews.delete_subject, name="delete_subject"
|
||||
),
|
||||
path("manage_student/", adminViews.manage_student, name="manage_student"),
|
||||
path("add_student/", adminViews.add_student, name="add_student"),
|
||||
path(
|
||||
"edit_student/<int:student_id>/", adminViews.edit_student, name="edit_student"
|
||||
),
|
||||
path(
|
||||
"delete_student/<int:student_id>/",
|
||||
adminViews.delete_student,
|
||||
name="delete_student",
|
||||
),
|
||||
path("manage_teacher/", adminViews.manage_teacher, name="manage_teacher"),
|
||||
path("add_teacher/", adminViews.add_teacher, name="add_teacher"),
|
||||
path(
|
||||
"edit_teacher/<int:teacher_id>/", adminViews.edit_teacher, name="edit_teacher"
|
||||
),
|
||||
path(
|
||||
"delete_teacher/<int:teacher_id>/",
|
||||
adminViews.delete_teacher,
|
||||
name="delete_teacher",
|
||||
),
|
||||
path(
|
||||
"student_feedback_message/",
|
||||
adminViews.student_feedback_message,
|
||||
name="student_feedback_message",
|
||||
),
|
||||
path(
|
||||
"student_feedback_message_reply/",
|
||||
adminViews.student_feedback_message_reply,
|
||||
name="student_feedback_message_reply",
|
||||
),
|
||||
path(
|
||||
"teacher_feedback/",
|
||||
adminViews.teacher_feedback,
|
||||
name="teacher_feedback",
|
||||
),
|
||||
path(
|
||||
"teacher_feedback_replied/",
|
||||
adminViews.teacher_feedback_replied,
|
||||
name="teacher_feedback_replied",
|
||||
),
|
||||
path(
|
||||
"student_leave_view/", adminViews.student_leave_view, name="student_leave_view"
|
||||
),
|
||||
path(
|
||||
"student_leave_approve/<leave_id>/",
|
||||
adminViews.student_leave_approve,
|
||||
name="student_leave_approve",
|
||||
),
|
||||
path(
|
||||
"student_leave_reject/<leave_id>/",
|
||||
adminViews.student_leave_reject,
|
||||
name="student_leave_reject",
|
||||
),
|
||||
path(
|
||||
"teacher_leave_view/", adminViews.teacher_leave_view, name="teacher_leave_view"
|
||||
),
|
||||
path(
|
||||
"teacher_leave_approve/<leave_id>/",
|
||||
adminViews.teacher_leave_approve,
|
||||
name="teacher_leave_approve",
|
||||
),
|
||||
path(
|
||||
"teacher_leave_reject/<leave_id>/",
|
||||
adminViews.teacher_leave_reject,
|
||||
name="teacher_leave_reject",
|
||||
),
|
||||
path(
|
||||
"admin_view_attendance/",
|
||||
adminViews.admin_view_attendance,
|
||||
name="admin_view_attendance",
|
||||
),
|
||||
path(
|
||||
"admin_get_attendance_dates/",
|
||||
adminViews.admin_get_attendance_dates,
|
||||
name="admin_get_attendance_dates",
|
||||
),
|
||||
path(
|
||||
"admin_get_attendance_student/",
|
||||
adminViews.admin_get_attendance_student,
|
||||
name="admin_get_attendance_student",
|
||||
),
|
||||
# ── Student ───────────────────────────────────────────────────────────
|
||||
path(
|
||||
"student_dashboard/", studentViews.student_dashboard, name="student_dashboard"
|
||||
),
|
||||
# ── teacher ───────────────────────────────────────────────────────────
|
||||
path(
|
||||
"teacher_dashboard/", teacherViews.teacher_dashboard, name="teacher_dashboard"
|
||||
),
|
||||
]
|
||||
|
||||
+1
-1
@@ -2,5 +2,5 @@ from django.contrib.auth import authenticate, login, logout
|
||||
from django.http import HttpResponseRedirect, HttpResponse
|
||||
from django.shortcuts import render, redirect
|
||||
from django.contrib import messages
|
||||
|
||||
from django.contrib.auth.decorators import login_required
|
||||
# Create your views here.
|
||||
@@ -16,6 +16,7 @@ from student_management_system.jazzmin import JAZZMIN_SETTINGS, JAZZMIN_UI_TWEAK
|
||||
# Build paths inside the project like this: BASE_DIR / 'subdir'.
|
||||
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
|
||||
|
||||
# Quick-start development settings - unsuitable for production
|
||||
# See https://docs.djangoproject.com/en/5.1/howto/deployment/checklist/
|
||||
|
||||
|
||||
@@ -0,0 +1,149 @@
|
||||
{% extends "admin/base_site.html" %}
|
||||
{% block page_title %}{{ title }}{% endblock %}
|
||||
{% load static %}
|
||||
{% block extrastyle %}
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css"
|
||||
rel="stylesheet" />
|
||||
{% endblock %}
|
||||
{% block content %}
|
||||
<div class="container mt-4">
|
||||
<h2 class="mb-4">Add Student</h2>
|
||||
<form method="POST">
|
||||
{% csrf_token %}
|
||||
<div class="row">
|
||||
<!-- Name Fields -->
|
||||
<div class="col-md-4 mb-3">
|
||||
<label for="first_name" class="form-label">First Name</label>
|
||||
<input type="text"
|
||||
class="form-control"
|
||||
id="first_name"
|
||||
name="first_name"
|
||||
required />
|
||||
</div>
|
||||
<div class="col-md-4 mb-3">
|
||||
<label for="middle_name" class="form-label">Middle Name</label>
|
||||
<input type="text" class="form-control" id="middle_name" name="middle_name" />
|
||||
</div>
|
||||
<div class="col-md-4 mb-3">
|
||||
<label for="last_name" class="form-label">Last Name</label>
|
||||
<input type="text"
|
||||
class="form-control"
|
||||
id="last_name"
|
||||
name="last_name"
|
||||
required />
|
||||
</div>
|
||||
<!-- Course and Academic Year -->
|
||||
<div class="col-md-6 mb-3">
|
||||
<label for="course" class="form-label">Course</label>
|
||||
<select class="form-select" id="course" name="course" required>
|
||||
<option value="">Select Course</option>
|
||||
{% for course in courses %}<option value="{{ course.id }}">{{ course.name }}</option>{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-6 mb-3">
|
||||
<label for="academic_year" class="form-label">Academic Year</label>
|
||||
<select class="form-select" id="academic_year" name="academic_year" required>
|
||||
<option value="">Select Academic Year</option>
|
||||
{% for year in academic_years %}<option value="{{ year.id }}">{{ year.start_date }}</option>{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
<!-- Personal Information -->
|
||||
<div class="col-md-6 mb-3">
|
||||
<label for="email" class="form-label">Email</label>
|
||||
<input type="email" class="form-control" id="email" name="email" required />
|
||||
</div>
|
||||
<div class="col-md-6 mb-3">
|
||||
<label for="phone" class="form-label">Phone</label>
|
||||
<input type="text" class="form-control" id="phone" name="phone" required />
|
||||
</div>
|
||||
<div class="col-md-6 mb-3">
|
||||
<label for="dob" class="form-label">Date of Birth</label>
|
||||
<input type="date" class="form-control" id="dob" name="dob" required />
|
||||
</div>
|
||||
<div class="col-md-6 mb-3">
|
||||
<label for="gender" class="form-label">Gender</label>
|
||||
<select class="form-select" id="gender" name="gender" required>
|
||||
<option value="">Select Gender</option>
|
||||
<option value="M">Male</option>
|
||||
<option value="F">Female</option>
|
||||
</select>
|
||||
</div>
|
||||
<!-- Address -->
|
||||
<div class="col-12 mb-3">
|
||||
<label for="address" class="form-label">Address</label>
|
||||
<textarea class="form-control" id="address" name="address" rows="3" required></textarea>
|
||||
</div>
|
||||
<!-- Parent Information -->
|
||||
<div class="col-md-6 mb-3">
|
||||
<label for="father_name" class="form-label">Father's Name</label>
|
||||
<input type="text"
|
||||
class="form-control"
|
||||
id="father_name"
|
||||
name="father_name"
|
||||
required />
|
||||
</div>
|
||||
<div class="col-md-6 mb-3">
|
||||
<label for="mother_name" class="form-label">Mother's Name</label>
|
||||
<input type="text"
|
||||
class="form-control"
|
||||
id="mother_name"
|
||||
name="mother_name"
|
||||
required />
|
||||
</div>
|
||||
<div class="col-md-6 mb-3">
|
||||
<label for="parents_number" class="form-label">Parents' Contact Number</label>
|
||||
<input type="text"
|
||||
class="form-control"
|
||||
id="parents_number"
|
||||
name="parents_number"
|
||||
required />
|
||||
</div>
|
||||
<div class="col-md-6 mb-3">
|
||||
<label for="father_occupation" class="form-label">Father's Occupation</label>
|
||||
<select class="form-select" id="father_occupation" name="father_occupation">
|
||||
<option value="">Select Occupation</option>
|
||||
{% for key, value in occupation_choices %}<option value="{{ key }}">{{ value }}</option>{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-6 mb-3">
|
||||
<label for="mother_occupation" class="form-label">Mother's Occupation</label>
|
||||
<select class="form-select" id="mother_occupation" name="mother_occupation">
|
||||
<option value="">Select Occupation</option>
|
||||
{% for key, value in occupation_choices %}<option value="{{ key }}">{{ value }}</option>{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
<!-- Guardian Information -->
|
||||
<div class="col-md-6 mb-3">
|
||||
<label for="guardian_name" class="form-label">Guardian's Name</label>
|
||||
<input type="text"
|
||||
class="form-control"
|
||||
id="guardian_name"
|
||||
name="guardian_name"
|
||||
required />
|
||||
</div>
|
||||
<div class="col-md-6 mb-3">
|
||||
<label for="guardian_number" class="form-label">Guardian's Contact</label>
|
||||
<input type="text"
|
||||
class="form-control"
|
||||
id="guardian_number"
|
||||
name="guardian_number"
|
||||
required />
|
||||
</div>
|
||||
<div class="col-md-6 mb-3">
|
||||
<label for="relationship_with_student" class="form-label">Relationship with Student</label>
|
||||
<select class="form-select"
|
||||
id="relationship_with_student"
|
||||
name="relationship_with_student"
|
||||
required>
|
||||
<option value="">Select Relationship</option>
|
||||
{% for key, value in relationship_choices %}<option value="{{ key }}">{{ value }}</option>{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-center mt-4">
|
||||
<button type="submit" class="btn btn-primary">Save</button>
|
||||
<a href="{% url 'manage_student' %}" class="btn btn-secondary">Cancel</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,100 @@
|
||||
{% extends 'admin/base_site.html' %}
|
||||
{% block content %}
|
||||
<div class="container mt-4">
|
||||
<h2 class="mb-4">{{ title }}</h2>
|
||||
<form method="POST" action="{% url 'add_teacher' %}">
|
||||
{% csrf_token %}
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<label for="first_name">First Name</label>
|
||||
<input type="text"
|
||||
class="form-control"
|
||||
id="first_name"
|
||||
name="first_name"
|
||||
required>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label for="middle_name">Middle Name</label>
|
||||
<input type="text" class="form-control" id="middle_name" name="middle_name">
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label for="last_name">Last Name</label>
|
||||
<input type="text"
|
||||
class="form-control"
|
||||
id="last_name"
|
||||
name="last_name"
|
||||
required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mt-3">
|
||||
<div class="col-md-6">
|
||||
<label for="email">Email</label>
|
||||
<input type="email" class="form-control" id="email" name="email" required>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label for="phone">Phone</label>
|
||||
<input type="text" class="form-control" id="phone" name="phone" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mt-3">
|
||||
<div class="col-md-4">
|
||||
<label for="dob">Date of Birth</label>
|
||||
<input type="date" class="form-control" id="dob" name="dob" required>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label for="gender">Gender</label>
|
||||
<select class="form-control" id="gender" name="gender" required>
|
||||
<option value="">Select Gender</option>
|
||||
<option value="M">Male</option>
|
||||
<option value="F">Female</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label for="qualification">Qualification</label>
|
||||
<select class="form-control" id="qualification" name="qualification" required>
|
||||
<option value="">Select Qualification</option>
|
||||
{% for key, value in qualification_choices %}<option value="{{ key }}">{{ value }}</option>{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mt-3">
|
||||
<div class="col-md-6">
|
||||
<label for="specialization_on">Specialization</label>
|
||||
<input type="text"
|
||||
class="form-control"
|
||||
id="specialization_on"
|
||||
name="specialization_on"
|
||||
required>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label for="marital_status">Marital Status</label>
|
||||
<select class="form-control"
|
||||
id="marital_status"
|
||||
name="marital_status"
|
||||
required>
|
||||
<option value="">Select Status</option>
|
||||
{% for key, value in marital_status_choices %}<option value="{{ key }}">{{ value }}</option>{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mt-3">
|
||||
<div class="col-md-6">
|
||||
<label for="date_of_joining">Date of Joining</label>
|
||||
<input type="date"
|
||||
class="form-control"
|
||||
id="date_of_joining"
|
||||
name="date_of_joining"
|
||||
required>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label for="address">Address</label>
|
||||
<textarea class="form-control" id="address" name="address" rows="2" required></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-right mt-4">
|
||||
<button type="submit" class="btn btn-primary">Add Teacher</button>
|
||||
<a href="{% url 'manage_teacher' %}" class="btn btn-secondary">Cancel</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,212 @@
|
||||
{% extends "admin/base_site.html" %}
|
||||
{% load static %}
|
||||
{% block extrastyle %}
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css"
|
||||
rel="stylesheet" />
|
||||
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css"
|
||||
rel="stylesheet" />
|
||||
<style>
|
||||
.page-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 1rem;
|
||||
background-color: #f8f9fa;
|
||||
border-bottom: 1px solid #dee2e6;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
</style>
|
||||
{% endblock %}
|
||||
{% block content %}
|
||||
<div class="container mt-4">
|
||||
<div class ="page-header">
|
||||
<h1 class="page-title">
|
||||
<i class="nav-icon fas fa-edit"></i>
|
||||
Edit Student
|
||||
</h1>
|
||||
<a href="{% url 'manage_student' %}" class="btn btn-primary">
|
||||
<i class="fas fa-list"></i> Back to Student
|
||||
</a>
|
||||
</div>
|
||||
<form method="POST" action="{% url 'edit_student' student.id %}">
|
||||
{% csrf_token %}
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<label for="first_name">First Name</label>
|
||||
<input type="text"
|
||||
class="form-control"
|
||||
id="first_name"
|
||||
name="first_name"
|
||||
value="{{ student.first_name }}"
|
||||
required>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label for="middle_name">Middle Name</label>
|
||||
<input type="text"
|
||||
class="form-control"
|
||||
id="middle_name"
|
||||
name="middle_name"
|
||||
value="{{ student.middle_name }}">
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label for="last_name">Last Name</label>
|
||||
<input type="text"
|
||||
class="form-control"
|
||||
id="last_name"
|
||||
name="last_name"
|
||||
value="{{ student.last_name }}"
|
||||
required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mt-3">
|
||||
<div class="col-md-4">
|
||||
<label for="email">Email</label>
|
||||
<input type="email"
|
||||
class="form-control"
|
||||
id="email"
|
||||
name="email"
|
||||
value="{{ student.email }}"
|
||||
required>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label for="phone">Phone</label>
|
||||
<input type="text"
|
||||
class="form-control"
|
||||
id="phone"
|
||||
name="phone"
|
||||
value="{{ student.phone }}"
|
||||
required>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label for="dob">Date of Birth</label>
|
||||
<input type="date"
|
||||
class="form-control"
|
||||
id="dob"
|
||||
name="dob"
|
||||
value="{{ student.dob|date:'Y-m-d' }}"
|
||||
required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mt-3">
|
||||
<div class="col-md-4">
|
||||
<label for="gender">Gender</label>
|
||||
<select class="form-control" id="gender" name="gender" required>
|
||||
<option value="M" {% if student.gender == "M" %}selected{% endif %}>Male</option>
|
||||
<option value="F" {% if student.gender == "F" %}selected{% endif %}>Female</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label for="course">Course</label>
|
||||
<select class="form-control" id="course" name="course" required>
|
||||
<option value="">Select Course</option>
|
||||
{% for course in courses %}
|
||||
<option value="{{ course.id }}"
|
||||
{% if student.course.id == course.id %}selected{% endif %}>
|
||||
{{ course.name }}
|
||||
</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label for="academic_year">Academic Year</label>
|
||||
<select class="form-control" id="academic_year" name="academic_year" required>
|
||||
<option value="">Select Academic Year</option>
|
||||
{% for year in academic_years %}
|
||||
<option value="{{ year.id }}"
|
||||
{% if student.academic_year.id == year.id %}selected{% endif %}>
|
||||
{{ year.start_date }}
|
||||
</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mt-3">
|
||||
<div class="col-md-4">
|
||||
<label for="father_name">Father's Name</label>
|
||||
<input type="text"
|
||||
class="form-control"
|
||||
id="father_name"
|
||||
name="father_name"
|
||||
value="{{ student.father_name }}"
|
||||
required>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label for="father_occupation">Father's Occupation</label>
|
||||
<select class="form-control"
|
||||
id="father_occupation"
|
||||
name="father_occupation"
|
||||
required>
|
||||
{% for key, value in occupation_choices %}
|
||||
<option value="{{ key }}"
|
||||
{% if student.father_occupation == key %}selected{% endif %}>{{ value }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label for="mother_name">Mother's Name</label>
|
||||
<input type="text"
|
||||
class="form-control"
|
||||
id="mother_name"
|
||||
name="mother_name"
|
||||
value="{{ student.mother_name }}"
|
||||
required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mt-3">
|
||||
<div class="col-md-4">
|
||||
<label for="mother_occupation">Mother's Occupation</label>
|
||||
<select class="form-control"
|
||||
id="mother_occupation"
|
||||
name="mother_occupation"
|
||||
required>
|
||||
{% for key, value in occupation_choices %}
|
||||
<option value="{{ key }}"
|
||||
{% if student.mother_occupation == key %}selected{% endif %}>{{ value }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label for="guardian_name">Guardian's Name</label>
|
||||
<input type="text"
|
||||
class="form-control"
|
||||
id="guardian_name"
|
||||
name="guardian_name"
|
||||
value="{{ student.guardian_name }}"
|
||||
required>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label for="guardian_number">Guardian's Number</label>
|
||||
<input type="text"
|
||||
class="form-control"
|
||||
id="guardian_number"
|
||||
name="guardian_number"
|
||||
value="{{ student.guardian_number }}"
|
||||
required>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label for="relationship_with_student">Relationship with Student</label>
|
||||
<select class="form-control"
|
||||
id="relationship_with_student"
|
||||
name="relationship_with_student"
|
||||
required>
|
||||
{% for key, value in relationship_choices %}
|
||||
<option value="{{ key }}"
|
||||
{% if student.relationship_with_student == key %}selected{% endif %}>
|
||||
{{ value }}
|
||||
</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group mt-3">
|
||||
<label for="address">Address</label>
|
||||
<textarea class="form-control" id="address" name="address" rows="3" required>{{ student.address }}</textarea>
|
||||
</div>
|
||||
<div class="text-right mt-4">
|
||||
<button type="submit" class="btn btn-primary">Update</button>
|
||||
<a href="{% url 'manage_student' %}" class="btn btn-secondary">Cancel</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,126 @@
|
||||
{% extends 'admin/base_site.html' %}
|
||||
{% block content %}
|
||||
<div class="container mt-4">
|
||||
<h2 class="mb-4">Edit Teacher</h2>
|
||||
<form method="POST" action="{% url 'edit_teacher' teacher.id %}">
|
||||
{% csrf_token %}
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<label for="first_name">First Name</label>
|
||||
<input type="text"
|
||||
class="form-control"
|
||||
id="first_name"
|
||||
name="first_name"
|
||||
value="{{ teacher.first_name }}"
|
||||
required>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label for="middle_name">Middle Name</label>
|
||||
<input type="text"
|
||||
class="form-control"
|
||||
id="middle_name"
|
||||
name="middle_name"
|
||||
value="{{ teacher.middle_name }}">
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label for="last_name">Last Name</label>
|
||||
<input type="text"
|
||||
class="form-control"
|
||||
id="last_name"
|
||||
name="last_name"
|
||||
value="{{ teacher.last_name }}"
|
||||
required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mt-3">
|
||||
<div class="col-md-6">
|
||||
<label for="email">Email</label>
|
||||
<input type="email"
|
||||
class="form-control"
|
||||
id="email"
|
||||
name="email"
|
||||
value="{{ teacher.email }}"
|
||||
required>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label for="phone">Phone</label>
|
||||
<input type="text"
|
||||
class="form-control"
|
||||
id="phone"
|
||||
name="phone"
|
||||
value="{{ teacher.phone }}"
|
||||
required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mt-3">
|
||||
<div class="col-md-4">
|
||||
<label for="dob">Date of Birth</label>
|
||||
<input type="date"
|
||||
class="form-control"
|
||||
id="dob"
|
||||
name="dob"
|
||||
value="{{ teacher.dob }}"
|
||||
required>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label for="gender">Gender</label>
|
||||
<select class="form-control" id="gender" name="gender" required>
|
||||
<option value="M" {% if teacher.gender == "M" %}selected{% endif %}>Male</option>
|
||||
<option value="F" {% if teacher.gender == "F" %}selected{% endif %}>Female</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label for="qualification">Qualification</label>
|
||||
<select class="form-control" id="qualification" name="qualification" required>
|
||||
{% for key, value in qualification_choices %}
|
||||
<option value="{{ key }}"
|
||||
{% if teacher.qualification == key %}selected{% endif %}>{{ value }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mt-3">
|
||||
<div class="col-md-6">
|
||||
<label for="specialization_on">Specialization</label>
|
||||
<input type="text"
|
||||
class="form-control"
|
||||
id="specialization_on"
|
||||
name="specialization_on"
|
||||
value="{{ teacher.specialization_on }}"
|
||||
required>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label for="marital_status">Marital Status</label>
|
||||
<select class="form-control"
|
||||
id="marital_status"
|
||||
name="marital_status"
|
||||
required>
|
||||
{% for key, value in marital_status_choices %}
|
||||
<option value="{{ key }}"
|
||||
{% if teacher.marital_status == key %}selected{% endif %}>{{ value }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mt-3">
|
||||
<div class="col-md-6">
|
||||
<label for="date_of_joining">Date of Joining</label>
|
||||
<input type="date"
|
||||
class="form-control"
|
||||
id="date_of_joining"
|
||||
name="date_of_joining"
|
||||
value="{{ teacher.date_of_joining }}"
|
||||
required>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label for="address">Address</label>
|
||||
<textarea class="form-control" id="address" name="address" rows="2" required>{{ teacher.address }}</textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-right mt-4">
|
||||
<button type="submit" class="btn btn-primary">Update Teacher</button>
|
||||
<a href="{% url 'manage_teacher' %}" class="btn btn-secondary">Cancel</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,65 @@
|
||||
{% extends "admin/base_site.html" %}
|
||||
{% block page_title %}{{ title }}{% endblock %}
|
||||
{% block content %}
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<h1 class="h3">Manage Students</h1>
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<a href="{% url 'add_student' %}" class="btn btn-primary">Add New Student</a>
|
||||
</div>
|
||||
</div>
|
||||
<form method="GET">
|
||||
<div class="row my-3">
|
||||
<div class="col-md-6">
|
||||
<input type="text"
|
||||
name="search"
|
||||
class="form-control"
|
||||
placeholder="Search students by name or email..."
|
||||
value="{{ search_query }}" />
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<button type="submit" class="btn btn-secondary">Search</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>S.N</th>
|
||||
<th>Full Name</th>
|
||||
<th>Course</th>
|
||||
<th>Academic Year</th>
|
||||
<th>Phone</th>
|
||||
<th>Email</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for student in students %}
|
||||
<tr>
|
||||
<td>{{ forloop.counter }}</td>
|
||||
<td>{{ student.first_name }}</td>
|
||||
<td>{{ student.course.name }}</td>
|
||||
<td>{{ student.academic_year.start_date|date:"Y" }}</td>
|
||||
<td>{{ student.phone }}</td>
|
||||
<td>{{ student.email }}</td>
|
||||
<td>
|
||||
<a href="{% url 'edit_student' student.id %}"
|
||||
class="btn btn-sm btn-warning">Edit</a>
|
||||
<a href="{% url 'delete_student' student.id %}"
|
||||
class="btn btn-sm btn-danger">Delete</a>
|
||||
</td>
|
||||
</tr>
|
||||
{% empty %}
|
||||
<tr>
|
||||
<td colspan="7" class="text-center">No students found</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -1,5 +1,5 @@
|
||||
{% extends "admin/base_site.html" %}
|
||||
{% block page_title %}Manage Subjects{% endblock %}
|
||||
{% block page_title %}{{ title }}{% endblock %}
|
||||
{% load static %}
|
||||
{% block extrastyle %}
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css"
|
||||
@@ -7,57 +7,122 @@
|
||||
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css"
|
||||
rel="stylesheet" />
|
||||
<style>
|
||||
.course-filter, .duration-filter {
|
||||
margin-bottom: 20px;
|
||||
.page-header {
|
||||
background-color: #f8f9fa;
|
||||
padding: 1rem;
|
||||
margin-bottom: 2rem;
|
||||
border-bottom: 1px solid #dee2e6;
|
||||
}
|
||||
|
||||
.card {
|
||||
box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);
|
||||
border-radius: 0.5rem;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.table {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.table thead th {
|
||||
background-color: #f8f9fa;
|
||||
border-bottom: 2px solid #dee2e6;
|
||||
color: #495057;
|
||||
font-weight: 600;
|
||||
text-transform: uppercase;
|
||||
font-size: 0.875rem;
|
||||
}
|
||||
|
||||
.table td {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.btn-action {
|
||||
padding: 0.375rem 0.75rem;
|
||||
font-size: 0.875rem;
|
||||
border-radius: 0.25rem;
|
||||
transition: all 0.2s ease-in-out;
|
||||
}
|
||||
|
||||
.btn-edit {
|
||||
background-color: #ffc107;
|
||||
border-color: #ffc107;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.btn-edit:hover {
|
||||
background-color: #e0a800;
|
||||
border-color: #d39e00;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.btn-delete {
|
||||
background-color: #dc3545;
|
||||
border-color: #dc3545;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.btn-delete:hover {
|
||||
background-color: #c82333;
|
||||
border-color: #bd2130;
|
||||
}
|
||||
|
||||
.empty-state {
|
||||
padding: 3rem;
|
||||
text-align: center;
|
||||
background-color: #f8f9fa;
|
||||
border-radius: 0.5rem;
|
||||
}
|
||||
|
||||
.empty-state-icon {
|
||||
font-size: 3rem;
|
||||
color: #6c757d;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.search-box {
|
||||
max-width: 300px;
|
||||
}
|
||||
</style>
|
||||
{% endblock %}
|
||||
{% block content %}
|
||||
<div class="container py-4">
|
||||
<h1 class="h3 mb-4">Manage Subjects</h1>
|
||||
<!-- Course Filter -->
|
||||
<div class="course-filter">
|
||||
<form method="get" class="form-inline">
|
||||
<div class="form-group mb-3">
|
||||
<label for="course" class="form-label">Select Course</label>
|
||||
<select class="form-control" id="course" name="course">
|
||||
<option value="">All Courses</option>
|
||||
{% for course in courses %}
|
||||
<option value="{{ course.id }}"
|
||||
{% if course.id == selected_course_id %}selected{% endif %}>
|
||||
{{ course.name }}
|
||||
</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<div class="page-header">
|
||||
<div class="container-fluid">
|
||||
<div class="row align-items-center">
|
||||
<div class="col">
|
||||
<h1 class="h3 mb-0">Manage Subjects</h1>
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<a href="{% url 'add_subject' %}" class="btn btn-primary">
|
||||
<i class="fas fa-plus me-1"></i> Add New Subject
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="container-fluid">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<!-- Search and Filter -->
|
||||
<div class="row mb-4">
|
||||
<div class="col-md-6">
|
||||
<div class="search-box">
|
||||
<input type="text"
|
||||
class="form-control"
|
||||
id="subjectSearch"
|
||||
placeholder="Search subjects..." />
|
||||
</div>
|
||||
<!-- Duration Filter -->
|
||||
<div class="form-group mb-3">
|
||||
<label for="duration" class="form-label">Select Duration</label>
|
||||
<select class="form-control" id="duration" name="duration">
|
||||
<option value="">All Durations</option>
|
||||
<option value="1" {% if selected_duration == "1" %}selected{% endif %}>1</option>
|
||||
<option value="2" {% if selected_duration == "2" %}selected{% endif %}>2</option>
|
||||
<option value="3" {% if selected_duration == "3" %}selected{% endif %}>3</option>
|
||||
<option value="4" {% if selected_duration == "4" %}selected{% endif %}>4</option>
|
||||
<option value="5" {% if selected_duration == "5" %}selected{% endif %}>5</option>
|
||||
<option value="6" {% if selected_duration == "6" %}selected{% endif %}>6</option>
|
||||
</select>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary">
|
||||
<i class="fas fa-search"></i> Filter
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
<!-- Subjects Table -->
|
||||
{% if subjects %}
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th width="5%">S.N</th>
|
||||
<th width="30%">Subject Name</th>
|
||||
<th width="20%">Course Name</th>
|
||||
<th width="25%">Duration</th>
|
||||
<th width="25%">Subject Name</th>
|
||||
<th width="20%">Course</th>
|
||||
<th width="20%">Duration</th>
|
||||
<th width="20%">Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
@@ -91,7 +156,35 @@
|
||||
</table>
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="alert alert-info">No subjects found for the selected filters.</div>
|
||||
<div class="empty-state">
|
||||
<i class="fas fa-book empty-state-icon"></i>
|
||||
<h3>No Subjects Found</h3>
|
||||
<p class="text-muted">Start by adding your first subject using the button above.</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% block extrajs %}
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
|
||||
<script>
|
||||
document
|
||||
.getElementById("subjectSearch")
|
||||
.addEventListener("keyup", function () {
|
||||
const searchText = this.value.toLowerCase();
|
||||
const tableRows = document.querySelectorAll("tbody tr");
|
||||
|
||||
tableRows.forEach((row) => {
|
||||
const subjectName = row.cells[1].textContent.toLowerCase();
|
||||
const courseName = row.cells[2].textContent.toLowerCase();
|
||||
|
||||
if (subjectName.includes(searchText) || courseName.includes(searchText)) {
|
||||
row.style.display = "";
|
||||
} else {
|
||||
row.style.display = "none";
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,43 @@
|
||||
{% extends 'admin/base_site.html' %}
|
||||
{% block content %}
|
||||
<div class="container mt-4">
|
||||
<h2 class="mb-4">Manage Teachers</h2>
|
||||
<a href="{% url 'add_teacher' %}" class="btn btn-primary mb-3">Add Teacher</a>
|
||||
<table class="table table-bordered table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>S.N</th>
|
||||
<th>Name</th>
|
||||
<th>Email</th>
|
||||
<th>Phone</th>
|
||||
<th>Gender</th>
|
||||
<th>Qualification</th>
|
||||
<th>Marital Status</th>
|
||||
<th>Date of Joining</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for teacher in teachers %}
|
||||
<tr>
|
||||
<td>{{ forloop.counter }}</td>
|
||||
<td>{{ teacher.first_name }} {{ teacher.middle_name }} {{ teacher.last_name }}</td>
|
||||
<td>{{ teacher.email }}</td>
|
||||
<td>{{ teacher.phone }}</td>
|
||||
<td>{{ teacher.get_gender_display }}</td>
|
||||
<td>{{ teacher.get_qualification_display }}</td>
|
||||
<td>{{ teacher.get_marital_status_display }}</td>
|
||||
<td>{{ teacher.date_of_joining }}</td>
|
||||
<td>
|
||||
<a href="{% url 'edit_teacher' teacher.id %}"
|
||||
class="btn btn-sm btn-warning">Edit</a>
|
||||
<a href="{% url 'delete_teacher' teacher.id %}"
|
||||
class="btn btn-sm btn-danger"
|
||||
onclick="return confirm('Are you sure you want to delete this teacher?');">Delete</a>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,144 @@
|
||||
{% extends 'admin/base_site.html' %}
|
||||
{% block content %}
|
||||
{% load static %}
|
||||
<section class="content">
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<!-- general form elements -->
|
||||
<div class="card card-primary">
|
||||
<div class="card-header">
|
||||
<h3 class="card-title">Student Feedback</h3>
|
||||
</div>
|
||||
<!-- /.card-header -->
|
||||
<div class="table-responsive">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>S.N</th>
|
||||
<th>Student Name</th>
|
||||
<th>Student Session</th>
|
||||
<th>Message</th>
|
||||
<th>Sended On</th>
|
||||
<th>Reply</th>
|
||||
</tr>
|
||||
</thead>
|
||||
{% for feedback in feedbacks %}
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>{{ forloop.counter }}</td>
|
||||
<td>{{ feedback.student_id.first_name }}</td>
|
||||
<td>{{ feedback.student_id.academic_year.start_date }}</td>
|
||||
<td>{{ feedback.feedback }}</td>
|
||||
<td>{{ feedback.created_at }}</td>
|
||||
<td>
|
||||
{% if feedback.feedback_reply == "" %}
|
||||
<button class="btn btn-success reply_open_modal"
|
||||
data-toggle="modal"
|
||||
data-target="#replyModal">Reply</button>
|
||||
{% else %}
|
||||
{{ feedback.feedback_reply }}
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
{% endfor %}
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<!-- /.card -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- /.container-fluid -->
|
||||
</section>
|
||||
{% comment %} Modal to Reply Feedback {% endcomment %}
|
||||
<!-- Modal -->
|
||||
<div class="modal fade"
|
||||
id="replyModal"
|
||||
tabindex="-1"
|
||||
role="dialog"
|
||||
aria-labelledby="exampleModalLabel"
|
||||
aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="exampleModalLabel">Reply Feedback</h5>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p>
|
||||
Reply to: <b><span id="reply_name"></span></b>
|
||||
</p>
|
||||
<input type="hidden" id="reply_id" name="reply_id" />
|
||||
<textarea class="form-control" rows="5" id="reply_message"></textarea>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
{% comment %} <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button> {% endcomment %}
|
||||
<button type="button" class="btn btn-primary btn-block" id="reply_button">Reply</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
{% comment %} Custom JS to Identify the Reply and Post Reply {% endcomment %}
|
||||
{% block custom_js %}
|
||||
<script>
|
||||
$(document).ready(function(){
|
||||
$(".reply_open_modal").click(function(){
|
||||
// Getting Value from Table
|
||||
var id = $(this).parents("tr").children("td:eq(0)").text(); //Getting Selected Row ID (Frist Column)
|
||||
var name = $(this).parents("tr").children("td:eq(2)").text(); //Getting Selected Name (3rd Column)
|
||||
|
||||
// Adding the Value from Table to Modal form
|
||||
$("#reply_id").val(id);
|
||||
$("#reply_name").text(name);
|
||||
});
|
||||
|
||||
$(document).on("click", "#reply_button", function(){
|
||||
//Disabling the Button while data is being saved in Server
|
||||
$(this).attr("disabled", "disabled")
|
||||
$(this).text("Sending Reply...")
|
||||
|
||||
//console.log("SAVE")
|
||||
|
||||
|
||||
var id=$("#reply_id").val();
|
||||
var reply=$("#reply_message").val();
|
||||
//console.log(student_data);
|
||||
|
||||
// Saving Attendance Data into Database
|
||||
|
||||
$.ajax({
|
||||
url:'{% url 'student_feedback_message_reply' %}',
|
||||
type:'POST',
|
||||
data:{id:id, reply:reply},
|
||||
})
|
||||
|
||||
|
||||
.done(function(response){
|
||||
|
||||
if(response=="True")
|
||||
{
|
||||
alert("Reply Sent!")
|
||||
}
|
||||
else
|
||||
{
|
||||
alert("Failed to Send Reply!")
|
||||
}
|
||||
location.reload()
|
||||
|
||||
//console.log(response)
|
||||
})
|
||||
|
||||
.fail(function(){
|
||||
alert("Error in Sending Feedback Reply.")
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
})
|
||||
</script>
|
||||
{% endblock custom_js %}
|
||||
@@ -0,0 +1,188 @@
|
||||
{% extends "admin/base_site.html" %}
|
||||
{% block page_title %}{{ title }}{% endblock %}
|
||||
{% load static %}
|
||||
{% block extrastyle %}
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css"
|
||||
rel="stylesheet" />
|
||||
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css"
|
||||
rel="stylesheet" />
|
||||
<style>
|
||||
.page-header {
|
||||
background-color: #f8f9fa;
|
||||
padding: 1rem;
|
||||
margin-bottom: 2rem;
|
||||
border-bottom: 1px solid #dee2e6;
|
||||
}
|
||||
|
||||
.card {
|
||||
box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);
|
||||
border-radius: 0.5rem;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.table {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.table thead th {
|
||||
background-color: #f8f9fa;
|
||||
border-bottom: 2px solid #dee2e6;
|
||||
color: #495057;
|
||||
font-weight: 600;
|
||||
text-transform: uppercase;
|
||||
font-size: 0.875rem;
|
||||
}
|
||||
|
||||
.table td {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.btn-action {
|
||||
padding: 0.375rem 0.75rem;
|
||||
font-size: 0.875rem;
|
||||
border-radius: 0.25rem;
|
||||
transition: all 0.2s ease-in-out;
|
||||
}
|
||||
|
||||
.btn-approve {
|
||||
background-color: #28a745;
|
||||
border-color: #28a745;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.btn-approve:hover {
|
||||
background-color: #218838;
|
||||
border-color: #1e7e34;
|
||||
}
|
||||
|
||||
.btn-reject {
|
||||
background-color: #dc3545;
|
||||
border-color: #dc3545;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.btn-reject:hover {
|
||||
background-color: #c82333;
|
||||
border-color: #bd2130;
|
||||
}
|
||||
|
||||
.empty-state {
|
||||
padding: 3rem;
|
||||
text-align: center;
|
||||
background-color: #f8f9fa;
|
||||
border-radius: 0.5rem;
|
||||
}
|
||||
|
||||
.empty-state-icon {
|
||||
font-size: 3rem;
|
||||
color: #6c757d;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.search-box {
|
||||
max-width: 300px;
|
||||
}
|
||||
</style>
|
||||
{% endblock %}
|
||||
{% block content %}
|
||||
<div class="page-header">
|
||||
<div class="container-fluid">
|
||||
<div class="row align-items-center">
|
||||
<div class="col">
|
||||
<h1 class="h3 mb-0">Leave Applications</h1>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="container-fluid">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<!-- Search and Filter -->
|
||||
<div class="row mb-4">
|
||||
<div class="col-md-6">
|
||||
<div class="search-box">
|
||||
<input type="text"
|
||||
class="form-control"
|
||||
id="leaveSearch"
|
||||
placeholder="Search leave applications..." />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% if leaves %}
|
||||
<div class="table-responsive table-bordered">
|
||||
<table class="table table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th width="1%">S.N</th>
|
||||
<th width="20%">Student Name</th>
|
||||
<th width="10%">Leave Date</th>
|
||||
<th width="25%">Leave Message</th>
|
||||
<th width="10%">Applied On</th>
|
||||
<th width="15%">Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for leave in leaves %}
|
||||
<tr>
|
||||
<td>{{ forloop.counter }}</td>
|
||||
<td>{{ leave.student_id.first_name }}</td>
|
||||
<td>{{ leave.leave_date }}</td>
|
||||
<td>{{ leave.leave_message }}</td>
|
||||
<td>{{ leave.created_at }}</td>
|
||||
<td>
|
||||
{% if leave.leave_status == 0 %}
|
||||
<a href="{% url 'student_leave_approve' leave_id=leave.id %}"
|
||||
class="btn btn-action btn-approve me-2">
|
||||
<i class="fas fa-check-circle me-1"></i>Approve
|
||||
</a>
|
||||
<a href="{% url 'student_leave_reject' leave_id=leave.id %}"
|
||||
class="btn btn-action btn-reject">
|
||||
<i class="fas fa-times-circle me-1"></i>Reject
|
||||
</a>
|
||||
{% elif leave.leave_status == 1 %}
|
||||
<button class="btn btn-action btn-approve" disabled>Approved</button>
|
||||
{% else %}
|
||||
<button class="btn btn-action btn-reject" disabled>Rejected</button>
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="empty-state">
|
||||
<i class="fas fa-calendar-times empty-state-icon"></i>
|
||||
<h3>No Leave Applications Found</h3>
|
||||
<p class="text-muted">There are no leave applications to display at the moment.</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% block extrajs %}
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
|
||||
<script>
|
||||
document
|
||||
.getElementById("leaveSearch")
|
||||
.addEventListener("keyup", function () {
|
||||
const searchText = this.value.toLowerCase();
|
||||
const tableRows = document.querySelectorAll("tbody tr");
|
||||
|
||||
tableRows.forEach((row) => {
|
||||
const studentName = row.cells[1].textContent.toLowerCase();
|
||||
const leaveMessage = row.cells[3].textContent.toLowerCase();
|
||||
|
||||
if (
|
||||
studentName.includes(searchText) ||
|
||||
leaveMessage.includes(searchText)
|
||||
) {
|
||||
row.style.display = "";
|
||||
} else {
|
||||
row.style.display = "none";
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,115 @@
|
||||
{% extends 'admin/base_site.html' %}
|
||||
{% block content %}
|
||||
<!-- Main content -->
|
||||
<section class="content">
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<!-- general form elements -->
|
||||
<div class="card card-primary">
|
||||
<div class="card-header">
|
||||
<h3 class="card-title">Staff Feedback</h3>
|
||||
</div>
|
||||
<!-- /.card-header -->
|
||||
<!-- form start -->
|
||||
<div class="table">
|
||||
<table class="table">
|
||||
<tr>
|
||||
<th>S.N</th>
|
||||
<th>Staff Name</th>
|
||||
<th>Message</th>
|
||||
<th>Sended On</th>
|
||||
<th>Reply</th>
|
||||
</tr>
|
||||
{% for feedback in feedbacks %}
|
||||
<tr>
|
||||
<td>{{ forloop.counter }}</td>
|
||||
<td>{{ feedback.teacher_id.first_name }} {{ feedback.teacher_id.last_name }}</td>
|
||||
<td>{{ feedback.feedback }}</td>
|
||||
<td>{{ feedback.created_at }}</td>
|
||||
<td>
|
||||
{% if feedback.feedback_reply == "" %}
|
||||
<button class="btn btn-success reply_open_modal"
|
||||
data-toggle="modal"
|
||||
data-target="#reply_modal">Reply</button>
|
||||
{% else %}
|
||||
{{ feedback.feedback_reply }}
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<!-- /.card -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- Modal -->
|
||||
<div class="modal fade" id="reply_modal" role="dialog">
|
||||
<div class="modal-dialog">
|
||||
<!-- Modal content-->
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h4 class="modal-title">Reply</h4>
|
||||
<button type="button" class="close" data-dismiss="modal">×</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p>
|
||||
Reply To : <span id="reply_name"></span>
|
||||
</p>
|
||||
<input type="hidden" id="reply_id" name="reply_id">
|
||||
<textarea class="form-control" rows="5" id="reply_message"></textarea>
|
||||
<button id="reply_btn" class="btn btn-info btn-block">Reply</button>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- /.content -->
|
||||
{% endblock %}
|
||||
{% block custom_js %}
|
||||
<script>
|
||||
$(document).ready(function(){
|
||||
$(".reply_open_modal").click(function(){
|
||||
var id=$(this).parents("tr").children("td:eq(0)").text();
|
||||
var name=$(this).parents("tr").children("td:eq(2)").text();
|
||||
$("#reply_id").val(id);
|
||||
$("#reply_name").text(name);
|
||||
});
|
||||
|
||||
|
||||
$(document).on("click","#reply_btn",function(){
|
||||
|
||||
$(this).attr("disabled","disabled")
|
||||
$(this).text("Sending Reply...")
|
||||
|
||||
var id=$("#reply_id").val();
|
||||
var message=$("#reply_message").val()
|
||||
|
||||
$.ajax({
|
||||
url:'{% url 'teacher_feedback_replied' %}',
|
||||
type:'POST',
|
||||
data:{id:id,message:message},
|
||||
})
|
||||
.done(function(response){
|
||||
|
||||
if(response=="True"){
|
||||
alert("Reply Sent")
|
||||
}
|
||||
else{
|
||||
alert("Error in Sending Reply")
|
||||
}
|
||||
location.reload()
|
||||
})
|
||||
.fail(function(){
|
||||
alert("Error in Sending Reply")
|
||||
})
|
||||
});
|
||||
|
||||
});
|
||||
</script>
|
||||
{% endblock custom_js %}
|
||||
@@ -0,0 +1,186 @@
|
||||
{% extends "admin/base_site.html" %}
|
||||
{% block page_title %}{{ title }}{% endblock %}
|
||||
{% load static %}
|
||||
{% block extrastyle %}
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css"
|
||||
rel="stylesheet" />
|
||||
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css"
|
||||
rel="stylesheet" />
|
||||
<style>
|
||||
.page-header {
|
||||
background-color: #f8f9fa;
|
||||
padding: 1rem;
|
||||
margin-bottom: 2rem;
|
||||
border-bottom: 1px solid #dee2e6;
|
||||
}
|
||||
|
||||
.card {
|
||||
box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);
|
||||
border-radius: 0.5rem;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.table {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.table thead th {
|
||||
background-color: #f8f9fa;
|
||||
border-bottom: 2px solid #dee2e6;
|
||||
color: #495057;
|
||||
font-weight: 600;
|
||||
text-transform: uppercase;
|
||||
font-size: 0.875rem;
|
||||
}
|
||||
|
||||
.table td {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.btn-action {
|
||||
padding: 0.375rem 0.75rem;
|
||||
font-size: 0.875rem;
|
||||
border-radius: 0.25rem;
|
||||
transition: all 0.2s ease-in-out;
|
||||
}
|
||||
|
||||
.btn-approve {
|
||||
background-color: #28a745;
|
||||
border-color: #28a745;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.btn-approve:hover {
|
||||
background-color: #218838;
|
||||
border-color: #1e7e34;
|
||||
}
|
||||
|
||||
.btn-reject {
|
||||
background-color: #dc3545;
|
||||
border-color: #dc3545;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.btn-reject:hover {
|
||||
background-color: #c82333;
|
||||
border-color: #bd2130;
|
||||
}
|
||||
|
||||
.empty-state {
|
||||
padding: 3rem;
|
||||
text-align: center;
|
||||
background-color: #f8f9fa;
|
||||
border-radius: 0.5rem;
|
||||
}
|
||||
|
||||
.empty-state-icon {
|
||||
font-size: 3rem;
|
||||
color: #6c757d;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.search-box {
|
||||
max-width: 300px;
|
||||
}
|
||||
</style>
|
||||
{% endblock %}
|
||||
{% block content %}
|
||||
<div class="page-header">
|
||||
<div class="container-fluid">
|
||||
<div class="row align-items-center">
|
||||
<div class="col">
|
||||
<h1 class="h3 mb-0">Leave Applications</h1>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="container-fluid">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<!-- Search and Filter -->
|
||||
<div class="row mb-4">
|
||||
<div class="col-md-6">
|
||||
<div class="search-box">
|
||||
<input type="text"
|
||||
class="form-control"
|
||||
id="leaveSearch"
|
||||
placeholder="Search leave applications..." />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% if leaves %}
|
||||
<div class="table-responsive table-bordered">
|
||||
<table class="table table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th width="1%">S.N</th>
|
||||
<th width="20%">Teacher Name</th>
|
||||
<th width="10%">Leave Date</th>
|
||||
<th width="25%">Leave Message</th>
|
||||
<th width="10%">Applied On</th>
|
||||
<th width="15%">Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for leave in leaves %}
|
||||
<tr>
|
||||
<td>{{ forloop.counter }}</td>
|
||||
<td>{{ leave.teacher_id.first_name }}{{ leave.teacher_id.middle_name }} {{ leave.teacher_id.last_name }}</td>
|
||||
<td>{{ leave.leave_date }}</td>
|
||||
<td>{{ leave.leave_message }}</td>
|
||||
<td>{{ leave.created_at }}</td>
|
||||
<td>
|
||||
{% if leave.leave_status == 0 %}
|
||||
<a href="{% url 'teacher_leave_approve' leave_id=leave.id %}"
|
||||
class="btn btn-action btn-approve me-2">
|
||||
<i class="fas fa-check-circle me-1"></i>Approve
|
||||
</a>
|
||||
<a href="{% url 'teacher_leave_reject' leave_id=leave.id %}"
|
||||
class="btn btn-action btn-reject">
|
||||
<i class="fas fa-times-circle me-1"></i>Reject
|
||||
</a>
|
||||
{% elif leave.leave_status == 1 %}
|
||||
<button class="btn btn-action btn-approve" disabled>Approved</button>
|
||||
{% else %}
|
||||
<button class="btn btn-action btn-reject" disabled>Rejected</button>
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="empty-state">
|
||||
<i class="fas fa-calendar-times empty-state-icon"></i>
|
||||
<h3>No Leave Applications Found</h3>
|
||||
<p class="text-muted">There are no leave applications to display at the moment.</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% block extrajs %}
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
|
||||
<script>
|
||||
document.getElementById("leaveSearch").addEventListener("keyup", function () {
|
||||
const searchText = this.value.toLowerCase();
|
||||
const tableRows = document.querySelectorAll("tbody tr");
|
||||
|
||||
tableRows.forEach((row) => {
|
||||
const teacherName = row.cells[1].textContent.toLowerCase();
|
||||
const leaveMessage = row.cells[3].textContent.toLowerCase();
|
||||
|
||||
if (
|
||||
teacherName.includes(searchText) ||
|
||||
leaveMessage.includes(searchText)
|
||||
) {
|
||||
row.style.display = "";
|
||||
} else {
|
||||
row.style.display = "none";
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,208 @@
|
||||
{% extends 'admin/base_site.html' %}
|
||||
{% block content %}
|
||||
{% load static %}
|
||||
<section class="content">
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<!-- general form elements -->
|
||||
<div class="card card-primary">
|
||||
<div class="card-header">
|
||||
<h3 class="card-title">View Attendance</h3>
|
||||
</div>
|
||||
<!-- /.card-header -->
|
||||
{% comment %} Display Messages {% endcomment %}
|
||||
{% if messages %}
|
||||
<div class="form-group">
|
||||
<div class="col-12">
|
||||
{% for message in messages %}
|
||||
{% if message.tags == "error" %}
|
||||
<div class="alert alert-danger alert-dismissible fade show"
|
||||
role="alert"
|
||||
style="margin-top: 10px">
|
||||
{{ message }}
|
||||
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
{% elif message.tags == "success" %}
|
||||
<div class="alert alert-success alert-dismissible fade show"
|
||||
role="alert"
|
||||
style="margin-top: 10px">
|
||||
{{ message }}
|
||||
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="card-body">
|
||||
<div class="form-group">
|
||||
<label>Subject</label>
|
||||
<select class="form-control" name="subject" id="subject">
|
||||
{% for subject in subjects %}<option value="{{ subject.id }}">{{ subject.name }}</option>{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Academic Year</label>
|
||||
<select class="form-control" name="session_year_id" id="session_year_id">
|
||||
{% for academic_year in academic_years %}
|
||||
<option value="{{ academic_year.id }}">{{ academic_year.start_date }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<!-- /.card-body -->
|
||||
<div class="card-footer">
|
||||
<button type="button" class="btn btn-primary" id="fetch_attendance">Fetch Attendance Date</button>
|
||||
</div>
|
||||
<div class="card-footer">
|
||||
<div class="form-group" id="attendance_block" style="display:none;">
|
||||
<label>Attendance Date</label>
|
||||
<select class="form-control" name="attendance_date" id="attendance_date"></select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="alert alert-danger" id="error_attendance" style="display:none"></div>
|
||||
<div class="alert alert-success"
|
||||
id="success_attendance"
|
||||
style="display:none"></div>
|
||||
</div>
|
||||
<div class="card-footer" id="fetch_student_block" style="display:none;">
|
||||
<button type="button" class="btn btn-primary" id="fetch_student">Fetch Student Data</button>
|
||||
</div>
|
||||
<!-- /.card-body -->
|
||||
{% comment %} <div class="card-footer">
|
||||
<button type="button" class="btn btn-primary" id="save_student">Save Data</button>
|
||||
</div> {% endcomment %}
|
||||
</div>
|
||||
{% comment %} Displaying Students Here {% endcomment %}
|
||||
<div class="card-footer" id="student_data"></div>
|
||||
</div>
|
||||
<!-- /.card -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- /.container-fluid -->
|
||||
</section>
|
||||
{% endblock %}
|
||||
{% block custom_js %}
|
||||
<script>
|
||||
$(document).ready(function(){
|
||||
|
||||
|
||||
//Fetching Attendance Date
|
||||
|
||||
$("#fetch_attendance").click(function(){
|
||||
var subject = $("#subject").val()
|
||||
var academic_year_id = $("#academic_year_id").val()
|
||||
//console.log(subject)
|
||||
//console.log(session_year_id)
|
||||
|
||||
$.ajax({
|
||||
url:'{% url 'get_attendance_dates' %}',
|
||||
type:'POST',
|
||||
data:{subject:subject, academic_year_id:academic_year_id},
|
||||
})
|
||||
|
||||
|
||||
.done(function(response){
|
||||
var json_data = JSON.parse(response);
|
||||
if(json_data.length>0)
|
||||
{
|
||||
var html_data = "";
|
||||
for (key in json_data)
|
||||
{
|
||||
html_data+="<option value='"+ json_data[key]["id"] +"'>"+ json_data[key]["attendance_date"] +"</option>"
|
||||
}
|
||||
$("#error_attendance").html("");
|
||||
$("#error_attendance").hide();
|
||||
$("#attendance_block").show();
|
||||
$("#fetch_student_block").show();
|
||||
$("#attendance_date").html(html_data);
|
||||
//console.log(response)
|
||||
//alert("Something")
|
||||
}
|
||||
else
|
||||
{
|
||||
$("#error_attendance").html("No Attendance Data Found.");
|
||||
$("#error_attendance").show();
|
||||
$("#attendance_block").hide();
|
||||
$("#fetch_student_block").hide();
|
||||
$("#attendance_date")="" //Empty the Date Dropdown also
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
.fail(function(){
|
||||
alert("Error in getting Attendance Dates.")
|
||||
$("#error_attendance").html("");
|
||||
$("#fetch_student_block").hide();
|
||||
$("#attendance_block").hide();
|
||||
});
|
||||
|
||||
|
||||
})
|
||||
|
||||
// Now Working on Fetch Student after attendance date selected
|
||||
$("#fetch_student").click(function(){
|
||||
|
||||
// Displaying Students Based on Staff, Course and Session Enrolled
|
||||
|
||||
//var subject=$("#subject").val()
|
||||
//var session_year=$("#session_year").val()
|
||||
var attendance_date=$("#attendance_date").val()
|
||||
|
||||
$.ajax({
|
||||
url:'{% url 'admin_get_attendance_student' %}',
|
||||
type:'POST',
|
||||
data:{attendance_date:attendance_date},
|
||||
})
|
||||
|
||||
|
||||
.done(function(response){
|
||||
var json_data=JSON.parse(response);
|
||||
//console.log(json_data)
|
||||
//Displaying Attendance Date Input and Students Attendance
|
||||
var div_data="<div class='form-group'><label>Student Attendance: </label></div>"
|
||||
div_data+="<div class='form-group'><div class='row'>"
|
||||
|
||||
for(key in json_data)
|
||||
{
|
||||
div_data+="<div class='col-lg-3'><div class='form-check'>";
|
||||
|
||||
div_data+="<label class='form-check-label'>"+ json_data[key]['name']+" </label> ";
|
||||
|
||||
// Displaying Present and Absent
|
||||
|
||||
if(json_data[key]['status'])
|
||||
{
|
||||
div_data+="<b>[ Present ]</b>";
|
||||
}
|
||||
else
|
||||
{
|
||||
div_data+="<b>[ Absent ]</b>";
|
||||
}
|
||||
//Displaying Present and Absent Ends Here
|
||||
|
||||
|
||||
div_data+="</div></div> ";
|
||||
}
|
||||
div_data+="</div></div>";
|
||||
|
||||
$("#student_data").html(div_data);
|
||||
|
||||
})
|
||||
.fail(function(){
|
||||
alert("Error in Fetching Students.")
|
||||
})
|
||||
|
||||
|
||||
})
|
||||
|
||||
})
|
||||
</script>
|
||||
{% endblock custom_js %}
|
||||
@@ -0,0 +1,83 @@
|
||||
{% extends "admin/base_site.html" %}
|
||||
{% block content %}
|
||||
<h2 class="col-12">Dashboard</h2>
|
||||
<p class="col-12">Welcome</p>
|
||||
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
||||
<div class="row g-4 col-12">
|
||||
<div class="col-12 col-md-6 col-lg-3">
|
||||
<div class="card text-center p-3">
|
||||
<h5>Course</h5>
|
||||
<p class="fs-2">DCOM</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-md-6 col-lg-3">
|
||||
<div class="card text-center p-3">
|
||||
<h5>Current Semester</h5>
|
||||
<p class="fs-2">5</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-md-6 col-lg-3">
|
||||
<div class="card text-center p-3">
|
||||
<h5>Total Subject</h5>
|
||||
<p class="fs-2">12</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Subject Attendance Bar Chart -->
|
||||
<div class="row col-12 col-lg-6 chart-container">
|
||||
<canvas id="attendanceBarChart"></canvas>
|
||||
</div>
|
||||
<!-- Subject Results Bar Chart -->
|
||||
<div class="row col-12 col-lg-6 chart-container">
|
||||
<canvas id="resultBarChart"></canvas>
|
||||
</div>
|
||||
<script>
|
||||
// Bar Chart for Subject Attendance
|
||||
const attendanceCtx = document.getElementById("attendanceBarChart").getContext("2d");
|
||||
new Chart(attendanceCtx, {
|
||||
type: "bar",
|
||||
data: {
|
||||
labels: ["Math", "Science", "English", "History", "Geography"], // Example subject names
|
||||
datasets: [
|
||||
{
|
||||
label: "Attendance Percentage",
|
||||
data: [90, 80, 85, 75, 95], // Example attendance percentages for each subject
|
||||
backgroundColor: ["#FF6384", "#36A2EB", "#FFCE56", "#4CAF50", "#FF8C00"],
|
||||
},
|
||||
],
|
||||
},
|
||||
options: {
|
||||
scales: {
|
||||
y: {
|
||||
beginAtZero: true,
|
||||
max: 100, // Percentage scale
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
// Bar Chart for Subject Results (Example)
|
||||
const resultCtx = document.getElementById("resultBarChart").getContext("2d");
|
||||
new Chart(resultCtx, {
|
||||
type: "bar",
|
||||
data: {
|
||||
labels: ["Math", "Science", "English", "History", "Geography"], // Example subject names
|
||||
datasets: [
|
||||
{
|
||||
label: "Results (Percentage)",
|
||||
data: [88, 75, 80, 70, 92], // Example result percentages for each subject
|
||||
backgroundColor: ["#FF5733", "#33FF57", "#3357FF", "#FF5733", "#FF8C00"],
|
||||
},
|
||||
],
|
||||
},
|
||||
options: {
|
||||
scales: {
|
||||
y: {
|
||||
beginAtZero: true,
|
||||
max: 100, // Percentage scale
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,83 @@
|
||||
{% extends "admin/base_site.html" %}
|
||||
{% block content %}
|
||||
<h2 class="col-12">Dashboard</h2>
|
||||
<p class="col-12">Welcome</p>
|
||||
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
||||
<div class="row g-4 col-12">
|
||||
<div class="col-12 col-md-6 col-lg-3">
|
||||
<div class="card text-center p-3">
|
||||
<h5>Course</h5>
|
||||
<p class="fs-2">DCOM</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-md-6 col-lg-3">
|
||||
<div class="card text-center p-3">
|
||||
<h5>Current Semester</h5>
|
||||
<p class="fs-2">5</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-md-6 col-lg-3">
|
||||
<div class="card text-center p-3">
|
||||
<h5>Total Subject</h5>
|
||||
<p class="fs-2">12</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Subject Attendance Bar Chart -->
|
||||
<div class="row col-12 col-lg-6 chart-container">
|
||||
<canvas id="attendanceBarChart"></canvas>
|
||||
</div>
|
||||
<!-- Subject Results Bar Chart -->
|
||||
<div class="row col-12 col-lg-6 chart-container">
|
||||
<canvas id="resultBarChart"></canvas>
|
||||
</div>
|
||||
<script>
|
||||
// Bar Chart for Subject Attendance
|
||||
const attendanceCtx = document.getElementById("attendanceBarChart").getContext("2d");
|
||||
new Chart(attendanceCtx, {
|
||||
type: "bar",
|
||||
data: {
|
||||
labels: ["Math", "Science", "English", "History", "Geography"], // Example subject names
|
||||
datasets: [
|
||||
{
|
||||
label: "Attendance Percentage",
|
||||
data: [90, 80, 85, 75, 95], // Example attendance percentages for each subject
|
||||
backgroundColor: ["#FF6384", "#36A2EB", "#FFCE56", "#4CAF50", "#FF8C00"],
|
||||
},
|
||||
],
|
||||
},
|
||||
options: {
|
||||
scales: {
|
||||
y: {
|
||||
beginAtZero: true,
|
||||
max: 100, // Percentage scale
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
// Bar Chart for Subject Results (Example)
|
||||
const resultCtx = document.getElementById("resultBarChart").getContext("2d");
|
||||
new Chart(resultCtx, {
|
||||
type: "bar",
|
||||
data: {
|
||||
labels: ["Math", "Science", "English", "History", "Geography"], // Example subject names
|
||||
datasets: [
|
||||
{
|
||||
label: "Results (Percentage)",
|
||||
data: [88, 75, 80, 70, 92], // Example result percentages for each subject
|
||||
backgroundColor: ["#FF5733", "#33FF57", "#3357FF", "#FF5733", "#FF8C00"],
|
||||
},
|
||||
],
|
||||
},
|
||||
options: {
|
||||
scales: {
|
||||
y: {
|
||||
beginAtZero: true,
|
||||
max: 100, // Percentage scale
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
Reference in new issue
Block a user