fix(admin): resolver pantalla en blanco al editar ficha de usuario (GET /admin/users/edit/:id)

This commit is contained in:
2026-09-23 15:58:03 -03:00
parent 9ebfedd17f
commit 7b6baca2b5
3 changed files with 65 additions and 15 deletions
+42 -7
View File
@@ -382,28 +382,63 @@ const handleUserAdd = async (req, res) => {
title: 'Nuevo Usuario — Edu-Space Admin',
user: null,
roles,
document_types
document_types,
error: req.query.error || null,
msg: req.query.msg || null
});
} catch (err) {
console.error('Error in user add:', err.message);
res.render('admin/users/form', { title: 'Nuevo Usuario', user: null, roles: MOCK_ROLES, document_types: [] });
res.render('admin/users/form', {
title: 'Nuevo Usuario — Edu-Space Admin',
user: null,
roles: MOCK_ROLES,
document_types: [],
error: req.query.error || null,
msg: null
});
}
};
const handleUserEdit = async (req, res) => {
try {
const { users, roles, document_types } = await fetchUsersAndRoles(req.apiClient);
const userId = req.params.id || req.query.id;
const targetUser = (userId ? users.find(u => String(u.id) === String(userId)) : null) || users[0] || MOCK_USERS[0];
const { users, roles, document_types } = await fetchUsersAndRoles(req.apiClient);
let targetUser = userId ? users.find(u => String(u.id) === String(userId)) : null;
// Si no se encontró en la lista general y hay userId, intentar fetch individual
if (!targetUser && userId && req.apiClient) {
try {
const singleRes = await req.apiClient.get(`/users/${userId}`);
if (singleRes.data && (singleRes.data.user || singleRes.data.data)) {
targetUser = singleRes.data.user || singleRes.data.data;
}
} catch (e) {
console.warn(`User ${userId} not found via single endpoint:`, e.message);
}
}
targetUser = targetUser || (userId ? null : users[0]) || MOCK_USERS[0];
const userName = targetUser ? (targetUser.name || `${targetUser.first_name || ''} ${targetUser.last_name || ''}`.trim() || targetUser.email || `Usuario #${targetUser.id}`) : 'Usuario';
res.render('admin/users/form', {
title: `Editar Usuario: ${targetUser.name} — Edu-Space Admin`,
title: `Editar Usuario: ${userName} — Edu-Space Admin`,
user: targetUser,
roles,
document_types
document_types,
error: req.query.error || null,
msg: req.query.msg || null
});
} catch (err) {
console.error('Error in user edit:', err.message);
res.render('admin/users/form', { title: 'Editar Usuario', user: MOCK_USERS[0], roles: MOCK_ROLES, document_types: [] });
res.render('admin/users/form', {
title: 'Editar Usuario — Edu-Space Admin',
user: MOCK_USERS[0],
roles: MOCK_ROLES,
document_types: [],
error: 'No se pudo cargar la información del usuario.',
msg: null
});
}
};
+9 -8
View File
@@ -1,3 +1,4 @@
{% set auth_user = current_user if (current_user and current_user.is_authenticated) else user %}
<!DOCTYPE html>
<html lang="{{ current_lang }}" data-bs-theme="dark">
<head>
@@ -11,7 +12,7 @@
<!-- Script Anti-Flicker para Modo Claro / Oscuro -->
<script>
(function() {
let userTheme = "{{ user.theme_preference if (user and user.is_authenticated) else '' }}";
let userTheme = "{{ auth_user.theme_preference if (auth_user and auth_user.is_authenticated) else '' }}";
let theme = userTheme;
if (!theme || theme === 'auto') {
const storedTheme = localStorage.getItem('theme');
@@ -570,8 +571,8 @@
{% block extra_css %}{% endblock %}
</head>
<body data-user-authenticated="{{ 'true' if (user and user.is_authenticated) else 'false' }}">
{% if user.is_authenticated %}
<body data-user-authenticated="{{ 'true' if (auth_user and auth_user.is_authenticated) else 'false' }}">
{% if auth_user and auth_user.is_authenticated %}
<div class="app-wrapper">
<!-- Sidebar -->
@@ -591,7 +592,7 @@
<div class="sidebar-body flex-grow-1 overflow-y-auto p-2">
<ul class="sidebar-nav" id="sidebarNav">
{% set user_role = role if role else 'admin' %}
{% set user_role = role if role else (auth_user.role if auth_user else 'admin') %}
{% if user_role == 'admin' %}
<!-- ADMIN -->
<li class="nav-item">
@@ -700,15 +701,15 @@
<div class="dropdown dropup">
<a href="#" class="d-flex align-items-center text-decoration-none dropdown-toggle text-body w-100" data-bs-toggle="dropdown" aria-expanded="false">
<div class="user-avatar-small bg-primary text-white rounded-circle d-flex align-items-center justify-content-center" style="width:32px; height:32px; font-weight:bold; flex-shrink:0;">
{{ user.name[0]|upper if user.name else 'U' }}
{{ auth_user.name[0]|upper if auth_user.name else 'U' }}
</div>
<div class="ms-2 sidebar-footer-text text-truncate flex-grow-1" style="min-width:0;">
<small class="d-block fw-semibold text-truncate">{{ user.first_name }}</small>
<small class="text-muted d-block text-truncate" style="font-size:0.7rem;">{{ user.role_badge_display.label }}</small>
<small class="d-block fw-semibold text-truncate">{{ auth_user.first_name or auth_user.name }}</small>
<small class="text-muted d-block text-truncate" style="font-size:0.7rem;">{{ auth_user.role_badge_display.label if (auth_user and auth_user.role_badge_display) else (auth_user.role|capitalize if auth_user else 'Usuario') }}</small>
</div>
</a>
<ul class="dropdown-menu shadow-sm border-0 mb-2">
<li><h6 class="dropdown-header">{{ user.email }}</h6></li>
<li><h6 class="dropdown-header">{{ auth_user.email if auth_user else '' }}</h6></li>
<li><a class="dropdown-item" href="/auth/profile"><i class="bi bi-person me-2"></i>Mi Perfil</a></li>
<li><a class="dropdown-item" href="/auth/change_password"><i class="bi bi-key me-2"></i>Cambiar Contraseña</a></li>
<li><hr class="dropdown-divider"></li>