201 lines
12 KiB
HTML
201 lines
12 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="{{ current_lang }}" data-bs-theme="dark">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>{% block title %}{% trans %}Edu-Space Admin{% endtrans %}{% endblock %}</title>
|
|
|
|
<!-- Favicon -->
|
|
<link rel="icon" type="image/png" href="{{ url_for('static', filename='img/favicon.png') }}">
|
|
|
|
<!-- Script Anti-Flicker para Modo Claro / Oscuro -->
|
|
<script>
|
|
(function() {
|
|
let userTheme = "{{ current_user.theme_preference if (current_user and current_user.is_authenticated) else '' }}";
|
|
let theme = userTheme;
|
|
if (!theme || theme === 'auto') {
|
|
const storedTheme = localStorage.getItem('theme');
|
|
theme = storedTheme || (window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light');
|
|
}
|
|
document.documentElement.setAttribute('data-bs-theme', theme);
|
|
})();
|
|
</script>
|
|
|
|
<!-- Bootstrap 5 CSS -->
|
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
|
|
<!-- Bootstrap Icons -->
|
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.0/font/bootstrap-icons.css" rel="stylesheet">
|
|
<!-- Design System & Custom Theme -->
|
|
<link href="{{ url_for('static', filename='css/theme.css') }}" rel="stylesheet">
|
|
<link href="{{ url_for('static', filename='css/style.css') }}" rel="stylesheet">
|
|
|
|
{% block extra_css %}{% endblock %}
|
|
</head>
|
|
<body data-user-authenticated="{{ 'true' if (current_user and current_user.is_authenticated) else 'false' }}">
|
|
{% if current_user.is_authenticated %}
|
|
<!-- Navigation -->
|
|
<nav class="navbar navbar-expand-lg navbar-dark navbar-app fixed-top">
|
|
<div class="container-fluid">
|
|
<a class="navbar-brand d-flex align-items-center" href="{{ url_for('main.dashboard') }}">
|
|
<img src="{{ url_for('static', filename='img/logo_unicaba_mini.png') }}" alt="Logo UniCABA" class="navbar-logo me-2">
|
|
<span>Edu-Space Admin</span>
|
|
</a>
|
|
|
|
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav">
|
|
<span class="navbar-toggler-icon"></span>
|
|
</button>
|
|
|
|
<div class="collapse navbar-collapse" id="navbarNav">
|
|
<ul class="navbar-nav me-auto">
|
|
<li class="nav-item">
|
|
<a class="nav-link" href="{{ url_for('main.dashboard') }}">
|
|
<i class="bi bi-speedometer2"></i> {% trans %}Dashboard{% endtrans %}
|
|
</a>
|
|
</li>
|
|
<li class="nav-item dropdown">
|
|
<a class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown">
|
|
<i class="bi bi-door-open"></i> {% trans %}Classrooms{% endtrans %}
|
|
</a>
|
|
<ul class="dropdown-menu">
|
|
<li><a class="dropdown-item" href="{{ url_for('classrooms.list_classrooms') }}">
|
|
<i class="bi bi-list"></i> {% trans %}All Classrooms{% endtrans %}
|
|
</a></li>
|
|
{% if current_user.has_permission('classrooms', 'read_write') %}
|
|
<li><a class="dropdown-item" href="{{ url_for('classrooms.add_classroom') }}">
|
|
<i class="bi bi-plus-circle"></i> {% trans %}Add Classroom{% endtrans %}
|
|
</a></li>
|
|
{% endif %}
|
|
<li><hr class="dropdown-divider"></li>
|
|
<li><a class="dropdown-item" href="{{ url_for('buildings.list_buildings') }}">
|
|
<i class="bi bi-buildings"></i> {% trans %}Buildings{% endtrans %}
|
|
</a></li>
|
|
</ul>
|
|
</li>
|
|
<li class="nav-item dropdown">
|
|
<a class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown">
|
|
<i class="bi bi-calendar3"></i> {% trans %}Schedule{% endtrans %}
|
|
</a>
|
|
<ul class="dropdown-menu">
|
|
<li><a class="dropdown-item" href="{{ url_for('schedule.calendar_view') }}">
|
|
<i class="bi bi-calendar-week"></i> {% trans %}Calendar View{% endtrans %}
|
|
</a></li>
|
|
<li><a class="dropdown-item" href="{{ url_for('schedule.list_reservations') }}">
|
|
<i class="bi bi-list-check"></i> {% trans %}All Reservations{% endtrans %}
|
|
</a></li>
|
|
{% if current_user.has_permission('reservations', 'read_write') %}
|
|
<li><a class="dropdown-item" href="{{ url_for('schedule.add_reservation') }}">
|
|
<i class="bi bi-plus-circle"></i> {% trans %}New Reservation{% endtrans %}
|
|
</a></li>
|
|
{% endif %}
|
|
<li><a class="dropdown-item" href="{{ url_for('schedule.today_schedule') }}">
|
|
<i class="bi bi-calendar-today"></i> {% trans %}Today's Schedule{% endtrans %}
|
|
</a></li>
|
|
{% if current_user.has_permission('optimizer', 'read') or (current_user.role and current_user.role|upper == 'ADMIN') %}
|
|
<li><hr class="dropdown-divider"></li>
|
|
<li><a class="dropdown-item" href="{{ url_for('genetic_algorithm_web.genetic_optimizer') }}">
|
|
<i class="bi bi-cpu text-info me-2"></i>{% trans %}Optimizador de Aulas (IA){% endtrans %}
|
|
</a></li>
|
|
{% endif %}
|
|
</ul>
|
|
</li>
|
|
{% if current_user.is_authenticated and current_user.can_manage() %}
|
|
<li class="nav-item dropdown">
|
|
<a class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown">
|
|
<i class="bi bi-shield-lock"></i> {% trans %}Management{% endtrans %}
|
|
</a>
|
|
<ul class="dropdown-menu shadow-sm">
|
|
<li><a class="dropdown-item" href="{{ url_for('admin.users_list') }}"><i class="bi bi-people me-2"></i>{% trans %}Users{% endtrans %}</a></li>
|
|
<li><a class="dropdown-item" href="{{ url_for('admin.roles_list') }}"><i class="bi bi-person-badge me-2"></i>{% trans %}Roles & Groups{% endtrans %}</a></li>
|
|
<li><a class="dropdown-item" href="{{ url_for('buildings.list_buildings') }}"><i class="bi bi-buildings me-2"></i>{% trans %}Buildings{% endtrans %}</a></li>
|
|
<li><a class="dropdown-item" href="{{ url_for('admin.milestone_types_list') }}"><i class="bi bi-tags me-2 text-warning"></i>{% trans %}Tipificaciones{% endtrans %}</a></li>
|
|
<li><hr class="dropdown-divider"></li>
|
|
<li><a class="dropdown-item" href="{{ url_for('admin.google_sheets_import') }}"><i class="bi bi-file-earmark-spreadsheet me-2 text-success"></i>{% trans %}Import from Google Sheets{% endtrans %}</a></li>
|
|
</ul>
|
|
</li>
|
|
{% endif %}
|
|
</ul>
|
|
|
|
<ul class="navbar-nav align-items-center">
|
|
<!-- Theme Mode Toggle Button -->
|
|
<li class="nav-item me-2">
|
|
<button class="theme-toggle-btn" type="button" aria-label="Cambiar tema" title="Modo Claro/Oscuro">
|
|
<i class="bi bi-moon-stars-fill"></i>
|
|
</button>
|
|
</li>
|
|
|
|
<!-- Language Switcher -->
|
|
<li class="nav-item me-2">
|
|
{% include 'partials/language_switcher.html' %}
|
|
</li>
|
|
|
|
<!-- User Dropdown with Avatar -->
|
|
<li class="nav-item dropdown">
|
|
<a class="nav-link dropdown-toggle d-flex align-items-center py-1" href="#" role="button" data-bs-toggle="dropdown">
|
|
<span class="user-avatar-small">{{ current_user.name[:1]|upper if current_user.name else 'U' }}</span>
|
|
<span>{{ current_user.first_name }}</span>
|
|
</a>
|
|
<ul class="dropdown-menu dropdown-menu-end shadow-sm border-0">
|
|
<li>
|
|
<div class="px-3 py-2 border-bottom">
|
|
<small class="text-muted d-block">{% trans %}Signed in as{% endtrans %}</small>
|
|
<span class="fw-bold small">{{ current_user.email }}</span>
|
|
</div>
|
|
</li>
|
|
<li><a class="dropdown-item" href="{{ url_for('auth.profile') }}">
|
|
<i class="bi bi-person me-2"></i> {% trans %}Profile{% endtrans %}
|
|
</a></li>
|
|
<li><a class="dropdown-item" href="{{ url_for('auth.change_password') }}">
|
|
<i class="bi bi-key me-2"></i> {% trans %}Change Password{% endtrans %}
|
|
</a></li>
|
|
<li><hr class="dropdown-divider"></li>
|
|
<li><a class="dropdown-item text-danger" href="{{ url_for('auth.logout') }}">
|
|
<i class="bi bi-box-arrow-right me-2"></i> {% trans %}Logout{% endtrans %}
|
|
</a></li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</nav>
|
|
{% endif %}
|
|
|
|
<!-- Flash Messages -->
|
|
<div class="toast-container position-fixed bottom-0 end-0 p-3" style="z-index: 1080;">
|
|
{% with messages = get_flashed_messages(with_categories=true) %}
|
|
{% if messages %}
|
|
{% for category, message in messages %}
|
|
<div class="toast align-items-center text-white bg-{{ 'danger' if category == 'error' else 'success' if category == 'success' else 'info' if category == 'info' else 'warning' }} border-0 shadow" role="alert">
|
|
<div class="d-flex">
|
|
<div class="toast-body">
|
|
{{ message }}
|
|
</div>
|
|
<button type="button" class="btn-close btn-close-white me-2 m-auto" data-bs-dismiss="toast"></button>
|
|
</div>
|
|
</div>
|
|
{% endfor %}
|
|
{% endif %}
|
|
{% endwith %}
|
|
</div>
|
|
|
|
<!-- Main Content -->
|
|
{% block content %}{% endblock %}
|
|
|
|
<!-- Bootstrap JS -->
|
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
|
|
<!-- jQuery -->
|
|
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
|
|
<!-- Theme Toggle JS -->
|
|
<script src="{{ url_for('static', filename='js/theme-toggle.js') }}"></script>
|
|
<!-- Custom JS -->
|
|
<script src="{{ url_for('static', filename='js/main.js') }}"></script>
|
|
|
|
<!-- Show flash messages -->
|
|
<script>
|
|
$(document).ready(function() {
|
|
$('.toast').toast('show');
|
|
});
|
|
</script>
|
|
|
|
{% block extra_js %}{% endblock %}
|
|
</body>
|
|
</html> |