From 5cc33cc7a004197a5c3b3e7f00ab88cdf9dbc945 Mon Sep 17 00:00:00 2001 From: Carlos Tello Date: Thu, 3 Sep 2026 03:08:49 -0300 Subject: [PATCH] feat: gestion RBAC granular, importacion sheets, filtrado de aulas virtuales y pisos, capacidad infinita y traduccion --- CHANGELOG_SESSION.md | 241 +++- app.py | 2 +- app/__init__.py | 52 +- app/forms/building.py | 28 + app/forms/classroom.py | 27 +- app/models/__init__.py | 10 +- app/models/building.py | 45 + app/models/career.py | 27 + app/models/classroom.py | 12 + app/models/reservation.py | 50 +- app/models/role.py | 142 ++ app/models/subject.py | 12 +- app/models/user.py | 23 +- app/resources/icon/favicon.png | Bin 0 -> 2540 bytes app/resources/icon_clear.png | Bin 0 -> 20887 bytes app/resources/icon_old.png | Bin 0 -> 25964 bytes app/resources/icons/icon-128.webp | Bin 0 -> 8041 bytes app/resources/icons/icon-192.webp | Bin 0 -> 13342 bytes app/resources/icons/icon-256.webp | Bin 0 -> 18938 bytes app/resources/icons/icon-48.webp | Bin 0 -> 2454 bytes app/resources/icons/icon-512.webp | Bin 0 -> 42760 bytes app/resources/icons/icon-72.webp | Bin 0 -> 4122 bytes app/resources/icons/icon-96.webp | Bin 0 -> 5856 bytes app/resources/logo_unicaba copy.png | Bin 0 -> 32191 bytes app/resources/logo_unicaba.png | Bin 0 -> 32191 bytes app/resources/logo_unicaba_mini copy.png | Bin 0 -> 20887 bytes app/resources/logo_unicaba_mini.png | Bin 0 -> 20887 bytes app/routes/__init__.py | 4 +- app/routes/admin.py | 342 +++++ app/routes/auth.py | 47 +- app/routes/buildings.py | 193 +++ app/routes/classrooms.py | 23 +- app/routes/main.py | 269 ++-- app/routes/schedule.py | 253 +++- app/services/__init__.py | 3 + app/services/sheets_importer.py | 413 ++++++ app/static/css/style.css | 151 +- app/static/css/theme.css | 668 +++++++++ app/static/img/favicon.png | Bin 0 -> 2540 bytes app/static/img/icons/icon-128.webp | Bin 0 -> 8041 bytes app/static/img/icons/icon-192.webp | Bin 0 -> 13342 bytes app/static/img/icons/icon-256.webp | Bin 0 -> 18938 bytes app/static/img/icons/icon-48.webp | Bin 0 -> 2454 bytes app/static/img/icons/icon-512.webp | Bin 0 -> 42760 bytes app/static/img/icons/icon-72.webp | Bin 0 -> 4122 bytes app/static/img/icons/icon-96.webp | Bin 0 -> 5856 bytes app/static/img/logo_unicaba.png | Bin 0 -> 32191 bytes app/static/img/logo_unicaba_mini.png | Bin 0 -> 20887 bytes app/static/js/theme-toggle.js | 88 ++ app/templates/admin/import.html | 242 ++++ app/templates/admin/roles/edit.html | 191 +++ app/templates/admin/roles/list.html | 124 ++ app/templates/admin/users/form.html | 107 ++ app/templates/admin/users/list.html | 182 +++ app/templates/auth/login.html | 191 +-- app/templates/auth/profile.html | 55 +- app/templates/base.html | 92 +- app/templates/buildings/form.html | 95 ++ app/templates/buildings/list.html | 223 +++ app/templates/buildings/view.html | 177 +++ app/templates/classrooms/add.html | 25 +- app/templates/classrooms/edit.html | 162 +++ app/templates/classrooms/list.html | 8 +- app/templates/classrooms/view.html | 165 +++ app/templates/dashboard.html | 241 ++-- app/templates/partials/language_switcher.html | 27 +- app/templates/schedule/add.html | 148 +- app/templates/schedule/calendar.html | 617 ++++++-- app/templates/schedule/commissions.html | 2 +- app/templates/schedule/list.html | 490 +++---- app/templates/schedule/today.html | 659 ++++----- app/templates/schedule/view.html | 15 +- app/utils/__init__.py | 3 + app/utils/decorators.py | 41 + config/config.py | 4 +- .../src/app/app-routing.module.ts | 26 + .../src/app/app.component.html | 3 + .../src/app/app.component.scss | 0 .../src/app/app.component.spec.ts | 21 + .../src/app/app.component.ts | 70 + .../aulas-unicaba-mvp/src/app/app.module.ts | 17 + .../agenda-modal/agenda-modal.component.html | 48 + .../agenda-modal/agenda-modal.component.scss | 77 + .../agenda-modal.component.spec.ts | 22 + .../agenda-modal/agenda-modal.component.ts | 68 + .../credencial-modal.component.html | 74 + .../credencial-modal.component.scss | 93 ++ .../credencial-modal.component.ts | 132 ++ .../evento-modal/evento-modal.component.html | 101 ++ .../evento-modal/evento-modal.component.scss | 52 + .../evento-modal/evento-modal.component.ts | 117 ++ .../info-modal/info-modal.component.html | 326 +++++ .../info-modal/info-modal.component.scss | 238 ++++ .../info-modal/info-modal.component.ts | 21 + .../src/app/home/home-routing.module.ts | 16 + .../src/app/home/home.module.ts | 24 + .../src/app/home/home.page.html | 231 +++ .../src/app/home/home.page.scss | 743 ++++++++++ .../src/app/home/home.page.spec.ts | 24 + .../src/app/home/home.page.ts | 1268 +++++++++++++++++ .../src/app/perfil/perfil-routing.module.ts | 16 + .../src/app/perfil/perfil.module.ts | 17 + .../src/app/perfil/perfil.page.html | 214 +++ .../src/app/perfil/perfil.page.scss | 309 ++++ .../src/app/perfil/perfil.page.ts | 355 +++++ .../src/app/services/auth.service.ts | 120 ++ .../src/app/services/credencial.service.ts | 342 +++++ .../src/app/services/data.spec.ts | 16 + .../src/app/services/data.ts | 345 +++++ .../src/app/services/eventos.service.ts | 113 ++ .../src/app/services/local-storage.service.ts | 229 +++ .../src/app/services/siu-guarani.service.ts | 332 +++++ .../src/assets/icon/favicon.png | Bin 0 -> 2540 bytes .../src/assets/icon_clear.png | Bin 0 -> 20887 bytes .../aulas-unicaba-mvp/src/assets/icon_old.png | Bin 0 -> 25964 bytes .../src/assets/icons/icon-128.webp | Bin 0 -> 8041 bytes .../src/assets/icons/icon-192.webp | Bin 0 -> 13342 bytes .../src/assets/icons/icon-256.webp | Bin 0 -> 18938 bytes .../src/assets/icons/icon-48.webp | Bin 0 -> 2454 bytes .../src/assets/icons/icon-512.webp | Bin 0 -> 42760 bytes .../src/assets/icons/icon-72.webp | Bin 0 -> 4122 bytes .../src/assets/icons/icon-96.webp | Bin 0 -> 5856 bytes .../src/assets/logo_unicaba.png | Bin 0 -> 32191 bytes .../src/assets/logo_unicaba_mini.png | Bin 0 -> 20887 bytes .../aulas-unicaba-mvp/src/assets/shapes.svg | 1 + .../src/environments/environment.prod.ts | 3 + .../src/environments/environment.ts | 16 + example/aulas-unicaba-mvp/src/global.scss | 37 + example/aulas-unicaba-mvp/src/index.html | 27 + example/aulas-unicaba-mvp/src/main.ts | 22 + .../src/manifest.webmanifest | 46 + example/aulas-unicaba-mvp/src/polyfills.ts | 55 + example/aulas-unicaba-mvp/src/test.ts | 14 + .../src/theme/variables.scss | 17 + example/aulas-unicaba-mvp/src/zone-flags.ts | 6 + init_db.py | 209 ++- translations/en/LC_MESSAGES/messages.po | 895 +++++++++++- translations/es/LC_MESSAGES/messages.po | 930 +++++++++++- 138 files changed, 14419 insertions(+), 1490 deletions(-) create mode 100644 app/forms/building.py create mode 100644 app/models/building.py create mode 100644 app/models/career.py create mode 100644 app/models/role.py create mode 100644 app/resources/icon/favicon.png create mode 100644 app/resources/icon_clear.png create mode 100644 app/resources/icon_old.png create mode 100644 app/resources/icons/icon-128.webp create mode 100644 app/resources/icons/icon-192.webp create mode 100644 app/resources/icons/icon-256.webp create mode 100644 app/resources/icons/icon-48.webp create mode 100644 app/resources/icons/icon-512.webp create mode 100644 app/resources/icons/icon-72.webp create mode 100644 app/resources/icons/icon-96.webp create mode 100644 app/resources/logo_unicaba copy.png create mode 100644 app/resources/logo_unicaba.png create mode 100644 app/resources/logo_unicaba_mini copy.png create mode 100644 app/resources/logo_unicaba_mini.png create mode 100644 app/routes/admin.py create mode 100644 app/routes/buildings.py create mode 100644 app/services/__init__.py create mode 100644 app/services/sheets_importer.py create mode 100644 app/static/css/theme.css create mode 100644 app/static/img/favicon.png create mode 100644 app/static/img/icons/icon-128.webp create mode 100644 app/static/img/icons/icon-192.webp create mode 100644 app/static/img/icons/icon-256.webp create mode 100644 app/static/img/icons/icon-48.webp create mode 100644 app/static/img/icons/icon-512.webp create mode 100644 app/static/img/icons/icon-72.webp create mode 100644 app/static/img/icons/icon-96.webp create mode 100644 app/static/img/logo_unicaba.png create mode 100644 app/static/img/logo_unicaba_mini.png create mode 100644 app/static/js/theme-toggle.js create mode 100644 app/templates/admin/import.html create mode 100644 app/templates/admin/roles/edit.html create mode 100644 app/templates/admin/roles/list.html create mode 100644 app/templates/admin/users/form.html create mode 100644 app/templates/admin/users/list.html create mode 100644 app/templates/buildings/form.html create mode 100644 app/templates/buildings/list.html create mode 100644 app/templates/buildings/view.html create mode 100644 app/templates/classrooms/edit.html create mode 100644 app/templates/classrooms/view.html create mode 100644 app/utils/__init__.py create mode 100644 app/utils/decorators.py create mode 100644 example/aulas-unicaba-mvp/src/app/app-routing.module.ts create mode 100644 example/aulas-unicaba-mvp/src/app/app.component.html create mode 100644 example/aulas-unicaba-mvp/src/app/app.component.scss create mode 100644 example/aulas-unicaba-mvp/src/app/app.component.spec.ts create mode 100644 example/aulas-unicaba-mvp/src/app/app.component.ts create mode 100644 example/aulas-unicaba-mvp/src/app/app.module.ts create mode 100644 example/aulas-unicaba-mvp/src/app/components/agenda-modal/agenda-modal.component.html create mode 100644 example/aulas-unicaba-mvp/src/app/components/agenda-modal/agenda-modal.component.scss create mode 100644 example/aulas-unicaba-mvp/src/app/components/agenda-modal/agenda-modal.component.spec.ts create mode 100644 example/aulas-unicaba-mvp/src/app/components/agenda-modal/agenda-modal.component.ts create mode 100644 example/aulas-unicaba-mvp/src/app/components/credencial-modal/credencial-modal.component.html create mode 100644 example/aulas-unicaba-mvp/src/app/components/credencial-modal/credencial-modal.component.scss create mode 100644 example/aulas-unicaba-mvp/src/app/components/credencial-modal/credencial-modal.component.ts create mode 100644 example/aulas-unicaba-mvp/src/app/components/evento-modal/evento-modal.component.html create mode 100644 example/aulas-unicaba-mvp/src/app/components/evento-modal/evento-modal.component.scss create mode 100644 example/aulas-unicaba-mvp/src/app/components/evento-modal/evento-modal.component.ts create mode 100644 example/aulas-unicaba-mvp/src/app/components/info-modal/info-modal.component.html create mode 100644 example/aulas-unicaba-mvp/src/app/components/info-modal/info-modal.component.scss create mode 100644 example/aulas-unicaba-mvp/src/app/components/info-modal/info-modal.component.ts create mode 100644 example/aulas-unicaba-mvp/src/app/home/home-routing.module.ts create mode 100644 example/aulas-unicaba-mvp/src/app/home/home.module.ts create mode 100644 example/aulas-unicaba-mvp/src/app/home/home.page.html create mode 100644 example/aulas-unicaba-mvp/src/app/home/home.page.scss create mode 100644 example/aulas-unicaba-mvp/src/app/home/home.page.spec.ts create mode 100644 example/aulas-unicaba-mvp/src/app/home/home.page.ts create mode 100644 example/aulas-unicaba-mvp/src/app/perfil/perfil-routing.module.ts create mode 100644 example/aulas-unicaba-mvp/src/app/perfil/perfil.module.ts create mode 100644 example/aulas-unicaba-mvp/src/app/perfil/perfil.page.html create mode 100644 example/aulas-unicaba-mvp/src/app/perfil/perfil.page.scss create mode 100644 example/aulas-unicaba-mvp/src/app/perfil/perfil.page.ts create mode 100644 example/aulas-unicaba-mvp/src/app/services/auth.service.ts create mode 100644 example/aulas-unicaba-mvp/src/app/services/credencial.service.ts create mode 100644 example/aulas-unicaba-mvp/src/app/services/data.spec.ts create mode 100644 example/aulas-unicaba-mvp/src/app/services/data.ts create mode 100644 example/aulas-unicaba-mvp/src/app/services/eventos.service.ts create mode 100644 example/aulas-unicaba-mvp/src/app/services/local-storage.service.ts create mode 100644 example/aulas-unicaba-mvp/src/app/services/siu-guarani.service.ts create mode 100644 example/aulas-unicaba-mvp/src/assets/icon/favicon.png create mode 100644 example/aulas-unicaba-mvp/src/assets/icon_clear.png create mode 100644 example/aulas-unicaba-mvp/src/assets/icon_old.png create mode 100644 example/aulas-unicaba-mvp/src/assets/icons/icon-128.webp create mode 100644 example/aulas-unicaba-mvp/src/assets/icons/icon-192.webp create mode 100644 example/aulas-unicaba-mvp/src/assets/icons/icon-256.webp create mode 100644 example/aulas-unicaba-mvp/src/assets/icons/icon-48.webp create mode 100644 example/aulas-unicaba-mvp/src/assets/icons/icon-512.webp create mode 100644 example/aulas-unicaba-mvp/src/assets/icons/icon-72.webp create mode 100644 example/aulas-unicaba-mvp/src/assets/icons/icon-96.webp create mode 100644 example/aulas-unicaba-mvp/src/assets/logo_unicaba.png create mode 100644 example/aulas-unicaba-mvp/src/assets/logo_unicaba_mini.png create mode 100644 example/aulas-unicaba-mvp/src/assets/shapes.svg create mode 100644 example/aulas-unicaba-mvp/src/environments/environment.prod.ts create mode 100644 example/aulas-unicaba-mvp/src/environments/environment.ts create mode 100644 example/aulas-unicaba-mvp/src/global.scss create mode 100644 example/aulas-unicaba-mvp/src/index.html create mode 100644 example/aulas-unicaba-mvp/src/main.ts create mode 100644 example/aulas-unicaba-mvp/src/manifest.webmanifest create mode 100644 example/aulas-unicaba-mvp/src/polyfills.ts create mode 100644 example/aulas-unicaba-mvp/src/test.ts create mode 100644 example/aulas-unicaba-mvp/src/theme/variables.scss create mode 100644 example/aulas-unicaba-mvp/src/zone-flags.ts diff --git a/CHANGELOG_SESSION.md b/CHANGELOG_SESSION.md index e812aba..1a7bce9 100644 --- a/CHANGELOG_SESSION.md +++ b/CHANGELOG_SESSION.md @@ -12,7 +12,7 @@ * Manual de despliegue en producción con arquitectura WSGI (Gunicorn), Nginx como proxy inverso, Systemd unit y contenedorización Docker / Docker Compose. * **Archivos Base:** * Creación de `.env.example` con todas las variables requeridas (PostgreSQL, Flask, Secret Key, Babel). - * Creación de `init_db.py` para bootstrap inicial seguro de base de datos y usuario administrador por defecto (`admin@edu-space.com` / `admin123`). + * Creación y posterior actualización de `init_db.py` para bootstrap inicial seguro de base de datos, roles RBAC y usuario administrador por defecto (`admin@edu-space.com` / `admin123`). --- @@ -20,65 +20,234 @@ * **Preferencia de Idioma Persistente:** * Migración en PostgreSQL agregando la columna `preferred_language VARCHAR(10)` a la tabla `users`. * Actualización del modelo `User` en `app/models/user.py` con el campo `preferred_language`. +* **Preferencia de Tema Visual Persistente:** + * Migración agregando la columna `theme_preference VARCHAR(10) DEFAULT 'auto' NOT NULL` a la tabla `users`. + * Soporte en el modelo `User` para valores `'auto'`, `'light'` y `'dark'`. +* **Control de Acceso Basado en Roles (RBAC):** + * Migración creando las tablas `roles` y `permissions`, y agregando la clave foránea `role_id` a la tabla `users`. + * Modelos `Role` y `Permission` en `app/models/role.py`. + * Métodos `has_permission(module, min_level)` y `can_manage()` en `User`. --- -## 3. Implementación de Vistas y Plantillas Faltantes +## 3. Implementación de Vistas y Plantillas * **Perfil de Usuario (`app/templates/auth/profile.html`):** * Vista completa con datos del usuario, rol, estado, fecha de registro y reservas recientes. - * Formulario interactivo para configurar la **Preferencia de Idioma** (*Detectar automáticamente del navegador*, *Español*, *English*). + * Formulario integral para configurar **Idioma de la interfaz** (*Detectar automáticamente del navegador*, *Español*, *English*) y **Tema visual** (*Automático*, *Modo Claro*, *Modo Oscuro*). * **Cambio de Contraseña (`app/templates/auth/change_password.html`):** * Formulario seguro para actualización de credenciales. * **Manejo de Errores (`app/templates/auth/403.html`):** - * Pantalla de error 403 Forbidden estilizada. + * Pantalla de error 403 Forbidden estilizada e integrada con el sistema de diseño. --- -## 4. Correcciones de UX y Bugs de Rutas +## 4. Correcciones de UX, Linter y Bugs de Rutas * **Navbar Limpio (`app/templates/base.html`):** * Eliminación del bloque duplicado del menú de usuario `System Administrator`. * **Corrección de BuildError en Comisiones:** * En `app/routes/classrooms.py`, se agregó el alias de ruta `@classrooms_bp.route('/', endpoint='index')` para resolver enlaces a `classrooms.index`. * En `app/templates/schedule/commissions.html`, se reemplazó el filtro inválido de Django `truncatewords(20)` por el filtro estándar de Jinja2 `truncate(100)`. * **Corrección Visual en `/genetic-optimizer` (`app/templates/genetic_optimizer.html`):** - * Se agregó el espaciado `pt-5 mt-4` evitando que la barra de navegación fija superior (`fixed-top`) se monte sobre el contenido. + * Se agregó el espaciado `pt-5 mt-4` evitando que la barra fija superior se monte sobre el contenido. * Rediseño de tarjeta hero con contraste óptimo y reemplazo de iconos faltantes por Bootstrap Icons (`bi bi-...`). -* **Corrección en Calendario (`app/templates/schedule/calendar.html`):** - * Inclusión de contenedor con espaciado superior y bundle de localización `locales-all.min.js` para FullCalendar. +* **Corrección de Errores del Linter en `schedule/add.html` y `schedule/view.html`:** + * En `add.html`: Desacople de iteraciones Jinja a ` +{% endblock %} diff --git a/app/templates/admin/roles/edit.html b/app/templates/admin/roles/edit.html new file mode 100644 index 0000000..293548d --- /dev/null +++ b/app/templates/admin/roles/edit.html @@ -0,0 +1,191 @@ +{% extends "base.html" %} + +{% block title %}{% if role %}{% trans %}Editar Rol{% endtrans %}: {{ role.name }}{% else %}{% trans %}Nuevo Rol{% endtrans %}{% endif %} - Edu-Space Admin{% endblock %} + +{% block content %} +
+ +
+
+

+ + {% if role %}{% trans %}Editar Rol y Permisos de Acceso{% endtrans %}{% else %}{% trans %}Crear Rol y Permisos de Acceso{% endtrans %}{% endif %} +

+

{% trans %}Configure permisos granulares por módulo con la matriz de acceso estilo FortiGate.{% endtrans %}

+
+
+ + {% trans %}Volver a Roles{% endtrans %} + +
+
+ +
+
+ +
+
+
+
+ {% trans %}Información del Rol{% endtrans %} +
+
+
+
+ + + {% if role and role.is_system %} + + {% trans %}Rol del sistema protegido.{% endtrans %} + + {% endif %} +
+ +
+ + +
+ +
+ +
+ + + {% trans %}Cancelar{% endtrans %} + +
+
+
+
+ + +
+
+ +
+ + {% trans %}Permisos de Acceso{% endtrans %} + + + + +
+ + +
+ + + + + + + + + {% for mod in modules %} + {% set cur_level = current_perms.get(mod.id, 'none') %} + + + + + {% endfor %} + +
{% trans %}Módulo del Sistema{% endtrans %}{% trans %}Nivel de Permiso{% endtrans %}
+
+
+ +
+
+
{{ mod.name }}
+ {{ mod.description }} +
+
+
+ + + + +
+ + + +
+
+
+
+
+
+
+
+{% endblock %} + +{% block extra_js %} + +{% endblock %} diff --git a/app/templates/admin/roles/list.html b/app/templates/admin/roles/list.html new file mode 100644 index 0000000..9d49822 --- /dev/null +++ b/app/templates/admin/roles/list.html @@ -0,0 +1,124 @@ +{% extends "base.html" %} + +{% block title %}{% trans %}Roles y Grupos de Acceso{% endtrans %} - Edu-Space Admin{% endblock %} + +{% block content %} +
+ +
+
+

+ {% trans %}Roles y Grupos de Acceso{% endtrans %} +

+

{% trans %}Administración de perfiles de usuario y matriz granular de permisos por módulo del sistema.{% endtrans %}

+
+
+ + {% trans %}Nuevo Rol{% endtrans %} + +
+
+ + +
+
+ + + + + + + + + + + + {% for role in roles %} + + + + + + + + {% endfor %} + +
{% trans %}Nombre del Rol{% endtrans %}{% trans %}Descripción{% endtrans %}{% trans %}Integrantes{% endtrans %}{% trans %}Resumen de Permisos{% endtrans %}{% trans %}Acciones{% endtrans %}
+
+
+ +
+
+
{{ role.name }}
+ {% if role.is_system %} + {% trans %}Protegido del Sistema{% endtrans %} + {% endif %} +
+
+
+ {{ role.description or _('Sin descripción provista.') }} + + + {{ role.users|length }} {% trans %}usuarios{% endtrans %} + + +
+ {% for mod in modules %} + {% set p_level = role.get_permission(mod.id) %} + {% if p_level == 'read_write' %} + + {{ mod.name }}: RW + + {% elif p_level == 'read' %} + + {{ mod.name }}: R + + {% else %} + + {{ mod.name }}: - + + {% endif %} + {% endfor %} +
+
+
+ + {% trans %}Permisos{% endtrans %} + + {% if not role.is_system %} + + {% endif %} +
+ + {% if not role.is_system %} + + + {% endif %} +
+
+
+
+{% endblock %} diff --git a/app/templates/admin/users/form.html b/app/templates/admin/users/form.html new file mode 100644 index 0000000..19075ba --- /dev/null +++ b/app/templates/admin/users/form.html @@ -0,0 +1,107 @@ +{% extends "base.html" %} + +{% block title %}{% if user %}{% trans %}Edit User{% endtrans %}: {{ user.name }}{% else %}{% trans %}New User{% endtrans %}{% endif %} - Edu-Space Admin{% endblock %} + +{% block content %} +
+ +
+
+

+ + {% if user %}{% trans %}Edit User Account{% endtrans %}{% else %}{% trans %}Create User Account{% endtrans %}{% endif %} +

+

{% trans %}Configure user credentials, profile information, and role assignment.{% endtrans %}

+
+
+ + {% trans %}Back to Users{% endtrans %} + +
+
+ +
+
+
+
+
+ {% trans %}Account Details{% endtrans %} +
+
+
+
+
+ + +
+ +
+ + +
+ +
+ + + {% if user %} + + {% trans %}Only fill this in if you want to reset this user's password.{% endtrans %} + + {% endif %} +
+ +
+ + + + + {% trans %}View or manage roles and permissions{% endtrans %} + + +
+ +
+ + + + {% trans %}Inactive users are prevented from signing in to the platform.{% endtrans %} + + {% if user and user.id == current_user.id %} + + {% endif %} +
+ +
+ + {% trans %}Cancel{% endtrans %} + + +
+
+
+
+
+
+
+{% endblock %} diff --git a/app/templates/admin/users/list.html b/app/templates/admin/users/list.html new file mode 100644 index 0000000..88870f1 --- /dev/null +++ b/app/templates/admin/users/list.html @@ -0,0 +1,182 @@ +{% extends "base.html" %} + +{% block title %}{% trans %}User Management{% endtrans %} - Edu-Space Admin{% endblock %} + +{% block content %} +
+ +
+
+

+ {% trans %}User Management{% endtrans %} +

+

{% trans %}Manage user accounts, assign roles, and control active status.{% endtrans %}

+
+
+ + {% trans %}New User{% endtrans %} + +
+
+ + +
+
+
+
+
+ + + + +
+
+
+ +
+
+ +
+
+ + {% if search or role_filter or status_filter %} + + + + {% endif %} +
+
+
+
+ + +
+
+ + + + + + + + + + + + + {% for u in users %} + + + + + + + + + {% else %} + + + + {% endfor %} + +
{% trans %}User{% endtrans %}{% trans %}Email{% endtrans %}{% trans %}Role / Group{% endtrans %}{% trans %}Status{% endtrans %}{% trans %}Last Login{% endtrans %}{% trans %}Actions{% endtrans %}
+
+
+ {{ (u.first_name[0] if u.first_name else 'U')|upper }} +
+
+
{{ u.name }}
+ ID: #{{ u.id }} +
+
+
+ {{ u.email }} + + {% if u.role_obj %} + + {{ u.role_obj.name }} + + {% else %} + + {{ u.role or _('No Role') }} + + {% endif %} + + {% if u.is_active %} + + {% trans %}Active{% endtrans %} + + {% else %} + + {% trans %}Inactive{% endtrans %} + + {% endif %} + + + {% if u.last_login %} + {{ format_datetime(u.last_login, format='short') }} + {% else %} + {% trans %}Never{% endtrans %} + {% endif %} + + +
+ + + + {% if u.id != current_user.id %} +
+ +
+ {% endif %} +
+
+ + {% trans %}No users found matching the criteria.{% endtrans %} +
+
+ + + {% if pagination.pages > 1 %} + + {% endif %} +
+
+{% endblock %} diff --git a/app/templates/auth/login.html b/app/templates/auth/login.html index 9ffc30b..6de8322 100644 --- a/app/templates/auth/login.html +++ b/app/templates/auth/login.html @@ -1,114 +1,115 @@ - + {% trans %}Login - Edu-Space Admin{% endtrans %} + + + + + + + + - + + -
-
-
- {% include 'partials/language_switcher.html' %} -
- -

Edu-Space Admin

-

{% trans %}Classroom Management System{% endtrans %}

-
- -
- {% with messages = get_flashed_messages(with_categories=true) %} - {% if messages %} - {% for category, message in messages %} - - {% endfor %} - {% endif %} - {% endwith %} - -
- {{ form.hidden_tag() }} - -
- -
- - -
- {% for error in form.email.errors %} -
{{ error }}
- {% endfor %} -
- -
- -
- - -
- {% for error in form.password.errors %} -
{{ error }}
- {% endfor %} -
- -
- {{ form.remember_me(class="form-check-input") }} - -
- -
- + {% include 'partials/language_switcher.html' %}
-
+ + +

Edu-Space Admin

+

{% trans %}Classroom Management System{% endtrans %}

+
-
- - - {% trans %}Secure Login • All access is logged{% endtrans %} - +
+ + {% with messages = get_flashed_messages(with_categories=true) %} + {% if messages %} + {% for category, message in messages %} + + {% endfor %} + {% endif %} + {% endwith %} + +
+ {{ form.hidden_tag() }} + +
+ +
+ + + + +
+ {% for error in form.email.errors %} +
{{ error }}
+ {% endfor %} +
+ +
+ +
+ + + + +
+ {% for error in form.password.errors %} +
{{ error }}
+ {% endfor %} +
+ +
+ {{ form.remember_me(class="form-check-input") }} + +
+ +
+ +
+
+ +
+ + + {% trans %}Secure Login • All access is logged{% endtrans %} + +
+ \ No newline at end of file diff --git a/app/templates/auth/profile.html b/app/templates/auth/profile.html index d4a9279..60b9d5b 100644 --- a/app/templates/auth/profile.html +++ b/app/templates/auth/profile.html @@ -76,17 +76,19 @@
- +
- -

- {% trans %}If set, this language overrides the browser configuration for all your sessions.{% endtrans %} -

-
-
- @@ -97,13 +99,38 @@ English + + {% trans %}If set, this language overrides the browser configuration for all your sessions.{% endtrans %} +
-
- + + +
+ + + + {% trans %}Choose your preferred visual theme.{% endtrans %} +
+ +
+ +