| import streamlit as st
|
| import logging
|
| from datetime import datetime, timezone
|
| from dateutil.parser import parse
|
|
|
|
|
| logging.basicConfig(level=logging.INFO)
|
| logger = logging.getLogger(__name__)
|
|
|
|
|
|
|
| from ..utils.widget_utils import generate_unique_key
|
| from session_state import initialize_session_state, logout
|
|
|
| from translations import get_translations
|
|
|
| from ..auth.auth import authenticate_user, authenticate_student, authenticate_admin
|
|
|
| from ..admin.admin_ui import admin_page
|
|
|
| from ..chatbot import display_sidebar_chat
|
|
|
|
|
| from ..studentact.student_activities_v2 import display_student_activities
|
| from ..studentact.current_situation_interface import display_current_situation_interface
|
| from ..studentact.current_situation_analysis import analyze_text_dimensions
|
|
|
|
|
|
|
|
|
| from ..database.sql_db import (
|
| get_user,
|
| get_admin_user,
|
| get_student_user,
|
| get_teacher_user,
|
| create_user,
|
| create_student_user,
|
| create_teacher_user,
|
| create_admin_user,
|
| update_student_user,
|
| delete_student_user,
|
| record_login,
|
| record_logout,
|
| get_recent_sessions,
|
| get_user_total_time,
|
| store_application_request,
|
| store_student_feedback
|
| )
|
|
|
| from ..database.mongo_db import (
|
| get_collection,
|
| insert_document,
|
| find_documents,
|
| update_document,
|
| delete_document
|
| )
|
|
|
| from ..database.morphosintax_mongo_db import (
|
| store_student_morphosyntax_result,
|
| get_student_morphosyntax_analysis,
|
| update_student_morphosyntax_analysis,
|
| delete_student_morphosyntax_analysis,
|
| get_student_morphosyntax_data
|
| )
|
|
|
| from ..database.chat_mongo_db import store_chat_history, get_chat_history
|
|
|
|
|
| from ..morphosyntax.morphosyntax_interface import (
|
| display_morphosyntax_interface,
|
| display_arc_diagram
|
| )
|
|
|
| from ..semantic.semantic_interface import (
|
| display_semantic_interface,
|
| display_semantic_results
|
| )
|
|
|
| from ..semantic.semantic_live_interface import display_semantic_live_interface
|
|
|
| from ..discourse.discourse_live_interface import display_discourse_live_interface
|
|
|
| from ..discourse.discourse_interface import (
|
| display_discourse_interface,
|
| display_discourse_results
|
| )
|
|
|
|
|
|
|
|
|
| def user_page(lang_code, t):
|
| logger.info(f"Entrando en user_page para el estudiante: {st.session_state.username}")
|
|
|
|
|
| if 'selected_tab' not in st.session_state:
|
| st.session_state.selected_tab = 0
|
|
|
|
|
| if 'semantic_live_active' not in st.session_state:
|
| st.session_state.semantic_live_active = False
|
|
|
|
|
| if 'user_data' not in st.session_state:
|
| with st.spinner(t.get('loading_data', "Cargando tus datos...")):
|
| try:
|
| st.session_state.user_data = get_student_morphosyntax_data(st.session_state.username)
|
| st.session_state.last_data_fetch = datetime.now(timezone.utc).isoformat()
|
| except Exception as e:
|
| logger.error(f"Error al obtener datos del usuario: {str(e)}")
|
| st.error(t.get('data_load_error', "Hubo un problema al cargar tus datos. Por favor, intenta recargar la p谩gina."))
|
| return
|
|
|
| logger.info(f"Idioma actual: {st.session_state.lang_code}")
|
| logger.info(f"Modelos NLP cargados: {'nlp_models' in st.session_state}")
|
|
|
|
|
| languages = {'Espa帽ol': 'es', 'English': 'en', 'Fran莽ais': 'fr', 'Portugu锚s': 'pt'}
|
|
|
|
|
| st.markdown("""
|
| <style>
|
| .stSelectbox > div > div {
|
| padding-top: 0px;
|
| }
|
| .stButton > button {
|
| padding-top: 2px;
|
| margin-top: 0px;
|
| }
|
| div[data-testid="stHorizontalBlock"] > div:nth-child(3) {
|
| display: flex;
|
| justify-content: flex-end;
|
| align-items: center;
|
| }
|
| </style>
|
| """, unsafe_allow_html=True)
|
|
|
|
|
| with st.container():
|
| col1, col2, col3 = st.columns([2, 2, 1])
|
| with col1:
|
| st.markdown(f"<h3 style='margin-bottom: 0; padding-top: 10px;'>{t['welcome']}, {st.session_state.username}</h3>",
|
| unsafe_allow_html=True)
|
| with col2:
|
| selected_lang = st.selectbox(
|
| t['select_language'],
|
| list(languages.keys()),
|
| index=list(languages.values()).index(st.session_state.lang_code),
|
| key=f"language_selector_{st.session_state.username}_{st.session_state.lang_code}"
|
| )
|
| new_lang_code = languages[selected_lang]
|
| if st.session_state.lang_code != new_lang_code:
|
| st.session_state.lang_code = new_lang_code
|
| st.rerun()
|
| with col3:
|
| if st.button(t['logout'],
|
| key=f"logout_button_{st.session_state.username}_{st.session_state.lang_code}"):
|
| st.session_state.clear()
|
| st.rerun()
|
|
|
| st.markdown("---")
|
|
|
|
|
| chatbot_t = t.get('CHATBOT_TRANSLATIONS', {}).get(lang_code, {})
|
|
|
|
|
| display_sidebar_chat(lang_code, chatbot_t)
|
|
|
|
|
| if 'tab_states' not in st.session_state:
|
| st.session_state.tab_states = {
|
| 'current_situation_active': False,
|
| 'morpho_active': False,
|
|
|
| 'semantic_active': False,
|
|
|
| 'discourse_active': False,
|
| 'activities_active': False,
|
| 'feedback_active': False
|
| }
|
|
|
|
|
| tab_names = [
|
| t.get('current_situation_tab', "Mi Situaci贸n Actual"),
|
| t.get('morpho_tab', 'An谩lisis Morfosint谩ctico'),
|
|
|
| t.get('semantic_tab', 'An谩lisis Sem谩ntico'),
|
|
|
| t.get('discourse_tab', 'An谩lisis comparado de textos'),
|
| t.get('activities_tab', 'Registro de mis actividades'),
|
| t.get('feedback_tab', 'Formulario de Comentarios')
|
| ]
|
|
|
| tabs = st.tabs(tab_names)
|
|
|
|
|
| for index, tab in enumerate(tabs):
|
| with tab:
|
| try:
|
|
|
| if tab.selected and st.session_state.selected_tab != index:
|
| can_switch = True
|
| for state_key in st.session_state.tab_states.keys():
|
| if st.session_state.tab_states[state_key] and index != get_tab_index(state_key):
|
| can_switch = False
|
| break
|
| if can_switch:
|
| st.session_state.selected_tab = index
|
|
|
| if index == 0:
|
| st.session_state.tab_states['current_situation_active'] = True
|
| display_current_situation_interface(
|
| st.session_state.lang_code,
|
| st.session_state.nlp_models,
|
| t
|
| )
|
|
|
| elif index == 1:
|
| st.session_state.tab_states['morpho_active'] = True
|
| display_morphosyntax_interface(
|
| st.session_state.lang_code,
|
| st.session_state.nlp_models,
|
| t
|
| )
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| elif index == 2:
|
| st.session_state.tab_states['semantic_active'] = True
|
| display_semantic_interface(
|
| st.session_state.lang_code,
|
| st.session_state.nlp_models,
|
| t
|
| )
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| elif index == 3:
|
| st.session_state.tab_states['discourse_active'] = True
|
| display_discourse_interface(
|
| st.session_state.lang_code,
|
| st.session_state.nlp_models,
|
| t
|
| )
|
|
|
| elif index == 4:
|
| st.session_state.tab_states['activities_active'] = True
|
| display_student_activities(
|
| username=st.session_state.username,
|
| lang_code=st.session_state.lang_code,
|
| t=t
|
| )
|
|
|
| elif index == 5:
|
| st.session_state.tab_states['feedback_active'] = True
|
| display_feedback_form(
|
| st.session_state.lang_code,
|
| t
|
| )
|
|
|
| except Exception as e:
|
|
|
| state_key = get_state_key_for_index(index)
|
| if state_key:
|
| st.session_state.tab_states[state_key] = False
|
| logger.error(f"Error en tab {index}: {str(e)}")
|
| st.error(t.get('tab_error', 'Error al cargar esta secci贸n'))
|
|
|
|
|
| if st.session_state.get('debug_mode', False):
|
| with st.expander("Debug Info"):
|
| st.write(f"P谩gina actual: {st.session_state.page}")
|
| st.write(f"Usuario: {st.session_state.get('username', 'No logueado')}")
|
| st.write(f"Rol: {st.session_state.get('role', 'No definido')}")
|
| st.write(f"Idioma: {st.session_state.lang_code}")
|
| st.write(f"Tab seleccionado: {st.session_state.selected_tab}")
|
| st.write(f"脷ltima actualizaci贸n de datos: {st.session_state.get('last_data_fetch', 'Nunca')}")
|
| st.write(f"Traducciones disponibles: {list(t.keys())}")
|
|
|
|
|
| def get_tab_index(state_key):
|
| """Obtiene el 铆ndice del tab basado en la clave de estado"""
|
| index_map = {
|
| 'current_situation_active': 0,
|
| 'morpho_active': 1,
|
|
|
| 'semantic_active': 2,
|
|
|
| 'discourse_active': 3,
|
| 'activities_active': 4,
|
| 'feedback_active': 5
|
| }
|
| return index_map.get(state_key, -1)
|
|
|
| def get_state_key_for_index(index):
|
| """Obtiene la clave de estado basada en el 铆ndice del tab"""
|
| state_map = {
|
| 0: 'current_situation_active',
|
| 1: 'morpho_active',
|
|
|
| 2: 'semantic_active',
|
|
|
| 3: 'discourse_active',
|
| 4: 'activities_active',
|
| 5: 'feedback_active'
|
| }
|
| return state_map.get(index)
|
|
|
| def display_feedback_form(lang_code, t):
|
| """
|
| Muestra el formulario de retroalimentaci贸n
|
| Args:
|
| lang_code: C贸digo de idioma
|
| t: Diccionario de traducciones
|
| """
|
| logging.info(f"display_feedback_form called with lang_code: {lang_code}")
|
|
|
|
|
| feedback_t = t.get('FEEDBACK', {})
|
|
|
|
|
| if not feedback_t:
|
| feedback_t = t
|
|
|
|
|
|
|
| name = st.text_input(feedback_t.get('name', 'Nombre'))
|
| email = st.text_input(feedback_t.get('email', 'Correo electr贸nico'))
|
| feedback = st.text_area(feedback_t.get('feedback', 'Retroalimentaci贸n'))
|
|
|
| if st.button(feedback_t.get('submit', 'Enviar')):
|
| if name and email and feedback:
|
| if store_student_feedback(st.session_state.username, name, email, feedback):
|
| st.success(feedback_t.get('feedback_success', 'Gracias por tu respuesta'))
|
| else:
|
| st.error(feedback_t.get('feedback_error', 'Hubo un problema al enviar el formulario. Por favor, intenta de nuevo.'))
|
| else:
|
| st.warning(feedback_t.get('complete_all_fields', 'Por favor, completa todos los campos')) |