| 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.semantic_mongo_db import get_student_semantic_analysis |
|
|
| |
| from ..auth.auth import hash_password |
|
|
| |
| 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}") |
|
|
| |
| tab1, tab2, tab3 = st.tabs([ |
| "Gestión de Usuarios", |
| "Búsqueda de Usuarios", |
| "Actividad de la Plataforma" |
| ]) |
|
|
| |
| |
| |
| with tab1: |
| st.header("Crear Nuevo Usuario Estudiante") |
| |
| |
| 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: |
| try: |
| |
| 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") |
|
|
| |
| |
| 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: |
| |
| 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_semantic_analysis(username, limit=10) |
| 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") |
|
|
| |
| |
| with tab3: |
| st.header("Actividad Reciente") |
| |
| |
| if st.button("Actualizar datos", key="refresh_sessions", type="primary"): |
| st.rerun() |
| |
| |
| with st.spinner("Cargando datos de sesiones..."): |
| |
| recent_sessions = get_recent_sessions(20) |
| |
| if recent_sessions: |
| |
| sessions_data = [] |
| for session in recent_sessions: |
| try: |
| |
| login_val = session.get('loginTime') |
| if isinstance(login_val, datetime): |
| login_time = login_val.strftime("%Y-%m-%d %H:%M:%S") |
| else: |
| login_time = str(login_val) if login_val else "N/A" |
| |
| |
| logout_val = session.get('logoutTime') |
| if isinstance(logout_val, datetime): |
| logout_time = logout_val.strftime("%Y-%m-%d %H:%M:%S") |
| elif logout_val == "Activo" or not logout_val: |
| logout_time = "Activo" |
| else: |
| logout_time = str(logout_val) |
|
|
| |
| 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 |
| |
| |
| 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) |
| |
| |
| 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") |
| } |
| ) |
| |
| |
| total_sessions = len(sessions_data) |
| total_users = len(set(s['Usuario'] for s 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.") |
| |
| 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") |
|
|
| |
| |
| st.markdown("---") |
|
|
| |
| |
| 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() |