AIdeaText commited on
Commit
111157d
verified
1 Parent(s): f9cdb15

Update modules/ui/user_page.py

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