AIdeaText commited on
Commit
0ea7e19
verified
1 Parent(s): 1402254

Create user_page.py

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