Spaces:
No application file
No application file
| {% extends "base.html" %} | |
| {% block content %} | |
| <div style="margin-bottom: 2rem;"> | |
| <a href="{{ url_for('students') }}" style="color: #2563eb; text-decoration: none;">← Back to Students</a> | |
| </div> | |
| <div class="card" style="margin-bottom: 2rem;"> | |
| <h2 style="margin-bottom: 1.5rem;">π¨βπ Student Details</h2> | |
| <div style="display: grid; grid-template-columns: repeat(2, 1fr); gap: 1rem;"> | |
| <div> | |
| <strong>Student ID:</strong> {{ student.id }} | |
| </div> | |
| <div> | |
| <strong>Name:</strong> {{ student.name }} | |
| </div> | |
| <div> | |
| <strong>Email:</strong> {{ student.email }} | |
| </div> | |
| <div> | |
| <strong>Department:</strong> {{ student.department or 'N/A' }} | |
| </div> | |
| <div> | |
| <strong>Contact:</strong> {{ student.contact or 'N/A' }} | |
| </div> | |
| </div> | |
| </div> | |
| <div style="display: grid; grid-template-columns: repeat(4, 1fr); gap: 1rem; margin-bottom: 2rem;"> | |
| <a href="#all-section" style="text-decoration: none;"> | |
| <div class="card" style="text-align: center; padding: 1.5rem; cursor: pointer; transition: transform 0.2s;" | |
| onmouseover="this.style.transform='scale(1.05)'" onmouseout="this.style.transform='scale(1)'"> | |
| <div style="font-size: 2rem; font-weight: bold; color: #2563eb;">{{ issues_with_books|length }}</div> | |
| <div style="color: #6b7280;">Total Issues</div> | |
| <small style="color: #9ca3af; font-size: 0.8rem;">Click to view all</small> | |
| </div> | |
| </a> | |
| <a href="#active-section" style="text-decoration: none;"> | |
| <div class="card" style="text-align: center; padding: 1.5rem; cursor: pointer; transition: transform 0.2s;" | |
| onmouseover="this.style.transform='scale(1.05)'" onmouseout="this.style.transform='scale(1)'"> | |
| <div style="font-size: 2rem; font-weight: bold; color: #f59e0b;">{{ active_count }}</div> | |
| <div style="color: #6b7280;">Active Books</div> | |
| <small style="color: #9ca3af; font-size: 0.8rem;">Click to view</small> | |
| </div> | |
| </a> | |
| <a href="#returned-section" style="text-decoration: none;"> | |
| <div class="card" style="text-align: center; padding: 1.5rem; cursor: pointer; transition: transform 0.2s;" | |
| onmouseover="this.style.transform='scale(1.05)'" onmouseout="this.style.transform='scale(1)'"> | |
| <div style="font-size: 2rem; font-weight: bold; color: #10b981;">{{ returned_count }}</div> | |
| <div style="color: #6b7280;">Returned</div> | |
| <small style="color: #9ca3af; font-size: 0.8rem;">Click to view</small> | |
| </div> | |
| </a> | |
| <div class="card" style="text-align: center; padding: 1.5rem;"> | |
| <div style="font-size: 2rem; font-weight: bold; color: #ef4444;">{{ overdue_count }}</div> | |
| <div style="color: #6b7280;">Currently Overdue</div> | |
| <small style="color: #ef4444; font-weight: 600; font-size: 0.9rem; margin-top: 0.5rem; display: block;"> | |
| Total overdue times: {{ total_overdue_times }} | |
| </small> | |
| </div> | |
| </div> | |
| <div class="card" id="all-section" style="margin-bottom: 2rem;"> | |
| <h3 style="margin-bottom: 1rem;">π All Issue History</h3> | |
| {% if issues_with_books %} | |
| <table> | |
| <tr> | |
| <th>Book</th> | |
| <th>Issue Date</th> | |
| <th>Due Date</th> | |
| <th>Return Date</th> | |
| <th>Status</th> | |
| </tr> | |
| {% for item in issues_with_books %} | |
| {% set issue = item.issue %} | |
| {% set book = item.book %} | |
| {% set is_overdue = issue.is_overdue() %} | |
| {% set was_overdue = issue.status == 'returned' and issue.days_overdue() > 0 %} | |
| <tr> | |
| <td> | |
| <strong>{{ book.title if book else 'Unknown' }}</strong><br> | |
| <small style="color: #6b7280;">ID: {{ issue.book_id }}</small> | |
| </td> | |
| <td>{{ issue.issue_date.strftime('%Y-%m-%d %H:%M') }}</td> | |
| <td>{{ issue.due_date.strftime('%Y-%m-%d') }}</td> | |
| <td> | |
| {% if issue.return_date %} | |
| {{ issue.return_date.strftime('%Y-%m-%d %H:%M') }} | |
| {% else %} | |
| <span style="color: #9ca3af;">Not returned</span> | |
| {% endif %} | |
| </td> | |
| <td> | |
| {% if issue.status == 'returned' %} | |
| {% if was_overdue %} | |
| <span style="background: #fee2e2; color: #991b1b; padding: 0.25rem 0.75rem; border-radius: 12px; font-size: 0.875rem;"> | |
| β Returned Late ({{ issue.days_overdue() }} days) | |
| </span> | |
| {% else %} | |
| <span style="background: #d1fae5; color: #065f46; padding: 0.25rem 0.75rem; border-radius: 12px; font-size: 0.875rem;"> | |
| β Returned On Time | |
| </span> | |
| {% endif %} | |
| {% elif is_overdue %} | |
| <span style="background: #fee2e2; color: #991b1b; padding: 0.25rem 0.75rem; border-radius: 12px; font-size: 0.875rem; font-weight: bold;"> | |
| β OVERDUE ({{ issue.days_overdue() }} days) | |
| </span> | |
| {% else %} | |
| <span style="background: #fef3c7; color: #92400e; padding: 0.25rem 0.75rem; border-radius: 12px; font-size: 0.875rem;"> | |
| π Active | |
| </span> | |
| {% endif %} | |
| </td> | |
| </tr> | |
| {% endfor %} | |
| </table> | |
| {% else %} | |
| <p style="text-align: center; color: #9ca3af; padding: 2rem;">No issue history found</p> | |
| {% endif %} | |
| </div> | |
| <div class="card" id="active-section" style="margin-bottom: 2rem;"> | |
| <h3 style="margin-bottom: 1rem;">π Active Books</h3> | |
| {% set active_books = issues_with_books|selectattr('issue.status', 'equalto', 'issued')|list %} | |
| {% if active_books %} | |
| <table> | |
| <tr> | |
| <th>Book</th> | |
| <th>Issue Date</th> | |
| <th>Due Date</th> | |
| <th>Status</th> | |
| </tr> | |
| {% for item in active_books %} | |
| {% set issue = item.issue %} | |
| {% set book = item.book %} | |
| {% set is_overdue = issue.is_overdue() %} | |
| <tr> | |
| <td> | |
| <strong>{{ book.title if book else 'Unknown' }}</strong><br> | |
| <small style="color: #6b7280;">ID: {{ issue.book_id }}</small> | |
| </td> | |
| <td>{{ issue.issue_date.strftime('%Y-%m-%d %H:%M') }}</td> | |
| <td>{{ issue.due_date.strftime('%Y-%m-%d') }}</td> | |
| <td> | |
| {% if is_overdue %} | |
| <span style="background: #fee2e2; color: #991b1b; padding: 0.25rem 0.75rem; border-radius: 12px; font-size: 0.875rem; font-weight: bold;"> | |
| β OVERDUE ({{ issue.days_overdue() }} days) | |
| </span> | |
| {% else %} | |
| <span style="background: #fef3c7; color: #92400e; padding: 0.25rem 0.75rem; border-radius: 12px; font-size: 0.875rem;"> | |
| π Active | |
| </span> | |
| {% endif %} | |
| </td> | |
| </tr> | |
| {% endfor %} | |
| </table> | |
| {% else %} | |
| <p style="text-align: center; color: #9ca3af; padding: 2rem;">No active books</p> | |
| {% endif %} | |
| </div> | |
| <div class="card" id="returned-section"> | |
| <h3 style="margin-bottom: 1rem;">β Returned Books</h3> | |
| {% set returned_books = issues_with_books|selectattr('issue.status', 'equalto', 'returned')|list %} | |
| {% if returned_books %} | |
| <table> | |
| <tr> | |
| <th>Book</th> | |
| <th>Issue Date</th> | |
| <th>Due Date</th> | |
| <th>Return Date</th> | |
| <th>Status</th> | |
| </tr> | |
| {% for item in returned_books %} | |
| {% set issue = item.issue %} | |
| {% set book = item.book %} | |
| {% set was_overdue = issue.days_overdue() > 0 %} | |
| <tr> | |
| <td> | |
| <strong>{{ book.title if book else 'Unknown' }}</strong><br> | |
| <small style="color: #6b7280;">ID: {{ issue.book_id }}</small> | |
| </td> | |
| <td>{{ issue.issue_date.strftime('%Y-%m-%d %H:%M') }}</td> | |
| <td>{{ issue.due_date.strftime('%Y-%m-%d') }}</td> | |
| <td>{{ issue.return_date.strftime('%Y-%m-%d %H:%M') }}</td> | |
| <td> | |
| {% if was_overdue %} | |
| <span style="background: #fee2e2; color: #991b1b; padding: 0.25rem 0.75rem; border-radius: 12px; font-size: 0.875rem;"> | |
| β Returned Late ({{ issue.days_overdue() }} days) | |
| </span> | |
| {% else %} | |
| <span style="background: #d1fae5; color: #065f46; padding: 0.25rem 0.75rem; border-radius: 12px; font-size: 0.875rem;"> | |
| β Returned On Time | |
| </span> | |
| {% endif %} | |
| </td> | |
| </tr> | |
| {% endfor %} | |
| </table> | |
| {% else %} | |
| <p style="text-align: center; color: #9ca3af; padding: 2rem;">No returned books</p> | |
| {% endif %} | |
| </div> | |
| {% endblock %} | |