Files
2025-04-03 16:30:28 +05:45

1049 lines
40 KiB
HTML

{% extends "admin/base_site.html" %}
{% load static %}
{% load app_filters %}
{% block extrahead %}
{{ block.super }}
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=5.0, user-scalable=yes">
{% endblock %}
{% block extrastyle %}
{{ block.super }}
<!-- Bootstrap CSS -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<!-- Font Awesome -->
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" rel="stylesheet" />
<style>
:root {
--primary: #2196F3;
--primary-light: #BBDEFB;
--primary-dark: #1976D2;
--secondary: #607D8B;
--success: #4CAF50;
--info: #00BCD4;
--warning: #FFC107;
--danger: #F44336;
--light: #FAFAFA;
--dark: #212121;
--gray: #9E9E9E;
}
body {
background-color: var(--light);
color: var(--dark);
}
.content-card {
background: white;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
padding: 24px;
margin-bottom: 24px;
transition: box-shadow 0.3s ease;
}
.content-card:hover {
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15);
}
.welcome-section {
background: linear-gradient(135deg, var(--primary) 0%, var(--primary-dark) 100%);
color: white;
padding: 32px;
border-radius: 8px;
margin-bottom: 32px;
}
.summary-card {
background: white;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
transition: transform 0.3s ease, box-shadow 0.3s ease;
}
.summary-card:hover {
transform: translateY(-4px);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}
.summary-card .card-header {
background: none;
border-bottom: 1px solid rgba(0, 0, 0, 0.05);
padding: 16px;
}
.summary-card .card-body {
padding: 24px;
}
.stat-number {
font-size: 2.5rem;
font-weight: 700;
color: var(--primary);
}
.stat-label {
color: var(--secondary);
font-size: 0.9rem;
}
.status-badge {
padding: 6px 12px;
border-radius: 16px;
font-size: 0.8rem;
font-weight: 500;
}
.completed {
background: #E8F5E9;
color: #2E7D32;
}
.ongoing {
background: #FFF3E0;
color: #E65100;
}
.upcoming {
background: #E3F2FD;
color: #1565C0;
}
.leave-pending {
background: #FFF8E1;
color: #F57F17;
}
.leave-approved {
background: #E8F5E9;
color: #2E7D32;
}
.leave-rejected {
background: #FFEBEE;
color: #C62828;
}
.btn-primary {
background-color: var(--primary);
border-color: var(--primary);
}
.btn-success {
background-color: var(--success);
border-color: var(--success);
}
.btn-info {
background-color: var(--info);
border-color: var(--info);
}
.btn-warning {
background-color: var(--warning);
border-color: var(--warning);
}
.btn-danger {
background-color: var(--danger);
border-color: var(--danger);
}
.progress {
height: 8px;
background-color: #f0f0f0;
border-radius: 4px;
overflow: hidden;
margin-bottom: 5px;
}
.progress-bar {
border-radius: 4px;
}
.table th {
color: var(--secondary);
font-weight: 600;
border-bottom-width: 1px;
}
.table td {
vertical-align: middle;
}
/* Teacher Ratings Section */
.teacher-rating-card {
background: white;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
padding: 20px;
margin-bottom: 20px;
transition: transform 0.3s ease;
}
.teacher-rating-card:hover {
transform: translateY(-4px);
}
/* Monthly Statistics Section */
.stat-box {
background: white;
border-radius: 8px;
padding: 24px;
text-align: center;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
transition: transform 0.3s ease;
}
.stat-box:hover {
transform: translateY(-4px);
}
.stat-box i {
font-size: 2.5rem;
margin-bottom: 16px;
}
/* Institute Feedback Section */
.feedback-card {
background: white;
border-radius: 8px;
padding: 20px;
margin-bottom: 20px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
.rating-stars i {
color: var(--warning);
margin-right: 2px;
}
/* Activity Scroll */
.activity-scroll {
max-height: 250px;
overflow-y: auto;
padding-right: 5px;
scrollbar-width: thin;
}
/* Responsive Design */
@media (max-width: 1200px) {
.welcome-section {
padding: 28px;
}
.content-card {
padding: 20px;
}
.stat-number {
font-size: 2.2rem;
}
}
@media (max-width: 992px) {
.welcome-section {
padding: 24px;
}
.content-card {
padding: 16px;
}
.stat-box {
padding: 20px;
}
.stat-box i {
font-size: 2rem;
}
}
@media (max-width: 768px) {
.welcome-section {
padding: 20px;
margin-bottom: 24px;
}
.welcome-section h2 {
font-size: 1.5rem;
}
.summary-card .card-body {
padding: 16px;
}
.stat-number {
font-size: 2rem;
}
.content-card {
padding: 16px;
}
.teacher-rating-card,
.feedback-card {
padding: 16px;
}
.activity-scroll {
max-height: 200px;
}
}
@media (max-width: 576px) {
.welcome-section {
padding: 16px;
margin-bottom: 20px;
}
.welcome-section h2 {
font-size: 1.3rem;
}
.welcome-section p {
font-size: 0.9rem;
}
.content-card {
padding: 12px;
}
.stat-number {
font-size: 1.8rem;
}
.stat-box {
padding: 16px;
}
.stat-box i {
font-size: 1.8rem;
}
.teacher-rating-card,
.feedback-card {
padding: 12px;
}
.activity-scroll {
max-height: 180px;
}
.table-responsive {
margin: 0 -12px;
}
}
@media (max-width: 375px) {
.welcome-section {
padding: 12px;
}
.welcome-section h2 {
font-size: 1.2rem;
}
.welcome-section p {
font-size: 0.8rem;
}
.content-card {
padding: 10px;
}
.stat-number {
font-size: 1.6rem;
}
.stat-box {
padding: 12px;
}
.stat-box i {
font-size: 1.6rem;
}
.teacher-rating-card,
.feedback-card {
padding: 10px;
}
.activity-scroll {
max-height: 160px;
}
.status-badge {
padding: 4px 8px;
font-size: 0.7rem;
}
}
/* Touch Device Optimizations */
@media (hover: none) {
.summary-card:hover,
.teacher-rating-card:hover,
.stat-box:hover {
transform: none;
}
.btn, .nav-link {
padding: 0.75rem 1rem;
}
}
/* High Contrast Mode Support */
@media (prefers-contrast: high) {
.summary-card,
.teacher-rating-card,
.stat-box,
.feedback-card {
border: 2px solid currentColor;
}
}
/* Reduced Motion Support */
@media (prefers-reduced-motion: reduce) {
.summary-card,
.teacher-rating-card,
.stat-box {
transition: none;
}
}
</style>
{% endblock %}
{% block content %}
<div class="container-fluid py-4">
<!-- Welcome Section -->
<div class="row mb-4">
<div class="col-12">
<div class="content-card welcome-section">
<div class="d-flex justify-content-between align-items-center flex-wrap">
<div class="flex-grow-1">
<h2 class="mb-1">Welcome, Admin!</h2>
<p class="mb-0">Student Management Dashboard</p>
</div>
<!-- Logout Button -->
<a href="{% url 'logout' %}" class="logout-btn">
<i class="fas fa-sign-out-alt"></i> <span class="logout-text">Logout</span>
</a>
</div>
</div>
</div>
</div>
<!-- Quick Stats Row -->
<div class="row mb-4">
<!-- Student Stats -->
<div class="col-xl-3 col-md-6 mb-3">
<div class="summary-card h-100">
<div class="card-header">
<h5 class="card-title mb-0 small"><i class="fas fa-users text-primary me-2"></i>Students</h5>
</div>
<div class="card-body p-2">
<div class="d-flex justify-content-between align-items-center">
<div>
<span class="d-block text-muted small">Total Students</span>
<h3>{{ total_students }}</h3>
</div>
</div>
<div class="mt-3">
<div class="d-flex justify-content-between mb-2">
<small class="mb-0">Active</small>
<span class="badge bg-success p-2">{{ active_students }}</span>
</div>
<div class="d-flex justify-content-between mb-2">
<small class="mb-0">Completed</small>
<span class="badge bg-info p-2">{{ completed_students }}</span>
</div>
<div class="d-flex justify-content-between">
<small class="mb-0">On Leave</small>
<span class="badge bg-warning p-2">{{ on_leave_students }}</span>
</div>
</div>
</div>
</div>
</div>
<!-- Course Stats -->
<div class="col-xl-3 col-md-6 mb-3">
<div class="summary-card h-100">
<div class="card-header">
<h5 class="card-title mb-0 small"><i class="fas fa-book text-success me-2"></i>Courses</h5>
</div>
<div class="card-body p-2">
<div class="d-flex justify-content-between align-items-center">
<div>
<span class="d-block text-muted small">Total Courses</span>
<h3>{{ total_courses }}</h3>
</div>
</div>
<div class="mt-3">
<div class="d-flex justify-content-between mb-2">
<small class="mb-0">Active</small>
<span class="badge bg-success p-2">{{ active_courses }}</span>
</div>
<div class="d-flex justify-content-between">
<small class="mb-0">Completed</small>
<span class="badge bg-info p-2">{{ completed_courses }}</span>
</div>
</div>
</div>
</div>
</div>
<!-- Staff Stats -->
<div class="col-xl-3 col-md-6 mb-3">
<div class="summary-card h-100">
<div class="card-header">
<h5 class="card-title mb-0 small"><i class="fas fa-chalkboard-teacher text-info me-2"></i>Staff</h5>
</div>
<div class="card-body p-2">
<div class="d-flex justify-content-between align-items-center">
<div>
<span class="d-block text-muted small">Total Staff</span>
<h3>{{ total_staff }}</h3>
</div>
</div>
<div class="mt-3">
<div class="d-flex justify-content-between mb-2">
<small class="mb-0">Active</small>
<span class="badge bg-success p-2">{{ active_staff }}</span>
</div>
<div class="d-flex justify-content-between">
<small class="mb-0">On Leave</small>
<span class="badge bg-warning p-2">{{ staff_on_leave }}</span>
</div>
</div>
</div>
</div>
</div>
<!-- Attendance Stats -->
<div class="col-xl-3 col-md-6 mb-3">
<div class="summary-card h-100">
<div class="card-header">
<h5 class="card-title mb-0 small"><i class="fas fa-calendar-check text-warning me-2"></i>Attendance</h5>
</div>
<div class="card-body p-2">
<div class="d-flex justify-content-between align-items-center">
<div>
<span class="d-block text-muted small">Classes Today</span>
<h3>{{ total_classes_today }}</h3>
</div>
<div class="text-end">
<span class="d-block text-muted small">Attendance Rate</span>
<h3 class="text-primary">{{ attendance_rate }}%</h3>
</div>
</div>
<div class="d-flex justify-content-between mb-1 mt-3">
<div><small>0%</small></div>
<div><small>100%</small></div>
</div>
<div class="progress mb-2">
<div class="progress-bar {% if attendance_rate < 75 %}bg-danger{% else %}bg-success{% endif %}"
role="progressbar"
style="width: {{ attendance_rate }}%"
aria-valuenow="{{ attendance_rate }}"
aria-valuemin="0"
aria-valuemax="100"></div>
</div>
<div class="d-flex justify-content-between mb-2">
<small class="mb-0">Students Present</small>
<span class="badge bg-success p-2">{{ students_present }}/{{ total_students_today }}</span>
</div>
</div>
</div>
</div>
</div>
<!-- Quick Actions -->
<div class="row mb-4">
<div class="col-12">
<div class="content-card">
<h5 class="mb-3">
<i class="fas fa-bolt text-warning me-2"></i>Quick Actions
</h5>
<div class="row g-3">
<div class="col-md-3">
<a href="/admin/app/student/add/" class="btn btn-primary w-100 py-3">
<i class="fas fa-user-plus mb-2 d-block"></i>
Add New Student
</a>
</div>
<div class="col-md-3">
<a href="/admin/app/staff/add/" class="btn btn-success w-100 py-3">
<i class="fas fa-user-tie mb-2 d-block"></i>
Add New Staff
</a>
</div>
<div class="col-md-3">
<a href="/admin/app/course/add/" class="btn btn-info w-100 py-3">
<i class="fas fa-book mb-2 d-block"></i>
Add New Course
</a>
</div>
<div class="col-md-3">
<a href="/admin/app/batch/add/" class="btn btn-warning w-100 py-3">
<i class="fas fa-users mb-2 d-block"></i>
Add New Batch
</a>
</div>
</div>
</div>
</div>
</div>
<!-- Recent Activity and Course Progress -->
<div class="row">
<!-- Course Progress -->
<div class="col-xl-8 mb-4">
<div class="content-card">
<h5 class="mb-3">
<i class="fas fa-graduation-cap text-primary me-2"></i>Course Progress
</h5>
<div class="table-responsive">
<table class="table">
<thead>
<tr>
<th>Course</th>
<th>Students</th>
<th>Progress</th>
<th>Status</th>
</tr>
</thead>
<tbody>
{% for progress in course_progress %}
<tr>
<td>{{ progress.course.name }}</td>
<td>{{ progress.total_students }}</td>
<td>
<div class="progress position-relative" style="height: 8px;">
<div class="progress-bar {% if progress.average_progress < 50 %}bg-warning{% elif progress.average_progress < 75 %}bg-info{% else %}bg-success{% endif %}"
role="progressbar"
style="width: {{ progress.average_progress }}%"
aria-valuenow="{{ progress.average_progress }}"
aria-valuemin="0"
aria-valuemax="100">
</div>
</div>
<small class="text-muted">{{ progress.average_progress }}%</small>
</td>
<td>
<span
class="status-badge {% if progress.average_progress == 100 %}completed{% elif progress.average_progress > 0 %}ongoing{% else %}upcoming{% endif %}">
{% if progress.average_progress == 100 %}
Completed
{% elif progress.average_progress > 0 %}
In Progress
{% else %}
Not Started
{% endif %}
</span>
</td>
</tr>
{% empty %}
<tr>
<td colspan="4" class="text-center py-3">No course progress data available</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
<!-- Recent Activity -->
<div class="col-xl-4 mb-4">
<div class="content-card">
<h5 class="mb-3">
<i class="fas fa-history text-success me-2"></i>Recent Activity
</h5>
<div class="activity-scroll">
{% for activity in recent_activities %}
<div class="d-flex align-items-center mb-2 pb-2 border-bottom">
<i class="fas fa-circle-dot text-primary me-2"></i>
<div>
<small class="mb-0 d-block fw-medium">{{ activity.title }}</small>
<small class="text-muted">{{ activity.description|truncatechars:50 }}</small>
<small class="d-block text-muted">{{ activity.timestamp|timesince }} ago</small>
</div>
</div>
{% empty %}
<div class="text-center">
<small class="text-muted">No recent activity</small>
</div>
{% endfor %}
</div>
</div>
</div>
</div>
<!-- Pending Leave Requests -->
<div class="row mb-4">
<div class="col-12">
<div class="content-card">
<h5 class="mb-3">
<i class="fas fa-calendar-alt text-warning me-2"></i>Pending Leave Requests
</h5>
<div class="table-responsive">
<table class="table">
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Start Date</th>
<th>End Date</th>
<th>Reason</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
{% for leave in pending_student_leaves %}
<tr>
<td>{{ leave.student.name }}</td>
<td>
<span class="badge bg-info">Student</span>
</td>
<td>{{ leave.start_date|date:"M d, Y" }}</td>
<td>{{ leave.end_date|date:"M d, Y" }}</td>
<td>{{ leave.message }}</td>
<td>
<form method="post" action="{% url 'approve_student_leave' leave.id %}"
class="d-inline">
{% csrf_token %}
<button type="submit" class="btn btn-sm btn-success me-1">
<i class="fas fa-check"></i>
</button>
</form>
<form method="post" action="{% url 'reject_student_leave' leave.id %}" class="d-inline">
{% csrf_token %}
<button type="submit" class="btn btn-sm btn-danger">
<i class="fas fa-times"></i>
</button>
</form>
</td>
</tr>
{% endfor %}
{% for leave in pending_staff_leaves %}
<tr>
<td>{{ leave.staff.name }}</td>
<td>
<span class="badge bg-primary">Staff</span>
</td>
<td>{{ leave.start_date|date:"M d, Y" }}</td>
<td>{{ leave.end_date|date:"M d, Y" }}</td>
<td>{{ leave.message }}</td>
<td>
<form method="post" action="{% url 'approve_staff_leave' leave.id %}" class="d-inline">
{% csrf_token %}
<button type="submit" class="btn btn-sm btn-success me-1">
<i class="fas fa-check"></i>
</button>
</form>
<form method="post" action="{% url 'reject_staff_leave' leave.id %}" class="d-inline">
{% csrf_token %}
<button type="submit" class="btn btn-sm btn-danger">
<i class="fas fa-times"></i>
</button>
</form>
</td>
</tr>
{% endfor %}
{% if not pending_student_leaves and not pending_staff_leaves %}
<tr>
<td colspan="6" class="text-center py-3">No pending leave requests</td>
</tr>
{% endif %}
</tbody>
</table>
</div>
</div>
</div>
</div>
<!-- Notice Board -->
<div class="row mb-4">
<div class="col-12">
<div class="content-card">
<h5 class="mb-3">
<i class="fas fa-bullhorn text-primary me-2"></i>Notice Board
</h5>
<form method="post" action="{% url 'add_notice' %}" class="mb-4" enctype="multipart/form-data">
{% csrf_token %}
<div class="row g-3">
<div class="col-md-4">
<input type="text" class="form-control" name="title" placeholder="Notice Title" required>
</div>
<div class="col-md-4">
<input type="text" class="form-control" name="message" placeholder="Notice Message" required>
</div>
<div class="col-md-2">
<input type="file" class="form-control" name="image" accept="image/*">
</div>
<div class="col-md-2">
<button type="submit" class="btn btn-primary w-100">
<i class="fas fa-plus me-2"></i>Add Notice
</button>
</div>
</div>
</form>
<div class="notices-list activity-scroll" style="max-height: 400px; overflow-y: auto;">
{% for notice in notices %}
<div class="card mb-3 border-0 shadow-sm">
<div class="card-body">
<div class="d-flex justify-content-between align-items-center mb-2">
<h6 class="mb-0">{{ notice.title }}</h6>
<div>
<small class="text-muted me-2">{{ notice.created_at|date:"M d, Y" }}</small>
<button class="btn btn-sm btn-outline-danger" onclick="deleteNotice({{ notice.id }})">
<i class="fas fa-trash"></i>
</button>
</div>
</div>
{% if notice.image %}
<img src="{{ notice.image.url }}" alt="Notice Image" class="img-fluid rounded mb-2"
style="max-height: 200px;">
{% endif %}
<p class="mb-0">{{ notice.message }}</p>
</div>
</div>
{% empty %}
<p class="text-center text-muted">No notices available</p>
{% endfor %}
</div>
</div>
</div>
</div>
<!-- Teacher Ratings Section -->
<div class="row mb-4">
<div class="col-12">
<div class="content-card">
<h5 class="mb-3">
<i class="fas fa-star text-warning me-2"></i>Teacher Ratings
</h5>
<div class="row">
{% for teacher in teacher_ratings %}
<div class="col-md-4 mb-4">
<div class="teacher-rating-card">
<div class="d-flex align-items-center mb-3">
{% if teacher.image %}
<img src="{{ teacher.image.url }}" alt="{{ teacher.name }}" class="rounded-circle me-3"
style="width: 60px; height: 60px; object-fit: cover;">
{% else %}
<div class="rounded-circle bg-light d-flex align-items-center justify-content-center me-3"
style="width: 60px; height: 60px;">
<i class="fas fa-user text-secondary"></i>
</div>
{% endif %}
<div>
<h6 class="mb-1">{{ teacher.name }}</h6>
<small class="text-muted">{{ teacher.designation }}</small>
</div>
</div>
<div class="rating-info mb-3">
<div class="d-flex justify-content-between align-items-center mb-2">
<span class="text-muted">Average Rating</span>
<span class="fw-bold">{{ teacher.avg_rating|floatformat:1 }}/5.0</span>
</div>
<div class="rating-stars mb-2">
{% for i in "12345"|make_list %}
<i
class="{% if forloop.counter <= teacher.avg_rating %}fas{% else %}far{% endif %} fa-star"></i>
{% endfor %}
</div>
<div class="progress position-relative">
<div class="progress-bar bg-warning" role="progressbar"
style="width: {{ teacher.avg_rating|multiply:20 }}%"
aria-valuenow="{{ teacher.avg_rating }}" aria-valuemin="0" aria-valuemax="5">
</div>
</div>
</div>
<div class="rating-stats">
<div class="d-flex justify-content-between mb-2">
<small class="text-muted">Total Reviews</small>
<small>{{ teacher.total_reviews }}</small>
</div>
<div class="d-flex justify-content-between">
<small class="text-muted">Students Taught</small>
<small>{{ teacher.total_students }}</small>
</div>
</div>
</div>
</div>
{% empty %}
<div class="col-12">
<p class="text-center text-muted">No teacher ratings available</p>
</div>
{% endfor %}
</div>
</div>
</div>
</div>
<!-- Monthly Statistics -->
<div class="row mb-4">
<div class="col-12">
<div class="content-card">
<h5 class="mb-3">
<i class="fas fa-chart-bar text-info me-2"></i>Monthly Statistics
</h5>
<div class="row">
<div class="col-md-3 mb-3">
<div class="stat-box">
<i class="fas fa-user-plus text-primary"></i>
<h3 class="mb-2">{{ monthly_stats.new_students }}</h3>
<p class="text-muted mb-0">New Students</p>
</div>
</div>
<div class="col-md-3 mb-3">
<div class="stat-box">
<i class="fas fa-user-tie text-success"></i>
<h3 class="mb-2">{{ monthly_stats.new_staff }}</h3>
<p class="text-muted mb-0">New Staff</p>
</div>
</div>
<div class="col-md-3 mb-3">
<div class="stat-box">
<i class="fas fa-calendar-check text-warning"></i>
<h3 class="mb-2">{{ monthly_stats.attendance_rate }}%</h3>
<p class="text-muted mb-0">Attendance Rate</p>
</div>
</div>
<div class="col-md-3 mb-3">
<div class="stat-box">
<i class="fas fa-calendar-alt text-danger"></i>
<h3 class="mb-2">{{ monthly_stats.leave_requests }}</h3>
<p class="text-muted mb-0">Leave Requests</p>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Institute Feedback -->
<div class="row mb-4">
<div class="col-12">
<div class="content-card">
<h5 class="mb-3">
<i class="fas fa-comments text-primary me-2"></i>Institute Feedback
</h5>
<div class="feedback-table-container" style="max-height: 420px; overflow-y: auto;">
<table class="table">
<thead class="sticky-top bg-white">
<tr>
<th>S.N</th>
<th>User</th>
<th>Category</th>
<th>Rating</th>
<th>Feedback</th>
<th>Date</th>
</tr>
</thead>
<tbody>
{% for feedback in recent_institute_feedback %}
<tr>
<td>{{ forloop.counter }}</td>
<td>
<div class="d-flex align-items-center">
{% if feedback.is_anonymous %}
<div class="student-avatar me-2">
<i class="fas fa-user-secret"></i>
</div>
<div>
<span class="d-block fw-medium">Anonymous User</span>
</div>
{% else %}
{% if feedback.user %}
<!-- This is a student feedback -->
{% if feedback.user.image %}
<img src="{{ feedback.user.image.url }}" alt="{{ feedback.display_name }}" class="profile-image-small rounded-circle me-2"
style="width: 40px; height: 40px;">
{% else %}
<div class="student-avatar me-2">
<i class="fas fa-user"></i>
</div>
{% endif %}
<div>
<span class="d-block fw-medium">{{ feedback.display_name }}</span>
<div class="d-flex flex-wrap gap-1 mt-1">
<span class="status-badge bg-info">Student</span>
{% if feedback.user.course %}
<span class="status-badge" style="background-color: var(--secondary);">
{{ feedback.user.course.name }}
</span>
{% endif %}
{% if feedback.user.current_semester %}
<span class="status-badge upcoming">
Semester {{ feedback.user.current_semester }}
</span>
{% endif %}
</div>
</div>
{% elif feedback.staff %}
<!-- This is a staff feedback -->
{% if feedback.staff.image %}
<img src="{{ feedback.staff.image.url }}" alt="{{ feedback.display_name }}" class="profile-image-small rounded-circle me-2"
style="width: 40px; height: 40px;">
{% else %}
<div class="student-avatar me-2">
<i class="fas fa-user-tie"></i>
</div>
{% endif %}
<div>
<span class="d-block fw-medium">{{ feedback.display_name }}</span>
<div class="d-flex flex-wrap gap-1 mt-1">
<span class="status-badge bg-primary">Staff</span>
{% if feedback.staff.designation %}
<span class="status-badge" style="background-color: var(--secondary);">
{{ feedback.staff.designation }}
</span>
{% endif %}
</div>
</div>
{% else %}
<!-- Fallback for any other feedback type -->
<div class="student-avatar me-2">
<i class="fas fa-user"></i>
</div>
<div>
<span class="d-block fw-medium">{{ feedback.display_name }}</span>
</div>
{% endif %}
{% endif %}
</div>
</td>
<td>{{ feedback.feedback_type }}</td>
<td>
<div class="rating-stars">
{% for i in "12345"|make_list %}
<i class="{% if forloop.counter <= feedback.rating %}fas{% else %}far{% endif %} fa-star"></i>
{% endfor %}
</div>
</td>
<td>
<div class="feedback-message p-2">
{{ feedback.feedback_text|truncatechars:100 }}
</div>
</td>
<td>{{ feedback.created_at|date:"M d, Y" }}</td>
</tr>
{% empty %}
<tr>
<td colspan="6" class="text-center py-3">
<div class="empty-state">
<i class="fas fa-comments fa-2x mb-2"></i>
<p>No institute feedback available</p>
</div>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
{% block extrajs %}
{{ block.super }}
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
<script>
function deleteNotice(noticeId) {
if (confirm('Are you sure you want to delete this notice?')) {
fetch(`/app/delete-notice/${noticeId}/`, {
method: 'POST',
headers: {
'X-CSRFToken': document.querySelector('[name=csrfmiddlewaretoken]').value,
'Content-Type': 'application/json',
},
})
.then(response => response.json())
.then(data => {
if (data.success) {
location.reload();
} else {
alert('Failed to delete notice');
}
})
.catch(error => {
console.error('Error:', error);
alert('An error occurred while deleting the notice');
});
}
}
</script>
{% endblock %}