|
|
|
|
|
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() |