huh new thing

This commit is contained in:
sankalp committed 2025-01-19 14:44:28 +05:45
1 parent 0975a125c7
commit 9a842c12bf
29 files changed
+2771 -255

No files matched your search

+30 -140
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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)
+163
View File
@@ -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")
+7
View File
@@ -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
View File
@@ -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
View File
@@ -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.
+1
View File
@@ -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/
+149
View File
@@ -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 %}
+100
View File
@@ -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 %}
+212
View File
@@ -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 %}
+126
View File
@@ -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 %}
+65
View File
@@ -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 %}
+133 -40
View File
@@ -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 %}
+43
View File
@@ -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 %}
+144
View File
@@ -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">&times;</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 %}
+188
View File
@@ -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 %}
+115
View File
@@ -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">&times;</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 %}
+186
View File
@@ -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 %}
+208
View File
@@ -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">&times;</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">&times;</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 %}
+83
View File
@@ -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 %}
+83
View File
@@ -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 %}