| {% load static %}
|
| <!DOCTYPE html>
|
| <html lang="en">
|
| <head>
|
| <meta charset="UTF-8" />
|
| <meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
| <title>{% block title %}EduCore{% endblock %} — School Management</title>
|
| <link rel="preconnect" href="https://fonts.googleapis.com" />
|
| <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
| <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet" />
|
|
|
| <script src="https://unpkg.com/lucide@latest/dist/umd/lucide.min.js"></script>
|
|
|
| <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.5/gsap.min.js"></script>
|
| <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.5/ScrollTrigger.min.js"></script>
|
| <link rel="stylesheet" href="{% static 'css/main.css' %}" />
|
| {% block extra_css %}{% endblock %}
|
| </head>
|
| <body>
|
|
|
| <div class="app-layout">
|
|
|
|
|
| <div id="sidebar-overlay" style="display:none;position:fixed;inset:0;background:rgba(0,0,0,.4);z-index:99;transition:.2s;"
|
| onclick="this.classList.remove('active');document.querySelector('.sidebar').classList.remove('open')"></div>
|
|
|
|
|
| <aside class="sidebar">
|
| <a href="{% url 'dashboard' %}" class="sidebar-brand">
|
| <div class="sidebar-brand-icon">🎓</div>
|
| <div class="sidebar-brand-text">
|
| <div class="sidebar-brand-name">EduCore</div>
|
| <div class="sidebar-brand-sub">School Management</div>
|
| </div>
|
| </a>
|
|
|
| <nav class="sidebar-nav">
|
|
|
| <div class="nav-section-label">Main</div>
|
|
|
| <div class="nav-item">
|
| <a href="{% url 'dashboard' %}" class="nav-link {% if request.resolver_match.url_name == 'dashboard' %}active{% endif %}">
|
| <i data-lucide="layout-dashboard" class="nav-icon"></i>
|
| Dashboard
|
| </a>
|
| </div>
|
|
|
| <div class="nav-section-label">Academic</div>
|
|
|
| <div class="nav-item">
|
| <a href="{% url 'student_list' %}" class="nav-link {% if 'student' in request.resolver_match.url_name %}active{% endif %}">
|
| <i data-lucide="users" class="nav-icon"></i>
|
| Students
|
| </a>
|
| </div>
|
|
|
| <div class="nav-item">
|
| <a href="{% url 'teacher_list' %}" class="nav-link {% if 'teacher' in request.resolver_match.url_name %}active{% endif %}">
|
| <i data-lucide="user-check" class="nav-icon"></i>
|
| Teachers
|
| </a>
|
| </div>
|
|
|
| <div class="nav-item">
|
| <a href="{% url 'class_list' %}" class="nav-link {% if 'class' in request.resolver_match.url_name %}active{% endif %}">
|
| <i data-lucide="book-open" class="nav-icon"></i>
|
| Classes
|
| </a>
|
| </div>
|
|
|
| <div class="nav-item">
|
| <a href="{% url 'subject_list' %}" class="nav-link {% if 'subject' in request.resolver_match.url_name %}active{% endif %}">
|
| <i data-lucide="library" class="nav-icon"></i>
|
| Subjects
|
| </a>
|
| </div>
|
|
|
| <div class="nav-section-label">Tracking</div>
|
|
|
| <div class="nav-item">
|
| <a href="{% url 'attendance_list' %}" class="nav-link {% if 'attendance' in request.resolver_match.url_name %}active{% endif %}">
|
| <i data-lucide="calendar-check" class="nav-icon"></i>
|
| Attendance
|
| </a>
|
| </div>
|
|
|
| <div class="nav-item">
|
| <a href="{% url 'grade_list' %}" class="nav-link {% if 'grade' in request.resolver_match.url_name %}active{% endif %}">
|
| <i data-lucide="bar-chart-2" class="nav-icon"></i>
|
| Grades
|
| </a>
|
| </div>
|
|
|
| <div class="nav-section-label">Communication</div>
|
|
|
| <div class="nav-item">
|
| <a href="{% url 'notice_list' %}" class="nav-link {% if 'notice' in request.resolver_match.url_name %}active{% endif %}">
|
| <i data-lucide="bell" class="nav-icon"></i>
|
| Notices
|
| </a>
|
| </div>
|
|
|
| <div class="nav-section-label">Reports</div>
|
|
|
| <div class="nav-item">
|
| <a href="{% url 'attendance_report' %}" class="nav-link {% if request.resolver_match.url_name == 'attendance_report' %}active{% endif %}">
|
| <i data-lucide="file-bar-chart" class="nav-icon"></i>
|
| Attendance Report
|
| </a>
|
| </div>
|
|
|
| </nav>
|
|
|
| <div class="sidebar-footer">
|
| {% if user.is_authenticated %}
|
| <div style="display:flex;align-items:center;gap:10px;padding:8px;border-radius:10px;background:var(--surface-2);">
|
| <div class="avatar" style="width:32px;height:32px;font-size:12px;">{{ user.username|first|upper }}</div>
|
| <div style="flex:1;min-width:0;">
|
| <div style="font-size:13px;font-weight:600;truncate;">{{ user.username }}</div>
|
| <div style="font-size:11px;color:var(--text-muted);">Administrator</div>
|
| </div>
|
| <a href="{% url 'logout' %}" data-tooltip="Logout" style="color:var(--text-muted);display:flex;">
|
| <i data-lucide="log-out" style="width:16px;height:16px;"></i>
|
| </a>
|
| </div>
|
| {% endif %}
|
| </div>
|
| </aside>
|
|
|
|
|
| <div class="main-content">
|
|
|
|
|
| <header class="topbar">
|
| <button id="sidebar-toggle" class="icon-btn" style="display:none;" aria-label="Menu">
|
| <i data-lucide="menu"></i>
|
| </button>
|
|
|
| <div class="topbar-title">{% block page_title %}Dashboard{% endblock %}</div>
|
|
|
| <div class="topbar-search">
|
| <i data-lucide="search" style="width:15px;height:15px;color:var(--text-muted);flex-shrink:0;"></i>
|
| <input type="text" id="table-search" placeholder="Search anything…" />
|
| </div>
|
|
|
| <div class="topbar-actions">
|
| <a href="{% url 'notice_list' %}" class="icon-btn" data-tooltip="Notices">
|
| <i data-lucide="bell" style="width:18px;height:18px;"></i>
|
| </a>
|
| <a href="{% url 'student_add' %}" class="icon-btn" data-tooltip="Add Student">
|
| <i data-lucide="user-plus" style="width:18px;height:18px;"></i>
|
| </a>
|
| <div class="avatar">{{ user.username|first|upper }}</div>
|
| </div>
|
| </header>
|
|
|
|
|
| {% if messages %}
|
| <div style="padding:12px 28px 0;">
|
| {% for message in messages %}
|
| <div class="alert alert-{{ message.tags }}">
|
| <i data-lucide="{% if message.tags == 'success' %}check-circle{% elif message.tags == 'error' %}x-circle{% else %}info{% endif %}" style="width:16px;height:16px;flex-shrink:0;margin-top:1px;"></i>
|
| <span>{{ message }}</span>
|
| <button class="alert-close" style="margin-left:auto;background:none;border:none;cursor:pointer;opacity:.6;padding:0;">
|
| <i data-lucide="x" style="width:14px;height:14px;"></i>
|
| </button>
|
| </div>
|
| {% endfor %}
|
| </div>
|
| {% endif %}
|
|
|
|
|
| <main class="page-content">
|
| {% block content %}{% endblock %}
|
| </main>
|
|
|
| </div>
|
| </div>
|
|
|
| <script>
|
|
|
| lucide.createIcons();
|
|
|
|
|
| if (window.innerWidth <= 768) {
|
| document.getElementById('sidebar-toggle').style.display = 'flex';
|
|
|
| const ov = document.getElementById('sidebar-overlay');
|
| ov.style.display = 'block';
|
| ov.style.opacity = '0';
|
| ov.style.pointerEvents = 'none';
|
| document.getElementById('sidebar-toggle').addEventListener('click', () => {
|
| const open = document.querySelector('.sidebar').classList.contains('open');
|
| ov.style.opacity = open ? '1' : '0';
|
| ov.style.pointerEvents = open ? 'auto' : 'none';
|
| });
|
| }
|
| </script>
|
| <script src="{% static 'js/main.js' %}"></script>
|
| {% block extra_js %}{% endblock %}
|
| </body>
|
| </html> |