|
|
|
|
| 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
|
|
|
|
|
| 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_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")
|
|
|
|
|
|
|
| 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:
|
|
|
| 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']
|
|
|
|
|
| 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"
|
|
|
|
|
| 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(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.")
|
|
|
|
|
| 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")
|
|
|
|
|
|
|
|
|
| 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() |