AIdeaText commited on
Commit
708de37
verified
1 Parent(s): 110113e

Create user_page.py

Browse files
Files changed (1) hide show
  1. modules/ui/user_page.py +278 -0
modules/ui/user_page.py ADDED
@@ -0,0 +1,278 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import logging
3
+ from datetime import datetime, timezone
4
+
5
+ from ..utils.widget_utils import generate_unique_key
6
+ from ..database.morphosintax_mongo_db import get_student_morphosyntax_data
7
+ from ..database.sql_db import store_student_feedback
8
+
9
+ # Importaciones de componentes de interfaz
10
+ from ..morphosyntax.morphosyntax_interface import display_morphosyntax_interface
11
+ from ..semantic.semantic_interface import display_semantic_interface
12
+ from ..semantic.semantic_live_interface import display_semantic_live_interface
13
+ from ..discourse.discourse_interface import display_discourse_interface
14
+ from ..discourse.discourse_live_interface import display_discourse_live_interface
15
+ from ..studentact.student_activities_v2 import display_student_activities
16
+ from ..chatbot.sidebar_chat import display_sidebar_chat
17
+
18
+ logger = logging.getLogger(__name__)
19
+
20
+ def user_page(lang_code, t):
21
+ logger.info(f"Entrando en user_page para el estudiante: {st.session_state.username}")
22
+
23
+ # Inicializar el tab seleccionado si no existe
24
+ if 'selected_tab' not in st.session_state:
25
+ st.session_state.selected_tab = 0
26
+
27
+ # Inicializar el estado del an谩lisis en vivo
28
+ if 'semantic_live_active' not in st.session_state:
29
+ st.session_state.semantic_live_active = False
30
+
31
+ # Manejar la carga inicial de datos del usuario
32
+ if 'user_data' not in st.session_state:
33
+ with st.spinner(t.get('loading_data', "Cargando tus datos...")):
34
+ try:
35
+ st.session_state.user_data = get_student_morphosyntax_data(st.session_state.username)
36
+ st.session_state.last_data_fetch = datetime.now(timezone.utc).isoformat()
37
+ except Exception as e:
38
+ logger.error(f"Error al obtener datos del usuario: {str(e)}")
39
+ st.error(t.get('data_load_error', "Hubo un problema al cargar tus datos. Por favor, intenta recargar la p谩gina."))
40
+ return
41
+
42
+ logger.info(f"Idioma actual: {st.session_state.lang_code}")
43
+ logger.info(f"Modelos NLP cargados: {'nlp_models' in st.session_state}")
44
+
45
+ # Configuraci贸n de idiomas disponibles
46
+ languages = {'Espa帽ol': 'es', 'English': 'en', 'Fran莽ais': 'fr'}
47
+
48
+ # Estilos CSS personalizados
49
+ st.markdown("""
50
+ <style>
51
+ .stSelectbox > div > div {
52
+ padding-top: 0px;
53
+ }
54
+ .stButton > button {
55
+ padding-top: 2px;
56
+ margin-top: 0px;
57
+ }
58
+ div[data-testid="stHorizontalBlock"] > div:nth-child(3) {
59
+ display: flex;
60
+ justify-content: flex-end;
61
+ align-items: center;
62
+ }
63
+ </style>
64
+ """, unsafe_allow_html=True)
65
+
66
+ # Barra superior con informaci贸n del usuario y controles
67
+ with st.container():
68
+ col1, col2, col3 = st.columns([2, 2, 1])
69
+ with col1:
70
+ st.markdown(f"<h3 style='margin-bottom: 0; padding-top: 10px;'>{t['welcome']}, {st.session_state.username}</h3>",
71
+ unsafe_allow_html=True)
72
+ with col2:
73
+ selected_lang = st.selectbox(
74
+ t['select_language'],
75
+ list(languages.keys()),
76
+ index=list(languages.values()).index(st.session_state.lang_code),
77
+ key=f"language_selector_{st.session_state.username}_{st.session_state.lang_code}"
78
+ )
79
+ new_lang_code = languages[selected_lang]
80
+ if st.session_state.lang_code != new_lang_code:
81
+ st.session_state.lang_code = new_lang_code
82
+ st.rerun()
83
+ with col3:
84
+ if st.button(t['logout'],
85
+ key=f"logout_button_{st.session_state.username}_{st.session_state.lang_code}"):
86
+ st.session_state.clear()
87
+ st.rerun()
88
+
89
+ st.markdown("---")
90
+
91
+ # Asegurarse de que tenemos las traducciones del chatbot
92
+ chatbot_t = t.get('CHATBOT_TRANSLATIONS', {}).get(lang_code, {})
93
+
94
+ # Mostrar chatbot en sidebar
95
+ display_sidebar_chat(lang_code, chatbot_t)
96
+
97
+ # Inicializar estados para todos los tabs
98
+ if 'tab_states' not in st.session_state:
99
+ st.session_state.tab_states = {
100
+ 'current_situation_active': False,
101
+ 'morpho_active': False,
102
+ 'semantic_live_active': False,
103
+ 'semantic_active': False,
104
+ 'discourse_live_active': False,
105
+ 'discourse_active': False,
106
+ 'activities_active': False,
107
+ 'feedback_active': False
108
+ }
109
+
110
+ # Sistema de tabs
111
+ tab_names = [
112
+ t.get('current_situation_tab', "Mi Situaci贸n Actual"),
113
+ t.get('morpho_tab', 'An谩lisis Morfosint谩ctico'),
114
+ t.get('semantic_live_tab', 'An谩lisis Sem谩ntico Vivo'),
115
+ t.get('semantic_tab', 'An谩lisis Sem谩ntico'),
116
+ t.get('discourse_live_tab', 'An谩lisis de Discurso Vivo'),
117
+ t.get('discourse_tab', 'An谩lsis de Discurso'),
118
+ t.get('activities_tab', 'Mis Actividades'),
119
+ t.get('feedback_tab', 'Formulario de Comentarios')
120
+ ]
121
+
122
+ tabs = st.tabs(tab_names)
123
+
124
+ # Manejar el contenido de cada tab
125
+ for index, tab in enumerate(tabs):
126
+ with tab:
127
+ try:
128
+ # Actualizar el tab seleccionado solo si no hay un an谩lisis activo
129
+ if tab.selected and st.session_state.selected_tab != index:
130
+ can_switch = True
131
+ for state_key in st.session_state.tab_states.keys():
132
+ if st.session_state.tab_states[state_key] and index != get_tab_index(state_key):
133
+ can_switch = False
134
+ break
135
+ if can_switch:
136
+ st.session_state.selected_tab = index
137
+
138
+ if index == 0: # Situaci贸n actual
139
+ st.session_state.tab_states['current_situation_active'] = True
140
+ display_current_situation_interface(
141
+ st.session_state.lang_code,
142
+ st.session_state.nlp_models,
143
+ t # Pasamos todo el diccionario de traducciones
144
+ )
145
+
146
+ elif index == 1: # Morfosint谩ctico
147
+ st.session_state.tab_states['morpho_active'] = True
148
+ display_morphosyntax_interface(
149
+ st.session_state.lang_code,
150
+ st.session_state.nlp_models,
151
+ t # Pasamos todo el diccionario de traducciones
152
+ )
153
+
154
+ elif index == 2: # Sem谩ntico Vivo
155
+ st.session_state.tab_states['semantic_live_active'] = True
156
+ display_semantic_live_interface(
157
+ st.session_state.lang_code,
158
+ st.session_state.nlp_models,
159
+ t # Pasamos todo el diccionario de traducciones
160
+ )
161
+
162
+ elif index == 3: # Sem谩ntico
163
+ st.session_state.tab_states['semantic_active'] = True
164
+ display_semantic_interface(
165
+ st.session_state.lang_code,
166
+ st.session_state.nlp_models,
167
+ t # Pasamos todo el diccionario de traducciones
168
+ )
169
+
170
+ elif index == 4: # Discurso Vivo
171
+ st.session_state.tab_states['discourse_live_active'] = True
172
+ display_discourse_live_interface(
173
+ st.session_state.lang_code,
174
+ st.session_state.nlp_models,
175
+ t # Pasamos todo el diccionario de traducciones
176
+ )
177
+
178
+ elif index == 5: # Discurso
179
+ st.session_state.tab_states['discourse_active'] = True
180
+ display_discourse_interface(
181
+ st.session_state.lang_code,
182
+ st.session_state.nlp_models,
183
+ t # Pasamos todo el diccionario de traducciones
184
+ )
185
+
186
+ elif index == 6: # Actividades
187
+ st.session_state.tab_states['activities_active'] = True
188
+ display_student_activities(
189
+ username=st.session_state.username,
190
+ lang_code=st.session_state.lang_code,
191
+ t=t # Pasamos todo el diccionario de traducciones
192
+ )
193
+
194
+ elif index == 7: # Feedback
195
+ st.session_state.tab_states['feedback_active'] = True
196
+ display_feedback_form(
197
+ st.session_state.lang_code,
198
+ t # Ya estaba recibiendo el diccionario completo
199
+ )
200
+
201
+ except Exception as e:
202
+ # Desactivar el estado en caso de error
203
+ state_key = get_state_key_for_index(index)
204
+ if state_key:
205
+ st.session_state.tab_states[state_key] = False
206
+ logger.error(f"Error en tab {index}: {str(e)}")
207
+ st.error(t.get('tab_error', 'Error al cargar esta secci贸n'))
208
+
209
+ # Panel de depuraci贸n (solo visible en desarrollo)
210
+ if st.session_state.get('debug_mode', False):
211
+ with st.expander("Debug Info"):
212
+ st.write(f"P谩gina actual: {st.session_state.page}")
213
+ st.write(f"Usuario: {st.session_state.get('username', 'No logueado')}")
214
+ st.write(f"Rol: {st.session_state.get('role', 'No definido')}")
215
+ st.write(f"Idioma: {st.session_state.lang_code}")
216
+ st.write(f"Tab seleccionado: {st.session_state.selected_tab}")
217
+ st.write(f"脷ltima actualizaci贸n de datos: {st.session_state.get('last_data_fetch', 'Nunca')}")
218
+ st.write(f"Traducciones disponibles: {list(t.keys())}")
219
+
220
+
221
+ def get_tab_index(state_key):
222
+ """Obtiene el 铆ndice del tab basado en la clave de estado"""
223
+ index_map = {
224
+ 'current_situation_active': 0,
225
+ 'morpho_active': 1,
226
+ 'semantic_live_active': 2,
227
+ 'semantic_active': 3,
228
+ 'discourse_live_active': 4,
229
+ 'discourse_active': 5,
230
+ 'activities_active': 6,
231
+ 'feedback_active': 7
232
+ }
233
+ return index_map.get(state_key, -1)
234
+
235
+ def get_state_key_for_index(index):
236
+ """Obtiene la clave de estado basada en el 铆ndice del tab"""
237
+ state_map = {
238
+ 0: 'current_situation_active',
239
+ 1: 'morpho_active',
240
+ 2: 'semantic_live_active',
241
+ 3: 'semantic_active',
242
+ 4: 'discourse_live_active',
243
+ 5: 'discourse_active',
244
+ 6: 'activities_active',
245
+ 7: 'feedback_active'
246
+ }
247
+ return state_map.get(index)
248
+
249
+ def display_feedback_form(lang_code, t):
250
+ """
251
+ Muestra el formulario de retroalimentaci贸n
252
+ Args:
253
+ lang_code: C贸digo de idioma
254
+ t: Diccionario de traducciones
255
+ """
256
+ logging.info(f"display_feedback_form called with lang_code: {lang_code}")
257
+
258
+ # Obtener traducciones espec铆ficas para el formulario de feedback
259
+ feedback_t = t.get('FEEDBACK', {})
260
+
261
+ # Si no hay traducciones espec铆ficas, usar el diccionario general
262
+ if not feedback_t:
263
+ feedback_t = t
264
+
265
+ st.header(feedback_t.get('feedback_title', 'Formulario de Opini贸n'))
266
+
267
+ name = st.text_input(feedback_t.get('name', 'Nombre'))
268
+ email = st.text_input(feedback_t.get('email', 'Correo electr贸nico'))
269
+ feedback = st.text_area(feedback_t.get('feedback', 'Retroalimentaci贸n'))
270
+
271
+ if st.button(feedback_t.get('submit', 'Enviar')):
272
+ if name and email and feedback:
273
+ if store_student_feedback(st.session_state.username, name, email, feedback):
274
+ st.success(feedback_t.get('feedback_success', 'Gracias por tu respuesta'))
275
+ else:
276
+ st.error(feedback_t.get('feedback_error', 'Hubo un problema al enviar el formulario. Por favor, intenta de nuevo.'))
277
+ else:
278
+ st.warning(feedback_t.get('complete_all_fields', 'Por favor, completa todos los campos'))