Spaces:
Sleeping
Sleeping
| #modules/admin/admin_ui.py | |
| import streamlit as st | |
| from datetime import datetime | |
| from ..database.sql_db import ( | |
| get_user, | |
| get_student_user, | |
| get_admin_user, | |
| get_teacher_user, | |
| create_student_user, | |
| update_student_user, | |
| delete_student_user, | |
| record_login, | |
| record_logout, | |
| get_recent_sessions, | |
| get_user_total_time | |
| ) | |
| from ..database.morphosintax_mongo_db import get_student_morphosyntax_analysis | |
| from ..auth.auth import hash_password # Agregar esta importación al inicio | |
| ######################################################## | |
| def format_duration(seconds): | |
| """Convierte segundos a formato legible""" | |
| if not seconds: | |
| return "0h 0m" | |
| hours = seconds // 3600 | |
| minutes = (seconds % 3600) // 60 | |
| return f"{hours}h {minutes}m" | |
| ######################################################## | |
| def admin_page(): | |
| st.title("Panel de Administración") | |
| st.write(f"Bienvenido, {st.session_state.username}") | |
| # Crear tres tabs para las diferentes secciones | |
| tab1, tab2, tab3 = st.tabs([ | |
| "Gestión de Usuarios", | |
| "Búsqueda de Usuarios", | |
| "Actividad de la Plataforma" | |
| ]) | |
| ######################################################## | |
| # Tab 1: Gestión de Usuarios | |
| with tab1: | |
| st.header("Crear Nuevo Usuario Estudiante") | |
| # Crear dos columnas para el formulario | |
| col1, col2 = st.columns(2) | |
| with col1: | |
| new_username = st.text_input( | |
| "Correo electrónico del nuevo usuario", | |
| key="admin_new_username" | |
| ) | |
| with col2: | |
| new_password = st.text_input( | |
| "Contraseña", | |
| type="password", | |
| key="admin_new_password" | |
| ) | |
| if st.button("Crear Usuario", key="admin_create_user", type="primary"): | |
| if new_username and new_password: # Verificamos que ambos campos tengan valor | |
| try: | |
| # Hashear la contraseña antes de crear el usuario | |
| hashed_password = hash_password(new_password) | |
| if create_student_user(new_username, hashed_password, {'partitionKey': new_username}): | |
| st.success(f"Usuario estudiante {new_username} creado exitosamente") | |
| else: | |
| st.error("Error al crear el usuario estudiante") | |
| except Exception as e: | |
| st.error(f"Error al crear usuario: {str(e)}") | |
| else: | |
| st.warning("Por favor complete todos los campos") | |
| ####################################################################### | |
| # Tab 2: Búsqueda de Usuarios | |
| with tab2: | |
| st.header("Búsqueda de Usuarios") | |
| search_col1, search_col2 = st.columns([2,1]) | |
| with search_col1: | |
| student_username = st.text_input( | |
| "Nombre de usuario del estudiante", | |
| key="admin_view_student" | |
| ) | |
| with search_col2: | |
| search_button = st.button( | |
| "Buscar", | |
| key="admin_view_student_data", | |
| type="primary" | |
| ) | |
| if search_button: | |
| student = get_student_user(student_username) | |
| if student: | |
| # Crear tabs para diferentes tipos de información | |
| info_tab1, info_tab2, info_tab3 = st.tabs([ | |
| "Información Básica", | |
| "Análisis Realizados", | |
| "Tiempo en Plataforma" | |
| ]) | |
| with info_tab1: | |
| st.subheader("Información del Usuario") | |
| st.json(student) | |
| with info_tab2: | |
| st.subheader("Análisis Realizados") | |
| student_data = get_student_morphosyntax_analysis(student_username) | |
| if student_data: | |
| st.json(student_data) | |
| else: | |
| st.info("No hay datos de análisis para este estudiante.") | |
| with info_tab3: | |
| st.subheader("Tiempo en Plataforma") | |
| total_time = get_user_total_time(student_username) | |
| if total_time: | |
| st.metric( | |
| "Tiempo Total", | |
| format_duration(total_time) | |
| ) | |
| else: | |
| st.info("No hay registros de tiempo para este usuario") | |
| else: | |
| st.error("Estudiante no encontrado") | |
| ####################################################################### | |
| # Tab 3: Actividad de la Plataforma | |
| with tab3: | |
| st.header("Actividad Reciente") | |
| # Agregar botón de actualización | |
| if st.button("Actualizar datos", key="refresh_sessions", type="primary"): | |
| st.rerun() | |
| # Mostrar spinner mientras carga | |
| with st.spinner("Cargando datos de sesiones..."): | |
| # Obtener sesiones recientes | |
| recent_sessions = get_recent_sessions(20) # Aumentado a 20 para más datos | |
| if recent_sessions: | |
| # Crear dataframe para mostrar los datos | |
| sessions_data = [] | |
| for session in recent_sessions: | |
| try: | |
| # Manejar el formato de fecha con manejo de excepciones | |
| try: | |
| login_time = datetime.fromisoformat( | |
| session['loginTime'].replace('Z', '+00:00') | |
| ).strftime("%Y-%m-%d %H:%M:%S") | |
| except Exception as e: | |
| login_time = session['loginTime'] | |
| # Manejar el caso de logout_time cuando la sesión está activa | |
| if session.get('logoutTime') and session['logoutTime'] != "Activo": | |
| try: | |
| logout_time = datetime.fromisoformat( | |
| session['logoutTime'].replace('Z', '+00:00') | |
| ).strftime("%Y-%m-%d %H:%M:%S") | |
| except Exception as e: | |
| logout_time = session['logoutTime'] | |
| else: | |
| logout_time = "Activo" | |
| # Agregar datos a la lista | |
| sessions_data.append({ | |
| "Usuario": session.get('username', 'Desconocido'), | |
| "Inicio de Sesión": login_time, | |
| "Fin de Sesión": logout_time, | |
| "Duración": format_duration(session.get('sessionDuration', 0)) | |
| }) | |
| except Exception as e: | |
| st.error(f"Error procesando sesión: {str(e)}") | |
| continue | |
| # Mostrar información de depuración si hay problemas | |
| with st.expander("Información de depuración", expanded=False): | |
| st.write("Datos crudos recuperados:") | |
| st.json(recent_sessions) | |
| st.write("Datos procesados para mostrar:") | |
| st.json(sessions_data) | |
| # Mostrar tabla con estilos | |
| st.dataframe( | |
| sessions_data, | |
| hide_index=True, | |
| column_config={ | |
| "Usuario": st.column_config.TextColumn( | |
| "Usuario", | |
| width="medium" | |
| ), | |
| "Inicio de Sesión": st.column_config.TextColumn( | |
| "Inicio de Sesión", | |
| width="medium" | |
| ), | |
| "Fin de Sesión": st.column_config.TextColumn( | |
| "Fin de Sesión", | |
| width="medium" | |
| ), | |
| "Duración": st.column_config.TextColumn( | |
| "Duración", | |
| width="small" | |
| ) | |
| } | |
| ) | |
| # Añadir métricas resumen | |
| total_sessions = len(sessions_data) | |
| total_users = len(set(session['Usuario'] for session in sessions_data)) | |
| metric_col1, metric_col2 = st.columns(2) | |
| with metric_col1: | |
| st.metric("Total de Sesiones", total_sessions) | |
| with metric_col2: | |
| st.metric("Usuarios Únicos", total_users) | |
| else: | |
| st.info("No hay registros de sesiones recientes o hubo un problema al recuperarlos.") | |
| # Ayuda de depuración | |
| if st.button("Mostrar diagnóstico"): | |
| st.write("Verificando la función get_recent_sessions:") | |
| container = get_container("users_sessions") | |
| if container: | |
| st.success("✅ Conectado al contenedor users_sessions") | |
| else: | |
| st.error("❌ No se pudo conectar al contenedor users_sessions") | |
| ################################################################## | |
| # Agregar una línea divisoria antes del botón | |
| st.markdown("---") | |
| ################################################################## | |
| # Centrar el botón de cierre de sesión | |
| col1, col2, col3 = st.columns([2,1,2]) | |
| with col2: | |
| if st.button("Cerrar Sesión", key="admin_logout", type="primary", use_container_width=True): | |
| from ..auth.auth import logout | |
| logout() | |
| st.rerun() |