From 84dd5d0b2fb43df71a82255ec8b617531207f287 Mon Sep 17 00:00:00 2001 From: S4NKALP Date: Sat, 29 Mar 2025 03:22:47 +0545 Subject: [PATCH] huge updates i donot track what updates i have made --- .env.example | 24 + .gitignore | 4 + README.md | 239 ++- app/admin.py | 572 ++++-- app/api_urls.py | 1 + app/api_views.py | 1 + app/auth.py | 298 ++++ app/backends.py | 20 +- app/forms.py | 18 +- app/migrations/0001_initial.py | 144 +- ...tudentfeedback_unique_together_and_more.py | 28 - ...002_create_staffinstitutefeedback_table.py | 24 + app/migrations/0003_coursetracking.py | 37 - ..._alter_studentfeedback_options_and_more.py | 34 - ...tudentfeedback_unique_together_and_more.py | 21 - app/migrations/0006_institutefeedback.py | 35 - ...nt_is_superuser_alter_student_is_active.py | 23 - app/models.py | 532 ++++-- app/serializers.py | 179 ++ app/staffviews.py | 585 ++++++ app/studentviews.py | 511 ++++++ app/templatetags/app_filters.py | 29 +- app/urls.py | 61 +- app/utils.py | 170 ++ app/views.py | 664 ++++--- assets/logo.png | Bin 24909 -> 0 bytes requirements.txt | 30 + static/css/custom.css | 22 + static/css/dashboard.css | 712 ++++++++ static/img/logo.png | Bin 0 -> 324362 bytes static/img/user.png | Bin 0 -> 19456 bytes static/js/dashboard.js | 563 ++++++ static/js/feedback_rating.js | 113 ++ student_management_system/jazzmin.py | 98 + student_management_system/settings.py | 137 +- student_management_system/urls.py | 25 +- templates/admin/app/routine/change_form.html | 555 ++++++ templates/base.html | 22 + templates/dashboard.html | 979 ++++++++-- templates/login/email_reset.html | 170 ++ .../email_templates/password_reset_email.html | 83 + .../password_reset_subject.txt | 1 + templates/login/login.html | 168 ++ templates/login/password_reset_complete.html | 113 ++ templates/login/password_reset_confirm.html | 178 ++ templates/login/password_reset_done.html | 107 ++ templates/login/password_reset_otp.html | 270 +++ templates/login/password_reset_phone.html | 197 ++ templates/login/password_reset_set.html | 160 ++ templates/login/password_reset_verify.html | 219 +++ templates/login/reset_options.html | 156 ++ templates/login/verify_reset_code.html | 61 + templates/student_dashboard.html | 1262 +++++++++++-- templates/teacher_attendance.html | 254 +++ templates/teacher_dashboard.html | 1578 ++++++++++++++--- 55 files changed, 11072 insertions(+), 1415 deletions(-) create mode 100644 .env.example create mode 100644 app/api_urls.py create mode 100644 app/api_views.py create mode 100644 app/auth.py delete mode 100644 app/migrations/0002_alter_studentfeedback_unique_together_and_more.py create mode 100644 app/migrations/0002_create_staffinstitutefeedback_table.py delete mode 100644 app/migrations/0003_coursetracking.py delete mode 100644 app/migrations/0004_alter_studentfeedback_options_and_more.py delete mode 100644 app/migrations/0005_alter_studentfeedback_unique_together_and_more.py delete mode 100644 app/migrations/0006_institutefeedback.py delete mode 100644 app/migrations/0007_student_is_superuser_alter_student_is_active.py create mode 100644 app/serializers.py create mode 100644 app/staffviews.py create mode 100644 app/studentviews.py create mode 100644 app/utils.py delete mode 100644 assets/logo.png create mode 100644 static/css/custom.css create mode 100644 static/css/dashboard.css create mode 100644 static/img/logo.png create mode 100644 static/img/user.png create mode 100644 static/js/dashboard.js create mode 100644 static/js/feedback_rating.js create mode 100644 student_management_system/jazzmin.py create mode 100644 templates/admin/app/routine/change_form.html create mode 100644 templates/base.html create mode 100644 templates/login/email_reset.html create mode 100644 templates/login/email_templates/password_reset_email.html create mode 100644 templates/login/email_templates/password_reset_subject.txt create mode 100644 templates/login/login.html create mode 100644 templates/login/password_reset_complete.html create mode 100644 templates/login/password_reset_confirm.html create mode 100644 templates/login/password_reset_done.html create mode 100644 templates/login/password_reset_otp.html create mode 100644 templates/login/password_reset_phone.html create mode 100644 templates/login/password_reset_set.html create mode 100644 templates/login/password_reset_verify.html create mode 100644 templates/login/reset_options.html create mode 100644 templates/login/verify_reset_code.html create mode 100644 templates/teacher_attendance.html diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..b52d6c4 --- /dev/null +++ b/.env.example @@ -0,0 +1,24 @@ +# Django Settings +DJANGO_SECRET_KEY=your-secret-key-here +DJANGO_DEBUG=True +DJANGO_ALLOWED_HOSTS=* + +# Firebase Configuration +FIREBASE_API_KEY=your_firebase_api_key_here +FIREBASE_AUTH_DOMAIN=your_project_id.firebaseapp.com +FIREBASE_PROJECT_ID=your_project_id +FIREBASE_STORAGE_BUCKET=your_project_id.firebasestorage.app +FIREBASE_MESSAGING_SENDER_ID=your_sender_id +FIREBASE_APP_ID=your_app_id +FIREBASE_MEASUREMENT_ID=your_measurement_id + +# Email Configuration +EMAIL_BACKEND=django.core.mail.backends.console.EmailBackend +DEFAULT_FROM_EMAIL=noreply@studentmanagementsystem.com + +# SMS Configuration +SMS_API_KEY=your_sms_api_key_here +SMS_SENDER_ID=SMSSYS + +# Cache Configuration +CACHE_LOCATION=unique-snowflake \ No newline at end of file diff --git a/.gitignore b/.gitignore index 7ec4427..e5db256 100644 --- a/.gitignore +++ b/.gitignore @@ -150,3 +150,7 @@ media/result_sheet/* # Custom dump.rdb *.DS_Store + +# Firebase configuration +firebase-config.json +firebase.json diff --git a/README.md b/README.md index 860c0e1..9c9ec51 100644 --- a/README.md +++ b/README.md @@ -1,27 +1,230 @@ -

- Logo -

+# ๐Ÿ“š Student Management System (SMS) -

Student Management System In Django

+
-

+[![Python](https://img.shields.io/badge/python-3.x-blue.svg)](https://www.python.org/) +[![Django](https://img.shields.io/badge/django-5.1.7-green.svg)](https://www.djangoproject.com/) +[![License](https://img.shields.io/badge/license-MIT-yellow.svg)](LICENSE) +[![Stars](https://img.shields.io/github/stars/S4NKALP/Student-Management-System-In-Django)](https://github.com/S4NKALP/Student-Management-System-In-Django/stargazers) +[![Arch Linux](https://img.shields.io/badge/Arch%20Linux-1793D1?logo=arch-linux&logoColor=white)](https://archlinux.org/) +[![Status](https://img.shields.io/badge/status-active-success.svg)]() - -People +A modern and comprehensive Student Management System built with Django. - -Stars +

- -Forks +## ๐Ÿ’ป Tech Stack - -Watches +
- -Last Updated -

+### ๐Ÿ”ฅ Core Technologies +| Python | Django | JavaScript | MySQL | REST API | +|:---:|:---:|:---:|:---:|:---:| +| Python | Django | JavaScript | MySQL | REST API | -
+### โšก Additional Technologies +| Redis | Nginx | Bootstrap | HTML5 | CSS3 | Git | +|:---:|:---:|:---:|:---:|:---:|:---:| +| Redis | Nginx | Bootstrap | HTML5 | CSS3 | Git | -# WIP +
+ +## ๐Ÿ–ฅ๏ธ Development Environment + +- **Processor**: Intel Core i5-7300U +- **Operating System**: Arch Linux +- **Window Manager**: [Hyprland](https://github.com/S4NKALP/hyprland) +- **Status Bar**: [Modus](https://github.com/S4NKALP/Modus) +- **Editor**: [Neovim](https://github.com/S4NKALP/nvim) + +## โœจ Key Features + +
+ +| Feature | Description | +|---------|-------------| +| ๐Ÿ‘ฅ Multi-User Roles | Admin, Staff, and Student interfaces | +| ๐Ÿ“š Course Management | Comprehensive course and subject tracking | +| ๐Ÿ“Š Attendance System | Real-time attendance monitoring | +| ๐Ÿ“ Leave Management | Streamlined leave application process | +| ๐Ÿ“ข Notice Board | Instant announcements and updates | +| ๐Ÿ’ฌ Feedback System | Student and staff feedback collection | +| ๐Ÿ” OTP Verification | Secure authentication system | +| โ˜๏ธ Cloud Storage | Google Cloud integration | +| ๐Ÿ”ฅ Firebase | Real-time notifications and auth | + +
+ +## ๐Ÿš€ Quick Start + +### Linux Users +```bash +# Clone & Setup +git clone https://github.com/S4NKALP/Student-Management-System-In-Django.git +cd Student-Management-System-In-Django +python -m venv venv && source venv/bin/activate +pip install -r requirements.txt + +# Configure +cp .env.example .env # Edit with your settings + +# Run +python manage.py migrate +python manage.py createsuperuser +python manage.py runserver +``` + +### Windows Users +```powershell +# Prerequisites +# Install Python from https://www.python.org/downloads/ +# Install Git from https://git-scm.com/download/win +# Install Visual C++ Build Tools: https://visualstudio.microsoft.com/visual-cpp-build-tools/ + +# Clone & Setup +git clone https://github.com/S4NKALP/Student-Management-System-In-Django.git +cd Student-Management-System-In-Django +python -m venv venv +.\venv\Scripts\activate +pip install -r requirements.txt + +# Configure +copy .env.example .env +# Edit .env file with your settings + +# Run +python manage.py migrate +python manage.py createsuperuser +python manage.py runserver +``` + +### โš ๏ธ Common Issues (Windows) +- If `pip install` fails, make sure you have Visual C++ Build Tools installed +- If `python` command not found, add Python to your PATH environment variable +- If permission errors occur, run Command Prompt as Administrator +- If virtualenv fails, try: `python -m pip install --upgrade virtualenv` + +### ๐Ÿ” Environment Variables (.env) +```env +# Django Settings +DEBUG=True +SECRET_KEY=your-secret-key-here +ALLOWED_HOSTS=localhost,127.0.0.1 + +# Database Configuration +DB_NAME=sms_db +DB_USER=your_db_user +DB_PASSWORD=your_db_password +DB_HOST=localhost +DB_PORT=3306 + +# Email Configuration (for OTP) +EMAIL_BACKEND=django.core.mail.backends.smtp.EmailBackend +EMAIL_HOST=smtp.gmail.com +EMAIL_PORT=587 +EMAIL_USE_TLS=True +EMAIL_HOST_USER=your-email@gmail.com +EMAIL_HOST_PASSWORD=your-app-specific-password + +# Firebase Configuration +FIREBASE_DATABASE_URL=your-firebase-url +FIREBASE_TYPE=service_account +FIREBASE_PROJECT_ID=your-project-id +FIREBASE_PRIVATE_KEY_ID=your-private-key-id +FIREBASE_PRIVATE_KEY=your-private-key +FIREBASE_CLIENT_EMAIL=your-client-email +FIREBASE_CLIENT_ID=your-client-id +FIREBASE_AUTH_URI=https://accounts.google.com/o/oauth2/auth +FIREBASE_TOKEN_URI=https://oauth2.googleapis.com/token +FIREBASE_AUTH_PROVIDER_X509_CERT_URL=https://www.googleapis.com/oauth2/v1/certs +FIREBASE_CLIENT_X509_CERT_URL=your-cert-url + +# Google Cloud Storage +GS_BUCKET_NAME=your-bucket-name +GS_CREDENTIALS=path/to/credentials.json +``` + +> **Note**: Never commit your `.env` file to version control. Keep your credentials secure! + +## ๐ŸŽฏ Project Roadmap + +
+ +### โš ๏ธ Important Notice +``` +This is a Minor Project created for educational purposes. +Features listed in the roadmap may or may not be implemented. +``` + +
+ +### ๐ŸŽฏ Current (v1.0) +- โœ… Core SMS functionality +- โœ… User management +- โœ… Course tracking +- โœ… Basic features + +### ๐Ÿ”œ Upcoming (v1.1+) +- ๐Ÿ‘จโ€๐Ÿ‘ฉโ€๐Ÿ‘งโ€๐Ÿ‘ฆ Parents dashboard +- ๐Ÿ“š Teacher study materials +- ๐Ÿ“– Library management +- ๐Ÿ“Š Enhanced analytics +- ๐Ÿค Parent-teacher meetings + +## ๐Ÿ“ฎ Support & Links + +
+ +[![GitHub Issues](https://img.shields.io/github/issues/S4NKALP/Student-Management-System-In-Django)](https://github.com/S4NKALP/Student-Management-System-In-Django/issues) +[![GitHub Pull Requests](https://img.shields.io/github/issues-pr/S4NKALP/Student-Management-System-In-Django)](https://github.com/S4NKALP/Student-Management-System-In-Django/pulls) +[![Documentation](https://img.shields.io/badge/docs-wiki-blue)](https://github.com/S4NKALP/Student-Management-System-In-Django/wiki) + +
+ +## ๐Ÿ™ Credits + +If you use this project in your work, please give credit where credit is due: + +```markdown +Student Management System +Created by Sankalp +GitHub: https://github.com/S4NKALP +``` + +### ๐Ÿ“ Citation +If you're using this project in an academic context, you can cite it as: + +```bibtex +@software{StudentManagementSystem2024, + author = {Sankalp}, + title = {Student Management System}, + year = {2024}, + publisher = {GitHub}, + url = {https://github.com/S4NKALP/Student-Management-System-In-Django} +} +``` + +### ๐Ÿค Acknowledgments +- Thanks to all contributors who have helped improve this project +- Special thanks to the open-source community for their valuable resources +- Appreciation to all users who have provided feedback and suggestions + +## ๐Ÿ“„ License + +
+ +[![License](https://img.shields.io/badge/license-MIT-yellow.svg)](LICENSE) + +
+ +--- + +
+ +### Made with โค๏ธ by [Sankalp](https://github.com/S4NKALP) + +[![GitHub](https://img.shields.io/badge/GitHub-100000?style=for-the-badge&logo=github&logoColor=white)](https://github.com/S4NKALP) + + +
diff --git a/app/admin.py b/app/admin.py index 4448edb..9de4070 100644 --- a/app/admin.py +++ b/app/admin.py @@ -10,17 +10,25 @@ from app.models import ( AttendanceRecord, Notice, Routine, - StudentRoutine, Staff_leave, Student_Leave, StudentFeedback, CourseTracking, InstituteFeedback, + StaffInstituteFeedback, + FCMDevice, ) from django.forms import ModelForm from django.contrib.auth.models import User, Group from django.contrib.auth.admin import UserAdmin, GroupAdmin from app.forms import StaffAdminForm, StudentAdminForm +from django.urls import path +from django.http import JsonResponse +import json +from django.db import transaction +from django.db.models import Q +from datetime import datetime + # Register your models here. @@ -39,7 +47,6 @@ class CustomAdminSite(admin.AdminSite): "group": "Authentication", "group_label": "authentication", }, - # Organization Models "Institute": { "group": "Organization", @@ -61,7 +68,6 @@ class CustomAdminSite(admin.AdminSite): "group": "Organization", "group_label": "organization", }, - # Human Management Models "Student": { "group": "Human Management", @@ -99,6 +105,10 @@ class CustomAdminSite(admin.AdminSite): "group": "Human Management", "group_label": "human_management", }, + "StaffInstituteFeedback": { + "group": "Human Management", + "group_label": "human_management", + }, } grouped_app_list = [{"name": "Main", "app_label": "dashboard", "models": []}] @@ -117,7 +127,21 @@ class CustomAdminSite(admin.AdminSite): } grouped_models[group]["models"].append(model) - grouped_app_list = list(grouped_models.values()) + dashboard_item = { + "name": "Dashboard", + "app_label": "dashboard", + "models": [ + { + "name": "Dashboard", + "object_name": "Dashboard", + "perms": {"has_module_perms": True}, + "admin_url": "/app/dashboard", + "view_only": True, + } + ], + } + + grouped_app_list = [dashboard_item] + list(grouped_models.values()) return grouped_app_list @@ -136,11 +160,29 @@ class InstituteModel(admin.ModelAdmin): @admin.register(Course, site=custom_admin_site) class CourseModel(admin.ModelAdmin): - list_display = ("id", "name", "duration", "duration_type") + list_display = ("id", "name", "duration", "duration_type", "get_total_duration") search_fields = ("name", "duration", "duration_type") - list_filter = ("name", "duration", "duration_type") + list_filter = ("duration_type", "duration") advanced_filter_fields = ("name", "duration", "duration_type") + def get_total_duration(self, obj): + if obj.duration_type == "Semester": + return f"{obj.duration} years ({obj.duration * 2} semesters)" + return f"{obj.duration} year{'s' if obj.duration > 1 else ''}" + + get_total_duration.short_description = "Total Duration" + + fieldsets = ( + (None, {"fields": ("name",)}), + ( + "Duration Settings", + { + "fields": ("duration", "duration_type"), + "description": "For yearly courses, duration is in years. For semester-based courses, duration is in years (2 semesters per year).", + }, + ), + ) + @admin.register(Batch, site=custom_admin_site) class BatchAdmin(admin.ModelAdmin): @@ -152,41 +194,78 @@ class BatchAdmin(admin.ModelAdmin): @admin.register(Subject, site=custom_admin_site) class SubjectModel(admin.ModelAdmin): - list_display = ("id", "name", "course", "semester_or_year") - search_fields = ("name", "course_id", "semester_or_year") - list_filter = ("name", "course_id", "semester_or_year") + list_display = ("id", "name", "course", "get_period_display", "has_syllabus") + search_fields = ("name", "course__name") + list_filter = ("course", "semester_or_year") + advanced_filter_fields = ("name", "course", "semester_or_year") + + def has_syllabus(self, obj): + return bool(obj.syllabus_pdf) + + has_syllabus.boolean = True + has_syllabus.short_description = "Has Syllabus" + + def get_period_display(self, obj): + if obj.course.duration_type == "Semester": + return f"Semester {obj.semester_or_year}" + return f"Year {obj.semester_or_year}" + + get_period_display.short_description = "Period" + + def add_view(self, request, form_url="", extra_context=None): + extra_context = extra_context or {} + extra_context["show_save_and_add_another"] = True + extra_context["show_save"] = False + return super().add_view(request, form_url, extra_context) + + def response_add(self, request, obj, post_url_continue=None): + if "_addanother" in request.POST: + # Pre-fill the course and semester fields for the next entry + return self.response_post_save_add(request, obj) + return super().response_add(request, obj, post_url_continue) + + def get_form(self, request, obj=None, **kwargs): + form = super().get_form(request, obj, **kwargs) + if obj and obj.course: + if obj.course.duration_type == "Semester": + form.base_fields["semester_or_year"].label = "Semester" + form.base_fields[ + "semester_or_year" + ].help_text = f"Enter semester number (1-{obj.course.duration * 2})" + else: + form.base_fields["semester_or_year"].label = "Year" + form.base_fields[ + "semester_or_year" + ].help_text = f"Enter year number (1-{obj.course.duration})" + + # Keep the last used course selected for next entry + if not obj and request.method == "GET": + if "course" in request.GET: + form.base_fields["course"].initial = request.GET["course"] + if "semester_or_year" in request.GET: + form.base_fields["semester_or_year"].initial = request.GET[ + "semester_or_year" + ] + return form + + def response_post_save_add(self, request, obj): + from django.http import HttpResponseRedirect + from django.urls import reverse + + opts = self.model._meta + url = reverse(f"admin:{opts.app_label}_{opts.model_name}_add") + return HttpResponseRedirect( + f"{url}?course={obj.course.id}&semester_or_year={obj.semester_or_year}" + ) @admin.register(Student, site=custom_admin_site) class StudentAdmin(admin.ModelAdmin): - list_display = ("id", "name", "status", "phone") form = StudentAdminForm - search_fields = ( - "name", - "phone", - "courses", - "gender", - "joining_date", - ) - list_filter = ( - "name", - "phone", - "courses", - "gender", - "joining_date", - "status", - ) - advanced_filter_fields = ( - "name", - "phone", - "courses", - "gender", - "joining_date", - "status", - ) - readonly_fields = ("password",) - ordering = ("name",) - filter_horizontal = ("groups",) + list_display = ("id", "name", "phone", "course", "status") + search_fields = ("name", "phone", "course__name") + list_filter = ("course", "status", "gender", "joining_date") + advanced_filter_fields = ("name", "phone", "course", "batch", "status") def has_view_permission(self, request, obj=None): """Check if user has view permission""" @@ -213,38 +292,14 @@ class StudentAdmin(admin.ModelAdmin): return self.readonly_fields + ("password",) return self.readonly_fields - class Media: - js = ("js/student_admin.js",) - @admin.register(Staff, site=custom_admin_site) class StaffAdmin(admin.ModelAdmin): - list_display = ["name", "phone", "designation", "joining_date"] form = StaffAdminForm - search_fields = ( - "name", - "phone", - "monthly_salary", - "designation", - "joining_date", - "gender", - ) - list_filter = ( - "name", - "phone", - "designation", - "joining_date", - "gender", - "groups", - ) - advanced_filter_fields = ( - "name", - "phone", - "designation", - "joining_date", - "gender", - "groups", - ) + list_display = ("id", "name", "phone", "designation", "joining_date") + search_fields = ("name", "phone", "designation") + list_filter = ("designation", "joining_date", "gender") + advanced_filter_fields = ("name", "phone", "designation") readonly_fields = ("password",) ordering = ("name",) filter_horizontal = ("groups",) @@ -274,9 +329,6 @@ class StaffAdmin(admin.ModelAdmin): return self.readonly_fields + ("password",) return self.readonly_fields - class Media: - js = ("js/staff_admin.js",) - class AttendanceRecordForm(ModelForm): def clean(self): @@ -334,9 +386,6 @@ class AttendanceAdmin(admin.ModelAdmin): formset.save_m2m() - class Media: - js = ("js/attendance_admin.js",) - @admin.register(Notice, site=custom_admin_site) class NoticeAdmin(admin.ModelAdmin): @@ -345,64 +394,242 @@ class NoticeAdmin(admin.ModelAdmin): list_filter = ("title", "message") advanced_filter_fields = ("title", "message") - class Media: - js = ("js/notice_admin.js",) - - -class StudentRoutineStackInline(admin.StackedInline): - model = StudentRoutine - extra = 0 - @admin.register(Routine, site=custom_admin_site) class RoutineAdmin(admin.ModelAdmin): - inlines = [StudentRoutineStackInline] - list_display = ["name", "start_time", "end_time", "teacher"] - search_fields = ("name", "start_time", "end_time", "teacher__name") - list_filter = ("name", "start_time", "end_time", "teacher") - advanced_filter_fields = ("name", "start_time", "end_time", "teacher") + list_display = [ + "course", + "subject", + "teacher", + "start_time", + "end_time", + "semester_or_year", + "is_active", + ] + list_filter = ["is_active", "course", "subject", "teacher", "semester_or_year"] + search_fields = ["course__name", "subject__name", "teacher__name"] + ordering = ["start_time"] + change_form_template = "admin/app/routine/change_form.html" + + def get_urls(self): + urls = super().get_urls() + custom_urls = [ + path( + "add-multiple/", + self.admin_site.admin_view(self.save_routines), + name="routine-add-multiple", + ), + ] + return custom_urls + urls + + def save_routines(self, request): + if request.method == "POST": + try: + data = json.loads(request.body) + routines = data.get("routines", []) + + if not routines: + return JsonResponse( + {"success": False, "message": "No routines data provided"} + ) + + with ( + transaction.atomic() + ): # Use transaction to ensure all routines are created or none + created_routines = [] + for index, routine_data in enumerate(routines): + try: + # Validate required fields + required_fields = [ + "course", + "subject", + "teacher", + "start_time", + "end_time", + "semester_or_year", + ] + missing_fields = [ + field + for field in required_fields + if field not in routine_data + or not routine_data.get(field) + ] + + if missing_fields: + error_msg = f"Missing required fields: {', '.join(missing_fields)}" + raise ValueError(error_msg) + + # Convert IDs to integers + try: + course_id = int(routine_data["course"]) + subject_id = int(routine_data["subject"]) + teacher_id = int(routine_data["teacher"]) + semester = int(routine_data["semester_or_year"]) + + except (ValueError, TypeError) as e: + raise ValueError(f"Error parsing IDs: {str(e)}") + + # Validate time format + try: + start_time = datetime.strptime( + routine_data["start_time"], "%H:%M" + ).time() + end_time = datetime.strptime( + routine_data["end_time"], "%H:%M" + ).time() + except ValueError as e: + raise ValueError( + "Invalid time format. Please use HH:MM format." + ) + + # Check for existing routine + existing_routine = Routine.objects.filter( + course_id=course_id, + subject_id=subject_id, + semester_or_year=semester, + start_time=start_time, + end_time=end_time, + ).first() + + if existing_routine: + # Update existing routine + existing_routine.teacher_id = teacher_id + existing_routine.save() + created_routines.append(existing_routine) + else: + # Create new routine + routine = Routine.objects.create( + course_id=course_id, + subject_id=subject_id, + teacher_id=teacher_id, + start_time=start_time, + end_time=end_time, + semester_or_year=semester, + is_active=True, + ) + created_routines.append(routine) + + except ValueError as e: + raise # Re-raise to trigger rollback + except Exception as e: + raise # Re-raise to trigger rollback + + return JsonResponse( + { + "success": True, + "message": f"Successfully saved {len(created_routines)} routines", + "routines": [ + { + "id": r.id, + "course": r.course.name, + "subject": r.subject.name, + "teacher": r.teacher.name, + "start_time": r.start_time.strftime("%H:%M"), + "end_time": r.end_time.strftime("%H:%M"), + "semester_or_year": r.semester_or_year, + } + for r in created_routines + ], + } + ) + + except ValueError as e: + return JsonResponse({"success": False, "message": str(e)}) + except json.JSONDecodeError as e: + return JsonResponse( + {"success": False, "message": f"Invalid JSON data: {str(e)}"} + ) + except Exception as e: + return JsonResponse({"success": False, "message": str(e)}) + + return JsonResponse({"success": False, "message": "Invalid request method"}) + + def formfield_for_foreignkey(self, db_field, request, **kwargs): + if db_field.name == "subject": + if request.GET.get("course"): + kwargs["queryset"] = Subject.objects.filter( + course_id=request.GET.get("course"), + semester_or_year=request.GET.get("semester_or_year", 1), + ) + else: + kwargs["queryset"] = Subject.objects.none() + elif db_field.name == "teacher": + kwargs["queryset"] = Staff.objects.filter( + Q(designation__icontains="Teacher") + | Q(designation__icontains="Staff") + | Q(designation__icontains="Principal") + | Q(designation__isnull=True) + | Q(designation="") + ).order_by("name") + return super().formfield_for_foreignkey(db_field, request, **kwargs) + + def get_form(self, request, obj=None, **kwargs): + form = super().get_form(request, obj, **kwargs) + if not obj: # Only for adding new routines + form.base_fields["course"].widget.attrs["class"] = "select2" + form.base_fields["subject"].widget.attrs["class"] = "select2" + form.base_fields["teacher"].widget.attrs["class"] = "select2" + form.base_fields["semester_or_year"].initial = 1 + return form + + def add_view(self, request, form_url="", extra_context=None): + extra_context = extra_context or {} + extra_context["show_save_and_add_another"] = True + return super().add_view(request, form_url, extra_context) class Media: - js = ("js/multiple_student_hover.js", "js/routine_admin.js") + css = { + "all": ( + "https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/css/select2.min.css", + ) + } + js = ("https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/js/select2.min.js",) @admin.register(Staff_leave, site=custom_admin_site) class StaffLeaveAdmin(admin.ModelAdmin): - list_display = ('staff', 'date', 'get_status_display', 'created_at') - list_filter = ('status', 'date', 'created_at') - search_fields = ('staff__name', 'message') - readonly_fields = ('created_at', 'updated_at') - ordering = ('-created_at',) - raw_id_fields = ('staff',) + list_display = ("staff", "date", "get_status_display", "created_at") + list_filter = ("status", "date", "created_at") + search_fields = ("staff__name", "message") + readonly_fields = ("created_at", "updated_at") + ordering = ("-created_at",) + raw_id_fields = ("staff",) @admin.register(Student_Leave, site=custom_admin_site) class StudentLeaveAdmin(admin.ModelAdmin): - list_display = ('student', 'date', 'get_status_display', 'created_at') - list_filter = ('status', 'date', 'created_at') - search_fields = ('student__name', 'message') - readonly_fields = ('created_at', 'updated_at') - ordering = ('-created_at',) - raw_id_fields = ('student',) + list_display = ("student", "date", "get_status_display", "created_at") + list_filter = ("status", "date", "created_at") + search_fields = ("student__name", "message") + readonly_fields = ("created_at", "updated_at") + ordering = ("-created_at",) + raw_id_fields = ("student",) @admin.register(StudentFeedback, site=custom_admin_site) class StudentFeedbackAdmin(admin.ModelAdmin): - list_display = ('student', 'rating', 'created_at') - list_filter = ('rating', 'created_at') - search_fields = ('student__name', 'feedback_text') - readonly_fields = ('created_at', 'updated_at') - ordering = ('-created_at',) + list_display = ("student", "rating", "created_at") + list_filter = ("rating", "created_at") + search_fields = ("student__name", "feedback_text") + readonly_fields = ("created_at", "updated_at") + ordering = ("-created_at",) @admin.register(CourseTracking, site=custom_admin_site) class CourseTrackingAdmin(admin.ModelAdmin): - list_display = ('student', 'course', 'progress_status', 'completion_percentage', 'start_date', 'expected_end_date') - list_filter = ('progress_status', 'course', 'start_date', 'expected_end_date') - search_fields = ('student__name', 'course__name', 'notes') - readonly_fields = ('enrollment_date', 'created_at', 'updated_at') - ordering = ('-created_at',) - raw_id_fields = ('student', 'course') + list_display = ( + "student", + "course", + "progress_status", + "completion_percentage", + "start_date", + "expected_end_date", + ) + list_filter = ("progress_status", "course", "start_date", "expected_end_date") + search_fields = ("student__name", "course__name", "notes") + readonly_fields = ("enrollment_date", "created_at", "updated_at") + ordering = ("-created_at",) + raw_id_fields = ("student", "course") list_per_page = 25 def has_view_permission(self, request, obj=None): @@ -420,44 +647,121 @@ class CourseTrackingAdmin(admin.ModelAdmin): def has_module_permission(self, request): return request.user.has_module_perms("app") - class Media: - js = ("js/course_tracking_admin.js",) - @admin.register(InstituteFeedback, site=custom_admin_site) class InstituteFeedbackAdmin(admin.ModelAdmin): - list_display = ('display_name', 'institute', 'feedback_type', 'rating', 'is_anonymous', 'is_public', 'created_at') - list_filter = ('feedback_type', 'rating', 'is_anonymous', 'is_public', 'created_at', 'institute') - search_fields = ('user__name', 'institute__name', 'feedback_text') - readonly_fields = ('created_at', 'updated_at') - date_hierarchy = 'created_at' - + list_display = ( + "display_name", + "institute", + "feedback_type", + "rating", + "is_anonymous", + "is_public", + "created_at", + ) + list_filter = ( + "feedback_type", + "rating", + "is_anonymous", + "is_public", + "created_at", + "institute", + ) + search_fields = ("user__name", "institute__name", "feedback_text") + readonly_fields = ("created_at", "updated_at") + date_hierarchy = "created_at" + def display_name(self, obj): return obj.display_name - display_name.short_description = 'Student Name' - + + display_name.short_description = "Student Name" + fieldsets = ( - ('Feedback Information', { - 'fields': ('institute', 'user', 'feedback_type', 'rating', 'feedback_text') - }), - ('Privacy Settings', { - 'fields': ('is_anonymous', 'is_public'), - 'classes': ('collapse',) - }), - ('Timestamps', { - 'fields': ('created_at', 'updated_at'), - 'classes': ('collapse',) - }), + (None, {"fields": ("institute", "user")}), + ( + "Feedback Details", + { + "fields": ( + "feedback_type", + "rating", + "feedback_text", + "is_anonymous", + "is_public", + ) + }, + ), + ( + "Metadata", + {"fields": ("created_at", "updated_at"), "classes": ("collapse",)}, + ), ) def get_queryset(self, request): - return super().get_queryset(request).select_related('user', 'institute') + return super().get_queryset(request).select_related("user", "institute") class Media: - css = { - 'all': ('admin/css/forms.css',) - } - js = ('admin/js/collapse.js',) + css = {"all": ("admin/css/forms.css",)} + js = ("admin/js/collapse.js",) + + +@admin.register(StaffInstituteFeedback, site=custom_admin_site) +class StaffInstituteFeedbackAdmin(admin.ModelAdmin): + list_display = ( + "display_name", + "institute", + "feedback_type", + "rating", + "is_anonymous", + "is_public", + "created_at", + ) + list_filter = ( + "feedback_type", + "rating", + "is_anonymous", + "is_public", + "created_at", + "institute", + ) + search_fields = ("staff__name", "institute__name", "feedback_text") + readonly_fields = ("created_at", "updated_at") + date_hierarchy = "created_at" + + def display_name(self, obj): + return obj.display_name + + display_name.short_description = "Staff Name" + + fieldsets = ( + (None, {"fields": ("institute", "staff")}), + ( + "Feedback Details", + { + "fields": ( + "feedback_type", + "rating", + "feedback_text", + "is_anonymous", + "is_public", + ) + }, + ), + ( + "Metadata", + {"fields": ("created_at", "updated_at"), "classes": ("collapse",)}, + ), + ) + + def get_queryset(self, request): + return super().get_queryset(request).select_related("staff", "institute") + + +@admin.register(FCMDevice) +class FCMDeviceAdmin(admin.ModelAdmin): + list_display = ("token",) + search_fields = ("token",) + list_filter = ("token",) + advanced_filter_fields = ("token",) custom_admin_site.register(User, UserAdmin) diff --git a/app/api_urls.py b/app/api_urls.py new file mode 100644 index 0000000..0519ecb --- /dev/null +++ b/app/api_urls.py @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/app/api_views.py b/app/api_views.py new file mode 100644 index 0000000..0519ecb --- /dev/null +++ b/app/api_views.py @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/app/auth.py b/app/auth.py new file mode 100644 index 0000000..0c0bc34 --- /dev/null +++ b/app/auth.py @@ -0,0 +1,298 @@ +from django.shortcuts import render, redirect +from django.contrib.auth import login +from django.views.decorators.csrf import csrf_exempt +from django.contrib.auth.models import User +from django.contrib.auth.hashers import make_password +from django.core.cache import cache +import uuid +from .models import Student, Staff +from .utils import ( + generate_otp, + store_otp, + verify_otp, + send_otp_sms, + send_password_reset_email, + verify_reset_code +) + +def reset_password_options(request): + """View for selecting between phone and email password reset""" + return render(request, "login/reset_options.html") + +def password_reset_phone(request): + """View for initiating password reset with phone number""" + if request.method == "POST": + phone = request.POST.get("phone") + + # Validate phone number + if not phone or not phone.isdigit(): + return render(request, "login/password_reset_phone.html", {"error": "Please enter a valid phone number", "is_email": False}) + + # Check if a user with this phone exists + student = Student.objects.filter(phone=phone).first() + staff = Staff.objects.filter(phone=phone).first() + + if not student and not staff: + return render(request, "login/password_reset_phone.html", {"error": "No account found with this phone number", "is_email": False}) + + # Generate and store OTP + otp = generate_otp() + store_otp(phone, otp) + + # Send OTP via SMS + send_result = send_otp_sms(phone, otp) + + if send_result: + # Redirect to OTP verification page + return render(request, "login/password_reset_otp.html", {"phone": phone, "is_email": False}) + else: + return render(request, "login/password_reset_phone.html", {"error": "Failed to send OTP. Please try again.", "is_email": False}) + + return render(request, "login/password_reset_phone.html", {"is_email": False}) + +def password_reset_phone_verify(request): + """View for verifying OTP for password reset""" + if request.method == "POST": + phone = request.POST.get("phone") + otp = request.POST.get("otp") + + if not phone or not otp: + return render(request, "login/password_reset_otp.html", { + "error": "Phone and OTP are required", + "phone": phone, + "is_email": False + }) + + # Verify OTP + if verify_otp(phone, otp): + # Generate a secure token for this reset + token = str(uuid.uuid4()) + # Store token with phone in cache for 15 minutes + cache.set(f"reset_token_{token}", phone, 60 * 15) + + # Redirect to set new password + return render(request, "login/password_reset_set.html", { + "phone": phone, + "token": token, + "is_email": False + }) + else: + return render(request, "login/password_reset_otp.html", { + "error": "Invalid or expired OTP", + "phone": phone, + "is_email": False + }) + + # If GET request, redirect to phone login + return redirect("phone_reset_password") + +def resend_phone_otp(request): + """View for resending OTP for password reset""" + if request.method == "POST": + phone = request.POST.get("phone") + + if not phone: + return redirect("phone_reset_password") + + # Generate and store new OTP + otp = generate_otp() + store_otp(phone, otp) + + # Send OTP via SMS + send_result = send_otp_sms(phone, otp) + + if send_result: + return render(request, "login/password_reset_otp.html", { + "phone": phone, + "message": "OTP resent successfully", + "is_email": False + }) + else: + return render(request, "login/password_reset_otp.html", { + "phone": phone, + "error": "Failed to resend OTP", + "is_email": False + }) + + return redirect("phone_reset_password") + +def password_reset_email(request): + """View for initiating password reset with email""" + if request.method == "POST": + email = request.POST.get("email") + + # Validate email + if not email: + return render(request, "login/email_reset.html", {"error": "Please enter a valid email address", "is_email": True}) + + # Check if a user with this email exists + student = Student.objects.filter(email=email).first() + staff = Staff.objects.filter(email=email).first() + + if not student and not staff: + return render(request, "login/email_reset.html", {"error": "No account found with this email address", "is_email": True}) + + # Get the user + user = student or staff + + # Send password reset email + if send_password_reset_email(user, request, email): + # Redirect to verification page + return render(request, "login/password_reset_otp.html", {"email": email, "is_email": True}) + else: + return render(request, "login/email_reset.html", {"error": "Failed to send verification code. Please try again.", "is_email": True}) + + return render(request, "login/email_reset.html", {"is_email": True}) + +def password_reset_email_verify(request): + """View for verifying reset code for email""" + if request.method == "POST": + email = request.POST.get("email") + code = request.POST.get("otp") + + if not email or not code: + return render(request, "login/password_reset_otp.html", { + "error": "Email and verification code are required", + "email": email, + "is_email": True + }) + + # Verify code + if verify_reset_code(email, code): + # Generate a secure token for this reset + token = str(uuid.uuid4()) + # Store token with email in cache for 15 minutes + cache.set(f"reset_token_{token}", email, 60 * 15) + + # Redirect to set new password + return render(request, "login/password_reset_set.html", { + "email": email, + "token": token, + "is_email": True + }) + else: + return render(request, "login/password_reset_otp.html", { + "error": "Invalid or expired code", + "email": email, + "is_email": True, + "message": "Please check your email for the verification code." + }) + + # For GET request, show the verification form with email pre-filled + email = request.GET.get("email") + return render(request, "login/password_reset_otp.html", { + "email": email, + "is_email": True, + "message": "Please check your email for the verification code." + }) + +def resend_email_code(request): + """View for resending verification code for password reset""" + if request.method == "POST": + email = request.POST.get("email") + + if not email: + return redirect("email_reset_password") + + # Find the user + student = Student.objects.filter(email=email).first() + staff = Staff.objects.filter(email=email).first() + user = student or staff + + if not user: + return render(request, "login/password_reset_otp.html", { + "email": email, + "is_email": True, + "error": "User not found" + }) + + # Send new verification code + if send_password_reset_email(user, request, email): + return render(request, "login/password_reset_otp.html", { + "email": email, + "is_email": True, + "message": "Verification code resent successfully" + }) + else: + return render(request, "login/password_reset_otp.html", { + "email": email, + "is_email": True, + "error": "Failed to resend verification code" + }) + + return redirect("email_reset_password") + +def set_new_password(request): + """View for setting new password after verification""" + if request.method == "POST": + phone = request.POST.get("phone") + email = request.POST.get("email") + token = request.POST.get("token") + new_password1 = request.POST.get("new_password1") + new_password2 = request.POST.get("new_password2") + + identifier = phone or email + is_email = bool(email) + + # Validate inputs + if not all([identifier, token, new_password1, new_password2]): + return render(request, "login/password_reset_set.html", { + "error": "All fields are required", + "phone": phone, + "email": email, + "token": token, + "is_email": is_email + }) + + # Verify token is valid + stored_identifier = cache.get(f"reset_token_{token}") + if not stored_identifier or stored_identifier != identifier: + return render(request, "login/password_reset_set.html", { + "error": "Invalid or expired reset session", + "phone": phone, + "email": email, + "token": token, + "is_email": is_email + }) + + # Check passwords match + if new_password1 != new_password2: + return render(request, "login/password_reset_set.html", { + "error": "Passwords do not match", + "phone": phone, + "email": email, + "token": token, + "is_email": is_email + }) + + # Find the user + if is_email: + student = Student.objects.filter(email=email).first() + staff = Staff.objects.filter(email=email).first() + else: + student = Student.objects.filter(phone=phone).first() + staff = Staff.objects.filter(phone=phone).first() + + user = student or staff + + if user: + # Set new password + user.password = make_password(new_password1) + user.save() + + # Invalidate reset token + cache.delete(f"reset_token_{token}") + + # Show success message + return render(request, "login/password_reset_complete.html") + else: + return render(request, "login/password_reset_set.html", { + "error": "User not found", + "phone": phone, + "email": email, + "token": token, + "is_email": is_email + }) + + # If GET request, redirect to options page + return redirect("reset_password_options") \ No newline at end of file diff --git a/app/backends.py b/app/backends.py index 7097874..1aa92f5 100644 --- a/app/backends.py +++ b/app/backends.py @@ -5,12 +5,12 @@ from .models import Staff, Student class MultiModelBackend(ModelBackend): def authenticate(self, request, username=None, password=None, **kwargs): """ - Authenticate the user based on username (phone for Student and Staff) and password. + Authenticate the user based on username (email or phone) and password. """ if username is None or password is None: return None - # Try authenticating as Staff + # Try authenticating as Staff by phone try: staff = Staff.objects.get(phone=username) if staff.check_password(password): @@ -18,7 +18,15 @@ class MultiModelBackend(ModelBackend): except Staff.DoesNotExist: pass - # Try authenticating as Student + # Try authenticating as Staff by email + try: + staff = Staff.objects.get(email=username) + if staff.check_password(password): + return staff + except Staff.DoesNotExist: + pass + + # Try authenticating as Student by phone try: student = Student.objects.get(phone=username) if student.check_password(password): @@ -26,6 +34,12 @@ class MultiModelBackend(ModelBackend): except Student.DoesNotExist: pass + # Try authenticating as Student by email + # Use filter().first() to handle multiple students with same email + student = Student.objects.filter(email=username).first() + if student and student.check_password(password): + return student + # Return None if no match return None diff --git a/app/forms.py b/app/forms.py index 4faadfb..deba05d 100644 --- a/app/forms.py +++ b/app/forms.py @@ -1,8 +1,18 @@ from django import forms from django.contrib.auth.hashers import make_password +from django.contrib.auth.forms import SetPasswordForm from .models import Staff, Student +class CustomSetPasswordForm(SetPasswordForm): + def save(self, commit=True): + user = self.user + user.set_password(self.cleaned_data["new_password1"]) + if commit: + user.save() + return user + + class StudentAdminForm(forms.ModelForm): new_password = forms.CharField( required=False, @@ -36,10 +46,10 @@ class StaffAdminForm(forms.ModelForm): fields = "__all__" def save(self, commit=True): - student = super().save(commit=False) + staff = super().save(commit=False) new_password = self.cleaned_data.get("new_password") if new_password: - student.password = make_password(new_password) + staff.password = make_password(new_password) if commit: - student.save() - return student + staff.save() + return staff diff --git a/app/migrations/0001_initial.py b/app/migrations/0001_initial.py index 5f3fe09..bb2e0b7 100644 --- a/app/migrations/0001_initial.py +++ b/app/migrations/0001_initial.py @@ -1,4 +1,4 @@ -# Generated by Django 5.1.7 on 2025-03-25 17:13 +# Generated by Django 5.1.7 on 2025-03-27 01:54 import django.contrib.auth.models import django.db.models.deletion @@ -95,6 +95,11 @@ class Migration(migrations.Migration): ('temporary_address', models.CharField(blank=True, max_length=255, null=True)), ('permanent_address', models.CharField(blank=True, max_length=255, null=True)), ('marital_status', models.CharField(blank=True, choices=[('Married', 'Married'), ('Unmarried', 'Unmarried'), ('Divorced', 'Divorced')], max_length=255, null=True)), + ('parent_name', models.CharField(blank=True, max_length=255, null=True)), + ('parent_phone', models.CharField(blank=True, max_length=255, null=True)), + ('citizenship_no', models.CharField(blank=True, max_length=255, null=True)), + ('passport', models.CharField(blank=True, max_length=255, null=True)), + ('image', models.ImageField(blank=True, null=True, upload_to='staff_image')), ('joining_date', models.DateField(blank=True, null=True)), ('password', models.CharField(editable=False, max_length=128, null=True)), ('groups', models.ManyToManyField(blank=True, help_text='The groups this staff belongs to.', related_name='staffs', to='auth.group', verbose_name='groups')), @@ -111,15 +116,16 @@ class Migration(migrations.Migration): migrations.CreateModel( name='Routine', fields=[ - ('id', models.BigAutoField(primary_key=True, serialize=False)), - ('name', models.CharField(blank=True, max_length=255, null=True)), - ('start_time', models.TimeField(blank=True, null=True)), - ('end_time', models.TimeField(blank=True, null=True)), - ('teacher', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='routines', to='app.staff')), + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('start_time', models.TimeField()), + ('end_time', models.TimeField()), + ('semester_or_year', models.PositiveIntegerField()), + ('is_active', models.BooleanField(default=True)), + ('course', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='app.course')), + ('teacher', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='app.staff')), ], options={ - 'verbose_name': 'Routine', - 'verbose_name_plural': 'Routines', + 'ordering': ['start_time'], }, ), migrations.CreateModel( @@ -168,11 +174,16 @@ class Migration(migrations.Migration): ('phone', models.CharField(blank=True, max_length=255, null=True, unique=True)), ('temporary_address', models.CharField(blank=True, max_length=500, null=True)), ('permanent_address', models.CharField(blank=True, max_length=500, null=True)), + ('marital_status', models.CharField(blank=True, choices=[('Married', 'Married'), ('Unmarried', 'Unmarried'), ('Divorced', 'Divorced')], max_length=255, null=True)), ('parent_name', models.CharField(blank=True, max_length=255, null=True)), ('parent_phone', models.CharField(blank=True, max_length=255, null=True)), + ('citizenship_no', models.CharField(blank=True, max_length=255, null=True)), + ('image', models.ImageField(blank=True, null=True, upload_to='student_image')), + ('current_semester', models.PositiveIntegerField(default=1, help_text='Current semester for semester-based courses')), ('joining_date', models.DateField(blank=True, null=True)), ('password', models.CharField(editable=False, max_length=128, null=True)), - ('courses', models.ManyToManyField(blank=True, related_name='students', to='app.course')), + ('batches', models.ManyToManyField(blank=True, related_name='students', to='app.batch')), + ('course', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='students', to='app.course')), ('groups', models.ManyToManyField(blank=True, help_text='The groups this student belongs to.', related_name='students', to='auth.group', verbose_name='groups')), ('user_permissions', models.ManyToManyField(blank=True, help_text='Specific permissions for this student.', related_name='student_set', related_query_name='student', to='auth.permission', verbose_name='user permissions')), ], @@ -210,56 +221,113 @@ class Migration(migrations.Migration): 'ordering': ['-created_at'], }, ), - migrations.CreateModel( - name='StudentRoutine', - fields=[ - ('id', models.BigAutoField(primary_key=True, serialize=False)), - ('course', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='app.course')), - ('routine', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='students', to='app.routine')), - ('student', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='routines', to='app.student')), - ], - ), migrations.CreateModel( name='Subject', fields=[ ('id', models.AutoField(primary_key=True, serialize=False)), ('name', models.CharField(max_length=255)), ('semester_or_year', models.PositiveIntegerField()), - ('course', models.ForeignKey(default=1, on_delete=django.db.models.deletion.CASCADE, to='app.course')), + ('syllabus_pdf', models.FileField(blank=True, help_text='Upload syllabus or study material PDF', null=True, upload_to='subject_pdfs/')), + ('course', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='app.course')), ], + options={ + 'ordering': ['course', 'semester_or_year', 'name'], + 'unique_together': {('name', 'course', 'semester_or_year')}, + }, + ), + migrations.AddField( + model_name='routine', + name='subject', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='app.subject'), + ), + migrations.CreateModel( + name='StaffInstituteFeedback', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('feedback_type', models.CharField(choices=[('General', 'General'), ('Facilities', 'Facilities'), ('Teaching', 'Teaching'), ('Infrastructure', 'Infrastructure'), ('Administration', 'Administration')], default='General', max_length=20)), + ('rating', models.DecimalField(choices=[(1.0, 1.0), (1.5, 1.5), (2.0, 2.0), (2.5, 2.5), (3.0, 3.0), (3.5, 3.5), (4.0, 4.0), (4.5, 4.5), (5.0, 5.0)], decimal_places=1, max_digits=2)), + ('feedback_text', models.TextField()), + ('is_anonymous', models.BooleanField(default=False)), + ('is_public', models.BooleanField(default=True)), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('updated_at', models.DateTimeField(auto_now=True)), + ('institute', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='staff_feedbacks', to='app.institute')), + ('staff', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='institute_feedbacks', to='app.staff')), + ], + options={ + 'verbose_name': 'Staff Institute Feedback', + 'verbose_name_plural': 'Staff Institute Feedbacks', + 'ordering': ['-created_at'], + 'unique_together': {('staff', 'institute', 'feedback_type')}, + }, + ), + migrations.CreateModel( + name='InstituteFeedback', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('feedback_type', models.CharField(choices=[('General', 'General'), ('Facilities', 'Facilities'), ('Teaching', 'Teaching'), ('Infrastructure', 'Infrastructure'), ('Administration', 'Administration')], default='General', max_length=20)), + ('rating', models.DecimalField(choices=[(1.0, 1.0), (1.5, 1.5), (2.0, 2.0), (2.5, 2.5), (3.0, 3.0), (3.5, 3.5), (4.0, 4.0), (4.5, 4.5), (5.0, 5.0)], decimal_places=1, max_digits=2)), + ('feedback_text', models.TextField()), + ('is_anonymous', models.BooleanField(default=False)), + ('is_public', models.BooleanField(default=True)), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('updated_at', models.DateTimeField(auto_now=True)), + ('institute', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='feedbacks', to='app.institute')), + ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='institute_feedbacks', to='app.student')), + ], + options={ + 'verbose_name': 'Student Institute Feedback', + 'verbose_name_plural': 'Student Institute Feedbacks', + 'ordering': ['-created_at'], + 'unique_together': {('user', 'institute', 'feedback_type')}, + }, + ), + migrations.CreateModel( + name='CourseTracking', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('enrollment_date', models.DateField(auto_now_add=True)), + ('start_date', models.DateField(blank=True, null=True)), + ('expected_end_date', models.DateField(blank=True, null=True)), + ('actual_end_date', models.DateField(blank=True, null=True)), + ('progress_status', models.CharField(choices=[('Not Started', 'Not Started'), ('In Progress', 'In Progress'), ('Completed', 'Completed'), ('Dropped', 'Dropped')], default='Not Started', max_length=20)), + ('completion_percentage', models.IntegerField(default=0, help_text='Percentage of course completion (0-100)')), + ('current_semester', models.PositiveIntegerField(default=1)), + ('semester_start_date', models.DateField(blank=True, null=True)), + ('semester_end_date', models.DateField(blank=True, null=True)), + ('notes', models.TextField(blank=True, null=True)), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('updated_at', models.DateTimeField(auto_now=True)), + ('course', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='student_trackings', to='app.course')), + ('student', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='course_trackings', to='app.student')), + ], + options={ + 'verbose_name': 'Course Tracking', + 'verbose_name_plural': 'Course Trackings', + 'ordering': ['-created_at'], + 'unique_together': {('student', 'course')}, + }, ), migrations.CreateModel( name='StudentFeedback', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('rating', models.IntegerField(choices=[(1, 1), (2, 2), (3, 3), (4, 4), (5, 5)])), + ('rating', models.DecimalField(choices=[(1.0, 1.0), (1.5, 1.5), (2.0, 2.0), (2.5, 2.5), (3.0, 3.0), (3.5, 3.5), (4.0, 4.0), (4.5, 4.5), (5.0, 5.0)], decimal_places=1, max_digits=2)), ('feedback_text', models.TextField()), ('created_at', models.DateTimeField(auto_now_add=True)), ('updated_at', models.DateTimeField(auto_now=True)), ('student', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='feedbacks', to='app.student')), - ('teacher', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='app.staff')), - ('subject', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='app.subject')), + ('teacher', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='feedbacks', to='app.staff')), ], options={ 'verbose_name': 'Student Feedback', 'verbose_name_plural': 'Student Feedbacks', - 'unique_together': {('student', 'subject', 'teacher')}, + 'ordering': ['-created_at'], + 'unique_together': {('student', 'teacher')}, }, ), - migrations.CreateModel( - name='TeacherFeedback', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('feedback_text', models.TextField()), - ('created_at', models.DateTimeField(auto_now_add=True)), - ('updated_at', models.DateTimeField(auto_now=True)), - ('subject', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='app.subject')), - ('teacher', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='feedbacks', to='app.staff')), - ], - options={ - 'verbose_name': 'Teacher Feedback', - 'verbose_name_plural': 'Teacher Feedbacks', - 'unique_together': {('teacher', 'subject')}, - }, + migrations.AlterUniqueTogether( + name='routine', + unique_together={('course', 'subject', 'teacher', 'start_time', 'end_time', 'semester_or_year')}, ), ] diff --git a/app/migrations/0002_alter_studentfeedback_unique_together_and_more.py b/app/migrations/0002_alter_studentfeedback_unique_together_and_more.py deleted file mode 100644 index c7b952a..0000000 --- a/app/migrations/0002_alter_studentfeedback_unique_together_and_more.py +++ /dev/null @@ -1,28 +0,0 @@ -# Generated by Django 5.1.7 on 2025-03-25 17:18 - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('app', '0001_initial'), - ] - - operations = [ - migrations.AlterUniqueTogether( - name='studentfeedback', - unique_together=set(), - ), - migrations.DeleteModel( - name='TeacherFeedback', - ), - migrations.RemoveField( - model_name='studentfeedback', - name='subject', - ), - migrations.RemoveField( - model_name='studentfeedback', - name='teacher', - ), - ] diff --git a/app/migrations/0002_create_staffinstitutefeedback_table.py b/app/migrations/0002_create_staffinstitutefeedback_table.py new file mode 100644 index 0000000..9601f31 --- /dev/null +++ b/app/migrations/0002_create_staffinstitutefeedback_table.py @@ -0,0 +1,24 @@ +from django.db import migrations + +class Migration(migrations.Migration): + + dependencies = [ + ('app', '0001_initial'), + ] + + operations = [ + migrations.RunSQL( + """ + CREATE TABLE IF NOT EXISTS "app_staffinstitutefeedback" ( + "id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, + "feedback_type" integer NOT NULL, + "feedback_text" text NOT NULL, + "rating" integer NOT NULL, + "is_anonymous" bool NOT NULL, + "created_at" datetime NOT NULL, + "staff_id" integer NOT NULL REFERENCES "app_staff" ("id") DEFERRABLE INITIALLY DEFERRED + ); + """, + "DROP TABLE IF EXISTS app_staffinstitutefeedback;" + ), + ] \ No newline at end of file diff --git a/app/migrations/0003_coursetracking.py b/app/migrations/0003_coursetracking.py deleted file mode 100644 index 735e412..0000000 --- a/app/migrations/0003_coursetracking.py +++ /dev/null @@ -1,37 +0,0 @@ -# Generated by Django 5.1.7 on 2025-03-25 18:18 - -import django.db.models.deletion -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('app', '0002_alter_studentfeedback_unique_together_and_more'), - ] - - operations = [ - migrations.CreateModel( - name='CourseTracking', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('enrollment_date', models.DateField(auto_now_add=True)), - ('start_date', models.DateField(blank=True, null=True)), - ('expected_end_date', models.DateField(blank=True, null=True)), - ('actual_end_date', models.DateField(blank=True, null=True)), - ('progress_status', models.CharField(choices=[('Not Started', 'Not Started'), ('In Progress', 'In Progress'), ('Completed', 'Completed'), ('Dropped', 'Dropped')], default='Not Started', max_length=20)), - ('completion_percentage', models.IntegerField(default=0, help_text='Percentage of course completion (0-100)')), - ('notes', models.TextField(blank=True, null=True)), - ('created_at', models.DateTimeField(auto_now_add=True)), - ('updated_at', models.DateTimeField(auto_now=True)), - ('course', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='student_trackings', to='app.course')), - ('student', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='course_trackings', to='app.student')), - ], - options={ - 'verbose_name': 'Course Tracking', - 'verbose_name_plural': 'Course Trackings', - 'ordering': ['-created_at'], - 'unique_together': {('student', 'course')}, - }, - ), - ] diff --git a/app/migrations/0004_alter_studentfeedback_options_and_more.py b/app/migrations/0004_alter_studentfeedback_options_and_more.py deleted file mode 100644 index d67251e..0000000 --- a/app/migrations/0004_alter_studentfeedback_options_and_more.py +++ /dev/null @@ -1,34 +0,0 @@ -# Generated by Django 5.1.7 on 2025-03-25 18:27 - -import django.db.models.deletion -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('app', '0003_coursetracking'), - ] - - operations = [ - migrations.AlterModelOptions( - name='studentfeedback', - options={'ordering': ['-created_at'], 'verbose_name': 'Student Feedback', 'verbose_name_plural': 'Student Feedbacks'}, - ), - migrations.AddField( - model_name='studentfeedback', - name='subject', - field=models.ForeignKey(default='1', on_delete=django.db.models.deletion.CASCADE, related_name='feedbacks', to='app.subject'), - preserve_default=False, - ), - migrations.AddField( - model_name='studentfeedback', - name='teacher', - field=models.ForeignKey(default='1', on_delete=django.db.models.deletion.CASCADE, related_name='feedbacks', to='app.staff'), - preserve_default=False, - ), - migrations.AlterUniqueTogether( - name='studentfeedback', - unique_together={('student', 'subject', 'teacher')}, - ), - ] diff --git a/app/migrations/0005_alter_studentfeedback_unique_together_and_more.py b/app/migrations/0005_alter_studentfeedback_unique_together_and_more.py deleted file mode 100644 index 826b095..0000000 --- a/app/migrations/0005_alter_studentfeedback_unique_together_and_more.py +++ /dev/null @@ -1,21 +0,0 @@ -# Generated by Django 5.1.7 on 2025-03-25 19:41 - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('app', '0004_alter_studentfeedback_options_and_more'), - ] - - operations = [ - migrations.AlterUniqueTogether( - name='studentfeedback', - unique_together={('student', 'teacher')}, - ), - migrations.RemoveField( - model_name='studentfeedback', - name='subject', - ), - ] diff --git a/app/migrations/0006_institutefeedback.py b/app/migrations/0006_institutefeedback.py deleted file mode 100644 index b3cf33e..0000000 --- a/app/migrations/0006_institutefeedback.py +++ /dev/null @@ -1,35 +0,0 @@ -# Generated by Django 5.1.7 on 2025-03-25 19:44 - -import django.db.models.deletion -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('app', '0005_alter_studentfeedback_unique_together_and_more'), - ] - - operations = [ - migrations.CreateModel( - name='InstituteFeedback', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('feedback_type', models.CharField(choices=[('General', 'General'), ('Facilities', 'Facilities'), ('Teaching', 'Teaching'), ('Infrastructure', 'Infrastructure'), ('Administration', 'Administration')], default='General', max_length=20)), - ('rating', models.IntegerField(choices=[(1, 1), (2, 2), (3, 3), (4, 4), (5, 5)])), - ('feedback_text', models.TextField()), - ('is_anonymous', models.BooleanField(default=False)), - ('is_public', models.BooleanField(default=True)), - ('created_at', models.DateTimeField(auto_now_add=True)), - ('updated_at', models.DateTimeField(auto_now=True)), - ('institute', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='feedbacks', to='app.institute')), - ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='institute_feedbacks', to='app.student')), - ], - options={ - 'verbose_name': 'Institute Feedback', - 'verbose_name_plural': 'Institute Feedbacks', - 'ordering': ['-created_at'], - 'unique_together': {('user', 'institute', 'feedback_type')}, - }, - ), - ] diff --git a/app/migrations/0007_student_is_superuser_alter_student_is_active.py b/app/migrations/0007_student_is_superuser_alter_student_is_active.py deleted file mode 100644 index 06b0dd2..0000000 --- a/app/migrations/0007_student_is_superuser_alter_student_is_active.py +++ /dev/null @@ -1,23 +0,0 @@ -# Generated by Django 5.1.7 on 2025-03-25 20:12 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('app', '0006_institutefeedback'), - ] - - operations = [ - migrations.AddField( - model_name='student', - name='is_superuser', - field=models.BooleanField(default=False), - ), - migrations.AlterField( - model_name='student', - name='is_active', - field=models.BooleanField(default=True), - ), - ] diff --git a/app/models.py b/app/models.py index 4425b95..d1ddf96 100644 --- a/app/models.py +++ b/app/models.py @@ -1,12 +1,11 @@ -from django.db import models +from django.db import models, transaction from django.contrib.auth.hashers import make_password from django.contrib.auth.models import AbstractUser -from django.utils.safestring import mark_safe -from django.utils import timezone -from datetime import date +from datetime import date, timedelta from django.db.models.signals import post_save from django.dispatch import receiver from django.core.cache import cache +from .utils import send_push_notification # Create your models here. duration_types_choices = (("Year", "Yearl Based"), ("Semester", "Semester Based")) @@ -61,12 +60,52 @@ class Course(models.Model): class Subject(models.Model): id = models.AutoField(primary_key=True) name = models.CharField(max_length=255) - course = models.ForeignKey(Course, on_delete=models.CASCADE, default=1) + course = models.ForeignKey(Course, on_delete=models.CASCADE) semester_or_year = models.PositiveIntegerField() + syllabus_pdf = models.FileField(upload_to='subject_pdfs/', null=True, blank=True, help_text="Upload syllabus or study material PDF") + + def __str__(self): + return f"{self.name} ({self.course.name} - {'Semester' if self.course.duration_type == 'Semester' else 'Year'} {self.semester_or_year})" + + def clean(self): + from django.core.exceptions import ValidationError + + # Validate semester/year based on course duration type + if self.course.duration_type == "Semester": + max_semesters = self.course.duration * 2 + if self.semester_or_year > max_semesters: + raise ValidationError(f"Semester cannot exceed {max_semesters}") + else: # Year based + if self.semester_or_year > self.course.duration: + raise ValidationError(f"Year cannot exceed {self.course.duration}") + + def save(self, *args, **kwargs): + self.clean() + super().save(*args, **kwargs) + + def get_pdf_url(self): + if self.syllabus_pdf: + return self.syllabus_pdf.url + return None + + class Meta: + unique_together = ['name', 'course', 'semester_or_year'] + ordering = ['course', 'semester_or_year', 'name'] + + +class Batch(models.Model): + id = models.BigAutoField(primary_key=True) + name = models.CharField(max_length=255) + start_date = models.DateField(null=True, blank=True) + end_date = models.DateField(null=True, blank=True) def __str__(self): return self.name + class Meta: + verbose_name = "Batch" + verbose_name_plural = "Batches" + class Student(AbstractUser): first_name = None @@ -76,27 +115,21 @@ class Student(AbstractUser): username = None email = None - # Add these fields - is_active = models.BooleanField(default=True) - is_staff = models.BooleanField(default=True) # This ensures admin access - is_superuser = models.BooleanField(default=False) - user_permissions = models.ManyToManyField( "auth.Permission", verbose_name="user permissions", blank=True, help_text="Specific permissions for this student.", - related_name="student_set", # This fixes the clash + related_name="student_set", related_query_name="student", ) - # Similarly, let's also update groups to be explicit groups = models.ManyToManyField( "auth.Group", verbose_name="groups", blank=True, help_text="The groups this student belongs to.", - related_name="students", # This matches your existing related_name + related_name="students", ) id = models.BigAutoField(primary_key=True) @@ -112,16 +145,29 @@ class Student(AbstractUser): phone = models.CharField(max_length=255, null=True, blank=True, unique=True) temporary_address = models.CharField(max_length=500, null=True, blank=True) permanent_address = models.CharField(max_length=500, null=True, blank=True) + marital_status = models.CharField( + max_length=255, choices=marital_status_choices, null=True, blank=True + ) parent_name = models.CharField(max_length=255, null=True, blank=True) parent_phone = models.CharField(max_length=255, null=True, blank=True) - courses = models.ManyToManyField(Course, related_name="students", blank=True) + citizenship_no = models.CharField(max_length=255, null=True, blank=True) + batches = models.ManyToManyField(Batch, related_name="students", blank=True) + image = models.ImageField(upload_to="student_image", null=True, blank=True) + course = models.ForeignKey( + Course, + on_delete=models.SET_NULL, + null=True, + blank=True, + related_name="students", + ) + current_semester = models.PositiveIntegerField( + default=1, help_text="Current semester for semester-based courses" + ) joining_date = models.DateField(null=True, blank=True) - password = models.CharField( - max_length=128, editable=False, null=True - ) # Editable is set to False to prevent direct editing + password = models.CharField(max_length=128, editable=False, null=True) USERNAME_FIELD = "phone" - REQUIRED_FIELDS = ["name"] # Add required fields + REQUIRED_FIELDS = ["name"] def __str__(self): return self.name @@ -132,41 +178,55 @@ class Student(AbstractUser): @property def is_staff(self): - """Check if student has any groups (permissions)""" return self.groups.exists() - @property - def is_authenticated(self): - """Required by Django's authentication system""" - return True - def has_perm(self, perm, obj=None): - """Check if student has a specific permission""" if not self.is_active: return False - # Get permissions from groups perms = set() for group in self.groups.all(): perms.update( group.permissions.values_list("content_type__app_label", "codename") ) - # Convert permission string to app_label and codename app_label, codename = perm.split(".") return (app_label, codename) in perms def has_module_perms(self, app_label): - """Check if student has any permissions in the given app""" if not self.is_active: return False - # Check if any group permissions match the app_label for group in self.groups.all(): if group.permissions.filter(content_type__app_label=app_label).exists(): return True return False + def get_current_subjects(self): + """Get subjects for current semester""" + if not self.course: + return Subject.objects.none() + return Subject.objects.filter( + course=self.course, semester_or_year=self.current_semester + ) + + def advance_semester(self): + """Advance to next semester if possible""" + if not self.course: + return False + + if self.course.duration_type == "Semester": + total_semesters = self.course.duration * 2 # 2 semesters per year + if self.current_semester < total_semesters: + self.current_semester += 1 + self.save() + return True + return False + + def save(self, *args, **kwargs): + # Remove the course tracking creation from here + super().save(*args, **kwargs) + class Meta: verbose_name = "Student" verbose_name_plural = "Students" @@ -213,6 +273,11 @@ class Staff(AbstractUser): marital_status = models.CharField( max_length=255, choices=marital_status_choices, null=True, blank=True ) + parent_name = models.CharField(max_length=255, null=True, blank=True) + parent_phone = models.CharField(max_length=255, null=True, blank=True) + citizenship_no = models.CharField(max_length=255, blank=True, null=True) + passport = models.CharField(max_length=255, blank=True, null=True) + image = models.ImageField(upload_to="staff_image", null=True, blank=True) joining_date = models.DateField(null=True, blank=True) password = models.CharField( max_length=128, editable=False, null=True @@ -269,49 +334,21 @@ class Staff(AbstractUser): verbose_name_plural = "Staffs" -class Batch(models.Model): - id = models.BigAutoField(primary_key=True) - name = models.CharField(max_length=255) - start_date = models.DateField(null=True, blank=True) - end_date = models.DateField(null=True, blank=True) - - def __str__(self): - return self.name - - class Meta: - verbose_name = "Batch" - verbose_name_plural = "Batches" - - class Routine(models.Model): - id = models.BigAutoField(primary_key=True) - name = models.CharField(max_length=255, null=True, blank=True) - start_time = models.TimeField(null=True, blank=True) - end_time = models.TimeField(null=True, blank=True) - teacher = models.ForeignKey( - Staff, related_name="routines", on_delete=models.CASCADE, null=True, blank=True - ) + course = models.ForeignKey(Course, on_delete=models.CASCADE) + subject = models.ForeignKey(Subject, on_delete=models.CASCADE) + teacher = models.ForeignKey(Staff, on_delete=models.CASCADE) + start_time = models.TimeField() + end_time = models.TimeField() + semester_or_year = models.PositiveIntegerField() + is_active = models.BooleanField(default=True) def __str__(self): - return self.name + return f"{self.subject.name} - {self.teacher.name} ({self.start_time} - {self.end_time})" class Meta: - verbose_name = "Routine" - verbose_name_plural = "Routines" - - -class StudentRoutine(models.Model): - id = models.BigAutoField(primary_key=True) - student = models.ForeignKey( - Student, related_name="routines", on_delete=models.CASCADE, null=True - ) - routine = models.ForeignKey( - Routine, related_name="students", on_delete=models.CASCADE, null=True - ) - course = models.ForeignKey(Course, on_delete=models.CASCADE, null=True, blank=True) - - def __str__(self): - return self.student.name + ordering = ['start_time'] + unique_together = ['course', 'subject', 'teacher', 'start_time', 'end_time', 'semester_or_year'] class Attendance(models.Model): @@ -395,11 +432,11 @@ class Notice(models.Model): class Staff_leave(models.Model): LEAVE_STATUS_CHOICES = ( - (0, 'Pending'), - (1, 'Approved'), - (2, 'Rejected'), + (0, "Pending"), + (1, "Approved"), + (2, "Rejected"), ) - + staff = models.ForeignKey(Staff, on_delete=models.CASCADE) date = models.DateField() message = models.TextField() @@ -413,16 +450,16 @@ class Staff_leave(models.Model): class Meta: verbose_name = "Staff Leave" verbose_name_plural = "Staff Leaves" - ordering = ['-created_at'] + ordering = ["-created_at"] class Student_Leave(models.Model): LEAVE_STATUS_CHOICES = ( - (0, 'Pending'), - (1, 'Approved'), - (2, 'Rejected'), + (0, "Pending"), + (1, "Approved"), + (2, "Rejected"), ) - + student = models.ForeignKey(Student, on_delete=models.CASCADE) date = models.DateField() message = models.TextField() @@ -436,13 +473,19 @@ class Student_Leave(models.Model): class Meta: verbose_name = "Student Leave" verbose_name_plural = "Student Leaves" - ordering = ['-created_at'] + ordering = ["-created_at"] class StudentFeedback(models.Model): - student = models.ForeignKey(Student, on_delete=models.CASCADE, related_name='feedbacks') - teacher = models.ForeignKey(Staff, on_delete=models.CASCADE, related_name='feedbacks') - rating = models.IntegerField(choices=[(i, i) for i in range(1, 6)]) # 1-5 rating + student = models.ForeignKey( + Student, on_delete=models.CASCADE, related_name="feedbacks" + ) + teacher = models.ForeignKey( + Staff, on_delete=models.CASCADE, related_name="feedbacks" + ) + rating = models.DecimalField( + max_digits=2, decimal_places=1, choices=[(i / 2, i / 2) for i in range(2, 11)] + ) # 1 to 5 rating feedback_text = models.TextField() created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True) @@ -453,23 +496,31 @@ class StudentFeedback(models.Model): class Meta: verbose_name = "Student Feedback" verbose_name_plural = "Student Feedbacks" - ordering = ['-created_at'] - unique_together = ['student', 'teacher'] # Updated unique constraint + ordering = ["-created_at"] + unique_together = ["student", "teacher"] class InstituteFeedback(models.Model): FEEDBACK_TYPE_CHOICES = ( - ('General', 'General'), - ('Facilities', 'Facilities'), - ('Teaching', 'Teaching'), - ('Infrastructure', 'Infrastructure'), - ('Administration', 'Administration'), + ("General", "General"), + ("Facilities", "Facilities"), + ("Teaching", "Teaching"), + ("Infrastructure", "Infrastructure"), + ("Administration", "Administration"), ) - institute = models.ForeignKey(Institute, on_delete=models.CASCADE, related_name='feedbacks') - user = models.ForeignKey(Student, on_delete=models.CASCADE, related_name='institute_feedbacks') - feedback_type = models.CharField(max_length=20, choices=FEEDBACK_TYPE_CHOICES, default='General') - rating = models.IntegerField(choices=[(i, i) for i in range(1, 6)]) # 1-5 rating + institute = models.ForeignKey( + Institute, on_delete=models.CASCADE, related_name="feedbacks" + ) + user = models.ForeignKey( + Student, on_delete=models.CASCADE, related_name="institute_feedbacks" + ) + feedback_type = models.CharField( + max_length=20, choices=FEEDBACK_TYPE_CHOICES, default="General" + ) + rating = models.DecimalField( + max_digits=2, decimal_places=1, choices=[(i / 2, i / 2) for i in range(2, 11)] + ) # 1 to 5 rating feedback_text = models.TextField() is_anonymous = models.BooleanField(default=False) is_public = models.BooleanField(default=True) @@ -482,33 +533,97 @@ class InstituteFeedback(models.Model): return f"{self.user.name} - {self.institute.name} - {self.feedback_type}" class Meta: - verbose_name = "Institute Feedback" - verbose_name_plural = "Institute Feedbacks" - ordering = ['-created_at'] - unique_together = ['user', 'institute', 'feedback_type'] # One feedback per type per user + verbose_name = "Student Institute Feedback" + verbose_name_plural = "Student Institute Feedbacks" + ordering = ["-created_at"] + unique_together = [ + "user", + "institute", + "feedback_type", + ] # One feedback per type per user @property def display_name(self): """Return anonymous if feedback is anonymous, otherwise return user's name""" - return 'Anonymous' if self.is_anonymous else self.user.name + return "Anonymous" if self.is_anonymous else self.user.name + + +class StaffInstituteFeedback(models.Model): + """Model for tracking feedback from staff members to the institute""" + FEEDBACK_TYPE_CHOICES = ( + ("General", "General"), + ("Facilities", "Facilities"), + ("Teaching", "Teaching"), + ("Infrastructure", "Infrastructure"), + ("Administration", "Administration"), + ) + + institute = models.ForeignKey( + Institute, on_delete=models.CASCADE, related_name="staff_feedbacks" + ) + staff = models.ForeignKey( + Staff, on_delete=models.CASCADE, related_name="institute_feedbacks" + ) + feedback_type = models.CharField( + max_length=20, choices=FEEDBACK_TYPE_CHOICES, default="General" + ) + rating = models.DecimalField( + max_digits=2, decimal_places=1, choices=[(i / 2, i / 2) for i in range(2, 11)] + ) # 1 to 5 rating + feedback_text = models.TextField() + is_anonymous = models.BooleanField(default=False) + is_public = models.BooleanField(default=True) + created_at = models.DateTimeField(auto_now_add=True) + updated_at = models.DateTimeField(auto_now=True) + + def __str__(self): + if self.is_anonymous: + return f"Anonymous - {self.institute.name} - {self.feedback_type}" + return f"{self.staff.name} - {self.institute.name} - {self.feedback_type}" + + class Meta: + verbose_name = "Staff Institute Feedback" + verbose_name_plural = "Staff Institute Feedbacks" + ordering = ["-created_at"] + unique_together = [ + "staff", + "institute", + "feedback_type", + ] # One feedback per type per staff + + @property + def display_name(self): + """Return anonymous if feedback is anonymous, otherwise return staff's name""" + return "Anonymous" if self.is_anonymous else self.staff.name class CourseTracking(models.Model): PROGRESS_STATUS_CHOICES = ( - ('Not Started', 'Not Started'), - ('In Progress', 'In Progress'), - ('Completed', 'Completed'), - ('Dropped', 'Dropped'), + ("Not Started", "Not Started"), + ("In Progress", "In Progress"), + ("Completed", "Completed"), + ("Dropped", "Dropped"), ) - student = models.ForeignKey(Student, on_delete=models.CASCADE, related_name='course_trackings') - course = models.ForeignKey(Course, on_delete=models.CASCADE, related_name='student_trackings') + student = models.ForeignKey( + Student, on_delete=models.CASCADE, related_name="course_trackings" + ) + course = models.ForeignKey( + Course, on_delete=models.CASCADE, related_name="student_trackings" + ) enrollment_date = models.DateField(auto_now_add=True) start_date = models.DateField(null=True, blank=True) expected_end_date = models.DateField(null=True, blank=True) actual_end_date = models.DateField(null=True, blank=True) - progress_status = models.CharField(max_length=20, choices=PROGRESS_STATUS_CHOICES, default='Not Started') - completion_percentage = models.IntegerField(default=0, help_text="Percentage of course completion (0-100)") + progress_status = models.CharField( + max_length=20, choices=PROGRESS_STATUS_CHOICES, default="Not Started" + ) + completion_percentage = models.IntegerField( + default=0, help_text="Percentage of course completion (0-100)" + ) + current_semester = models.PositiveIntegerField(default=1) + semester_start_date = models.DateField(null=True, blank=True) + semester_end_date = models.DateField(null=True, blank=True) notes = models.TextField(blank=True, null=True) created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True) @@ -516,18 +631,34 @@ class CourseTracking(models.Model): class Meta: verbose_name = "Course Tracking" verbose_name_plural = "Course Trackings" - unique_together = ['student', 'course'] # Ensure one tracking per student per course - ordering = ['-created_at'] + unique_together = ["student", "course"] + ordering = ["-created_at"] def __str__(self): return f"{self.student.name} - {self.course.name}" def clean(self): from django.core.exceptions import ValidationError + + if not self.student or not self.course: + raise ValidationError("Both student and course are required") + if self.start_date and self.expected_end_date and self.start_date > self.expected_end_date: raise ValidationError("Start date cannot be after expected end date") + if self.actual_end_date and self.start_date and self.actual_end_date < self.start_date: raise ValidationError("Actual end date cannot be before start date") + + if self.semester_start_date and self.semester_end_date and self.semester_start_date > self.semester_end_date: + raise ValidationError("Semester start date cannot be after semester end date") + + if self.current_semester < 1: + raise ValidationError("Current semester must be at least 1") + + if self.course.duration_type == "Semester": + max_semesters = self.course.duration * 2 + if self.current_semester > max_semesters: + raise ValidationError(f"Current semester cannot exceed {max_semesters}") def calculate_completion_percentage(self): if not self.start_date or not self.expected_end_date: @@ -536,9 +667,9 @@ class CourseTracking(models.Model): today = date.today() # If course is completed, return 100% - if self.progress_status == 'Completed': + if self.progress_status == "Completed": return 100 - elif self.progress_status == 'Dropped': + elif self.progress_status == "Dropped": return 0 # Calculate total duration in days @@ -552,11 +683,18 @@ class CourseTracking(models.Model): return 0 # Calculate percentage based on course duration type - if self.course.duration_type == 'Semester': - # For semester-based courses (6 months) - max_days = 180 # 6 months = 180 days - if elapsed_days >= max_days: - return 100 + if self.course.duration_type == "Semester": + # For semester-based courses + semester_duration = 180 # 6 months = 180 days + total_semesters = self.course.duration * 2 # 2 semesters per year + completed_semesters = self.current_semester - 1 + semester_progress = (completed_semesters / total_semesters) * 100 + + # If current semester is completed + if self.semester_end_date and today > self.semester_end_date: + semester_progress = (self.current_semester / total_semesters) * 100 + + return min(100, int(semester_progress)) else: # Yearly based max_days = 365 # 1 year = 365 days if elapsed_days >= max_days: @@ -567,32 +705,81 @@ class CourseTracking(models.Model): return percentage def save(self, *args, **kwargs): - # Validate dates + # Calculate dates if this is a new instance + if not self.pk: + self.start_date = self.start_date or date.today() + + # Calculate expected end date based on course duration + if self.course.duration_type == "Year": + years = self.course.duration + else: # Semester based + years = self.course.duration # Duration is already in years + + self.expected_end_date = self.start_date + timedelta(days=years * 365) + + # Set initial semester dates + self.semester_start_date = self.start_date + self.semester_end_date = self.start_date + timedelta(days=180) # 6 months + + # Validate dates and other fields self.clean() - + # Calculate completion percentage self.completion_percentage = self.calculate_completion_percentage() - + # Update progress status based on completion percentage if self.completion_percentage >= 100: - self.progress_status = 'Completed' + self.progress_status = "Completed" if not self.actual_end_date: self.actual_end_date = date.today() elif self.completion_percentage > 0: - self.progress_status = 'In Progress' - - super().save(*args, **kwargs) + self.progress_status = "In Progress" + + try: + super().save(*args, **kwargs) + except Exception as e: + print(f"Error saving course tracking for {self.student.name}: {str(e)}") + raise + + def advance_semester(self): + """Advance to next semester if possible""" + if not self.course or self.course.duration_type != "Semester": + return False + + total_semesters = self.course.duration * 2 + if self.current_semester < total_semesters: + self.current_semester += 1 + self.semester_start_date = date.today() + self.semester_end_date = self.semester_start_date + timedelta( + days=180 + ) # 6 months + # Update student's current semester as well + self.student.current_semester = self.current_semester + self.student.save() + self.save() + return True + return False @property def is_completed(self): - return self.progress_status == 'Completed' + return self.progress_status == "Completed" @property def is_active(self): - return self.progress_status == 'In Progress' + return self.progress_status == "In Progress" @property def remaining_days(self): + """Returns remaining days in current semester""" + if not self.semester_end_date: + return None + today = date.today() + remaining = (self.semester_end_date - today).days + return max(0, remaining) + + @property + def total_remaining_days(self): + """Returns remaining days for entire course""" if not self.expected_end_date: return None today = date.today() @@ -610,25 +797,19 @@ class CourseTracking(models.Model): return (self.expected_end_date - self.start_date).days def get_completion_percentage(self): - """ - Get completion percentage with caching - """ return get_cached_percentage(self.id) def force_update_percentage(self): - """ - Force update the completion percentage and clear cache - """ - cache_key = f'course_tracking_percentage_{self.id}' + cache_key = f"course_tracking_percentage_{self.id}" cache.delete(cache_key) - self.save() # This will recalculate and update the percentage + self.save() def get_cached_percentage(tracking_id): """ Get cached completion percentage for a course tracking """ - cache_key = f'course_tracking_percentage_{tracking_id}' + cache_key = f"course_tracking_percentage_{tracking_id}" percentage = cache.get(cache_key) if percentage is None: try: @@ -646,8 +827,95 @@ def update_completion_percentage(sender, instance, **kwargs): Signal to update completion percentage after save Also caches the percentage for 1 hour to avoid frequent recalculations """ - cache_key = f'course_tracking_percentage_{instance.id}' + cache_key = f"course_tracking_percentage_{instance.id}" cache.set(cache_key, instance.completion_percentage, 3600) # Cache for 1 hour +@receiver(post_save, sender=Student) +def create_course_tracking(sender, instance, created, **kwargs): + """ + Signal handler to create CourseTracking when a new student is created + or when a course is assigned to an existing student + """ + print(f"Signal triggered for student: {instance.name}") + print(f"Created: {created}") + print(f"Course: {instance.course}") + print(f"Current Semester: {instance.current_semester}") + # Check if student has a course assigned + if instance.course: + try: + # Check if course tracking already exists + existing_tracking = CourseTracking.objects.filter( + student=instance, + course=instance.course + ).first() + + if existing_tracking: + print(f"Course tracking already exists for {instance.name}") + return + + # Calculate dates based on course duration + start_date = instance.joining_date or date.today() + + # Calculate expected end date based on course duration type + if instance.course.duration_type == "Year": + # For year-based courses, each year is 365 days + years = instance.course.duration + duration_days = years * 365 + else: # Semester based + # For semester-based courses: + # - Each year has 2 semesters + # - Total years is the same as course duration + years = instance.course.duration + duration_days = years * 365 # Use full years for total duration + + expected_end_date = start_date + timedelta(days=duration_days) + + # Create course tracking with transaction + with transaction.atomic(): + course_tracking = CourseTracking.objects.create( + student=instance, + course=instance.course, + start_date=start_date, + expected_end_date=expected_end_date, + current_semester=instance.current_semester, + semester_start_date=start_date, + semester_end_date=start_date + timedelta(days=180) # 6 months for first semester + ) + + # Force initial percentage calculation + course_tracking.force_update_percentage() + + print(f"Successfully created course tracking for student {instance.name}") + print(f"Start Date: {start_date}") + print(f"Expected End Date: {expected_end_date}") + print(f"Current Semester: {instance.current_semester}") + + except Exception as e: + print(f"Error creating course tracking for student {instance.name}: {str(e)}") + # Log the error but don't prevent student creation + # You might want to add proper logging here instead of print statements + else: + print(f"No course assigned to student {instance.name}") + + +@receiver(post_save, sender=Student) +def sync_student_semester(sender, instance, created, **kwargs): + """Signal handler to sync student's current_semester with course tracking""" + if instance.course: + try: + course_tracking = CourseTracking.objects.get(student=instance, course=instance.course) + if course_tracking.current_semester != instance.current_semester: + course_tracking.current_semester = instance.current_semester + course_tracking.save() + except CourseTracking.DoesNotExist: + pass + + +@receiver(post_save, sender=CourseTracking) +def sync_course_tracking_semester(sender, instance, created, **kwargs): + """Signal handler to sync course tracking's current_semester with student""" + if instance.student.current_semester != instance.current_semester: + instance.student.current_semester = instance.current_semester + instance.student.save() diff --git a/app/serializers.py b/app/serializers.py new file mode 100644 index 0000000..8dfd092 --- /dev/null +++ b/app/serializers.py @@ -0,0 +1,179 @@ +import django.db +from rest_framework import serializers +from .models import ( + Attendance, AttendanceRecord, Batch, Course, FCMDevice, Institute, + Notice, Routine, Staff, Student, Subject, Staff_leave, Student_Leave, + StudentFeedback, InstituteFeedback, StaffInstituteFeedback, CourseTracking +) + +class FCMDeviceSerializer(serializers.ModelSerializer): + class Meta: + model = FCMDevice + fields = ['id', 'token'] + +class InstituteSerializer(serializers.ModelSerializer): + class Meta: + model = Institute + fields = ['id', 'name', 'phone', 'email', 'address', 'pan_no', 'reg_no', 'logo', 'description'] + +class SubjectSerializer(serializers.ModelSerializer): + syllabus_pdf_url = serializers.SerializerMethodField() + + class Meta: + model = Subject + fields = ['id', 'name', 'course', 'semester_or_year', 'syllabus_pdf', 'syllabus_pdf_url'] + + def get_syllabus_pdf_url(self, obj): + return obj.get_pdf_url() + +class CourseSerializer(serializers.ModelSerializer): + subjects = SubjectSerializer(many=True, read_only=True) + + class Meta: + model = Course + fields = ['id', 'name', 'duration', 'duration_type', 'subjects'] + +class BatchSerializer(serializers.ModelSerializer): + class Meta: + model = Batch + fields = ['id', 'name', 'start_date', 'end_date'] + +class StudentSerializer(serializers.ModelSerializer): + batches = BatchSerializer(many=True, read_only=True) + course = CourseSerializer(read_only=True) + + class Meta: + model = Student + fields = [ + 'id', 'name', 'status', 'gender', 'birth_date', 'email', 'phone', + 'temporary_address', 'permanent_address', 'marital_status', 'parent_name', + 'parent_phone', 'citizenship_no', 'image', 'batches', 'course', + 'current_semester', 'joining_date' + ] + read_only_fields = ['id'] + +class StaffSerializer(serializers.ModelSerializer): + class Meta: + model = Staff + fields = [ + 'id', 'name', 'gender', 'designation', 'birth_date', 'phone', 'email', + 'temporary_address', 'permanent_address', 'marital_status', 'parent_name', + 'parent_phone', 'citizenship_no', 'passport', 'image', 'joining_date', + 'is_active' + ] + read_only_fields = ['id'] + +class RoutineSerializer(serializers.ModelSerializer): + teacher = StaffSerializer(read_only=True) + subject = SubjectSerializer(read_only=True) + course = CourseSerializer(read_only=True) + + class Meta: + model = Routine + fields = [ + 'id', 'course', 'subject', 'teacher', 'start_time', 'end_time', + 'semester_or_year', 'is_active' + ] + +class AttendanceRecordSerializer(serializers.ModelSerializer): + student = StudentSerializer(read_only=True) + + class Meta: + model = AttendanceRecord + fields = ['id', 'attendance', 'student', 'student_attend'] + +class AttendanceSerializer(serializers.ModelSerializer): + records = AttendanceRecordSerializer(many=True, read_only=True) + routine = RoutineSerializer(read_only=True) + teacher = StaffSerializer(read_only=True) + + class Meta: + model = Attendance + fields = ['id', 'date', 'routine', 'teacher', 'teacher_attend', 'class_status', 'records'] + +class NoticeSerializer(serializers.ModelSerializer): + created_at = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", read_only=True) + image_url = serializers.SerializerMethodField() + + class Meta: + model = Notice + fields = ['id', 'title', 'message', 'image', 'image_url', 'created_at'] + read_only_fields = ['created_at'] + + def get_image_url(self, obj): + if obj.image: + return obj.image.url + return None + +class StaffLeaveSerializer(serializers.ModelSerializer): + staff = StaffSerializer(read_only=True) + created_at = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", read_only=True) + updated_at = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", read_only=True) + + class Meta: + model = Staff_leave + fields = ['id', 'staff', 'date', 'message', 'status', 'created_at', 'updated_at'] + read_only_fields = ['created_at', 'updated_at'] + +class StudentLeaveSerializer(serializers.ModelSerializer): + student = StudentSerializer(read_only=True) + created_at = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", read_only=True) + updated_at = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", read_only=True) + + class Meta: + model = Student_Leave + fields = ['id', 'student', 'date', 'message', 'status', 'created_at', 'updated_at'] + read_only_fields = ['created_at', 'updated_at'] + +class StudentFeedbackSerializer(serializers.ModelSerializer): + student = StudentSerializer(read_only=True) + teacher = StaffSerializer(read_only=True) + created_at = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", read_only=True) + updated_at = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", read_only=True) + + class Meta: + model = StudentFeedback + fields = ['id', 'student', 'teacher', 'rating', 'feedback_text', 'created_at', 'updated_at'] + read_only_fields = ['created_at', 'updated_at'] + +class InstituteFeedbackSerializer(serializers.ModelSerializer): + user = StudentSerializer(read_only=True) + created_at = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", read_only=True) + updated_at = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", read_only=True) + + class Meta: + model = InstituteFeedback + fields = [ + 'id', 'institute', 'user', 'feedback_type', 'rating', 'feedback_text', + 'is_anonymous', 'is_public', 'created_at', 'updated_at' + ] + read_only_fields = ['created_at', 'updated_at'] + +class StaffInstituteFeedbackSerializer(serializers.ModelSerializer): + staff = StaffSerializer(read_only=True) + created_at = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", read_only=True) + updated_at = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", read_only=True) + + class Meta: + model = StaffInstituteFeedback + fields = [ + 'id', 'institute', 'staff', 'feedback_type', 'rating', 'feedback_text', + 'is_anonymous', 'is_public', 'created_at', 'updated_at' + ] + read_only_fields = ['created_at', 'updated_at'] + +class CourseTrackingSerializer(serializers.ModelSerializer): + student = StudentSerializer(read_only=True) + course = CourseSerializer(read_only=True) + created_at = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", read_only=True) + updated_at = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", read_only=True) + + class Meta: + model = CourseTracking + fields = [ + 'id', 'student', 'course', 'enrollment_date', 'start_date', 'expected_end_date', + 'actual_end_date', 'progress_status', 'completion_percentage', 'current_semester', + 'semester_start_date', 'semester_end_date', 'notes', 'created_at', 'updated_at' + ] + read_only_fields = ['created_at', 'updated_at', 'enrollment_date'] + diff --git a/app/staffviews.py b/app/staffviews.py new file mode 100644 index 0000000..5096594 --- /dev/null +++ b/app/staffviews.py @@ -0,0 +1,585 @@ +from django.shortcuts import render, redirect +from django.http import JsonResponse +from django.contrib.auth.decorators import login_required +from django.db.models import Avg, Q +from django.utils import timezone +from datetime import timedelta, datetime +from django.views.decorators.http import require_http_methods, require_GET +from django.contrib import messages +from django.contrib.auth.hashers import check_password, make_password +from .models import ( + Staff, + Student, + Routine, + Attendance, + AttendanceRecord, + StudentFeedback, + Staff_leave, + Notice, + Institute, + StaffInstituteFeedback, + Subject, + InstituteFeedback +) +from app.admin import custom_admin_site + + +@login_required +def teacherDashboard(request): + """View to display the teacher dashboard with their classes and student information""" + teacher = Staff.objects.get(phone=request.user.phone) # Get the Staff object + today = timezone.now().date() + current_time = timezone.now().time() + last_week = today - timedelta(days=7) + + # Get only the active routines assigned to this teacher + today_routines = Routine.objects.filter( + teacher=teacher, # Filter by the current teacher + is_active=True, # Only include active routines + ).order_by("start_time") + + # Process routines to include status and attendance + processed_routines = [] + for routine in today_routines: + attendance = routine.attendances.filter(date=today).first() + + # Get total students from the course associated with the subject + total_students = Student.objects.filter(course=routine.subject.course).count() + attendance_count = ( + 0 + if not attendance + else AttendanceRecord.objects.filter( + attendance=attendance, student_attend=True + ).count() + ) + + # Add routine to processed_routines + processed_routines.append( + { + "id": routine.id, # Add the routine ID for use in the template + "name": routine.subject.name, + "start_time": routine.start_time, + "end_time": routine.end_time, + "is_completed": attendance is not None, # Only mark as completed if attendance exists + "is_ongoing": routine.start_time <= current_time <= routine.end_time, + "total_students": total_students, + "attendance_count": attendance_count, + "semester_or_year": routine.semester_or_year, + "course_name": routine.subject.course.name, + "has_attendance": attendance is not None, # Flag to check if attendance has been taken + } + ) + + # Calculate class statistics + total_classes = today_routines.count() + completed_classes = len([r for r in processed_routines if r["is_completed"]]) + remaining_classes = total_classes - completed_classes + + # Get student statistics - count unique students from teacher's assigned subjects and semesters + total_students = Student.objects.filter(status="Active").count() + + # Get present and absent students for today + present_students = AttendanceRecord.objects.filter( + attendance__date=today, + student_attend=True, + attendance__routine__teacher=teacher + ).values('student').distinct().count() + + # Calculate absent students based on teacher's classes today + today_class_students = set() + for routine in today_routines: + students = Student.objects.filter( + course=routine.subject.course, + current_semester=routine.semester_or_year, + status="Active" + ) + today_class_students.update(students.values_list('id', flat=True)) + + absent_students = len(today_class_students) - present_students if today_class_students else 0 + + # Get average rating from student feedback + avg_rating = StudentFeedback.objects.filter( + teacher=teacher + ).aggregate(Avg('rating'))['rating__avg'] or 0 + avg_rating_rounded = round(avg_rating) + remaining_stars = 5 - avg_rating_rounded + + # Get leave statistics + pending_leaves = Staff_leave.objects.filter(staff=teacher, status=0).count() + approved_leaves = Staff_leave.objects.filter(staff=teacher, status=1).count() + rejected_leaves = Staff_leave.objects.filter(staff=teacher, status=2).count() + + # Get recent leaves + recent_leaves = Staff_leave.objects.filter(staff=teacher).order_by('-created_at')[:5] + + # Get recent feedback + recent_feedback = StudentFeedback.objects.filter(teacher=teacher).order_by('-created_at')[:5] + + # Get notices + notices = Notice.objects.all().order_by('-created_at')[:5] + + # Get feedback types for institute feedback + feedback_types = InstituteFeedback.FEEDBACK_TYPE_CHOICES + + # Get institute feedback + institute_feedback = StaffInstituteFeedback.objects.filter(staff=teacher).order_by('-created_at')[:5] + + # Get all routines for the teacher (for the schedule) + all_routines = Routine.objects.filter( + teacher=teacher, + is_active=True, + semester_or_year__in=Student.objects.filter(status="Active") + .values_list('current_semester', flat=True) + .distinct() + ).order_by('start_time') + + # Get all attendance records for quick access + recent_attendance = ( + Attendance.objects.filter(teacher=teacher, date__gte=last_week) + .select_related("routine") + .order_by("-date") + ) + + # Add present/total counts to each attendance record + for attendance in recent_attendance: + attendance.present_count = AttendanceRecord.objects.filter( + attendance=attendance, student_attend=True + ).count() + attendance.total_count = AttendanceRecord.objects.filter( + attendance=attendance + ).count() + + # Attendance Management Data + routines = Routine.objects.filter( + teacher=teacher, + is_active=True + ).order_by('start_time') + + context = { + "teacher": teacher, + "title": "Teacher Dashboard", + "today_routines": processed_routines, + "total_classes": total_classes, + "completed_classes": completed_classes, + "remaining_classes": remaining_classes, + "total_students": total_students, + "present_students": present_students, + "absent_students": absent_students, + "avg_rating": avg_rating, + "avg_rating_rounded": avg_rating_rounded, + "remaining_stars": remaining_stars, + "pending_leaves": pending_leaves, + "approved_leaves": approved_leaves, + "rejected_leaves": rejected_leaves, + "recent_leaves": recent_leaves, + "recent_feedback": recent_feedback, + "notices": notices, + "feedback_types": feedback_types, + "institute_feedback": institute_feedback, + "all_routines": all_routines, + "recent_attendance": recent_attendance, + # Attendance Management Context + "routines": routines, + "today": today, + } + + return render(request, "teacher_dashboard.html", context) + + +@login_required +def request_staff_leave(request): + """View to handle leave requests from staff""" + if request.method == "POST": + staff = request.user + date = request.POST.get("date") + message = request.POST.get("message") + + try: + # Convert date string to timezone-aware datetime + leave_date = timezone.datetime.strptime(date, "%Y-%m-%d") + leave_date = timezone.make_aware(leave_date) + today = timezone.now() + + if leave_date.date() < today.date(): + messages.error(request, "Leave date cannot be in the past.") + return redirect("teacherDashboard") + + # Check if leave already exists for this date + existing_leave = Staff_leave.objects.filter( + staff=staff, date=leave_date.date() + ).first() + + if existing_leave: + messages.error( + request, "You have already requested leave for this date." + ) + return redirect("teacherDashboard") + + # Create leave request + leave = Staff_leave.objects.create( + staff=staff, + date=leave_date.date(), + message=message, + status=0, # Pending status + ) + messages.success(request, "Leave request submitted successfully.") + except Exception as e: + messages.error(request, f"Error submitting leave request: {str(e)}") + + return redirect("teacherDashboard") + + return redirect("teacherDashboard") + + +@login_required +def submit_staff_institute_feedback(request): + """View to handle feedback submission from staff to institute""" + if request.method == "POST": + staff = request.user + feedback_type = request.POST.get("feedback_type") + rating = request.POST.get("rating") + feedback_text = request.POST.get("feedback_text") + is_anonymous = request.POST.get("is_anonymous") == "on" + + try: + # Convert to float first to handle half-stars + rating_value = float(rating) + if rating_value < 0.5 or rating_value > 5: + messages.error(request, "Rating must be between 0.5 and 5") + return redirect("teacherDashboard") + + # Check if it's a valid half or full star rating + if rating_value % 0.5 != 0: + messages.error(request, "Rating must be a whole or half number") + return redirect("teacherDashboard") + + # Get the institute (assuming one institute for now) + institute = Institute.objects.first() + + if not institute: + # Create a default institute if none exists + institute = Institute.objects.create( + name="Default Institute", + phone="123456789", + email="default@example.com", + ) + + # Get the staff object + teacher = Staff.objects.get(phone=staff.phone) + + # Check if feedback already exists for this type + existing_feedback = StaffInstituteFeedback.objects.filter( + staff=teacher, institute=institute, feedback_type=feedback_type + ).first() + + if existing_feedback: + # Update existing feedback + existing_feedback.rating = rating_value + existing_feedback.feedback_text = feedback_text + existing_feedback.is_anonymous = is_anonymous + existing_feedback.save() + messages.success(request, "Institute feedback updated successfully.") + else: + # Create new feedback + feedback = StaffInstituteFeedback.objects.create( + staff=teacher, + institute=institute, + feedback_type=feedback_type, + rating=rating_value, + feedback_text=feedback_text, + is_anonymous=is_anonymous, + ) + messages.success(request, "Institute feedback submitted successfully.") + except ValueError: + messages.error(request, "Invalid rating value") + except Exception as e: + messages.error(request, f"Error submitting institute feedback: {str(e)}") + + return redirect("teacherDashboard") + + return redirect("teacherDashboard") + + +@login_required +def save_attendance(request): + """View to save attendance data""" + if request.method == "POST": + teacher = Staff.objects.get(phone=request.user.phone) + routine_id = request.POST.get("routine_id") + date_str = request.POST.get("date") + + # Convert class_status to boolean - "Conducted" is True, others are False + class_status_str = request.POST.get("class_status", "True") + class_status = class_status_str == "True" + + teacher_attend = request.POST.get("teacher_attend") == "on" + + try: + # Validate routine - strict check to ensure teacher can only access their assigned routines + routine = Routine.objects.get( + id=routine_id, + teacher=teacher, # Ensure this routine is assigned to this teacher + is_active=True, # Only allow active routines + ) + + # Validate date + attendance_date = timezone.datetime.strptime(date_str, "%Y-%m-%d").date() + + # Get or create attendance record + attendance, created = Attendance.objects.get_or_create( + routine=routine, + date=attendance_date, + defaults={ + "teacher": teacher, + "class_status": class_status, + "teacher_attend": teacher_attend, + }, + ) + + if not created: + # Update existing attendance + attendance.class_status = class_status + attendance.teacher_attend = teacher_attend + attendance.save() + + # Process student attendance + for key, value in request.POST.items(): + if key.startswith("student_"): + student_id = key.replace("student_", "") + student_attend = value == "on" + + try: + # Convert student_id to integer to ensure proper lookup + student_id_int = int(student_id) + student = Student.objects.get(id=student_id_int) + + # Get or create attendance record for this student + record, _ = AttendanceRecord.objects.get_or_create( + attendance=attendance, + student=student, + defaults={"student_attend": student_attend}, + ) + + # Update if record already exists + if record.student_attend != student_attend: + record.student_attend = student_attend + record.save() + + except Student.DoesNotExist: + continue + + messages.success( + request, + f"Attendance for {attendance_date.strftime('%d %b, %Y')} saved successfully.", + ) + + except Routine.DoesNotExist: + messages.error( + request, + "You do not have permission to take attendance for this class. Only teachers assigned to this class can manage its attendance.", + ) + except ValueError: + messages.error(request, "Invalid date format.") + except Exception as e: + messages.error(request, f"Error saving attendance: {str(e)}") + + # Redirect to teacher dashboard after saving attendance + return redirect("teacherDashboard") + + return redirect("teacherDashboard") + + +@login_required +@require_GET +def get_subject_schedule(request): + """View to get schedule for a subject""" + teacher = Staff.objects.get(phone=request.user.phone) + subject_id = request.GET.get("subject_id") + + if not subject_id: + return JsonResponse({"success": False, "message": "Subject ID is required"}) + + try: + routines = Routine.objects.filter( + teacher=teacher, subject_id=subject_id, is_active=True + ).values("id", "start_time", "end_time", "semester_or_year") + + return JsonResponse({"success": True, "schedule": list(routines)}) + except Exception as e: + return JsonResponse({"success": False, "message": str(e)}) + + +@login_required +def teacher_update_profile_picture(request): + """View to handle profile picture update for teachers""" + if request.method == "POST": + teacher = Staff.objects.get(phone=request.user.phone) + profile_picture = request.FILES.get("profile_picture") + + if profile_picture: + try: + # Update the teacher's profile picture + teacher.image = profile_picture + teacher.save() + messages.success(request, "Profile picture updated successfully.") + except Exception as e: + messages.error(request, f"Error updating profile picture: {str(e)}") + else: + messages.error(request, "No profile picture uploaded.") + + return redirect("teacherDashboard") + + return redirect("teacherDashboard") + + +@login_required +def teacher_change_password(request): + """View to handle password change for teachers""" + if request.method == "POST": + current_password = request.POST.get("current_password") + new_password = request.POST.get("new_password") + confirm_password = request.POST.get("confirm_password") + + # Get the current user + user = request.user + + # Validate inputs + if not current_password or not new_password or not confirm_password: + messages.error(request, "All password fields are required.") + return redirect("teacherDashboard") + + # Check if current password is correct + if not check_password(current_password, user.password): + messages.error(request, "Current password is incorrect.") + return redirect("teacherDashboard") + + # Check if new passwords match + if new_password != confirm_password: + messages.error(request, "New passwords do not match.") + return redirect("teacherDashboard") + + # Check if new password is strong enough (add more criteria as needed) + if len(new_password) < 8: + messages.error(request, "New password must be at least 8 characters long.") + return redirect("teacherDashboard") + + try: + # Update the password + user.password = make_password(new_password) + user.save() + messages.success( + request, + "Password changed successfully. Please log in again with your new password.", + ) + return redirect( + "login" + ) # Redirect to login page to log in with new password + except Exception as e: + messages.error(request, f"Error changing password: {str(e)}") + + return redirect("teacherDashboard") + + return redirect("teacherDashboard") + + +@login_required +def get_attendance_form(request): + """View to handle AJAX request for getting attendance form""" + routine_id = request.GET.get('routine_id') + date_str = request.GET.get('date') + + if not routine_id or not date_str: + return JsonResponse({ + 'error': 'Missing required parameters' + }) + + try: + routine = Routine.objects.get(id=routine_id, teacher=request.user) + date = datetime.strptime(date_str, '%Y-%m-%d').date() + + # Get existing attendance data if any + attendance_data = { + 'teacher_attend': False, + 'class_status': True, + 'records': {} + } + + try: + # Get attendance record with all related data in one query + attendance = Attendance.objects.select_related('routine').get( + routine=routine, + date=date + ) + + # Get all attendance records for this attendance in one query + records = AttendanceRecord.objects.filter(attendance=attendance).select_related('student') + + attendance_data = { + 'id': attendance.id, + 'date': attendance.date.strftime('%Y-%m-%d'), + 'teacher_attend': attendance.teacher_attend, + 'class_status': attendance.class_status, + 'records': { + str(record.student.id): record.student_attend + for record in records + } + } + except Attendance.DoesNotExist: + # No existing attendance record found - return default values + pass + + return JsonResponse(attendance_data) + + except Routine.DoesNotExist: + return JsonResponse({ + 'error': 'Invalid routine selected' + }, status=404) + except ValueError: + return JsonResponse({ + 'error': 'Invalid date format' + }, status=400) + except Exception as e: + return JsonResponse({ + 'error': str(e) + }, status=500) + + +@login_required +def get_students(request): + """View to handle AJAX request for getting students list""" + from django.http import JsonResponse + + routine_id = request.GET.get('routine_id') + + if not routine_id: + return JsonResponse({'error': 'Missing routine_id parameter'}, status=400) + + try: + routine = Routine.objects.get(id=routine_id, teacher=request.user) + + # Get students for this routine + students = Student.objects.filter( + course=routine.subject.course, + current_semester=routine.semester_or_year + ).order_by('name') + + # If no students found, try a more flexible approach + if not students.exists(): + students = Student.objects.filter( + course=routine.subject.course + ).order_by('name') + + # Format student data for JSON response + student_data = [{ + 'id': student.id, + 'name': student.name + } for student in students] + + return JsonResponse({ + 'students': student_data + }) + + except Routine.DoesNotExist: + return JsonResponse({'error': 'Invalid routine selected'}, status=404) + except Exception as e: + return JsonResponse({'error': str(e)}, status=500) diff --git a/app/studentviews.py b/app/studentviews.py new file mode 100644 index 0000000..33e2500 --- /dev/null +++ b/app/studentviews.py @@ -0,0 +1,511 @@ +from django.shortcuts import render, redirect, get_object_or_404 +from django.http import JsonResponse, HttpResponse +from django.contrib.auth.decorators import login_required +from django.contrib import messages +from django.db.models import Count, Q, Avg +from django.utils import timezone +from datetime import timedelta +from django.views.decorators.http import require_http_methods, require_GET +from .models import ( + Student, + Course, + CourseTracking, + Student_Leave, + Staff, + Attendance, + AttendanceRecord, + StudentFeedback, + Routine, + Notice, + Institute, + InstituteFeedback, + Subject, +) + + +@login_required +def studentDashboard(request): + """View to display the student dashboard with their personal information and progress""" + student = Student.objects.get(phone=request.user.phone) # Get the Student object + today = timezone.now().date() + last_week = today - timedelta(days=7) + last_month = today - timedelta(days=30) + + # Get all teachers for feedback form + teachers = Staff.objects.filter( + Q(designation__icontains="Teacher") + | Q(designation__icontains="Staff") + | Q(designation__icontains="Principal") + | Q(designation__isnull=True) + | Q(designation="") + ).order_by("name") + + # Get feedback types for institute feedback + feedback_types = InstituteFeedback.FEEDBACK_TYPE_CHOICES + + # Course Progress and Tracking + course_trackings = CourseTracking.objects.filter(student=student).select_related( + "course" + ) + total_courses = course_trackings.count() + completed_courses = course_trackings.filter(progress_status="Completed").count() + in_progress_courses = course_trackings.filter(progress_status="In Progress").count() + dropped_courses = course_trackings.filter(progress_status="Dropped").count() + + # Calculate overall completion percentage + overall_completion = 0 + if total_courses > 0: + total_percentage = sum( + tracking.completion_percentage for tracking in course_trackings + ) + overall_completion = total_percentage / total_courses + + # Course Summary + course_summary = { + "total_courses": total_courses, + "completed_courses": completed_courses, + "ongoing_courses": in_progress_courses, + "completion_percentage": overall_completion, + } + + # Course Details with enhanced information + course_details = [] + for tracking in course_trackings: + # Calculate expected end date based on course duration + if tracking.start_date: + if tracking.course.duration_type == "Year": + duration_days = tracking.course.duration * 365 # Years to days + else: # Semester based + duration_days = ( + tracking.course.duration * 365 + ) # Use full years for total duration + + expected_end_date = tracking.start_date + timedelta(days=duration_days) + else: + expected_end_date = None + + course_details.append( + { + "name": tracking.course.name, + "start_date": tracking.start_date, + "expected_end_date": expected_end_date, + "actual_end_date": tracking.actual_end_date, + "completion_percentage": tracking.completion_percentage, + "progress_status": tracking.progress_status, + "current_semester": tracking.current_semester, + "semester_start_date": tracking.semester_start_date, + "semester_end_date": tracking.semester_end_date, + "remaining_days": tracking.remaining_days, + "is_completed": tracking.is_completed, + "is_active": tracking.is_active, + "duration_type": tracking.course.duration_type, + "duration": tracking.course.duration, + "total_duration_days": tracking.total_duration_days, + "notes": tracking.notes, + "book": tracking.course.book + if hasattr(tracking.course, "book") + else None, + "topics": [], # This will be populated if you have topic tracking + } + ) + + # Get current subjects based on current semester + current_subjects = student.get_current_subjects() + + # Attendance Statistics with enhanced information + attendance_records = AttendanceRecord.objects.filter(student=student) + total_classes = attendance_records.count() + classes_attended = attendance_records.filter(student_attend=True).count() + attendance_percentage = ( + (classes_attended / total_classes * 100) if total_classes > 0 else 0 + ) + + # Calculate attendance streaks + current_streak = 0 + longest_streak = 0 + temp_streak = 0 + last_attendance_date = None + + for record in attendance_records.order_by("-attendance__date"): + if record.student_attend: + if last_attendance_date is None: + last_attendance_date = record.attendance.date + current_streak = 1 + temp_streak = 1 + elif (last_attendance_date - record.attendance.date).days == 1: + temp_streak += 1 + if temp_streak > longest_streak: + longest_streak = temp_streak + if record.attendance.date == today - timedelta(days=current_streak): + current_streak += 1 + else: + temp_streak = 1 + else: + temp_streak = 0 + if record.attendance.date == today: + current_streak = 0 + + # Attendance Summary + attendance_summary = { + "total_classes": total_classes, + "classes_attended": classes_attended, + "attendance_percentage": attendance_percentage, + "current_streak": current_streak, + "longest_streak": longest_streak, + } + + # Get attendance records with related information + attendance_records = attendance_records.select_related( + "attendance", "attendance__routine", "attendance__teacher" + ).order_by("-attendance__date") + + # Get recent attendance (last 7 days) + recent_attendance = attendance_records.filter( + attendance__date__gte=last_week + ).order_by("-attendance__date") + + # Get feedback + recent_feedback = student.feedbacks.all().order_by("-created_at")[:5] + institute_feedback = student.institute_feedbacks.all().order_by("-created_at")[:5] + + # Get notices + notices = Notice.objects.all().order_by("-created_at") + + # Get student leaves with status information + student_leaves = Student_Leave.objects.filter(student=student).order_by( + "-created_at" + ) + pending_leaves = student_leaves.filter(status=0).count() + approved_leaves = student_leaves.filter(status=1).count() + rejected_leaves = student_leaves.filter(status=2).count() + + # Get current semester routines + try: + # Get routines that match the student's course and current semester directly + current_semester_routines = Routine.objects.filter( + course=student.course, + semester_or_year=student.current_semester, + is_active=True, + ) + except Exception as e: + current_semester_routines = [] + + # Check if student has any routines for any semester + has_routines = False + try: + if student.course: + has_routines = Routine.objects.filter(course=student.course).exists() + except Exception as e: + has_routines = False + + context = { + "student": student, + "title": "Student Dashboard", + "teachers": teachers, + "feedback_types": feedback_types, + # Course Progress + "total_courses": total_courses, + "completed_courses": completed_courses, + "in_progress_courses": in_progress_courses, + "dropped_courses": dropped_courses, + "overall_completion": round(overall_completion, 1), + "course_details": course_details, + "course_summary": course_summary, + # Current Subjects + "current_subjects": current_subjects, + # Attendance + "attendance_summary": attendance_summary, + "attendance_records": attendance_records, + "recent_attendance": recent_attendance, + # Feedback + "recent_feedback": recent_feedback, + "institute_feedback": institute_feedback, + # Notices + "notices": notices, + # Leaves + "student_leaves": student_leaves, + "pending_leaves": pending_leaves, + "approved_leaves": approved_leaves, + "rejected_leaves": rejected_leaves, + # Routines + "current_semester_routines": current_semester_routines, + "has_routines": has_routines, + # Current date for display + "today": today, + } + + return render(request, "student_dashboard.html", context) + + +@login_required +def request_leave(request): + if request.method == "POST": + student = request.user + date = request.POST.get("date") + message = request.POST.get("message") + + try: + # Convert date string to timezone-aware datetime + leave_date = timezone.datetime.strptime(date, "%Y-%m-%d") + leave_date = timezone.make_aware(leave_date) + today = timezone.now() + + if leave_date.date() < today.date(): + messages.error(request, "Leave date cannot be in the past.") + return redirect("studentDashboard") + + # Check if leave already exists for this date + existing_leave = Student_Leave.objects.filter( + student=student, date=leave_date.date() + ).first() + + if existing_leave: + messages.error( + request, "You have already requested leave for this date." + ) + return redirect("studentDashboard") + + # Create leave request + leave = Student_Leave.objects.create( + student=student, + date=leave_date.date(), + message=message, + status=0, # Pending status + ) + messages.success(request, "Leave request submitted successfully.") + except Exception as e: + messages.error(request, f"Error submitting leave request: {str(e)}") + + return redirect("studentDashboard") + + return redirect("studentDashboard") + + +@login_required +def submit_feedback(request): + if request.method == "POST": + try: + feedback_type = request.POST.get("feedback_type") + rating = float(request.POST.get("rating", 0)) + feedback_text = request.POST.get("feedback_text", "").strip() + + # Validate rating range (1 to 5) + if not (1 <= rating <= 5): + return JsonResponse( + {"success": False, "message": "Rating must be between 1 and 5"} + ) + + if not feedback_text: + return JsonResponse( + {"success": False, "message": "Please provide feedback text"} + ) + + if feedback_type == "teacher": + teacher_id = request.POST.get("teacher_id") + if not teacher_id: + return JsonResponse( + {"success": False, "message": "Please select a teacher"} + ) + + try: + teacher = Staff.objects.get(id=teacher_id) + # Check if feedback already exists + existing_feedback = StudentFeedback.objects.filter( + student=request.user, teacher=teacher + ).first() + + if existing_feedback: + # Update existing feedback + existing_feedback.rating = rating + existing_feedback.feedback_text = feedback_text + existing_feedback.save() + else: + # Create new feedback + StudentFeedback.objects.create( + student=request.user, + teacher=teacher, + rating=rating, + feedback_text=feedback_text, + ) + + return JsonResponse( + { + "success": True, + "message": "Teacher feedback submitted successfully", + } + ) + + except Staff.DoesNotExist: + return JsonResponse( + {"success": False, "message": "Selected teacher does not exist"} + ) + + elif feedback_type == "institute": + category = request.POST.get("category") + is_anonymous = request.POST.get("is_anonymous") == "on" + + if not category: + return JsonResponse( + { + "success": False, + "message": "Please select a feedback category", + } + ) + + try: + institute = Institute.objects.first() # Assuming single institute + # Check if feedback already exists for this category - use new structure + existing_feedback = InstituteFeedback.objects.filter( + user_type="student", + content_object_id=request.user.id, + institute=institute, + feedback_type=category, + ).first() + + if existing_feedback: + # Update existing feedback + existing_feedback.rating = rating + existing_feedback.feedback_text = feedback_text + existing_feedback.is_anonymous = is_anonymous + existing_feedback.save() + else: + # Create new feedback - use new structure + InstituteFeedback.objects.create( + user_type="student", + content_object_id=request.user.id, + user=request.user, + institute=institute, + feedback_type=category, + rating=rating, + feedback_text=feedback_text, + is_anonymous=is_anonymous, + ) + + return JsonResponse( + { + "success": True, + "message": "Institute feedback submitted successfully", + } + ) + + except Institute.DoesNotExist: + return JsonResponse( + {"success": False, "message": "Institute not found"} + ) + + else: + return JsonResponse( + {"success": False, "message": "Invalid feedback type"} + ) + + except ValueError: + return JsonResponse({"success": False, "message": "Invalid rating value"}) + except Exception as e: + return JsonResponse( + {"success": False, "message": f"An error occurred: {str(e)}"} + ) + + return JsonResponse({"success": False, "message": "Invalid request method"}) + + +@login_required +def submit_institute_feedback(request): + if request.method == "POST": + student = request.user + feedback_type = request.POST.get("feedback_type") + rating = request.POST.get("rating") + feedback_text = request.POST.get("feedback_text") + is_anonymous = request.POST.get("is_anonymous") == "on" + + try: + # Convert to float first to handle half-stars + rating_value = float(rating) + if rating_value < 0.5 or rating_value > 5: + messages.error(request, "Rating must be between 0.5 and 5") + return redirect("studentDashboard") + + # Check if it's a valid half or full star rating + if rating_value % 0.5 != 0: + messages.error(request, "Rating must be a whole or half number") + return redirect("studentDashboard") + + # Get the institute (assuming one institute for now) + institute = Institute.objects.first() + + if not institute: + # Create a default institute if none exists + institute = Institute.objects.create( + name="Default Institute", + phone="123456789", + email="default@example.com", + ) + + # Check if feedback already exists for this type - using new structure + existing_feedback = InstituteFeedback.objects.filter( + user_type="student", + content_object_id=student.id, + institute=institute, + feedback_type=feedback_type, + ).first() + + if existing_feedback: + # Update existing feedback + existing_feedback.rating = rating_value + existing_feedback.feedback_text = feedback_text + existing_feedback.is_anonymous = is_anonymous + existing_feedback.save() + messages.success(request, "Institute feedback updated successfully.") + else: + # Create new feedback with new structure + feedback = InstituteFeedback.objects.create( + user_type="student", + content_object_id=student.id, + user=student, + institute=institute, + feedback_type=feedback_type, + rating=rating_value, + feedback_text=feedback_text, + is_anonymous=is_anonymous, + ) + messages.success(request, "Institute feedback submitted successfully.") + except ValueError: + messages.error(request, "Invalid rating value") + except Exception as e: + messages.error(request, f"Error submitting institute feedback: {str(e)}") + + return redirect("studentDashboard") + + return redirect("studentDashboard") + + +@login_required +@require_http_methods(["GET"]) +def get_subject_files(request, subject_id): + """View to get syllabus PDF for a subject""" + try: + subject = Subject.objects.get(id=subject_id) + pdf_url = subject.get_pdf_url() + + if not pdf_url: + return JsonResponse( + {"success": False, "message": "No syllabus available for this subject"} + ) + + return JsonResponse( + { + "success": True, + "files": [ + { + "title": f"{subject.name} Syllabus", + "description": f"Syllabus PDF for {subject.name}", + "file_url": pdf_url, + } + ], + } + ) + except Subject.DoesNotExist: + return JsonResponse({"success": False, "message": "Subject not found"}) + except Exception as e: + return JsonResponse( + {"success": False, "message": f"Error retrieving syllabus: {str(e)}"} + ) diff --git a/app/templatetags/app_filters.py b/app/templatetags/app_filters.py index 58b88c4..22b3526 100644 --- a/app/templatetags/app_filters.py +++ b/app/templatetags/app_filters.py @@ -8,4 +8,31 @@ def get_range(value): Returns a range of numbers from 0 to value-1 Used for creating star ratings """ - return range(value) \ No newline at end of file + try: + return range(int(value)) + except (ValueError, TypeError): + return range(0) + +@register.filter +def multiply(value, arg): + """Multiply the value by the argument""" + try: + return int(value) * int(arg) + except (ValueError, TypeError): + return value + +@register.filter +def get_item(dictionary, key): + """ + Gets a value from a dictionary by key. + Usage in template: {{ my_dict|get_item:key_variable }} + """ + if dictionary is None: + return None + + # Try with the key as is (likely integer ID) + if key in dictionary: + return dictionary.get(key) + + # Try with the key as string + return dictionary.get(str(key), None) \ No newline at end of file diff --git a/app/urls.py b/app/urls.py index 582fe4f..840a3b0 100644 --- a/app/urls.py +++ b/app/urls.py @@ -1,8 +1,59 @@ from django.urls import path -from app import views +from . import views +from django.contrib import admin +from . import auth +from . import staffviews urlpatterns = [ - path('dashboard/', views.dashboard, name='dashboard'), - path('student-dashboard/', views.studentDashboard, name='studentDashboard'), - path('teacher-dashboard/', views.teacherDashboard, name='teacherDashboard'), -] \ No newline at end of file + path("dashboard/", views.dashboard, name="dashboard"), + path("student-dashboard/", views.studentDashboard, name="studentDashboard"), + path("teacher-dashboard/", views.teacherDashboard, name="teacherDashboard"), + path("request-leave/", views.request_leave, name="request_leave"), + path("request-staff-leave/", views.request_staff_leave, name="request_staff_leave"), + path("submit-feedback/", views.submit_feedback, name="submit_feedback"), + path( + "submit-institute-feedback/", + views.submit_institute_feedback, + name="submit_institute_feedback", + ), + path( + "submit-staff-institute-feedback/", + views.submit_staff_institute_feedback, + name="submit_staff_institute_feedback", + ), + path("save-fcm-token/", views.saveFCMToken, name="saveFCMToken"), + path("firebase-messaging-sw.js", views.showFirebaseJS, name="showFirebaseJS"), + path("update-profile/", views.update_profile, name="update_profile"), + path("change-password/", views.change_password, name="change_password"), + path( + "subject//files/", + views.get_subject_files, + name="get_subject_files", + ), + path("get-subjects/", views.get_subjects, name="get_subjects"), + path('get-teachers/', views.get_teachers, name='get_teachers'), + path('get-course-duration/', views.get_course_duration, name='get_course_duration'), + path('save-attendance/', views.save_attendance, name='save_attendance'), + path('get-subject-schedule/', views.get_subject_schedule, name='get_subject_schedule'), + path('get-attendance-form/', staffviews.get_attendance_form, name='get_attendance_form'), + path('teacher-update-profile-picture/', views.teacher_update_profile_picture, name='teacher_update_profile_picture'), + path('teacher-change-password/', views.teacher_change_password, name='teacher_change_password'), + path('approve-student-leave//', views.approve_student_leave, name='approve_student_leave'), + path('reject-student-leave//', views.reject_student_leave, name='reject_student_leave'), + path('approve-staff-leave//', views.approve_staff_leave, name='approve_staff_leave'), + path('reject-staff-leave//', views.reject_staff_leave, name='reject_staff_leave'), + path('add-notice/', views.add_notice, name='add_notice'), + path('delete-notice//', views.delete_notice, name='delete_notice'), + + # Password reset paths + path('password-reset/', auth.reset_password_options, name='reset_password_options'), + path('password-reset/phone/', auth.password_reset_phone, name='phone_reset_password'), + path('password-reset/phone/verify/', auth.password_reset_phone_verify, name='verify_reset_otp'), + path('password-reset/phone/resend/', auth.resend_phone_otp, name='resend_phone_otp'), + path('password-reset/email/', auth.password_reset_email, name='email_reset_password'), + path('password-reset/email/verify/', auth.password_reset_email_verify, name='password_reset_done'), + path('password-reset/email/resend/', auth.resend_email_code, name='resend_reset_code'), + path('password-reset/set/', auth.set_new_password, name='set_new_password'), + path('get-students/', staffviews.get_students, name='get_students'), +] + diff --git a/app/utils.py b/app/utils.py new file mode 100644 index 0000000..34d8b68 --- /dev/null +++ b/app/utils.py @@ -0,0 +1,170 @@ +import random +import string +from django.core.cache import cache +import requests +from firebase_admin import messaging, initialize_app, get_app, credentials +import os +from django.template.loader import render_to_string +from django.core.mail import send_mail +from django.conf import settings +from django.contrib.auth.tokens import default_token_generator +from django.utils.http import urlsafe_base64_encode +from django.utils.encoding import force_bytes + +# OTP expiration time in seconds (5 minutes) +OTP_EXPIRY = 300 + + +def generate_otp(length=6): + """Generate a numeric OTP of specified length""" + digits = string.digits + return "".join(random.choice(digits) for _ in range(length)) + + +def store_otp(phone, otp): + """Store OTP in cache with phone as key""" + cache_key = f"otp_{phone}" + cache.set(cache_key, otp, OTP_EXPIRY) + return True + + +def verify_otp(phone, otp): + """Verify if the provided OTP matches the stored OTP for the phone""" + cache_key = f"otp_{phone}" + stored_otp = cache.get(cache_key) + + if stored_otp and stored_otp == otp: + # Delete the OTP after successful verification + cache.delete(cache_key) + return True + return False + + +def send_otp_sms(phone, otp): + """Send OTP via SMS using a service like Twilio, MSG91, etc.""" + try: + # This is a placeholder. You need to replace with actual SMS API implementation + # Example using a generic SMS API + # api_url = "https://api.example.com/send" + # payload = { + # "apikey": settings.SMS_API_KEY, + # "to": phone, + # "message": f"Your OTP for SMS login is: {otp}. Valid for 5 minutes." + # } + # response = requests.post(api_url, json=payload) + # return response.status_code == 200 + + print(f"OTP for {phone}: {otp}") + return True + except Exception as e: + print(f"Error sending OTP: {str(e)}") + return False + + +def send_push_notification(title, message, tokens): + """ + Send push notification using Firebase Cloud Messaging + """ + try: + try: + app = get_app() + except ValueError: + # Initialize Firebase Admin SDK if not already initialized + cred_path = os.path.join( + os.path.dirname(os.path.dirname(__file__)), + "firebase-key.json", + ) + if not os.path.exists(cred_path): + print(f"Firebase credentials file not found at {cred_path}") + return + + cred = credentials.Certificate(cred_path) + app = initialize_app(cred) + + if not tokens: + print("No FCM tokens available to send notifications") + return + + # Create message + message = messaging.MulticastMessage( + notification=messaging.Notification( + title=title, + body=message, + ), + tokens=list(tokens), + ) + + # Send message + response = messaging.send_multicast(message) + + if response.failure_count > 0: + failures = [] + for idx, resp in enumerate(response.responses): + if not resp.success: + failures.append( + f"Failed to send message to token {tokens[idx]}: {resp.exception}" + ) + print("\n".join(failures)) + + except Exception as e: + print(f"Error sending notification: {e}") + # Don't raise the exception to prevent save from failing + pass + + +def send_password_reset_email(user, request, email): + """ + Send password reset code to user's email using HTML template + """ + try: + # Generate a reset code (OTP) + reset_code = generate_otp(length=6) + + # Store the reset code in cache with user's email as key + cache_key = f"reset_code_{email}" + cache.set(cache_key, reset_code, OTP_EXPIRY) # 5 minutes expiry + + # Build email context + context = { + "user": user, + "domain": request.META.get("HTTP_HOST", "localhost:8000"), + "protocol": "https" if request.is_secure() else "http", + "reset_code": reset_code, + } + + # Render email content using template + subject = render_to_string("login/email_templates/password_reset_subject.txt") + message = render_to_string( + "login/email_templates/password_reset_email.html", context + ) + + # Send email using console backend + send_mail( + subject=subject, + message=message, + from_email="noreply@studentmanagement.com", + recipient_list=[email], + html_message=message, + fail_silently=False, + ) + print(f"\nPassword reset code sent to {email}") + print(f"Reset Code: {reset_code}\n") + return True + except Exception as e: + print(f"Failed to send email: {str(e)}") + return False + + +def verify_reset_code(email, code): + """ + Verify if the provided reset code matches the stored code for the email + """ + cache_key = f"reset_code_{email}" + stored_code = cache.get(cache_key) + + if stored_code and stored_code == code: + # Delete the code after successful verification + cache.delete(cache_key) + return True + return False + diff --git a/app/views.py b/app/views.py index 21721a8..6e537d0 100644 --- a/app/views.py +++ b/app/views.py @@ -16,10 +16,47 @@ from .models import ( AttendanceRecord, StudentFeedback, Routine, - StudentRoutine, Staff, + Notice, + Institute, + InstituteFeedback, + Subject, + Batch, ) from app.admin import custom_admin_site +from django.views.decorators.http import require_http_methods, require_GET +from django.core.files.storage import default_storage +from django.core.files.base import ContentFile +import json +import os +from django.db.models.base import transaction +from .utils import generate_otp, store_otp, verify_otp, send_otp_sms +from django.conf import settings +from dotenv import load_dotenv + +# Import views from studentviews.py +from .studentviews import ( + studentDashboard, + request_leave, + submit_feedback, + submit_institute_feedback, + get_subject_files, +) + +# Import views from staffviews.py +from .staffviews import ( + teacherDashboard, + request_staff_leave, + submit_staff_institute_feedback, + save_attendance, + get_subject_schedule, + teacher_update_profile_picture, + teacher_change_password, +) + +# Load environment variables +load_dotenv() + # Create your views here. @@ -33,48 +70,51 @@ def saveFCMToken(request, token): def showFirebaseJS(request): - data = """ + data = f""" importScripts('https://www.gstatic.com/firebasejs/11.0.2/firebase-app-compat.js'); importScripts('https://www.gstatic.com/firebasejs/11.0.2/firebase-messaging-compat.js'); - firebase.initializeApp({ - apiKey: "", - authDomain: "", - projectId: "", - storageBucket: "", - messagingSenderId: "", - appId: "", - measurementId: "" - }); + firebase.initializeApp({{ + apiKey: "{os.getenv('FIREBASE_API_KEY')}", + authDomain: "{os.getenv('FIREBASE_AUTH_DOMAIN')}", + projectId: "{os.getenv('FIREBASE_PROJECT_ID')}", + storageBucket: "{os.getenv('FIREBASE_STORAGE_BUCKET')}", + messagingSenderId: "{os.getenv('FIREBASE_MESSAGING_SENDER_ID')}", + appId: "{os.getenv('FIREBASE_APP_ID')}", + measurementId: "{os.getenv('FIREBASE_MEASUREMENT_ID')}" + }}); const messaging = firebase.messaging(); - messaging.onBackgroundMessage((payload) => { - + messaging.onBackgroundMessage((payload) => {{ const notificationTitle = payload.notification.title; - const notificationOptions = { + const notificationOptions = {{ body: payload.notification.body, icon: payload.notification.icon - }; + }}; return self.registration.showNotification(notificationTitle, notificationOptions); - }); + }}); """ return HttpResponse(data, content_type="text/javascript") @login_required def dashboard(request): + """Main dashboard view that redirects to appropriate dashboard based on user role""" user = request.user user_groups = user.groups.values_list("name", flat=True) + + # Redirect based on user role if "Student" in user_groups: return redirect("studentDashboard") elif "Teacher" in user_groups: return redirect("teacherDashboard") + # Get current date and date ranges today = timezone.now().date() - last_week = today - timedelta(days=7) - last_month = today - timedelta(days=30) + last_week = timezone.now() - timedelta(days=7) + last_month = timezone.now() - timedelta(days=30) # Student Statistics total_students = Student.objects.count() @@ -82,6 +122,13 @@ def dashboard(request): completed_students = Student.objects.filter(status="Completed").count() on_leave_students = Student.objects.filter(status="Leave").count() + # Staff Statistics + total_staff = Staff.objects.count() + active_staff = Staff.objects.filter(is_active=True).count() + staff_on_leave = ( + Staff_leave.objects.filter(status=1).values("staff").distinct().count() + ) + # Course Statistics total_courses = Course.objects.count() active_courses = ( @@ -110,15 +157,123 @@ def dashboard(request): created_at__gte=last_week ).order_by("-created_at")[:5] + # Pending Leave Requests + pending_student_leaves = Student_Leave.objects.filter(status=0) + pending_staff_leaves = Staff_leave.objects.filter(status=0).order_by("-created_at") + # Attendance Statistics - today_attendance = Attendance.objects.filter(date=today).count() - today_present = AttendanceRecord.objects.filter( - attendance__date=today, student_attend=True + today_classes = Attendance.objects.filter(date=today) + total_classes = today_classes.count() + total_students_today = AttendanceRecord.objects.filter(attendance__in=today_classes).count() + students_present = AttendanceRecord.objects.filter( + attendance__in=today_classes, student_attend=True ).count() # Recent Feedback recent_feedback = StudentFeedback.objects.order_by("-created_at")[:5] + # Recent Institute Feedback + recent_institute_feedback = InstituteFeedback.objects.filter( + is_public=True + ).order_by("-created_at")[:10] + + # Get notices + notices = Notice.objects.all().order_by("-created_at") + + # Get recent activities + recent_activities = [] + + # Add recent leaves + for leave in recent_student_leaves: + recent_activities.append( + { + "title": f"Student Leave Request", + "description": f"{leave.student.name} requested leave for {leave.date}", + "timestamp": leave.created_at, + } + ) + + for leave in recent_staff_leaves: + recent_activities.append( + { + "title": f"Staff Leave Request", + "description": f"{leave.staff.name} requested leave for {leave.date}", + "timestamp": leave.created_at, + } + ) + + # Add recent feedback + for feedback in recent_feedback: + recent_activities.append( + { + "title": f"New Feedback", + "description": f"Feedback received for {feedback.teacher.name if feedback.teacher else 'Institute'}", + "timestamp": feedback.created_at, + } + ) + + # Add recent institute feedback + for feedback in recent_institute_feedback: + recent_activities.append( + { + "title": f"Institute Feedback", + "description": f"New feedback from {feedback.display_name}", + "timestamp": feedback.created_at, + } + ) + + # Add recent notices + for notice in notices: + recent_activities.append( + { + "title": f"New Notice", + "description": notice.title, + "timestamp": notice.created_at, + } + ) + + # Sort all activities by timestamp + recent_activities.sort(key=lambda x: x["timestamp"], reverse=True) + # Take only the most recent 10 activities + recent_activities = recent_activities[:10] + + # Teacher Ratings + teacher_ratings = [] + teachers = Staff.objects.filter( + Q(designation__icontains="Teacher") + | Q(designation__icontains="Staff") + | Q(designation__icontains="Principal") + | Q(designation__isnull=True) + | Q(designation="") + ) + + for teacher in teachers: + feedback = StudentFeedback.objects.filter(teacher=teacher) + avg_rating = feedback.aggregate(Avg("rating"))["rating__avg"] or 0 + total_reviews = feedback.count() + + # Get total students taught by this teacher + total_students = ( + AttendanceRecord.objects.filter(attendance__routine__teacher=teacher) + .values("student") + .distinct() + .count() + ) + + teacher_ratings.append( + { + "name": teacher.name, + "designation": teacher.designation or "Teacher", + "image": teacher.image, + "avg_rating": avg_rating, + "total_reviews": total_reviews, + "total_students": total_students, + } + ) + + # Sort teachers by average rating (highest first) + teacher_ratings.sort(key=lambda x: x["avg_rating"], reverse=True) + # Course Progress Overview course_progress = [] for course in Course.objects.all(): @@ -142,25 +297,26 @@ def dashboard(request): # Monthly Statistics monthly_stats = { "new_students": Student.objects.filter(joining_date__gte=last_month).count(), - "completed_courses": completed_trackings.filter( - actual_end_date__gte=last_month - ).count(), + "new_staff": Staff.objects.filter(joining_date__gte=last_month).count(), "attendance_rate": round( ( AttendanceRecord.objects.filter( - attendance__date__gte=last_month, student_attend=True + attendance__date__gte=last_month.date(), student_attend=True ).count() / AttendanceRecord.objects.filter( - attendance__date__gte=last_month + attendance__date__gte=last_month.date() ).count() * 100 ) if AttendanceRecord.objects.filter( - attendance__date__gte=last_month + attendance__date__gte=last_month.date() ).exists() - else 0, - 1, + else 0 ), + "leave_requests": Student_Leave.objects.filter( + created_at__gte=last_month + ).count() + + Staff_leave.objects.filter(created_at__gte=last_month).count(), } context = { @@ -172,6 +328,10 @@ def dashboard(request): "active_students": active_students, "completed_students": completed_students, "on_leave_students": on_leave_students, + # Staff Statistics + "total_staff": total_staff, + "active_staff": active_staff, + "staff_on_leave": staff_on_leave, # Course Statistics "total_courses": total_courses, "active_courses": active_courses, @@ -183,212 +343,318 @@ def dashboard(request): # Leave Requests "recent_student_leaves": recent_student_leaves, "recent_staff_leaves": recent_staff_leaves, + "pending_student_leaves": pending_student_leaves, + "pending_staff_leaves": pending_staff_leaves, # Attendance Statistics - "today_attendance": today_attendance, - "today_present": today_present, + "total_classes_today": total_classes, + "total_students_today": total_students_today, + "students_present": students_present, "attendance_rate": round( - (today_present / today_attendance * 100) if today_attendance > 0 else 0, 1 + (students_present / total_students_today * 100) if total_students_today > 0 else 0 ), - # Recent Feedback + # Feedback "recent_feedback": recent_feedback, + "recent_institute_feedback": recent_institute_feedback, + "teacher_ratings": teacher_ratings, # Course Progress "course_progress": course_progress, # Monthly Statistics "monthly_stats": monthly_stats, + "notices": notices, # Add notices to context + "recent_activities": recent_activities, # Add recent activities to context } return render(request, "dashboard.html", context) @login_required -def studentDashboard(request): - """View to display the student dashboard with their personal information and progress""" - student = request.user - today = timezone.now().date() - last_week = today - timedelta(days=7) - last_month = today - timedelta(days=30) +def update_profile(request): + if request.method == "POST": + user = request.user + name = request.POST.get("name") + email = request.POST.get("email") + phone = request.POST.get("phone") + address = request.POST.get("address") + gender = request.POST.get("gender") + dob = request.POST.get("dob") - # Course Progress - course_trackings = CourseTracking.objects.filter(student=student) - total_courses = course_trackings.count() - completed_courses = course_trackings.filter(progress_status="Completed").count() - in_progress_courses = course_trackings.filter(progress_status="In Progress").count() - completion_percentage = ( - (completed_courses / total_courses * 100) if total_courses > 0 else 0 - ) + # Validate data + if not all([name, email, phone]): + messages.error(request, "Name, email and phone are required fields.") + return redirect("studentDashboard") - # Course Details - course_details = {} - for tracking in course_trackings: - course_details[tracking.course.name] = { - "start_date": tracking.start_date, - "end_date": tracking.end_date, - "completion_percentage": tracking.completion_percentage, - "progress_status": tracking.progress_status, - "book": tracking.course.book if hasattr(tracking.course, "book") else None, - "topics": [], # This will be populated if you have topic tracking - } + # Update profile based on user type + try: + if hasattr(user, "student"): + student = user + student.name = name + student.email = email + student.phone = phone + student.address = address + student.gender = gender + if dob: + student.dob = dob - # Attendance Statistics - attendance_records = AttendanceRecord.objects.filter(student=student) - total_classes = attendance_records.count() - classes_attended = attendance_records.filter(student_attend=True).count() - attendance_percentage = ( - (classes_attended / total_classes * 100) if total_classes > 0 else 0 - ) + # Handle profile image + if "profile_image" in request.FILES: + image = request.FILES["profile_image"] + if student.image: + # Delete old image if updating + if os.path.isfile(student.image.path): + os.remove(student.image.path) - # Calculate attendance streaks - current_streak = 0 - longest_streak = 0 - temp_streak = 0 + # Save new image + student.image = image - for record in attendance_records.order_by("-attendance__date"): - if record.student_attend: - temp_streak += 1 - if temp_streak > longest_streak: - longest_streak = temp_streak - if record.attendance.date >= last_week: - current_streak = temp_streak + student.save() + messages.success(request, "Profile updated successfully.") + + elif hasattr(user, "staff"): + staff = user + staff.name = name + staff.email = email + staff.phone = phone + staff.address = address + staff.gender = gender + if dob: + staff.dob = dob + + # Handle profile image + if "profile_image" in request.FILES: + image = request.FILES["profile_image"] + if staff.image: + # Delete old image if updating + if os.path.isfile(staff.image.path): + os.remove(staff.image.path) + + # Save new image + staff.image = image + + staff.save() + messages.success(request, "Profile updated successfully.") + + else: + messages.error(request, "User profile not found.") + + except Exception as e: + messages.error(request, f"Error updating profile: {str(e)}") + + # Redirect based on user type + if hasattr(user, "student"): + return redirect("studentDashboard") + elif hasattr(user, "staff"): + return redirect("teacherDashboard") else: - temp_streak = 0 + return redirect("dashboard") - # Recent Leave Requests - recent_leaves = Student_Leave.objects.filter(student=student).order_by( - "-created_at" - )[:5] - - # Recent Feedback - recent_feedback = StudentFeedback.objects.filter(student=student).order_by( - "-created_at" - )[:5] - - context = { - **custom_admin_site.each_context( - request - ), # This adds the admin context, including the sidebar. - "student": student, - "title": "Student Dashboard", - # Course Summary - "course_summary": { - "total_courses": total_courses, - "completed_courses": completed_courses, - "ongoing_courses": in_progress_courses, - "completion_percentage": completion_percentage, - "details": course_details, - }, - # Attendance Summary - "attendance_summary": { - "total_classes": total_classes, - "classes_attended": classes_attended, - "attendance_percentage": attendance_percentage, - "current_streak": current_streak, - "longest_streak": longest_streak, - }, - # Recent Activity - "recent_leaves": recent_leaves, - "recent_feedback": recent_feedback, - } - - return render(request, "student_dashboard.html", context) + return redirect("dashboard") @login_required -def teacherDashboard(request): - """View to display the teacher dashboard with their classes and student information""" - teacher = Staff.objects.get(phone=request.user.phone) # Get the Staff object - today = timezone.now().date() - current_time = timezone.now().time() +def change_password(request): + if request.method == "POST": + user = request.user + current_password = request.POST.get("current_password") + new_password = request.POST.get("new_password") + confirm_password = request.POST.get("confirm_password") - # Get today's routines through attendance - today_routines = Routine.objects.filter( - teacher=teacher, attendances__date=today - ).order_by("start_time") + # Validate input + if not all([current_password, new_password, confirm_password]): + messages.error(request, "All password fields are required.") + return redirect("studentDashboard") - # Process routines to include status and attendance - processed_routines = [] - for routine in today_routines: - attendance = routine.attendances.filter(date=today).first() + if new_password != confirm_password: + messages.error(request, "New passwords do not match.") + return redirect("studentDashboard") - total_students = StudentRoutine.objects.filter(routine=routine).count() - attendance_count = ( - 0 - if not attendance - else AttendanceRecord.objects.filter( - attendance=attendance, student_attend=True - ).count() - ) + # Check current password + if not user.check_password(current_password): + messages.error(request, "Current password is incorrect.") + return redirect("studentDashboard") - processed_routines.append( + # Set new password + try: + user.set_password(new_password) + user.save() + messages.success( + request, "Password changed successfully. Please login again." + ) + return redirect("login") + except Exception as e: + messages.error(request, f"Error changing password: {str(e)}") + + # Redirect based on user type + if hasattr(user, "student"): + return redirect("studentDashboard") + elif hasattr(user, "staff"): + return redirect("teacherDashboard") + else: + return redirect("dashboard") + + return redirect("dashboard") + + +@login_required +@require_GET +def get_subjects(request): + """Get subjects for a course and semester""" + course_id = request.GET.get("course_id") + semester = request.GET.get("semester", 1) + + if not course_id: + return JsonResponse({"success": False, "message": "Course ID is required"}) + + try: + subjects = Subject.objects.filter( + course_id=course_id, semester_or_year=semester + ).values("id", "name") + + return JsonResponse({"success": True, "subjects": list(subjects)}) + except Exception as e: + return JsonResponse({"success": False, "message": str(e)}) + + +@login_required +@require_GET +def get_teachers(request): + """Get teachers for the institute""" + try: + teachers = Staff.objects.filter( + Q(designation__icontains="Teacher") + | Q(designation__icontains="Staff") + | Q(designation__icontains="Principal") + | Q(designation__isnull=True) + | Q(designation="") + ).values("id", "name") + + return JsonResponse({"success": True, "teachers": list(teachers)}) + except Exception as e: + return JsonResponse({"success": False, "message": str(e)}) + + +@login_required +@require_GET +def get_course_duration(request): + """Get course duration details""" + course_id = request.GET.get("course_id") + + if not course_id: + return JsonResponse({"success": False, "message": "Course ID is required"}) + + try: + course = Course.objects.get(id=course_id) + + # Calculate number of semesters or years + total_periods = course.duration + if course.duration_type == "Semester": + total_periods = course.duration * 2 # 2 semesters per year + + # Create a list of periods + periods = [] + for i in range(1, total_periods + 1): + if course.duration_type == "Semester": + periods.append({"value": i, "label": f"Semester {i}"}) + else: + periods.append({"value": i, "label": f"Year {i}"}) + + return JsonResponse( { - "name": routine.name, - "start_time": routine.start_time, - "end_time": routine.end_time, - "is_completed": routine.end_time < current_time, - "is_ongoing": routine.start_time <= current_time <= routine.end_time, - "total_students": total_students, - "attendance_count": attendance_count, + "success": True, + "course": { + "id": course.id, + "name": course.name, + "duration": course.duration, + "duration_type": course.duration_type, + "total_periods": total_periods, + "periods": periods, + }, } ) + except Course.DoesNotExist: + return JsonResponse({"success": False, "message": "Course not found"}) + except Exception as e: + return JsonResponse({"success": False, "message": str(e)}) - # Calculate class statistics - total_classes = today_routines.count() - completed_classes = len([r for r in processed_routines if r["is_completed"]]) - # Get student statistics - total_students = ( - StudentRoutine.objects.filter(routine__teacher=teacher) - .values("student") - .distinct() - .count() - ) +@login_required +def approve_student_leave(request, leave_id): + """View to approve a student leave request""" + if request.method == "POST": + leave = get_object_or_404(Student_Leave, id=leave_id) + leave.status = 1 # Approved + leave.save() + messages.success( + request, f"Leave request for {leave.student.name} has been approved." + ) + return redirect("dashboard") - # Calculate present students for today - present_students = AttendanceRecord.objects.filter( - attendance__routine__teacher=teacher, - attendance__date=today, - student_attend=True, - ).count() - # Get teacher's feedback statistics - feedback = StudentFeedback.objects.filter(teacher=teacher) - avg_rating = feedback.aggregate(Avg("rating"))["rating__avg"] or 0 - avg_rating_rounded = int(avg_rating) - remaining_stars = 5 - avg_rating_rounded +@login_required +def reject_student_leave(request, leave_id): + """View to reject a student leave request""" + if request.method == "POST": + leave = get_object_or_404(Student_Leave, id=leave_id) + leave.status = 2 # Rejected + leave.save() + messages.warning( + request, f"Leave request for {leave.student.name} has been rejected." + ) + return redirect("dashboard") - # Get leave statistics - leaves = Staff_leave.objects.filter(staff=teacher) - pending_leaves = leaves.filter(status=0).count() - approved_leaves = leaves.filter(status=1).count() - rejected_leaves = leaves.filter(status=2).count() - # Get recent activity - recent_leaves = leaves.order_by("-created_at")[:5] - recent_feedback = feedback.order_by("-created_at")[:5] +@login_required +def approve_staff_leave(request, leave_id): + """View to approve a staff leave request""" + if request.method == "POST": + leave = get_object_or_404(Staff_leave, id=leave_id) + leave.status = 1 # Approved + leave.save() + messages.success( + request, f"Leave request for {leave.staff.name} has been approved." + ) + return redirect("dashboard") + + +@login_required +def reject_staff_leave(request, leave_id): + """View to reject a staff leave request""" + if request.method == "POST": + leave = get_object_or_404(Staff_leave, id=leave_id) + leave.status = 2 # Rejected + leave.save() + messages.warning( + request, f"Leave request for {leave.staff.name} has been rejected." + ) + return redirect("dashboard") + + +@login_required +def add_notice(request): + if request.method == "POST": + title = request.POST.get("title") + message = request.POST.get("message") + image = request.FILES.get("image") + + if title and message: + notice = Notice.objects.create(title=title, message=message, image=image) + messages.success(request, "Notice added successfully.") + else: + messages.error(request, "Title and message are required.") + + return redirect("dashboard") + + +@login_required +def delete_notice(request, notice_id): + if request.method == "POST": + try: + notice = Notice.objects.get(id=notice_id) + notice.delete() + return JsonResponse({"success": True}) + except Notice.DoesNotExist: + return JsonResponse({"success": False, "error": "Notice not found"}) + + return JsonResponse({"success": False, "error": "Invalid request method"}) + - context = { - **custom_admin_site.each_context( - request - ), # This adds the admin context, including the sidebar. - "teacher": teacher, - "title": "Teacher Dashboard", - # Class Statistics - "today_classes": total_classes, - "completed_classes": completed_classes, - "today_routines": processed_routines, - # Student Statistics - "total_students": total_students, - "present_students": present_students, - # Feedback Statistics - "avg_rating": avg_rating, - "avg_rating_rounded": avg_rating_rounded, - "remaining_stars": remaining_stars, - # Leave Statistics - "pending_leaves": pending_leaves, - "approved_leaves": approved_leaves, - "rejected_leaves": rejected_leaves, - # Recent Activity - "recent_leaves": recent_leaves, - "recent_feedback": recent_feedback, - } - return render(request, "teacher_dashboard.html", context) diff --git a/assets/logo.png b/assets/logo.png deleted file mode 100644 index 05e9f6976ba2a39068040959439e70bf8a9899c6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 24909 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 Zy>_xH#qk~j-;aQx@LE;2O4>B^zW@o!n1lcT diff --git a/requirements.txt b/requirements.txt index 1aea859..03275c1 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,13 +1,43 @@ asgiref==3.8.1 +CacheControl==0.14.2 +cachetools==5.5.2 certifi==2025.1.31 +cffi==1.17.1 charset-normalizer==3.4.1 +cryptography==44.0.2 Django==5.1.7 django-jazzmin==3.0.1 +django-mathfilters==1.0.0 django-rest-framework==0.1.0 djangorestframework==3.15.2 +firebase-admin==6.7.0 +google-api-core==2.24.2 +google-api-python-client==2.165.0 +google-auth==2.38.0 +google-auth-httplib2==0.2.0 +google-cloud-core==2.4.3 +google-cloud-firestore==2.20.1 +google-cloud-storage==3.1.0 +google-crc32c==1.7.1 +google-resumable-media==2.7.2 +googleapis-common-protos==1.69.2 +grpcio==1.71.0 +grpcio-status==1.71.0 +httplib2==0.22.0 idna==3.10 +msgpack==1.1.0 pillow==11.1.0 +proto-plus==1.26.1 +protobuf==5.29.4 +pyasn1==0.6.1 +pyasn1_modules==0.4.1 +pycparser==2.22 +PyJWT==2.10.1 +pyparsing==3.2.3 pytz==2025.2 requests==2.32.3 +rsa==4.9 sqlparse==0.5.3 +uritemplate==4.1.1 urllib3==2.3.0 +python-dotenv==1.0.1 diff --git a/static/css/custom.css b/static/css/custom.css new file mode 100644 index 0000000..5ee0c89 --- /dev/null +++ b/static/css/custom.css @@ -0,0 +1,22 @@ +/* Target the specific logo image */ +img[src*="/static/img/logo.png"] { + max-height: 100px !important; + width: auto !important; +} + +/* Target login page logo */ +.jazzmin-login-page .login-logo img { + max-height: 100px !important; + width: auto !important; +} + +/* Target admin interface logo */ +.brand-link img.img-circle { + max-height: 33px !important; + width: auto !important; + opacity: .8; + margin-left: .8rem; + margin-right: .5rem; + margin-top: -3px; +} + diff --git a/static/css/dashboard.css b/static/css/dashboard.css new file mode 100644 index 0000000..9dc9685 --- /dev/null +++ b/static/css/dashboard.css @@ -0,0 +1,712 @@ +/* Reset body padding since we removed the sidebar */ +body { + padding-left: 0 !important; + padding-top: 0 !important; +} + +/* Material Design Color System */ +:root { + --primary: #3F51B5; /* Indigo */ + --primary-light: #7986CB; + --secondary: #9E9E9E; /* Grey */ + --success: #4CAF50; /* Green */ + --warning: #FFC107; /* Amber */ + --danger: #F44336; /* Red */ + --info: #2196F3; /* Blue */ + --background: #F5F5F5; /* Grey 100 */ + --card-bg: #FFFFFF; + --text-primary: #212121; /* Grey 900 */ + --text-secondary: #757575; /* Grey 600 */ + --border-color: #BDBDBD; /* Grey 400 */ + --hover-bg: #E8EAF6; /* Indigo 50 */ + --card-shadow: 0 2px 5px rgba(0, 0, 0, 0.1); + --transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); +} + +/* Base Layout Styles */ +body { + background-color: var(--background); + min-height: 100vh; + padding-bottom: 80px; + position: relative; + color: var(--text-primary); + font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; +} + +/* Modern Card Styles */ +.content-card { + background-color: var(--card-bg); + border-radius: 8px; + box-shadow: 0 2px 5px rgba(0, 0, 0, 0.05); + padding: 20px; + margin-bottom: 20px; + transition: var(--transition); +} + +.content-card:hover { + transform: translateY(-2px); + box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1); +} + +/* Bottom Navigation */ +.bottom-nav { + position: fixed; + bottom: 0; + left: 0; + right: 0; + background-color: white; + box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.1); + z-index: 1000; +} + +.nav-container { + display: flex; + overflow-x: auto; + padding: 10px; + justify-content: space-around; +} + +.nav-item { + display: flex; + flex-direction: column; + align-items: center; + color: var(--secondary); + text-decoration: none; + padding: 8px; + font-size: 0.8rem; + transition: all 0.2s; + border-radius: 5px; + min-width: 60px; +} + +.nav-item i { + font-size: 1.2rem; + margin-bottom: 4px; +} + +.nav-item.active { + color: var(--primary); + background-color: var(--hover-bg); + transform: scale(1.1); +} + +.nav-item:hover:not(.active) { + background-color: rgba(0, 0, 0, 0.04); +} + +/* Content Section Styles */ +.content-section { + display: none; + opacity: 0; + transform: translateY(20px); + transition: opacity 0.3s ease, transform 0.3s ease; +} + +.content-section.active { + display: block; + opacity: 1; + transform: translateY(0); +} + +/* Summary Cards */ +.summary-card { + background-color: var(--card-bg); + border-radius: 8px; + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); + overflow: hidden; +} + +.summary-card .card-header { + background-color: var(--hover-bg); + padding: 12px 16px; + border-bottom: 1px solid var(--border-color); +} + +.card-body { + padding: 1.5rem; +} + +/* Progress Bars */ +.progress { + height: 12px; + background-color: #E8EAF6; + border-radius: 24px; + overflow: hidden; +} + +.progress-bar { + border-radius: 24px; + transition: var(--transition); +} + +/* Add this to replace inline style attributes */ +.progress-bar[style] { + width: var(--progress-width, 0%); +} + +/* Tables */ +.table { + background: #FFFFFF; + border-radius: 16px; + overflow: hidden; + box-shadow: var(--card-shadow); + border-collapse: separate; + border-spacing: 0; +} + +.table thead th { + background: var(--hover-bg); + border: none; + padding: 1rem 1.5rem; + font-weight: 600; + color: var(--primary); +} + +.table tbody td { + padding: 1rem 1.5rem; + border-top: 1px solid var(--border-color); + transition: var(--transition); +} + +.table tbody tr:hover td { + background-color: var(--hover-bg); +} + +/* Status Badges */ +.status-badge { + padding: 4px 8px; + border-radius: 4px; + font-size: 0.75rem; + font-weight: 500; + display: inline-block; +} + +.bg-success, .completed, .leave-approved { + background-color: var(--success) !important; + color: white; +} + +.bg-warning, .ongoing, .leave-pending { + background-color: var(--warning) !important; + color: #212121; /* Material design suggests dark text on light colors like Amber */ +} + +.bg-danger, .leave-rejected { + background-color: var(--danger) !important; + color: white; +} + +.bg-info, .upcoming { + background-color: var(--info) !important; + color: white; +} + +/* Animations */ +@keyframes fadeIn { + from { opacity: 0; transform: translateY(20px); } + to { opacity: 1; transform: translateY(0); } +} + +/* Responsive Design */ +@media (max-width: 768px) { + .container-fluid { + padding: 0.5rem; + } + + .content-card { + padding: 16px; + } + + .summary-card { + margin-bottom: 1rem; + } + + .card-header { + padding: 1rem; + } + + .card-body { + padding: 1rem; + } + + .table { + font-size: 0.875rem; + } + + .table th, + .table td { + padding: 0.75rem; + white-space: nowrap; + } + + .table-responsive { + margin: 0 -0.5rem; + } + + .row { + margin-left: -0.5rem; + margin-right: -0.5rem; + } + + .col-12, .col-md-6 { + padding-left: 0.5rem; + padding-right: 0.5rem; + } + + .bottom-nav { + padding: 0.5rem; + } + + .nav-item { + padding: 0.375rem; + } + + .nav-item i { + font-size: 1.25rem; + } + + .nav-item span { + display: none; + } + + .nav-item.active::after { + bottom: -0.5rem; + } + + /* Welcome Section */ + .welcome-section img { + width: 60px !important; + height: 60px !important; + } + + .welcome-section h2 { + font-size: 1.5rem; + } + + /* Course Cards */ + .course-card { + margin-bottom: 1rem; + } + + .course-card .card-title { + font-size: 1.1rem; + } + + /* Subject Cards */ + .subject-card { + margin-bottom: 1rem; + } + + /* Feedback Cards */ + .feedback-card { + margin-bottom: 1rem; + } + + /* Notice Cards */ + .notice-card { + margin-bottom: 1rem; + } + + /* Profile Section */ + .profile-image { + width: 120px !important; + height: 120px !important; + } + + /* Modal Adjustments */ + .modal-dialog { + margin: 0.5rem; + } + + .modal-body { + padding: 1rem; + } + + /* Form Elements */ + .form-control, + .form-select { + font-size: 0.875rem; + } + + .btn { + padding: 0.375rem 0.75rem; + font-size: 0.875rem; + } + + /* Rating Stars */ + .rating-container .fa-star { + font-size: 1.25rem; + } + + .nav-item { + min-width: auto; + } +} + +/* Small Mobile Devices */ +@media (max-width: 480px) { + .nav-container { + padding: 0 0.5rem; + } + + .nav-item { + padding: 0.25rem; + } + + .nav-item i { + font-size: 1.1rem; + } + + .nav-item span { + font-size: 0.65rem; + } + + .content-card { + padding: 0.75rem; + } + + .card-header { + padding: 0.75rem; + } + + .card-body { + padding: 0.75rem; + } + + .table th, + .table td { + padding: 0.5rem; + } + + .status-badge { + padding: 0.2rem 0.5rem; + font-size: 0.75rem; + } + + .btn { + padding: 0.25rem 0.5rem; + font-size: 0.75rem; + } +} + +/* Landscape Mode */ +@media (max-height: 500px) and (orientation: landscape) { + .bottom-nav { + position: static; + margin-top: 1rem; + } + + body { + padding-bottom: 0; + } + + .content-card { + margin-bottom: 1rem; + } +} + +/* High-DPI Screens */ +@media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) { + .content-card { + box-shadow: 0 5px 10px -3px rgba(0, 0, 0, 0.1); + } +} + +/* Print Styles */ +@media print { + .bottom-nav, + .btn-primary, + .modal, + .modal-backdrop { + display: none !important; + } + + .content-card { + box-shadow: none; + border: 1px solid #ddd; + } + + .table { + box-shadow: none; + } +} + +/* Modal styles */ +.modal { + z-index: 1050 !important; +} + +.modal-backdrop { + z-index: 1040 !important; +} + +.modal-content { + border-radius: 8px !important; + box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1) !important; +} + +.modal-header { + border-bottom: 1px solid #e5e7eb; + padding: 1rem 1.5rem; +} + +.modal-body { + padding: 1.5rem; +} + +.modal-footer { + border-top: 1px solid #e5e7eb; + padding: 1rem 1.5rem; +} + +/* Navigation enhanced styles */ +.nav-item { + transition: transform 0.2s ease-in-out; +} + +.content-section { + transition: opacity 0.3s ease-in-out, transform 0.3s ease-in-out; + opacity: 0; + transform: translateY(20px); +} + +.content-section.active { + opacity: 1; + transform: translateY(0); +} + +/* Improve active state visibility */ +.nav-item.active { + color: var(--primary); + font-weight: 600; +} + +.nav-item.active i { + transform: scale(1.1); +} + +/* Add ripple effect for touch devices */ +.nav-item { + position: relative; + overflow: hidden; +} + +.nav-item::after { + content: ''; + position: absolute; + top: 50%; + left: 50%; + width: 5px; + height: 5px; + background: rgba(79, 70, 229, 0.3); + opacity: 0; + border-radius: 100%; + transform: scale(1, 1) translate(-50%); + transform-origin: 50% 50%; +} + +.nav-item:active::after { + animation: ripple 0.6s ease-out; +} + +@keyframes ripple { + 0% { + transform: scale(0, 0); + opacity: 0.5; + } + 100% { + transform: scale(100, 100); + opacity: 0; + } +} + +/* Star Rating Styles */ +.rating-container .form-check-label { + cursor: pointer; + padding: 0.25rem; +} + +.rating-container .fa-star, +.rating-container .fa-star-half-alt { + color: #f8d74c; +} + +/* Profile Images */ +.profile-image-small { + width: 80px; + height: 80px; + object-fit: cover; +} + +.profile-image-large { + width: 200px; + height: 200px; + object-fit: cover; +} + +/* Add notification toast styles if they don't already exist */ +.notification-toast { + position: fixed; + top: 20px; + right: 20px; + z-index: 9999; + min-width: 250px; + box-shadow: 0 4px 8px rgba(0,0,0,0.1); + border-radius: 4px; +} + +/* Welcome Section */ +.welcome-section { + background: linear-gradient(to right, #4338ca, #6366f1); + color: white; + padding: 20px; +} + +/* Schedule styling */ +.schedule-item { + padding: 12px; + border-radius: 6px; + margin-bottom: 10px; + background-color: #f8f9fa; + border-left: 4px solid var(--primary); +} + +/* Rating stars styling */ +.rating-stars { + color: #FFD700; +} + +/* Custom tabs styling */ +.feedback-tabs { + border-bottom: 2px solid #e9ecef; + margin-bottom: 1.5rem; +} + +.feedback-tab-btn { + padding: 10px 20px; + cursor: pointer; + border-radius: 4px; + transition: var(--transition); + border: 1px solid var(--border-color); + background-color: white; + color: var(--text-primary); + text-align: center; + flex: 1; +} + +.feedback-tab-btn.active { + background-color: var(--primary); + color: white; + border-color: var(--primary); +} + +.feedback-tab-btn:hover:not(.active) { + background-color: var(--hover-bg); +} + +.tab-pane { + display: none; +} + +.tab-pane.active { + display: block; +} + +/* Star rating styling */ +.rating-container .form-check-label i.fas { + color: #FFD700; +} + +/* Custom smaller scrollbar styling */ +.activity-scroll::-webkit-scrollbar { + width: 4px; +} + +.activity-scroll::-webkit-scrollbar-track { + background: #f1f1f1; + border-radius: 10px; +} + +.activity-scroll::-webkit-scrollbar-thumb { + background: #ccc; + border-radius: 10px; +} + +.activity-scroll::-webkit-scrollbar-thumb:hover { + background: #999; +} + +/* Firefox scrollbar */ +.activity-scroll { + scrollbar-width: thin; + scrollbar-color: #ccc #f1f1f1; +} + +@media (min-width: 992px) { + .container-fluid { + padding-bottom: 60px; + } +} + +/* Custom Tab System */ +.custom-tabs { + display: flex; + border-bottom: 1px solid #dee2e6; + margin-bottom: 1rem; +} + +.custom-tab-btn { + padding: 0.5rem 1rem; + margin-bottom: -1px; + background: none; + border: 1px solid transparent; + border-top-left-radius: 0.25rem; + border-top-right-radius: 0.25rem; + cursor: pointer; + color: var(--secondary); +} + +.custom-tab-btn.active { + color: var(--primary); + background-color: #fff; + border-color: #dee2e6 #dee2e6 #fff; +} + +.custom-tab-content { + display: none; +} + +.custom-tab-content.active { + display: block; +} + +/* Fix for profile tab visibility */ +#profileSection.active .tab-pane.active { + display: block !important; +} + +#profileSection.active .nav-tabs .nav-link.active { + color: var(--primary); + border-color: var(--primary); + background-color: #fff; +} + +/* Action buttons enhanced */ +.action-button { + border-radius: 50px; + padding: 10px 20px; + font-weight: 500; + transition: var(--transition); + display: inline-flex; + align-items: center; + box-shadow: 0 2px 5px rgba(0, 0, 0, 0.15); +} + +.action-button:hover { + transform: translateY(-3px); + box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2); +} + +.action-button i { + margin-right: 8px; +} \ No newline at end of file diff --git a/static/img/logo.png b/static/img/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..1f51c1ac707bfbc2860f0398d6589eb08e5164fb GIT binary patch literal 324362 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 z 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

u(48~@QkKM;Fw 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ć#I$bDr0J%t4 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�{pXeKMC+}Bt@pO=?rpFyxq7eK#1d1(S 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 literal 0 HcmV?d00001 diff --git a/static/img/user.png b/static/img/user.png new file mode 100644 index 0000000000000000000000000000000000000000..7127aa8629ca756098a3265d8f08f00d427133b7 GIT binary patch literal 19456 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 { + const modalElement = document.getElementById(modal.id); + if (modalElement && modalElement.style.display === 'block') { + modal.closeFn(); + } + }); + } + }); + + // Navigation + const navItems = document.querySelectorAll('.nav-item'); + const contentSections = document.querySelectorAll('.content-section'); + + // Function to scroll to section with smooth animation + function scrollToSection(sectionId) { + const section = document.getElementById(sectionId); + if (section) { + const offset = 20; // Offset from top + const sectionPosition = section.getBoundingClientRect().top + window.pageYOffset - offset; + + window.scrollTo({ + top: sectionPosition, + behavior: 'smooth' + }); + } + } + + // Function to update active state + function updateActiveState(clickedItem) { + // Remove active class from all nav items + navItems.forEach(nav => { + nav.classList.remove('active'); + nav.style.transform = 'scale(1)'; + }); + + // Add active class to clicked item + clickedItem.classList.add('active'); + clickedItem.style.transform = 'scale(1.1)'; + + // Remove active class from all sections + contentSections.forEach(section => { + section.classList.remove('active'); + section.style.opacity = '0'; + section.style.transform = 'translateY(20px)'; + }); + + // Add active class to target section + const sectionId = clickedItem.dataset.section + 'Section'; + const targetSection = document.getElementById(sectionId); + if (targetSection) { + targetSection.classList.add('active'); + targetSection.style.opacity = '1'; + targetSection.style.transform = 'translateY(0)'; + } + } + + // Add click event listeners to nav items + navItems.forEach(item => { + item.addEventListener('click', function(e) { + e.preventDefault(); + const sectionId = this.dataset.section + 'Section'; + + // Update active state + updateActiveState(this); + + // Scroll to section + scrollToSection(sectionId); + }); + }); + + // Add scroll event listener to update active state based on scroll position + let scrollTimeout; + window.addEventListener('scroll', function() { + clearTimeout(scrollTimeout); + scrollTimeout = setTimeout(function() { + const scrollPosition = window.scrollY + 100; // Offset for better detection + + contentSections.forEach(section => { + const sectionTop = section.offsetTop - 100; + const sectionBottom = sectionTop + section.offsetHeight; + + if (scrollPosition >= sectionTop && scrollPosition < sectionBottom) { + const sectionId = section.id; + const navItem = document.querySelector(`.nav-item[data-section="${sectionId.replace('Section', '')}"]`); + if (navItem) { + updateActiveState(navItem); + } + } + }); + }, 100); + }); + + // Add touch feedback + navItems.forEach(item => { + item.addEventListener('touchstart', function() { + this.style.transform = 'scale(0.95)'; + }); + + item.addEventListener('touchend', function() { + this.style.transform = this.classList.contains('active') ? 'scale(1.1)' : 'scale(1)'; + }); + }); + + // Initialize first section as active + const firstNavItem = navItems[0]; + if (firstNavItem) { + updateActiveState(firstNavItem); + } + + // Initialize rating functionality + setupStarRating(); + + // Set up subject files buttons + document.querySelectorAll('.view-subject-files').forEach(button => { + button.addEventListener('click', function() { + const subjectId = this.getAttribute('data-subject-id'); + viewSubjectFiles(subjectId); + }); + }); + + // Handle image loading errors + document.querySelectorAll('img[src*="student.image.url"]').forEach(img => { + img.addEventListener('error', function() { + this.onerror = null; + this.src = '/static/img/user.png'; + }); + }); + + // Handle feedback form tabs + setupFeedbackTabs(); + + // Initialize Bootstrap tooltip and popover components + initializeBootstrapComponents(); + + // Setup custom tabs + setupCustomTabs(); + + // Add form validation for rating form + setupRatingFormValidation(); +}); + +// Modal Functions +function openLeaveModal() { + document.getElementById('customLeaveModal').style.display = 'block'; + document.body.style.overflow = 'hidden'; +} + +function closeLeaveModal() { + document.getElementById('customLeaveModal').style.display = 'none'; + document.body.style.overflow = ''; +} + +function openProfileModal() { + document.getElementById('profileModal').style.display = 'block'; + document.body.style.overflow = 'hidden'; +} + +function closeProfileModal() { + document.getElementById('profileModal').style.display = 'none'; + document.body.style.overflow = ''; +} + +function openPasswordModal() { + document.getElementById('passwordModal').style.display = 'block'; + document.body.style.overflow = 'hidden'; +} + +function closePasswordModal() { + document.getElementById('passwordModal').style.display = 'none'; + document.body.style.overflow = ''; +} + +function openFeedbackModal() { + document.getElementById('feedbackModal').style.display = 'block'; + document.body.style.overflow = 'hidden'; +} + +function closeFeedbackModal() { + document.getElementById('feedbackModal').style.display = 'none'; + document.body.style.overflow = ''; +} + +function openPdfViewerModal(url) { + document.getElementById('pdfViewer').src = url; + document.getElementById('pdfViewerModal').style.display = 'block'; + document.body.style.overflow = 'hidden'; +} + +function closePdfViewerModal() { + document.getElementById('pdfViewerModal').style.display = 'none'; + document.body.style.overflow = ''; +} + +function openSubjectFilesModal(subjectId) { + // Use the viewSubjectFiles function which fetches the files from the server + viewSubjectFiles(subjectId); +} + +function closeSubjectFilesModal() { + document.getElementById('subjectFilesModal').style.display = 'none'; + document.body.style.overflow = ''; +} + +// Setup custom tabs +function setupCustomTabs() { + const tabButtons = document.querySelectorAll('.custom-tab-btn'); + if (tabButtons.length > 0) { + tabButtons.forEach(button => { + button.addEventListener('click', function() { + // Remove active class from all buttons + tabButtons.forEach(btn => btn.classList.remove('active')); + + // Add active class to clicked button + this.classList.add('active'); + + // Hide all content + document.querySelectorAll('.custom-tab-content').forEach(content => { + content.classList.remove('active'); + }); + + // Show target content + const target = this.getAttribute('data-target'); + document.getElementById(target).classList.add('active'); + }); + }); + } +} + +// Setup feedback form validation +function setupRatingFormValidation() { + const ratingForm = document.querySelector('.feedback-form'); + const ratingInput = document.getElementById('selected_rating'); + const ratingError = document.getElementById('rating-error'); + + if (ratingForm && ratingInput && ratingError) { + // Add form validation before submission + ratingForm.addEventListener('submit', function(e) { + // Check if rating is selected + if (!ratingInput.value) { + e.preventDefault(); // Stop form submission + if (ratingError) { + ratingError.style.display = 'block'; + ratingError.scrollIntoView({ behavior: 'smooth' }); + } + return false; + } + return true; + }); + } +} + +// Implementation for subject files +function viewSubjectFiles(subjectId) { + // Show loading state + const filesList = document.getElementById('subjectFilesList'); + if (!filesList) return; + + filesList.innerHTML = ` +

+ `; + + // Show modal + document.getElementById('subjectFilesModal').style.display = 'block'; + document.body.style.overflow = 'hidden'; + + // Fetch syllabus + fetch(`/app/subject/${subjectId}/files/`) + .then(response => { + if (!response.ok) { + throw new Error('Network response was not ok'); + } + return response.json(); + }) + .then(data => { + if (data.success) { + if (!data.files || data.files.length === 0) { + filesList.innerHTML = ` +
+ +

No syllabus available for this subject

+
+ `; + } else { + let html = ''; + data.files.forEach(file => { + html += ` +
+ `; + }); + filesList.innerHTML = html; + } + } else { + throw new Error(data.message || 'Failed to load syllabus'); + } + }) + .catch(error => { + console.error('Error:', error); + filesList.innerHTML = ` +
+ +

Unable to load syllabus. Please try again later.

+ ${error.message} +
+ `; + }); +} + +// Setup feedback tabs +function setupFeedbackTabs() { + const teacherTabBtn = document.getElementById('teacher-tab-btn'); + const instituteTabBtn = document.getElementById('institute-tab-btn'); + + if (teacherTabBtn && instituteTabBtn) { + teacherTabBtn.addEventListener('click', function() { + switchFeedbackTab('teacher'); + }); + + instituteTabBtn.addEventListener('click', function() { + switchFeedbackTab('institute'); + }); + } +} + +// Tab switching function +function switchFeedbackTab(tabId) { + // Hide all tab contents + document.querySelectorAll('.tab-pane').forEach(tab => { + tab.classList.remove('active'); + }); + + // Deactivate all tab buttons + document.querySelectorAll('.feedback-tab-btn').forEach(btn => { + btn.classList.remove('active'); + }); + + // Show selected tab content and activate button + document.getElementById(`${tabId}-tab-content`).classList.add('active'); + document.getElementById(`${tabId}-tab-btn`).classList.add('active'); +} + +// Initialize Bootstrap components +function initializeBootstrapComponents() { + // Initialize tooltips if available + if (typeof bootstrap !== 'undefined' && bootstrap.Tooltip) { + const tooltipTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"]')); + tooltipTriggerList.map(function (tooltipTriggerEl) { + return new bootstrap.Tooltip(tooltipTriggerEl); + }); + } + + // Initialize popovers if available + if (typeof bootstrap !== 'undefined' && bootstrap.Popover) { + const popoverTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="popover"]')); + popoverTriggerList.map(function (popoverTriggerEl) { + return new bootstrap.Popover(popoverTriggerEl); + }); + } +} + +// Function to show notification toast +function showNotification(title, message, type = 'success') { + const toast = document.getElementById('notificationToast'); + if (!toast) return; + + const toastTitle = document.getElementById('toastTitle'); + const toastMessage = document.getElementById('toastMessage'); + + toastTitle.innerText = title; + toastMessage.innerText = message; + + // Set toast color based on type + toast.className = 'toast'; + if (type === 'success') { + toast.classList.add('bg-success', 'text-white'); + } else if (type === 'error') { + toast.classList.add('bg-danger', 'text-white'); + } else if (type === 'warning') { + toast.classList.add('bg-warning'); + } else if (type === 'info') { + toast.classList.add('bg-info', 'text-white'); + } + + const bsToast = new bootstrap.Toast(toast); + bsToast.show(); +} + +// Function to set up star rating +function setupStarRating() { + // Teacher feedback + setupStarRatingComponent('teacher-rating', 'teacherStar'); + // Institute feedback + setupStarRatingComponent('institute-rating', 'instituteStar'); + // Generic rating stars + setupGenericRatingStars(); +} + +function setupStarRatingComponent(containerId, inputPrefix) { + const container = document.getElementById(containerId); + if (!container) return; + + const stars = container.querySelectorAll('.form-check-label'); + const inputs = Array.from(container.querySelectorAll('input[type="radio"]')); + + stars.forEach((star, index) => { + // Click event + star.addEventListener('click', function() { + // Update visual state + updateStars(stars, index); + + // Update form input + inputs[index].checked = true; + }); + + // Hover effects + star.addEventListener('mouseenter', function() { + highlightStars(stars, index); + }); + + container.addEventListener('mouseleave', function() { + resetStars(stars, inputs); + }); + }); +} + +function setupGenericRatingStars() { + const stars = document.querySelectorAll('.rating-star'); + const ratingInput = document.getElementById('selected_rating'); + const ratingError = document.getElementById('rating-error'); + + if (stars.length > 0 && ratingInput) { + stars.forEach(star => { + // Click event + star.addEventListener('click', function() { + const value = parseInt(this.getAttribute('data-value')); + ratingInput.value = value; + + // Update the stars + stars.forEach((s, index) => { + if (index < value) { + s.className = 'fas fa-star fs-4 text-warning rating-star'; + } else { + s.className = 'far fa-star fs-4 text-warning rating-star'; + } + }); + + // Hide error message if displayed + if (ratingError) ratingError.style.display = 'none'; + }); + + // Hover events + star.addEventListener('mouseenter', function() { + const value = parseInt(this.getAttribute('data-value')); + + stars.forEach((s, index) => { + if (index < value) { + s.className = 'fas fa-star fs-4 text-warning rating-star'; + } + }); + }); + + star.addEventListener('mouseleave', function() { + const selectedValue = parseInt(ratingInput.value) || 0; + + stars.forEach((s, index) => { + if (index < selectedValue) { + s.className = 'fas fa-star fs-4 text-warning rating-star'; + } else { + s.className = 'far fa-star fs-4 text-warning rating-star'; + } + }); + }); + }); + } +} + +function updateStars(stars, selectedIndex) { + stars.forEach((star, i) => { + const starIcon = star.querySelector('i'); + if (i <= selectedIndex) { + starIcon.className = 'fas fa-star fs-4'; + } else { + starIcon.className = 'far fa-star fs-4'; + } + }); +} + +function highlightStars(stars, hoverIndex) { + stars.forEach((star, i) => { + const starIcon = star.querySelector('i'); + if (i <= hoverIndex) { + starIcon.className = 'fas fa-star fs-4'; + } + }); +} + +function resetStars(stars, inputs) { + const selectedIndex = inputs.findIndex(input => input.checked); + stars.forEach((star, i) => { + const starIcon = star.querySelector('i'); + if (selectedIndex >= 0 && i <= selectedIndex) { + starIcon.className = 'fas fa-star fs-4'; + } else { + starIcon.className = 'far fa-star fs-4'; + } + }); +} \ No newline at end of file diff --git a/static/js/feedback_rating.js b/static/js/feedback_rating.js new file mode 100644 index 0000000..7e7b505 --- /dev/null +++ b/static/js/feedback_rating.js @@ -0,0 +1,113 @@ +document.addEventListener('DOMContentLoaded', function() { + // Handle star rating selection for teacher feedback + const teacherStars = document.querySelectorAll('[id^="teacherStar"]'); + const teacherLabels = document.querySelectorAll('label[for^="teacherStar"]'); + + teacherLabels.forEach(label => { + label.addEventListener('click', function() { + const starId = this.getAttribute('for'); + const starNumber = parseInt(starId.replace('teacherStar', '')); + + // Update visual appearance + teacherLabels.forEach((lbl, index) => { + const star = lbl.querySelector('i'); + if (index < starNumber) { + star.className = 'fas fa-star fs-4 text-warning'; + } else { + star.className = 'far fa-star fs-4 text-warning'; + } + }); + + // Set the correct radio button + document.getElementById(starId).checked = true; + }); + + // Add hover effects + label.addEventListener('mouseenter', function() { + const starId = this.getAttribute('for'); + const starNumber = parseInt(starId.replace('teacherStar', '')); + + teacherLabels.forEach((lbl, index) => { + const star = lbl.querySelector('i'); + if (index < starNumber) { + star.className = 'fas fa-star fs-4 text-warning'; + } + }); + }); + + label.addEventListener('mouseleave', function() { + // Reset to selected state + let selectedValue = 0; + teacherStars.forEach((radio, index) => { + if (radio.checked) { + selectedValue = index + 1; + } + }); + + teacherLabels.forEach((lbl, index) => { + const star = lbl.querySelector('i'); + if (index < selectedValue) { + star.className = 'fas fa-star fs-4 text-warning'; + } else { + star.className = 'far fa-star fs-4 text-warning'; + } + }); + }); + }); + + // Handle star rating selection for institute feedback + const instituteStars = document.querySelectorAll('[id^="instituteStar"]'); + const instituteLabels = document.querySelectorAll('label[for^="instituteStar"]'); + + instituteLabels.forEach(label => { + label.addEventListener('click', function() { + const starId = this.getAttribute('for'); + const starNumber = parseInt(starId.replace('instituteStar', '')); + + // Update visual appearance + instituteLabels.forEach((lbl, index) => { + const star = lbl.querySelector('i'); + if (index < starNumber) { + star.className = 'fas fa-star fs-4 text-warning'; + } else { + star.className = 'far fa-star fs-4 text-warning'; + } + }); + + // Set the correct radio button + document.getElementById(starId).checked = true; + }); + + // Add hover effects + label.addEventListener('mouseenter', function() { + const starId = this.getAttribute('for'); + const starNumber = parseInt(starId.replace('instituteStar', '')); + + instituteLabels.forEach((lbl, index) => { + const star = lbl.querySelector('i'); + if (index < starNumber) { + star.className = 'fas fa-star fs-4 text-warning'; + } + }); + }); + + label.addEventListener('mouseleave', function() { + // Reset to selected state + let selectedValue = 0; + instituteStars.forEach((radio, index) => { + if (radio.checked) { + selectedValue = index + 1; + } + }); + + instituteLabels.forEach((lbl, index) => { + const star = lbl.querySelector('i'); + if (index < selectedValue) { + star.className = 'fas fa-star fs-4 text-warning'; + } else { + star.className = 'far fa-star fs-4 text-warning'; + } + }); + }); + }); +}); \ No newline at end of file diff --git a/student_management_system/jazzmin.py b/student_management_system/jazzmin.py new file mode 100644 index 0000000..8a3e150 --- /dev/null +++ b/student_management_system/jazzmin.py @@ -0,0 +1,98 @@ +JAZZMIN_SETTINGS = { + "site_title": "Student Management System", + "site_header": "Student Management", + "site_brand": "SMS", + "site_logo": "img/logo.png", + "login_logo": "img/logo.png", + "login_logo_dark": None, + "site_logo_classes": "img-circle", + "login_logo_classes": "", + "custom_css": "css/custom.css", + "welcome_sign": "Welcome to Student Management System", + "copyright": "Student Management System", + "search_model": ["app.Student", "app.Staff", "app.Course"], + "topmenu_links": [ + {"name": "Dashboard", "url": "admin:index", "permissions": ["auth.view_user"]}, + {"model": "auth.User"}, + ], + "usermenu_links": [{"model": "auth.user"}], + "show_sidebar": True, + "navigation_expanded": True, + "hide_apps": [], + "hide_models": [], + "order_with_respect_to": [ + "dashboard", + "authentication", + "organization", + "human_managementorganization.institute", + "organization.batch", + "organization.course", + "human_management.student", + "human_management.staff", + "human_management.routine", + "human_management.staff_leave", + "human_management.student_leave", + "human_management.studentfeedback", + "human_management.coursetracking", + "human_management.attendance", + "human_management.institutefeedback", + ], + "icons": { + "auth": "fas fa-users-cog", + "auth.user": "fas fa-user", + "auth.Group": "fas fa-users", + "app.student": "fas fa-user-graduate", + "app.staff": "fas fa-chalkboard-teacher", + "app.course": "fas fa-book", + "app.subject": "fas fa-book-open", + "app.attendance": "fas fa-calendar-check", + "app.studentfeedback": "fas fa-comment", + "app.institutefeedback": "fas fa-comments", + "app.student_leave": "fas fa-calendar-times", + "app.staff_leave": "fas fa-calendar-minus", + "app.notice": "fas fa-bullhorn", + }, + "default_icon_parents": "fas fa-chevron-circle-right", + "default_icon_children": "fas fa-circle", + "related_modal_active": False, + "custom_js": None, + "show_ui_builder": False, + "changeform_format": "horizontal_tabs", + "changeform_format_overrides": { + "auth.user": "collapsible", + "auth.group": "vertical_tabs", + }, + "language_chooser": False, +} + +JAZZMIN_UI_TWEAKS = { + "navbar_small_text": False, + "footer_small_text": False, + "body_small_text": False, + "brand_small_text": False, + "brand_colour": False, + "accent": "accent-primary", + "navbar": "navbar-dark", + "no_navbar_border": False, + "navbar_fixed": False, + "layout_boxed": False, + "footer_fixed": False, + "sidebar_fixed": False, + "sidebar": "sidebar-dark-primary", + "sidebar_nav_small_text": False, + "sidebar_disable_expand": False, + "sidebar_nav_child_indent": False, + "sidebar_nav_compact_style": False, + "sidebar_nav_legacy_style": False, + "sidebar_nav_flat_style": False, + "theme": "default", + "dark_mode_theme": None, + "button_classes": { + "primary": "btn-primary", + "secondary": "btn-secondary", + "info": "btn-info", + "warning": "btn-warning", + "danger": "btn-danger", + "success": "btn-success" + } +} diff --git a/student_management_system/settings.py b/student_management_system/settings.py index 64b90af..c12213d 100644 --- a/student_management_system/settings.py +++ b/student_management_system/settings.py @@ -11,21 +11,26 @@ https://docs.djangoproject.com/en/5.1/ref/settings/ """ import os +from pathlib import Path +from dotenv import load_dotenv +from student_management_system.jazzmin import JAZZMIN_SETTINGS, JAZZMIN_UI_TWEAKS + +# Load environment variables +load_dotenv() # Build paths inside the project like this: BASE_DIR / 'subdir'. -BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) +BASE_DIR = Path(__file__).resolve().parent.parent # Quick-start development settings - unsuitable for production # See https://docs.djangoproject.com/en/5.1/howto/deployment/checklist/ # SECURITY WARNING: keep the secret key used in production secret! -SECRET_KEY = "django-insecure-r))8$j-a-kc641we86oiyxr&x$1e43c!7y4#w-r1s@$$q8dik8" +SECRET_KEY = os.getenv('DJANGO_SECRET_KEY') # SECURITY WARNING: don't run with debug turned on in production! -DEBUG = True - -ALLOWED_HOSTS = [] +DEBUG = os.getenv('DJANGO_DEBUG', 'False') == 'True' +ALLOWED_HOSTS = os.getenv('DJANGO_ALLOWED_HOSTS', '*').split(',') # Application definition @@ -38,6 +43,7 @@ INSTALLED_APPS = [ "django.contrib.messages", "django.contrib.staticfiles", "rest_framework", + "mathfilters", "app", ] @@ -139,96 +145,37 @@ DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField" MEDIA_URL = "/media/" MEDIA_ROOT = os.path.join(BASE_DIR, "media") -JAZZMIN_SETTINGS = { - "site_title": "SMS", - "site_header": "SMS", - "site_brand": "SMS", - "site_logo_classes": "img-circle", - "welcome_sign": "WELCOME TO SMS", - "copyright": "S4NKALP: SMS", - "search_model": ["app.Student", "app.Course"], - "topmenu_links": [ - {"name": "Home", "url": "admin:index", "permissions": ["auth.view_user"]}, - {"name": "Dashboard", "url": "/app/dashboard", "permissions": []}, - {"model": "app.Student"}, - {"app": "app"}, - ], - "usermenu_links": [ - {"model": "auth.user"} - ], - "show_sidebar": True, - "navigation_expanded": True, - "hide_apps": [], - "hide_models": [], - "order_with_respect_to": [ - "dashboard", - "authentication","organization","human_management" - "organization.institute", "organization.batch", "organization.course", - "human_management.student", "human_management.staff", "human_management.routine", - "human_management.staff_leave", "human_management.student_leave", - "human_management.studentfeedback", "human_management.coursetracking", - "human_management.attendance", "human_management.institutefeedback" - ], - "icons": { - "auth": "fas fa-users-cog", - "auth.user": "fas fa-user", - "auth.Group": "fas fa-users", - "app.Student": "fas fa-user-graduate", - "app.Course": "fas fa-book", - "app.Staff": "fas fa-chalkboard-teacher", - "app.Attendance": "fas fa-calendar-check", - "app.CourseTracking": "fas fa-chart-line", - "app.StudentFeedback": "fas fa-comment", - }, - "default_icon_parents": "fas fa-chevron-circle-right", - "default_icon_children": "fas fa-circle", - "related_modal_active": False, - "custom_css": None, - "custom_js": None, - "show_ui_builder": False, - "changeform_format": "horizontal_tabs", - "changeform_format_overrides": {"auth.user": "collapsible", "auth.group": "vertical_tabs"}, - "language_chooser": False, - "custom_links": { - "app": [ - { - "name": "Dashboard", - "url": "/app/dashboard", - "icon": "fas fa-tachometer-alt", - "permissions": [] - } - ] - }, -} -JAZZMIN_UI_TWEAKS = { - "navbar_small_text": False, - "footer_small_text": False, - "body_small_text": False, - "brand_small_text": False, - "brand_colour": False, - "accent": "accent-primary", - "navbar": "navbar-dark", - "no_navbar_border": False, - "navbar_fixed": True, - "layout_boxed": False, - "footer_fixed": False, - "sidebar_fixed": True, - "sidebar": "sidebar-dark-primary", - "sidebar_nav_small_text": False, - "sidebar_disable_expand": False, - "sidebar_nav_child_indent": False, - "sidebar_nav_compact_style": False, - "sidebar_nav_legacy_style": False, - "sidebar_nav_flat_style": False, - "theme": "default", - "dark_mode_theme": None, - "button_classes": { - "primary": "btn-primary", - "secondary": "btn-secondary", - "info": "btn-info", - "warning": "btn-warning", - "danger": "btn-danger", - "success": "btn-success" +# Jazmin Settings +JAZZMIN_SETTINGS = JAZZMIN_SETTINGS +JAZZMIN_UI_TWEAKS = JAZZMIN_UI_TWEAKS + +# Login redirect URL +LOGIN_REDIRECT_URL = '/app/dashboard/' +LOGIN_URL = '/login/' + +# Email Configuration +EMAIL_BACKEND = os.getenv('EMAIL_BACKEND', 'django.core.mail.backends.console.EmailBackend') +DEFAULT_FROM_EMAIL = os.getenv('DEFAULT_FROM_EMAIL', 'noreply@studentmanagementsystem.com') + +# Cache configuration for OTP storage +CACHES = { + 'default': { + 'BACKEND': 'django.core.cache.backends.locmem.LocMemCache', + 'LOCATION': os.getenv('CACHE_LOCATION', 'unique-snowflake'), } } + +# SMS API configuration +SMS_API_KEY = os.getenv('SMS_API_KEY', '') +SMS_SENDER_ID = os.getenv('SMS_SENDER_ID', 'SMSSYS') + + +CSRF_TRUSTED_ORIGINS = [ + "https://ab4c-2405-acc0-1504-65ce-00-2.ngrok-free.app" +] + +CSRF_TRUSTED_ORIGINS = [ + "https://*.ngrok-free.app", + "https://*.ngrok.io" +] diff --git a/student_management_system/urls.py b/student_management_system/urls.py index ac6627c..260b3ac 100644 --- a/student_management_system/urls.py +++ b/student_management_system/urls.py @@ -19,9 +19,28 @@ from django.contrib import admin from django.urls import path, include from django.conf import settings from django.conf.urls.static import static +from django.contrib.auth import views as auth_views from app.admin import custom_admin_site +from django.views.generic import RedirectView +from app import views +from app import auth -urlpatterns = [ +# Serve media files without requiring authentication +urlpatterns = static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) + +# Add other URL patterns +urlpatterns += [ path("app/", include("app.urls")), - path("", custom_admin_site.urls), -] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) + path("admin/", custom_admin_site.urls), # Admin site at /admin/ + path("", RedirectView.as_view(url="/app/dashboard/", permanent=False)), # Redirect root to dashboard + + # Custom login and logout views + path('login/', auth_views.LoginView.as_view(template_name='login/login.html'), name='login'), + path('logout/', auth_views.LogoutView.as_view(next_page='/login/'), name='logout'), + + # Password reset views - main entry point + path('password-reset/', auth.reset_password_options, name='password_reset'), +] + +if settings.DEBUG: + urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT) diff --git a/templates/admin/app/routine/change_form.html b/templates/admin/app/routine/change_form.html new file mode 100644 index 0000000..dc240da --- /dev/null +++ b/templates/admin/app/routine/change_form.html @@ -0,0 +1,555 @@ +{% extends "admin/change_form.html" %} +{% load static %} +{% load mathfilters %} + +{% block extrahead %} +{{ block.super }} + + + +{% endblock %} + +{% block content %} +
+
+

Add Routines

+
+
+
+ {% csrf_token %} + +
+
+
+
+ + +
+
+
+
+ + +
+
+
+
+ +
+ + + + + + + + + + + + + + + +
SubjectTeacherStart TimeEnd TimeAction
+ Please select course and semester +
+
+ +
+
+ +
+
+
+
+
+ + +{% endblock %} \ No newline at end of file diff --git a/templates/base.html b/templates/base.html new file mode 100644 index 0000000..6acb351 --- /dev/null +++ b/templates/base.html @@ -0,0 +1,22 @@ +{% load static %} + + + + + + {% block title %}Student Management System{% endblock %} + + + + + + + + {% block extrastyle %}{% endblock %} + + + {% block content %}{% endblock %} + + {% block extrahead %}{% endblock %} + + \ No newline at end of file diff --git a/templates/dashboard.html b/templates/dashboard.html index 8a0e7c8..29deed2 100644 --- a/templates/dashboard.html +++ b/templates/dashboard.html @@ -1,225 +1,818 @@ {% extends "admin/base_site.html" %} {% load static %} {% load app_filters %} +{% block extrahead %} + {{ block.super }} + +{% endblock %} +{% block extrastyle %} + {{ block.super }} + + + + + +{% endblock %} {% block content %} -
- -
- -
-
-
-

{{ total_students }}

-

Total Students

-
- Active: {{ active_students }} | - Completed: {{ completed_students }} | - On Leave: {{ on_leave_students }} -
-
-
- -
+
+ +
+
+
+
+
+

Welcome, Admin!

+

Student Management Dashboard

+
+
+
+
+
+ +
+ +
+
+
+
+ Students +
-
- - -
-
-
-

{{ total_courses }}

-

Course Statistics

-
- Active: {{ active_courses }} | - Completed: {{ completed_courses }} +
+
+
+
{{ total_students }}
+
Total Students
-
- -
-
-
- - -
-
-
-

{{ in_progress_trackings }}

-

Course Progress

-
- In Progress | - Completed: {{ completed_trackings }} | - Dropped: {{ dropped_trackings }} +
+
+ Active + {{ active_students }}
-
-
- -
-
-
- - -
-
-
-

{{ today_present }}/{{ today_attendance }}

-

Today's Attendance

-
- Rate: {{ attendance_rate }}% +
+ Completed + {{ completed_students }} +
+
+ On Leave + {{ on_leave_students }}
-
-
-
- -
- -
-
-
-

Course Progress Overview

-
-
-
- - - - - - - - - - - - {% for progress in course_progress %} - - - - - - - - {% endfor %} - -
CourseTotal StudentsIn ProgressCompletedAvg Progress
{{ progress.course.name }}{{ progress.total_students }}{{ progress.in_progress }}{{ progress.completed }} -
-
- {{ progress.average_progress }}% -
-
-
-
-
+ +
+
+
+
+ Courses +
-
- - -
-
-
-

Recent Activity

+
+
+
+
{{ total_courses }}
+
Total Courses
+
-
- -
Recent Leave Requests
-
-
Students
- {% for leave in recent_student_leaves %} -
- {{ leave.created_at|date:"M d, Y" }} -
{{ leave.student.name }} - {{ leave.get_status_display }}
-
- {% empty %} -

No recent student leave requests

- {% endfor %} +
+
+ Active + {{ active_courses }}
- -
Staff
- {% for leave in recent_staff_leaves %} -
- {{ leave.created_at|date:"M d, Y" }} -
{{ leave.staff.name }} - {{ leave.get_status_display }}
+
+ Completed + {{ completed_courses }}
- {% empty %} -

No recent staff leave requests

- {% endfor %} - - -
Recent Feedback
- {% for feedback in recent_feedback %} -
- {{ feedback.created_at|date:"M d, Y" }} -
{{ feedback.student.name }} - {{ feedback.subject.name }}
-
- {% for i in feedback.rating|get_range %} - - {% endfor %} -
-
- {% empty %} -

No recent feedback

- {% endfor %}
- -
-
-
-
-

Monthly Statistics

+ +
+
+
+
+ Staff +
+
+
+
+
+
{{ total_staff }}
+
Total Staff
+
-
-
-
-
- - - -
- New Students - {{ monthly_stats.new_students }} -
-
-
-
-
- - - -
- Completed Courses - {{ monthly_stats.completed_courses }} -
-
-
-
-
- - - -
- Monthly Attendance Rate - {{ monthly_stats.attendance_rate }}% -
-
-
+
+
+ Active + {{ active_staff }} +
+
+ On Leave + {{ staff_on_leave }} +
+
+
+
+
+ + +
+
+
+
+ Attendance +
+
+
+
+
+
{{ total_classes_today }}
+
Classes Today
+
+
+
+
+ Students Present + {{ students_present }}/{{ total_students_today }} +
+
+ Attendance Rate + + {{ attendance_rate }}% +
-{% endblock %} \ No newline at end of file +
+ +
+
+ +
+
+ +
+ +
+
+
+Course Progress +
+
+ + + + + + + + + + +{% for progress in course_progress %} + + + + + + +{% empty %} + + + +{% endfor %} + +
CourseStudentsProgressStatus
{{ progress.course.name }}{{ progress.total_students }} +
+
+
+
+{{ progress.average_progress }}% +
+ +{% if progress.average_progress == 100 %} +Completed +{% elif progress.average_progress > 0 %} +In Progress +{% else %} +Not Started +{% endif %} + +
No course progress data available
+
+
+
+ +
+
+
+Recent Activity +
+
+{% for activity in recent_activities %} +
+
+
{{ activity.title }}
+

{{ activity.description }}

+{{ activity.timestamp|timesince }} ago +
+
+{% empty %} +

No recent activity

+{% endfor %} +
+
+
+
+ +
+
+
+
+Pending Leave Requests +
+
+ + + + + + + + + + + +{% for leave in pending_student_leaves %} + + + + + + + +{% endfor %} +{% for leave in pending_staff_leaves %} + + + + + + + +{% endfor %} +{% if not pending_student_leaves and not pending_staff_leaves %} + + + +{% endif %} + +
NameTypeDateReasonActions
{{ leave.student.name }} +Student +{{ leave.date|date:"M d, Y" }}{{ leave.message }} +
+ {% csrf_token %} + +
+
+ {% csrf_token %} + +
+
{{ leave.staff.name }} +Staff +{{ leave.date|date:"M d, Y" }}{{ leave.message }} +
+ {% csrf_token %} + +
+
+ {% csrf_token %} + +
+
No pending leave requests
+
+
+
+
+ +
+
+
+
+Notice Board +
+
+{% csrf_token %} +
+
+ +
+
+ +
+
+ +
+
+ +
+
+
+
+{% for notice in notices %} +
+
+
+
{{ notice.title }}
+{{ notice.created_at|date:"M d, Y" }} +
+{% if notice.image %} +Notice Image +{% endif %} +

{{ notice.message }}

+ +
+
+{% empty %} +

No notices available

+{% endfor %} +
+
+
+
+ +
+
+
+
+Teacher Ratings +
+
+{% for teacher in teacher_ratings %} +
+
+
+{% if teacher.image %} +{{ teacher.name }} +{% else %} +
+ +
+{% endif %} +
+
{{ teacher.name }}
+{{ teacher.designation }} +
+
+
+
+Average Rating +{{ teacher.avg_rating|floatformat:1 }}/5.0 +
+
+{% for i in "12345"|make_list %} + +{% endfor %} +
+
+
+
+
+
+
+
+Total Reviews +{{ teacher.total_reviews }} +
+
+Students Taught +{{ teacher.total_students }} +
+
+
+
+{% empty %} +
+

No teacher ratings available

+
+{% endfor %} +
+
+
+
+ +
+
+
+
+Monthly Statistics +
+
+
+
+ +

{{ monthly_stats.new_students }}

+

New Students

+
+
+
+
+ +

{{ monthly_stats.new_staff }}

+

New Staff

+
+
+
+
+ +

{{ monthly_stats.attendance_rate }}%

+

Attendance Rate

+
+
+
+
+ +

{{ monthly_stats.leave_requests }}

+

Leave Requests

+
+
+
+
+
+
+ +
+
+
+
+Institute Feedback +
+
+ + + + + + + + + + + + +{% for feedback in recent_institute_feedback %} + + + + + + + + +{% empty %} + + + +{% endfor %} + +
TypeCategoryNameRatingFeedbackDate
+ +{{ feedback.user_type|title }} + +{{ feedback.feedback_type }}{{ feedback.display_name }} +
+{% for i in "12345"|make_list %} + +{% endfor %} +
+
{{ feedback.feedback_text|truncatechars:100 }}{{ feedback.created_at|date:"M d, Y" }}
No institute feedback available
+
+
+
+
+
+ + +{% endblock %} +{% block extrajs %} +{{ block.super }} + + +{% endblock %} diff --git a/templates/login/email_reset.html b/templates/login/email_reset.html new file mode 100644 index 0000000..71a32ac --- /dev/null +++ b/templates/login/email_reset.html @@ -0,0 +1,170 @@ +{% extends "base.html" %} +{% load static %} + +{% block content %} +
+ +

Reset Password

+ +

Enter your email address and we'll send you a verification code to reset your password.

+ + {% if error %} +
+ {{ error }} +
+ {% endif %} + + {% if success %} +
+ {{ success }} +
+ {% endif %} + + {% if messages %} +
+ {% for message in messages %} + {{ message }} + {% endfor %} +
+ {% endif %} + +
+ {% csrf_token %} +
+ + +
+ + +
+ + โ† Back to Reset Options +
+ + +{% endblock %} \ No newline at end of file diff --git a/templates/login/email_templates/password_reset_email.html b/templates/login/email_templates/password_reset_email.html new file mode 100644 index 0000000..63db663 --- /dev/null +++ b/templates/login/email_templates/password_reset_email.html @@ -0,0 +1,83 @@ +{% autoescape off %} + + + + + + Password Reset + + + +
+
+

Password Reset

+
+ +
+

Hello,

+

We received a request to reset your password for your Student Management System account. If you did not make this request, please ignore this email.

+

To reset your password, use the following code:

+
{{ reset_code }}
+

This code will expire in 5 minutes.

+

If you have any questions, please contact the system administrator.

+

Thank you,
Student Management System Team

+
+ + +
+ + +{% endautoescape %} \ No newline at end of file diff --git a/templates/login/email_templates/password_reset_subject.txt b/templates/login/email_templates/password_reset_subject.txt new file mode 100644 index 0000000..db28747 --- /dev/null +++ b/templates/login/email_templates/password_reset_subject.txt @@ -0,0 +1 @@ +Password Reset for Student Management System \ No newline at end of file diff --git a/templates/login/login.html b/templates/login/login.html new file mode 100644 index 0000000..830d2b6 --- /dev/null +++ b/templates/login/login.html @@ -0,0 +1,168 @@ +{% extends "base.html" %} +{% load static %} + +{% block content %} + + + + + + Login - Student Management System + + + + + + +{% endblock %} \ No newline at end of file diff --git a/templates/login/password_reset_complete.html b/templates/login/password_reset_complete.html new file mode 100644 index 0000000..9fea7ce --- /dev/null +++ b/templates/login/password_reset_complete.html @@ -0,0 +1,113 @@ +{% extends "base.html" %} +{% load static %} + +{% block content %} + + + + + + Password Reset Complete - Student Management System + + + +
+ +

Password Reset Complete

+ +
โœ“
+ +
+

Your password has been successfully reset.

+
+ +

You can now use your new password to log in to your account.

+ + +
+ + +{% endblock %} \ No newline at end of file diff --git a/templates/login/password_reset_confirm.html b/templates/login/password_reset_confirm.html new file mode 100644 index 0000000..788ba0f --- /dev/null +++ b/templates/login/password_reset_confirm.html @@ -0,0 +1,178 @@ +{% extends "base.html" %} +{% load static %} + +{% block content %} + + + + + + Set New Password - Student Management System + + + +
+ +

Set New Password

+ + {% if validlink %} +

Please enter your new password below.

+ + {% if form.errors %} +
+ {% for field in form %} + {% for error in field.errors %} + {{ error }}
+ {% endfor %} + {% endfor %} +
+ {% endif %} + +
+ {% csrf_token %} +
+ + {{ form.new_password1 }} +
+ +
+ + {{ form.new_password2 }} +
+ + +
+ {% else %} +
+

The password reset link was invalid, possibly because it has already been used or has expired.

+
+

Please request a new password reset link.

+ Request New Reset Link + {% endif %} +
+ + +{% endblock %} \ No newline at end of file diff --git a/templates/login/password_reset_done.html b/templates/login/password_reset_done.html new file mode 100644 index 0000000..4546ca0 --- /dev/null +++ b/templates/login/password_reset_done.html @@ -0,0 +1,107 @@ +{% extends "base.html" %} +{% load static %} + +{% block content %} + + + + + + Password Reset Email Sent - Student Management System + + + +
+ +

Email Sent

+ +
โœ“
+ +
+

We've emailed you instructions for setting your password. You should receive them shortly.

+
+ +

If you don't receive an email, please make sure you've entered the address you registered with, and check your spam folder.

+ + โ† Return to Login +
+ + +{% endblock %} \ No newline at end of file diff --git a/templates/login/password_reset_otp.html b/templates/login/password_reset_otp.html new file mode 100644 index 0000000..53e1117 --- /dev/null +++ b/templates/login/password_reset_otp.html @@ -0,0 +1,270 @@ +{% extends "base.html" %} +{% load static %} + +{% block content %} + + + + + + Verify OTP - Student Management System + + + +
+ +

Verify OTP

+ + {% if is_email %} +

+ Code sent to: {{ email|stringformat:"s"|slice:":3" }}***@{{ email|stringformat:"s"|slice:"-10:" }} + Edit Email +

+ {% else %} +

+ Code sent to: +91 ******{{ phone|stringformat:"s"|slice:"-4:" }} + Edit Number +

+ {% endif %} + + {% if error %} +
+ {{ error }} +
+ {% endif %} + + {% if messages %} +
+ {% for message in messages %} + {{ message }} + {% endfor %} +
+ {% endif %} + + {% if is_email %} +
+ {% else %} + + {% endif %} + {% csrf_token %} +
+ + + {% if is_email %} + + {% else %} + + {% endif %} +
+ + +
+ +
+ Resend code in 60s + {% if is_email %} +
+ {% else %} + + {% endif %} + {% csrf_token %} + {% if is_email %} + + {% else %} + + {% endif %} + +
+
+ + +
+ + + + +{% endblock %} \ No newline at end of file diff --git a/templates/login/password_reset_phone.html b/templates/login/password_reset_phone.html new file mode 100644 index 0000000..4b02282 --- /dev/null +++ b/templates/login/password_reset_phone.html @@ -0,0 +1,197 @@ +{% extends "base.html" %} +{% load static %} + +{% block content %} + + + + + + Reset Password - Student Management System + + + +
+ +

Reset Password

+ + {% if is_email %} +

Enter your email address and we'll send you a verification code to reset your password.

+ {% else %} +

Enter your phone number and we'll send you a verification code to reset your password.

+ {% endif %} + + {% if error %} +
+ {{ error }} +
+ {% endif %} + + {% if success %} +
+ {{ success }} +
+ {% endif %} + + {% if messages %} +
+ {% for message in messages %} + {{ message }} + {% endfor %} +
+ {% endif %} + +
+ {% csrf_token %} +
+ {% if is_email %} + + + {% else %} + + + {% endif %} +
+ + +
+ + โ† Back to Reset Options +
+ + +{% endblock %} \ No newline at end of file diff --git a/templates/login/password_reset_set.html b/templates/login/password_reset_set.html new file mode 100644 index 0000000..6fd33e3 --- /dev/null +++ b/templates/login/password_reset_set.html @@ -0,0 +1,160 @@ +{% extends "base.html" %} +{% load static %} + +{% block content %} + + + + + + Set New Password - Student Management System + + + +
+ +

Set New Password

+ +

Please enter your new password below.

+ + {% if error %} +
+ {{ error }} +
+ {% endif %} + + {% if messages %} +
+ {% for message in messages %} + {{ message }} + {% endfor %} +
+ {% endif %} + +
+ {% csrf_token %} +
+ + +
+ +
+ + +
+ + {% if is_email %} + + {% else %} + + {% endif %} + + + +
+
+ + +{% endblock %} \ No newline at end of file diff --git a/templates/login/password_reset_verify.html b/templates/login/password_reset_verify.html new file mode 100644 index 0000000..a5b9c1f --- /dev/null +++ b/templates/login/password_reset_verify.html @@ -0,0 +1,219 @@ +{% extends "base.html" %} +{% load static %} + +{% block content %} + + + + + + Verify OTP - Student Management System + + + +
+ +

Verify OTP

+

OTP sent to: {{ phone }}

+ + {% if error %} +
+ {{ error }} +
+ {% endif %} + + {% if messages %} +
+ {% for message in messages %} + {{ message }} + {% endfor %} +
+ {% endif %} + +
+ {% csrf_token %} +
+ + + +
+ + + +
+ Resend OTP in 60s + + {% csrf_token %} + + + +
+ + + +
+ + + + +{% endblock %} \ No newline at end of file diff --git a/templates/login/reset_options.html b/templates/login/reset_options.html new file mode 100644 index 0000000..f365771 --- /dev/null +++ b/templates/login/reset_options.html @@ -0,0 +1,156 @@ +{% extends "base.html" %} +{% load static %} + +{% block content %} + + + + + + Reset Password - Student Management System + + + + + + +{% endblock %} \ No newline at end of file diff --git a/templates/login/verify_reset_code.html b/templates/login/verify_reset_code.html new file mode 100644 index 0000000..a2fa42c --- /dev/null +++ b/templates/login/verify_reset_code.html @@ -0,0 +1,61 @@ +{% extends 'base.html' %} + +{% block content %} +
+
+
+
+
+

Reset Password

+
+
+ {% if message %} +
{{ message }}
+ {% endif %} + + {% if error %} +
{{ error }}
+ {% endif %} + +
+ {% csrf_token %} +
+ + +
+ +
+ + + + Enter the 6-digit code sent to your email. + +
+ +
+ + + + Your password must contain at least 8 characters. + +
+ +
+ + +
+ +
+ +
+
+ +
+

Didn't receive the code? Request a new one

+
+
+
+
+
+
+{% endblock %} \ No newline at end of file diff --git a/templates/student_dashboard.html b/templates/student_dashboard.html index 22c7a1c..676ddb0 100644 --- a/templates/student_dashboard.html +++ b/templates/student_dashboard.html @@ -1,217 +1,1097 @@ -{% extends 'admin/base_site.html' %} +{% extends "base.html" %} {% load static %} +{% load tz %} +{% load app_filters %} + +{% block extrastyle %} +{{ block.super }} + + + + + + + + + + +{% endblock %} + +{% block extrahead %} +{{ block.super }} + + + + + + +{% endblock %} {% block content %} +
- + +
+
+
+
+ {% if student.image %} + {{ student.name }} + {% else %} + Default User + {% endif %} +
+

Welcome, {{ student.name }}!

+

Student ID: {{ student.id }}

+
+
+
+
+
+ + +
+
-
-
-
- {% if student.image %} - {{ student.name }} + +
+
+
+
Attendance Summary
+
+
+
+
+ Total Classes +

{{ attendance_summary.total_classes }}

+
+
+ Attendance Rate +

{{ attendance_summary.attendance_percentage|floatformat:1 }}%

+
+
+
+ Current: {{ attendance_summary.current_streak }} days + Best: {{ attendance_summary.longest_streak }} days +
+
+
+
+ + +
+
+
+
Course Progress
+
+
+
+
+ Total Courses +

{{ course_summary.total_courses }}

+
+
+ Completion Rate +

{{ course_summary.completion_percentage|floatformat:1 }}%

+
+
+
+
+ Completed + {{ course_summary.completed_courses }} +
+
+ Ongoing + {{ course_summary.ongoing_courses }} +
+
+
+
+
+ + +
+
+
+
Recent Activity
+
+
+
+ {% for leave in recent_leaves %} +
+ +
+ Leave Request ({{ leave.date|date:"M d" }}) + {{ leave.get_status_display }} + {{ leave.created_at|timesince }} ago +
+
+ {% endfor %} + + {% for feedback in recent_feedback %} +
+ +
+ Gave feedback {% if feedback.teacher %}to {{ feedback.teacher.name }}{% endif %} +
+ {% for i in "12345"|make_list %} + {% if forloop.counter <= feedback.rating %} + + {% else %} + {% endif %} -
-

Welcome, {{ student.name }}!

-

Student ID: {{ student.id }}

-
+ {% endfor %} + {{ feedback.created_at|timesince }} ago +
-
-
-
+
+ {% endfor %} - + {% for notice in notices %} +
+ +
+ {{ notice.title }} + {{ notice.created_at|timesince }} ago +
+
+ {% endfor %} + + {% for record in attendance_records %} +
+ +
+ {% if record.student_attend %}Attended{% else %}Missed{% endif %} {{ record.attendance.routine.subject.name|truncatechars:15 }} + {{ record.attendance.date|date:"M d" }} +
+
+ {% endfor %} + + {% if not recent_leaves and not recent_feedback and not notices and not attendance_records %} +
+ No recent activity +
+ {% endif %} +
+
+
+
+ + +
+
+
+
Leave Status
+
+
+
+ Pending + {{ pending_leaves }} +
+
+ Approved + {{ approved_leaves }} +
+
+ Rejected + {{ rejected_leaves }} +
+ +
+
+
+
+ +
- -
-
-
-
-
-
Course Progress
-
{{ course_summary.completion_percentage|floatformat:1 }}%
-
-
-
-
-
-
- Completed: {{ course_summary.completed_courses }}/{{ course_summary.total_courses }} - Ongoing: {{ course_summary.ongoing_courses }} -
-
-
- -
-
-
-
-
+
+
+

+ Course Details +

+ + {% if course_details %} + {% for course in course_details %} +
+
+
{{ course.name }}
+ + {{ course.progress_status }} + +
- -
-
-
-
-
-
Attendance Rate
-
{{ attendance_summary.attendance_percentage|floatformat:1 }}%
-
-
-
-
-
-
- Present: {{ attendance_summary.classes_attended }}/{{ attendance_summary.total_classes }} -
-
-
- -
-
+ +
+
+ {{ course.completion_percentage }}%
-
-
+
- -
-
-
-
-
-
Attendance Streaks
-
- Current: {{ attendance_summary.current_streak }} days -
-
- Best Streak: {{ attendance_summary.longest_streak }} days -
-
-
- -
-
+ +
+
+ + + + + + + + + + + + + + + + + + + {% if course.actual_end_date %} + + + + + {% endif %} + +
Start Date{{ course.start_date|date:"M d, Y" }}
Duration Type{{ course.duration_type }}
Total Duration + {% if course.duration_type == "Semester" %} + {{ course.duration }} years ({{ course.duration|multiply:2 }} semesters) + {% else %} + {{ course.duration }} years + {% endif %} +
Expected End Date{{ course.expected_end_date|date:"M d, Y" }}
Actual End Date{{ course.actual_end_date|date:"M d, Y" }}
+
+ + + + + + + + + + + + + + + {% if course.remaining_days is not None %} + + + + + {% endif %} + {% if course.total_remaining_days is not None %} + + + + + {% endif %} + +
Current Semester{{ course.current_semester }}
Semester Start{{ course.semester_start_date|date:"M d, Y" }}
Semester End{{ course.semester_end_date|date:"M d, Y" }}
Semester Days Remaining{{ course.remaining_days }} days
Total Course Days Remaining{{ course.total_remaining_days }} days
+
+
+ {% endfor %} + {% else %} +
+ No courses assigned yet. +
+ {% endif %}
+
+
- -
- -
-
-
-
Course Details
-
+
+
+

+ Current Semester Subjects +

+ {% if current_subjects %} +
+ {% for subject in current_subjects %} +
+
- {% for course_name, details in course_summary.details.items %} -
-
{{ course_name }}
-
-
-

Start Date: {{ details.start_date|default:'-' }}

-

End Date: {{ details.end_date|default:'-' }}

-

Status: {{ details.progress_status }}

-
-
-

Progress:

-
-
{{ details.completion_percentage }}%
-
- {% if details.book %} - - {% endif %} -
-
-
-
- {% empty %} -

No courses enrolled yet.

- {% endfor %} +
{{ subject.name }}
+

+ Semester: {{ subject.semester_or_year }} +

+
+ +
+
+ {% endfor %}
- - -
- -
-
-
Recent Leave Requests
-
-
- {% for leave in recent_leaves %} -
-
- {{ leave.date }} - - {{ leave.get_status_display }} - -
-

{{ leave.message|truncatechars:100 }}

-
-
- {% empty %} -

No recent leave requests.

- {% endfor %} -
-
- - -
-
-
Recent Feedback
-
-
- {% for feedback in recent_feedback %} - - {% empty %} -

No recent feedback.

- {% endfor %} -
-
+ {% else %} +
+ No subjects assigned for the current semester.
+ {% endif %}
+
+ +
+
+

+ Class Routine +

+
+ + + + + + + + + + {% if current_semester_routines %} + {% for routine in current_semester_routines %} + + + + + + {% endfor %} + {% elif has_routines %} + + + + {% else %} + + + + {% endif %} + +
TimeSubjectTeacher
{{ routine.start_time|time:"H:i" }} - {{ routine.end_time|time:"H:i" }}{{ routine.subject.name }}{{ routine.teacher.name }}
No routines for current semester (Semester {{ student.current_semester }}).
No routines assigned yet.
+
+ + +
+

+ Attendance Record +

+
+ + + + + + + + + + + {% for record in attendance_records %} + + + + + + + {% empty %} + + + + {% endfor %} + +
DateSubjectTeacherStatus
{{ record.attendance.date|date:"M d, Y" }}{{ record.attendance.routine.name }}{{ record.attendance.teacher.name }} + + {% if record.student_attend %}Present{% else %}Absent{% endif %} + +
No attendance records found.
+
+
+
+
+ +
+
+

+ Leave Management +

+
+
+ +
+
+
+ + + + + + + + + + + {% for leave in student_leaves %} + + + + + + + {% empty %} + + + + {% endfor %} + +
DateMessageStatusCreated At
{{ leave.date|date:"M d, Y" }}{{ leave.message }} + + {{ leave.get_status_display }} + + {{ leave.created_at|date:"M d, Y H:i" }}
No leave requests found.
+
+
+
+ +
+
+

+ Feedback +

+
+ +
+ +
+
+

Teacher Feedback

+ {% for feedback in student.feedbacks.all %} +
+
+
+
{{ feedback.teacher.name }}
+
+ {% for i in "12345"|make_list %} + {% with i_float=forloop.counter|floatformat:0|add:"0" %} + {% if feedback.rating >= i_float %} + + {% elif feedback.rating >= i_float|add:"-0.5" %} + + {% else %} + + {% endif %} + {% endwith %} + {% endfor %} +
+
+ +
+ {{ feedback.created_at|timesince }} ago + {{ feedback.rating }}/5 +
+
+
+ {% empty %} +
+ No feedback given to teachers yet. +
+ {% endfor %} +
+
+

Institute Feedback

+ {% for feedback in student.institute_feedbacks.all %} +
+
+
+
{{ feedback.feedback_type }}
+
+ {% for i in "12345"|make_list %} + {% with i_float=forloop.counter|floatformat:0|add:"0" %} + {% if feedback.rating >= i_float %} + + {% elif feedback.rating >= i_float|add:"-0.5" %} + + {% else %} + + {% endif %} + {% endwith %} + {% endfor %} +
+
+ +
+ {{ feedback.created_at|timesince }} ago + {{ feedback.rating }}/5 +
+
+
+ {% empty %} +
+ No institute feedback given yet. +
+ {% endfor %} +
+
+
+
+ +
+
+

+ Notices +

+
+ {% for notice in notices %} +
+
+ {% if notice.image %} + {{ notice.title }} + {% endif %} +
+
{{ notice.title }}
+

{{ notice.message }}

+
+ {{ notice.created_at|date:"M d, Y" }} + {% if notice.file %} + + Download + + {% endif %} +
+
+
+
+ {% empty %} +
+

No notices available.

+
+ {% endfor %} +
+
+
+ +
+
+

+ Profile Information +

+
+ +
+
+
+ {% if student.image %} + {{ student.name }} + {% else %} + Default User + {% endif %} +
+

{{ student.name }}

+

+ {{ student.id }} + {{ student.email }} + {{ student.phone }} +

+
+ + {{ student.status }} + + {% if student.course %} + {{ student.course.name }} + {% endif %} + Semester {{ student.current_semester }} +
+
+
+
+ + +
+
+
+ + +
+
+
+
Personal Information
+
+
+
+
+ Full Name +

{{ student.name }}

+
+
+ Gender +

{{ student.gender }}

+
+
+ Birth Date +

{{ student.birth_date|date:"M d, Y" }}

+
+
+ Marital Status +

{{ student.marital_status }}

+
+
+ Citizenship No. +

{{ student.citizenship_no|default:"Not provided" }}

+
+
+ Joining Date +

{{ student.joining_date|date:"M d, Y" }}

+
+
+
+
+
+ + +
+
+
+
Contact Information
+
+
+
+
+ Email Address +

{{ student.email }}

+
+
+ Phone Number +

{{ student.phone }}

+
+
+ Parent Name +

{{ student.parent_name|default:"Not provided" }}

+
+
+ Parent Phone +

{{ student.parent_phone|default:"Not provided" }}

+
+
+ Temporary Address +

{{ student.temporary_address|default:"Not provided" }}

+
+
+ Permanent Address +

{{ student.permanent_address|default:"Not provided" }}

+
+
+
+
+
+ + +
+
+
+
Academic Information
+
+
+
+
+ Course +

{{ student.course.name|default:"Not assigned" }}

+
+
+ Current Semester +

{{ student.current_semester }}

+
+
+ Joining Date +

{{ student.joining_date|date:"M d, Y" }}

+
+
+ Batches +

+ {% for batch in student.batches.all %} + {{ batch.name }} + {% empty %} + No batches assigned + {% endfor %} +

+
+
+
+
+
+
+
+
+ + + + + +
- - -{% endblock %} \ No newline at end of file + + // Run on load and resize + adjustLayout(); + window.addEventListener('resize', adjustLayout); + }); + + + + + + +
+ +
+{% endblock %} diff --git a/templates/teacher_attendance.html b/templates/teacher_attendance.html new file mode 100644 index 0000000..848b204 --- /dev/null +++ b/templates/teacher_attendance.html @@ -0,0 +1,254 @@ +{% extends 'base.html' %} +{% load static %} +{% load app_filters %} +{% block extrastyle %} + + + + + +{% endblock %} +{% block content %} +
+ +
+

Manage Attendance

+ + Back to Dashboard + +
+
+ +
+
+
Your Routines
+ {% if routines %} + + {% else %} +
+ You don't have any active routines. +
+ {% endif %} +
+
+ +
+
+ {% if selected_routine %} +
+
+
{{ selected_routine.subject.name }}
+

{{ selected_routine.course.name }} - Semester {{ selected_routine.semester_or_year }}

+
+
+
+ + + +
+
+
+
+ +
+ {% csrf_token %} + + +
+
+ + +
+
+
+ + +
+ +
Student Attendance
+ {% if students %} +
+ + + + + + + + + + + {% for student in students %} + + + + + + + {% endfor %} + +
#NameRoll/IDPresent
{{ forloop.counter }}{{ student.name }}{{ student.roll_no|default:student.id }} +
+ +
+
+
+
+
+ + +
+ +
+ {% else %} +
+ No students found for this course and semester. +
+ {% endif %} +
+ {% else %} +
+ +
Select a routine to manage attendance
+

Choose a class from the list on the left to take attendance.

+
+ {% endif %} +
+
+
+
+{% endblock %} +{% block extrahead %} + + +{% endblock %} diff --git a/templates/teacher_dashboard.html b/templates/teacher_dashboard.html index e449724..b23a32f 100644 --- a/templates/teacher_dashboard.html +++ b/templates/teacher_dashboard.html @@ -1,250 +1,1386 @@ -{% extends 'admin/base_site.html' %} +{% extends 'base.html' %} {% load static %} +{% load tz %} +{% load app_filters %} + +{% block extrastyle %} + + + + + + + + + +{% endblock %} {% block content %}
- -
-
-
-
- {% if teacher.image %} - {{ teacher.name }} - {% endif %} -
-

Welcome, {{ teacher.name }}!

-

{{ teacher.designation }}

-
-
-
+ +
+
+
+
+ {% if teacher.image %} + {{ teacher.name }} + {% else %} + Default User + {% endif %} +
+

Welcome, {{ teacher.name }}!

+

{{ teacher.designation }} ID: {{ teacher.id }}

+
+
+
+
+ + + + + +
+ +
+
+
+
+
Students
+
+
+
+

{{ total_students }}

+

Total Students

+
+
+
+
+

{{ present_students }}

+

Present Today

+
+
+

{{ absent_students }}

+

Absent Today

+
+
+
+
+
+
+ +
+
+
+
Today's Classes
+
+
+
+

{{ today_classes }}

+

Total Classes

+
+
+ {% if today_routines %} +
+ +
+ {% else %} +

No classes scheduled for today

+ {% endif %} +
+
+
+
+ +
+
+
+
Feedback Rating
+
+
+

{{ avg_rating|floatformat:1 }}/5.0

+
+ {% for i in "12345"|make_list %} + {% if forloop.counter <= avg_rating_rounded %} + + {% else %} + + {% endif %} + {% endfor %} +
+

Based on {{ recent_feedback.count }} student feedbacks

+
+
+
+ +
+
+
+
Leave Status
+
+
+
+

Pending

+ {{ pending_leaves }} +
+
+

Approved

+ {{ approved_leaves }} +
+
+

Rejected

+ {{ rejected_leaves }} +
+ +
+
+
- +
- -
-
-
-
-
-
Today's Classes
-
{{ today_classes }}
-
- Completed: {{ completed_classes }} -
-
-
- -
-
-
+
+
+
Today's Classes
+ + {% if today_routines %} + +
+ + + + + + + + + + + + + + {% for routine in today_routines %} + + + + + + + + + + {% endfor %} + +
SubjectCourseSemester/YearTimeAttendanceStatusAction
{{ routine.name }}{{ routine.course_name }}{{ routine.semester_or_year }}{{ routine.start_time|time:"h:i A" }} - {{ routine.end_time|time:"h:i A" }}{{ routine.attendance_count }}/{{ routine.total_students }} + {% if routine.is_completed %} + Completed + {% elif routine.is_ongoing %} + In Progress + {% else %} + Upcoming + {% endif %} + + {% if routine.has_attendance %} + + {% else %} + + {% endif %} +
-
- - -
-
-
-
-
-
Total Students
-
{{ total_students }}
-
- Present Today: {{ present_students }} -
-
-
- -
-
-
-
-
- - -
-
-
-
-
-
Average Rating
-
- {{ avg_rating|floatformat:1 }}/5.0 -
-
-
- {% with ''|center:avg_rating_rounded as range %} - {% for _ in range %} - - {% endfor %} - {% endwith %} - {% with ''|center:remaining_stars as range %} - {% for _ in range %} - - {% endfor %} - {% endwith %} -
-
-
-
- -
-
-
-
-
- - -
-
-
-
-
-
Leave Requests
-
{{ pending_leaves }}
-
- Approved: {{ approved_leaves }} | - Rejected: {{ rejected_leaves }} -
-
-
- -
-
-
+ {% else %} +
+ No classes scheduled for today.
+ {% endif %}
+
- +
- -
-
-
-
Today's Schedule
-
-
- {% if today_routines %} -
- - - - - - - - - - - {% for routine in today_routines %} - - - - - - - {% endfor %} - -
TimeCourseStatusAttendance
{{ routine.start_time|time:"g:i A" }} - {{ routine.end_time|time:"g:i A" }}{{ routine.name }} - {% if routine.is_completed %} - Completed - {% elif routine.is_ongoing %} - Ongoing - {% else %} - Upcoming - {% endif %} - {{ routine.attendance_count }}/{{ routine.total_students }}
-
- {% else %} -

No classes scheduled for today.

- {% endif %} -
-
-
- - -
- -
-
-
Recent Leave Requests
-
-
- {% for leave in recent_leaves %} -
-
- {{ leave.date }} - - {{ leave.get_status_display }} - -
-

{{ leave.message|truncatechars:100 }}

-
-
- {% empty %} -

No recent leave requests.

+ +
+
+
Recent Feedback
+ {% if recent_feedback %} +
+ {% for feedback in recent_feedback %} +
+
+
{{ feedback.student.name }}
+ {{ feedback.created_at|timesince }} ago +
+
+ {% for i in "12345"|make_list %} + {% if forloop.counter <= feedback.rating %} + + {% else %} + + {% endif %} {% endfor %} +
+

{{ feedback.feedback_text }}

+ {% endfor %}
- - -
-
-
Recent Feedback
-
-
- {% for feedback in recent_feedback %} - - {% empty %} -

No recent feedback.

- {% endfor %} -
+ {% else %} +
+ No recent feedback.
+ {% endif %}
+
+ + +
+
+
Recent Notices
+ {% if notices %} +
+ {% for notice in notices %} +
+
+
{{ notice.title }}
+ {{ notice.created_at|timesince }} ago +
+

{{ notice.message }}

+
+ {% endfor %} +
+ {% else %} +
+ No recent notices. +
+ {% endif %} +
+
+
+ + +
+
+
Your Class Schedule
+ + {% if all_routines %} +
+
+ {% for routine in all_routines %} +
+
+
{{ routine.subject.name }}
+ {{ routine.start_time|time:"h:i A" }} - {{ routine.end_time|time:"h:i A" }} +
+

{{ routine.course.name }} - Semester {{ routine.semester_or_year }}

+
+ {% endfor %} +
+
+ {% else %} +
+ No class schedules found. +
+ {% endif %} +
+
+ + +
+
+ +
+
+
Attendance Management
+ +
+ + +
+ {% if recent_attendance %} +
+ + + + + + + + + + + + + {% for attendance in recent_attendance %} + + + + + + + + + {% endfor %} + +
DateSubjectTimeStatusPresent/TotalAction
{{ attendance.date|date:"M d, Y" }}{{ attendance.routine.subject.name }}{{ attendance.routine.start_time|time:"h:i A" }} - {{ attendance.routine.end_time|time:"h:i A" }} + + {{ attendance.class_status }} + + + {{ attendance.present_count|default:"0" }}/{{ attendance.total_count|default:"0" }} + + +
+
+ {% else %} +
+ No recent attendance records found. +
+ {% endif %} +
+
+ + + +
+
+ + +
+
+
Notices & Announcements
+ + {% if notices %} +
+ {% for notice in notices %} +
+
+
{{ notice.title }}
+ {{ notice.created_at|date:"M d, Y" }} +
+

{{ notice.message }}

+ Posted {{ notice.created_at|timesince }} ago +
+ {% endfor %} +
+ {% else %} +
+ No notices available. +
+ {% endif %} +
+
+ + +
+
+ +
+
+
Give Feedback to Institute
+ +
+
+ + +
+
+
Your Recent Feedback
+ + {% if institute_feedback %} +
+ {% for feedback in institute_feedback %} +
+
+
{{ feedback.get_feedback_type_display }}
+ {{ feedback.created_at|timesince }} ago +
+
+ {% for i in "12345"|make_list %} + {% if forloop.counter <= feedback.rating %} + + {% else %} + + {% endif %} + {% endfor %} +
+

{{ feedback.feedback_text }}

+ + {% if feedback.is_anonymous %} + Anonymous + {% else %} + Public + {% endif %} + +
+ {% endfor %} +
+ {% else %} +
+ You haven't submitted any feedback yet. +
+ {% endif %} +
+
+
+
+ + +
+
+

+ Profile Information +

+
+ +
+
+
+ {% if teacher.image %} + {{ teacher.name }} + {% else %} + Default User + {% endif %} +
+

{{ teacher.name }}

+

+ {{ teacher.id }} + {{ teacher.email }} + {{ teacher.phone }} +

+
+ + {{ teacher.is_active|yesno:"Active,Inactive" }} + + {{ teacher.designation }} +
+
+
+
+ + +
+
+
+ + +
+
+
+
Personal Information
+
+
+
+
+ Full Name +

{{ teacher.name }}

+
+
+ Gender +

{{ teacher.gender|default:"Not provided" }}

+
+
+ Birth Date +

{{ teacher.birth_date|date:"M d, Y"|default:"Not provided" }}

+
+
+ Marital Status +

{{ teacher.marital_status|default:"Not provided" }}

+
+
+ Citizenship No. +

{{ teacher.citizenship_no|default:"Not provided" }}

+
+
+ Passport +

{{ teacher.passport|default:"Not provided" }}

+
+
+
+
+
+ + +
+
+
+
Contact Information
+
+
+
+
+ Email Address +

{{ teacher.email|default:"Not provided" }}

+
+
+ Phone Number +

{{ teacher.phone|default:"Not provided" }}

+
+
+ Parent Name +

{{ teacher.parent_name|default:"Not provided" }}

+
+
+ Parent Phone +

{{ teacher.parent_phone|default:"Not provided" }}

+
+
+ Temporary Address +

{{ teacher.temporary_address|default:"Not provided" }}

+
+
+ Permanent Address +

{{ teacher.permanent_address|default:"Not provided" }}

+
+
+
+
+
+ + +
+
+
+
Employment Information
+
+
+
+
+ Employee ID +

{{ teacher.id }}

+
+
+ Designation +

{{ teacher.designation|default:"Not provided" }}

+
+
+ Joining Date +

{{ teacher.joining_date|date:"M d, Y"|default:"Not provided" }}

+
+
+ Status +

+ + {{ teacher.is_active|yesno:"Active,Inactive" }} + +

+
+
+ Permissions +

+ {% for group in teacher.groups.all %} + {{ group.name }} + {% empty %} + No specific permissions + {% endfor %} +

+
+
+
+
+
+ + +
+
+
+
Qualifications
+
+
+
+
+ Educational Background + {% if teacher.education_set.all %} + {% for education in teacher.education_set.all %} +
+

{{ education.degree }}, {{ education.institution }} ({{ education.year }})

+ {{ education.specialization }} +
+ {% endfor %} + {% else %} +

No educational qualifications recorded

+ {% endif %} + + {% if teacher.qualification %} +
+ Additional Qualifications +

{{ teacher.qualification }}

+
+ {% endif %} +
+ + {% if teacher.skills %} +
+ Skills & Specialization +

{{ teacher.specialization|default:"No specialization information available" }}

+ +
+ {% for skill in teacher.skills %} + {{ skill.strip }} + {% endfor %} +
+
+ {% endif %} +
+
+
+
+
+
+
+ + +
+
+

+ Leave Management +

+
+
+ +
+
+ +
+
+
+
+ +

{{ pending_leaves }}

+

Pending Requests

+
+
+
+
+
+
+ +

{{ approved_leaves }}

+

Approved Requests

+
+
+
+
+
+
+ +

{{ rejected_leaves }}

+

Rejected Requests

+
+
+
+
+ +
+
Leave History
+
+ + + + + + + + + + + {% if recent_leaves %} + {% for leave in recent_leaves %} + + + + + + + {% endfor %} + {% else %} + + + + {% endif %} + +
DateReasonStatusApplied On
{{ leave.date|date:"M d, Y" }}{{ leave.message }} + + {{ leave.get_status_display }} + + {{ leave.created_at|date:"M d, Y" }}
No leave history available
+
+
+
+
- - -{% endblock %} \ No newline at end of file + }); + +{% endblock %}