AIdeaText commited on
Commit
9002a31
verified
1 Parent(s): 4fa1b3b

Update src/modules/ui/ui.py

Browse files
Files changed (1) hide show
  1. src/modules/ui/ui.py +341 -341
src/modules/ui/ui.py CHANGED
@@ -1,342 +1,342 @@
1
- # modules/ui/ui.py
2
- import streamlit as st
3
- from streamlit_player import st_player
4
- import logging
5
- from datetime import datetime
6
- from dateutil.parser import parse
7
-
8
- # Configura el logger PRIMERO, antes de cualquier uso
9
- logging.basicConfig(level=logging.INFO)
10
- logger = logging.getLogger(__name__)
11
-
12
- # Importaciones locales
13
- from session_state import initialize_session_state, logout
14
- from translations import get_translations, get_landing_translations
15
- from ..auth.auth import authenticate_user, authenticate_student, authenticate_admin
16
- from ..database.sql_db import store_application_request
17
-
18
- # Intento de importaci贸n con logger YA DEFINIDO
19
- try:
20
- from .user_page import user_page
21
- except ImportError as e:
22
- logger.error(f"No se pudo importar user_page: {str(e)}. Aseg煤rate de que el archivo existe.")
23
-
24
- # Funci贸n de respaldo
25
- def user_page(lang_code, t):
26
- st.error("La p谩gina de usuario no est谩 disponible. Por favor, contacta al administrador.")
27
-
28
- from ..admin.admin_ui import admin_page
29
-
30
- #############################################################
31
- def main():
32
- logger.info(f"Entrando en main() - P谩gina actual: {st.session_state.page}")
33
-
34
- if 'nlp_models' not in st.session_state:
35
- logger.error("Los modelos NLP no est谩n inicializados.")
36
- st.error("Los modelos NLP no est谩n inicializados. Por favor, reinicie la aplicaci贸n.")
37
- return
38
-
39
- lang_code = st.session_state.get('lang_code', 'es')
40
- t = get_translations(lang_code)
41
-
42
- logger.info(f"P谩gina actual antes de la l贸gica de enrutamiento: {st.session_state.page}")
43
-
44
- if st.session_state.get('logged_out', False):
45
- st.session_state.logged_out = False
46
- st.session_state.page = 'login'
47
- st.rerun()
48
-
49
- if not st.session_state.get('logged_in', False):
50
- logger.info("Usuario no ha iniciado sesi贸n. Mostrando p谩gina de login/registro")
51
- login_register_page(lang_code, t)
52
- elif st.session_state.page == 'user':
53
- if st.session_state.role == 'Administrador':
54
- logger.info("Redirigiendo a la p谩gina de administrador")
55
- st.session_state.page = 'Admin'
56
- st.rerun()
57
- else:
58
- logger.info("Renderizando p谩gina de usuario")
59
- user_page(lang_code, t)
60
- elif st.session_state.page == "Admin":
61
- logger.info("Renderizando p谩gina de administrador")
62
- admin_page()
63
- else:
64
- logger.error(f"P谩gina no reconocida: {st.session_state.page}")
65
- st.error(t.get('unrecognized_page', 'P谩gina no reconocida'))
66
- # Redirigir a la p谩gina de usuario en caso de error
67
- st.session_state.page = 'user'
68
- st.rerun()
69
-
70
- logger.info(f"Saliendo de main() - Estado final de la sesi贸n: {st.session_state}")
71
-
72
- #############################################################
73
- #############################################################
74
- def login_register_page(lang_code, t):
75
- # Obtener traducciones espec铆ficas para landing page
76
- landing_t = get_landing_translations(lang_code)
77
-
78
- # Language selection dropdown at the top
79
- languages = {'Espa帽ol': 'es', 'English': 'en', 'Fran莽ais': 'fr', 'Portugu锚s': 'pt'}
80
-
81
- # Estilo personalizado para mejorar el espaciado y alineaci贸n
82
- st.markdown("""
83
- <style>
84
- div.row-widget.stHorizontalBlock {
85
- align-items: center;
86
- }
87
- </style>
88
- """, unsafe_allow_html=True)
89
-
90
- # Crear contenedor para logos y selector de idioma usando columnas de Streamlit
91
- col1, col2, col3, col4, col5 = st.columns([0.25, 0.25, 1, 1, 1])
92
-
93
- with col1:
94
- # Logo de ALPHA
95
- st.image("https://huggingface.co/spaces/AIdeaText/v3/resolve/main/assets/img/ALPHA_Startup%20Badges.png", width=100)
96
-
97
- with col2:
98
- # Logo de AIdeaText
99
- st.image("https://huggingface.co/spaces/AIdeaText/v3/resolve/main/assets/img/AIdeaText_Logo_vectores.png", width=100)
100
-
101
- with col5:
102
- # Selector de idioma
103
- selected_lang = st.selectbox(
104
- landing_t['select_language'],
105
- list(languages.keys()),
106
- index=list(languages.values()).index(lang_code),
107
- key=f"landing_language_selector_{lang_code}"
108
- )
109
- new_lang_code = languages[selected_lang]
110
- if lang_code != new_lang_code:
111
- st.session_state.lang_code = new_lang_code
112
- st.rerun()
113
-
114
- # Main content with columns
115
- left_column, right_column = st.columns([1, 3])
116
-
117
- with left_column:
118
- tab1, tab2 = st.tabs([landing_t['login'], landing_t['register']])
119
-
120
- with tab1:
121
- login_form(lang_code, landing_t)
122
-
123
- with tab2:
124
- register_form(lang_code, landing_t)
125
-
126
- with right_column:
127
- display_videos_and_info(lang_code, landing_t)
128
-
129
- #############################################################
130
- #############################################################
131
- def login_form(lang_code, landing_t):
132
- with st.form("login_form"):
133
- username = st.text_input(landing_t['email'])
134
- password = st.text_input(landing_t['password'], type="password")
135
- submit_button = st.form_submit_button(landing_t['login_button'])
136
-
137
- if submit_button:
138
- success, role = authenticate_user(username, password)
139
- if success:
140
- st.session_state.logged_in = True
141
- st.session_state.username = username
142
- st.session_state.role = role
143
- if role == 'Administrador':
144
- st.session_state.page = 'Admin'
145
- else:
146
- st.session_state.page = 'user'
147
- logger.info(f"Usuario autenticado: {username}, Rol: {role}")
148
- st.rerun()
149
- else:
150
- st.error(landing_t['invalid_credentials'])
151
-
152
-
153
- #############################################################
154
- #############################################################
155
- def register_form(lang_code, landing_t):
156
- name = st.text_input(landing_t['name'])
157
- lastname = st.text_input(landing_t['lastname'])
158
- institution = st.text_input(landing_t['institution'])
159
- current_role = st.selectbox(landing_t['current_role'],
160
- [landing_t['professor'], landing_t['student'], landing_t['administrative']])
161
-
162
- # Definimos el rol por defecto como estudiante
163
- desired_role = landing_t['student']
164
-
165
- email = st.text_input(landing_t['institutional_email'])
166
- reason = st.text_area(landing_t['interest_reason'])
167
-
168
- if st.button(landing_t['submit_application']):
169
- logger.info(f"Intentando enviar solicitud para {email}")
170
- logger.debug(f"Datos del formulario: name={name}, lastname={lastname}, email={email}, institution={institution}, current_role={current_role}, desired_role={desired_role}, reason={reason}")
171
-
172
- if not name or not lastname or not email or not institution or not reason:
173
- logger.warning("Env铆o de formulario incompleto")
174
- st.error(landing_t['complete_all_fields'])
175
- elif not is_institutional_email(email):
176
- logger.warning(f"Email no institucional utilizado: {email}")
177
- st.error(landing_t['use_institutional_email'])
178
- else:
179
- logger.info(f"Intentando almacenar solicitud para {email}")
180
- success = store_application_request(name, lastname, email, institution, current_role, desired_role, reason)
181
- if success:
182
- st.success(landing_t['application_sent'])
183
- logger.info(f"Solicitud almacenada exitosamente para {email}")
184
- else:
185
- st.error(landing_t['application_error'])
186
- logger.error(f"Error al almacenar solicitud para {email}")
187
-
188
-
189
- #############################################################
190
- #############################################################
191
- def is_institutional_email(email):
192
- forbidden_domains = ['gmail.com', 'hotmail.com', 'yahoo.com', 'outlook.com']
193
- return not any(domain in email.lower() for domain in forbidden_domains)
194
-
195
-
196
- #############################################################
197
- #############################################################
198
- def display_videos_and_info(lang_code, landing_t):
199
- # Crear tabs para cada secci贸n
200
- tab_use_case, tab_videos, tab_events, tab_gallery, tab_news = st.tabs([
201
- landing_t['use_cases'],
202
- landing_t['presentation_videos'],
203
- landing_t['academic_presentations'],
204
- landing_t['event_photos'],
205
- landing_t['version_control']
206
- ])
207
-
208
- # Tab de Casos de uso
209
- with tab_use_case:
210
- use_case_videos = {
211
- "English - Radar use chart": "https://youtu.be/fFbbtlIewgs",
212
- "English - Use AI Bot and arcs charts fuctions": "https://youtu.be/XjM-1oOl-ao",
213
- "English - Arcs use charts, example 1": "https://youtu.be/PdK_bgigVaM",
214
- "English - Arcs use charts, excample 2": "https://youtu.be/7uaV1njPOng",
215
- "Espa帽ol - Uso del diagrama radar para verificar redacci贸n": "https://www.youtube.com/watch?v=nJP6xscPLBU",
216
- "Espa帽ol - Uso de los diagramas de arco, ejemplo 1": "https://www.youtube.com/watch?v=ApBIAr2S-bE",
217
- "Espa帽ol - Uso de los diagramas de arco, ejemplo 2": "https://www.youtube.com/watch?v=JnP2U1Fm0rc",
218
- "Espa帽ol - Uso de los diagramas de arco, ejemplo 3": "https://www.youtube.com/watch?v=waWWwPTaI-Y",
219
- "Espa帽ol - Uso del bot para buscar respuestas" : "https://www.youtube.com/watch?v=GFKDS0K2s7E"
220
- }
221
-
222
- selected_title = st.selectbox(landing_t['select_use_case'], list(use_case_videos.keys()))
223
- if selected_title in use_case_videos:
224
- try:
225
- st_player(use_case_videos[selected_title])
226
- except Exception as e:
227
- st.error(f"Error al cargar el video: {str(e)}")
228
-
229
- # Tab de Videos
230
- with tab_videos:
231
- videos = {
232
- "Reel AIdeaText": "https://youtu.be/hXnwUvN1Q9Q",
233
- "Presentaci贸n en SENDA, UNAM. Ciudad de M茅xico, M茅xico" : "https://www.youtube.com/watch?v=XFLvjST2cE0",
234
- "Presentaci贸n en PyCon 2024. Colombia, Medell铆n": "https://www.youtube.com/watch?v=Jn545-IKx5Q",
235
- "Presentaci贸n en Fundaci贸n Ser Maaestro. Lima, Per煤": "https://www.youtube.com/watch?v=imc4TI1q164",
236
- "Presentaci贸n en Explora del IFE, TEC de Monterrey, Nuevo Le贸n, M茅xico": "https://www.youtube.com/watch?v=Fqi4Di_Rj_s",
237
- "Entrevista con el Dr. Guillermo Ru铆z. Lima, Per煤": "https://www.youtube.com/watch?v=_ch8cRja3oc",
238
- "Demo de la versi贸n de escritorio.": "https://www.youtube.com/watch?v=nP6eXbog-ZY"
239
- }
240
-
241
- selected_title = st.selectbox(landing_t['select_presentation'], list(videos.keys()))
242
- if selected_title in videos:
243
- try:
244
- st_player(videos[selected_title])
245
- except Exception as e:
246
- st.error(f"Error al cargar el video: {str(e)}")
247
-
248
- # Tab de Eventos
249
- with tab_events:
250
- st.markdown("""
251
- ## 2025
252
-
253
- **El Agente Cognitivo Vinculante como Innovaci贸n en el Aprendizaje Adaptativo: el caso de AIdeaText**
254
- IFE CONFERENCE 2025. Organizado por el Instituto para el Futuro de la Educaci贸n del TEC de Monterrey.
255
- Nuevo Le贸n, M茅xico. Del 28 al 30 enero 2025
256
-
257
- ## 2024
258
- [1]
259
- AIdeaText, AIdeaText, recurso digital que emplea la t茅cnica de An谩lisis de Resonancia Central para perfeccionar textos acad茅micos**
260
- V Temporada SENDA - Organizado por el Seminario de Entornos y Narrativas Digitales en la Academia del
261
- Instituto de Investigaciones Antropol贸gicas (IIA) de la Universidad Auton贸ma de M茅xico (UNAM). 22 noviembre 2024
262
-
263
- [2]
264
- Aproximaci贸n al Agente Cognitivo Vinculante (ACV) desde la Teor铆a del Actor Red (TAR)**
265
- Congreso HeETI 2024: Horizontes Expandidos de la Educaci贸n, la Tecnolog铆a y la Innovaci贸n
266
- Universidad el Claustro de Sor Juana. Del 25 al 27 septiembre 2024
267
-
268
- [3]
269
- AIdeaText, visualizaci贸n de mapas sem谩nticos**
270
- PyCon 2024, Organizado por el grupo de desarrolladores independientes de Python.
271
- Universidad EAFIT, Medell铆n, Colombia. Del 7 al 9 de junio de 2024.
272
-
273
- ## 2023
274
- **Aproximaci贸n al Agente Cognitivo Vinculante (ACV) desde la Teor铆a del Actor Red (TAR)**
275
- [1]
276
- XVII Congreso Nacional de Investigaci贸n Educativa - VII Encuentro de Estudiantes de Posgrado Educaci贸n.
277
- Consejo Mexicano de Investigaci贸n Educativa (COMIE)
278
- Villahermosa, Tabasco, M茅xico.
279
- Del 4 al 8 de diciembre 2023
280
-
281
- [2]
282
- XXXI Encuentro Internacional de Educaci贸n a Distancia
283
- Universidad de Guadalajara. Jalisco, M茅xico.
284
- Del 27 al 30 noviembre 2023
285
-
286
- [3]
287
- IV Temporada SENDA - Seminario de Entornos y Narrativas Digitales en la Academia
288
- Instituto de Investigaciones Antropol贸gicas (IIA), UNAM.
289
- 22 noviembre 2023
290
-
291
- [4]
292
- 1er Congreso Internacional de Educaci贸n Digital
293
- Instituto Polit茅cnico Nacional, sede Zacatecas. M茅xico.
294
- Del 23 al 24 de noviembre de 2023
295
-
296
- [5]
297
- La cuesti贸n de la centralidad del maestro frente a las tecnolog铆as digitales generativas**
298
- Innova F贸rum: Ecosistemas de Aprendizaje
299
- Universidad de Guadalajara. Jalisco, M茅xico.
300
- Del 16 al 18 de mayo 2023
301
- """)
302
-
303
- # Tab de Galer铆a
304
- with tab_gallery:
305
- # Contenedor con ancho m谩ximo
306
- with st.container():
307
- # Dividimos en dos columnas principales
308
- col_left, col_right = st.columns(2)
309
-
310
- # Columna izquierda: Foto 1 grande
311
- with col_left:
312
- # Foto 2 arriba
313
- st.image("assets/img/socialmedia/_MG_2845.JPG",
314
- caption="MakerFaire CDMX 2024",
315
- width=480) # Ajusta este valor seg煤n necesites
316
- # use_column_width=True)
317
-
318
- # Foto 3 abajo
319
- st.image("assets/img/socialmedia/Facebook_CoverPhoto-1_820x312.jpg",
320
- caption="MakerFaire CDMX 2024",
321
- width=480) # Ajusta este valor seg煤n necesites
322
- # use_column_width=True)
323
-
324
- # Columna derecha: Fotos 2 y 3 una encima de otra
325
- with col_right:
326
- st.image("assets/img/socialmedia/_MG_2790.jpg",
327
- caption="MakerFaire CDMX 2024",
328
- width=540) # Ajusta este valor seg煤n necesites
329
-
330
-
331
- # Tab de Novedades - Usar contenido traducido
332
- with tab_news:
333
- st.markdown(f"### {landing_t['latest_version_title']}")
334
- for update in landing_t['version_updates']:
335
- st.markdown(f"- {update}")
336
-
337
- # Definici贸n de __all__ para especificar qu茅 se exporta
338
- __all__ = ['main', 'login_register_page', 'initialize_session_state']
339
-
340
- # Bloque de ejecuci贸n condicional
341
- if __name__ == "__main__":
342
  main()
 
1
+ # modules/ui/ui.py
2
+ import streamlit as st
3
+ from streamlit_player import st_player
4
+ import logging
5
+ from datetime import datetime
6
+ from dateutil.parser import parse
7
+
8
+ # Configura el logger PRIMERO, antes de cualquier uso
9
+ logging.basicConfig(level=logging.INFO)
10
+ logger = logging.getLogger(__name__)
11
+
12
+ # Importaciones locales
13
+ from session_state import initialize_session_state, logout
14
+ from translations import get_translations, get_landing_translations
15
+ from ..auth.auth import authenticate_user, authenticate_student, authenticate_admin
16
+ from ..database.sql_db import store_application_request
17
+
18
+ # Intento de importaci贸n con logger YA DEFINIDO
19
+ try:
20
+ from .user_page import user_page
21
+ except ImportError as e:
22
+ logger.error(f"No se pudo importar user_page: {str(e)}. Aseg煤rate de que el archivo existe.")
23
+
24
+ # Funci贸n de respaldo
25
+ def user_page(lang_code, t):
26
+ st.error("La p谩gina de usuario no est谩 disponible. Por favor, contacta al administrador.")
27
+
28
+ from ..admin.admin_ui import admin_page
29
+
30
+ #############################################################
31
+ def main():
32
+ logger.info(f"Entrando en main() - P谩gina actual: {st.session_state.page}")
33
+
34
+ if 'nlp_models' not in st.session_state:
35
+ logger.error("Los modelos NLP no est谩n inicializados.")
36
+ st.error("Los modelos NLP no est谩n inicializados. Por favor, reinicie la aplicaci贸n.")
37
+ return
38
+
39
+ lang_code = st.session_state.get('lang_code', 'es')
40
+ t = get_translations(lang_code)
41
+
42
+ logger.info(f"P谩gina actual antes de la l贸gica de enrutamiento: {st.session_state.page}")
43
+
44
+ if st.session_state.get('logged_out', False):
45
+ st.session_state.logged_out = False
46
+ st.session_state.page = 'login'
47
+ st.rerun()
48
+
49
+ if not st.session_state.get('logged_in', False):
50
+ logger.info("Usuario no ha iniciado sesi贸n. Mostrando p谩gina de login/registro")
51
+ login_register_page(lang_code, t)
52
+ elif st.session_state.page == 'user':
53
+ if st.session_state.role == 'Administrador':
54
+ logger.info("Redirigiendo a la p谩gina de administrador")
55
+ st.session_state.page = 'Admin'
56
+ st.rerun()
57
+ else:
58
+ logger.info("Renderizando p谩gina de usuario")
59
+ user_page(lang_code, t)
60
+ elif st.session_state.page == "Admin":
61
+ logger.info("Renderizando p谩gina de administrador")
62
+ admin_page()
63
+ else:
64
+ logger.error(f"P谩gina no reconocida: {st.session_state.page}")
65
+ st.error(t.get('unrecognized_page', 'P谩gina no reconocida'))
66
+ # Redirigir a la p谩gina de usuario en caso de error
67
+ st.session_state.page = 'user'
68
+ st.rerun()
69
+
70
+ logger.info(f"Saliendo de main() - Estado final de la sesi贸n: {st.session_state}")
71
+
72
+ #############################################################
73
+ #############################################################
74
+ def login_register_page(lang_code, t):
75
+ # Obtener traducciones espec铆ficas para landing page
76
+ landing_t = get_landing_translations(lang_code)
77
+
78
+ # Language selection dropdown at the top
79
+ languages = {'Espa帽ol': 'es', 'English': 'en', 'Fran莽ais': 'fr', 'Portugu锚s': 'pt'}
80
+
81
+ # Estilo personalizado para mejorar el espaciado y alineaci贸n
82
+ st.markdown("""
83
+ <style>
84
+ div.row-widget.stHorizontalBlock {
85
+ align-items: center;
86
+ }
87
+ </style>
88
+ """, unsafe_allow_html=True)
89
+
90
+ # Crear contenedor para logos y selector de idioma usando columnas de Streamlit
91
+ col1, col2, col3, col4, col5 = st.columns([0.25, 0.25, 1, 1, 1])
92
+
93
+ with col1:
94
+ # Logo de ALPHA
95
+ st.image("https://huggingface.co/spaces/AIdeaText/v3/resolve/main/assets/img/ALPHA_Startup%20Badges.png", width=100)
96
+
97
+ with col2:
98
+ # Logo de AIdeaText
99
+ st.image("https://huggingface.co/spaces/AIdeaText/v3/resolve/main/assets/img/AIdeaText_Logo_vectores.png", width=100)
100
+
101
+ with col5:
102
+ # Selector de idioma
103
+ selected_lang = st.selectbox(
104
+ landing_t['select_language'],
105
+ list(languages.keys()),
106
+ index=list(languages.values()).index(lang_code),
107
+ key=f"landing_language_selector_{lang_code}"
108
+ )
109
+ new_lang_code = languages[selected_lang]
110
+ if lang_code != new_lang_code:
111
+ st.session_state.lang_code = new_lang_code
112
+ st.rerun()
113
+
114
+ # Main content with columns
115
+ left_column, right_column = st.columns([1, 3])
116
+
117
+ with left_column:
118
+ tab1, tab2 = st.tabs([landing_t['login'], landing_t['register']])
119
+
120
+ with tab1:
121
+ login_form(lang_code, landing_t)
122
+
123
+ with tab2:
124
+ register_form(lang_code, landing_t)
125
+
126
+ with right_column:
127
+ display_videos_and_info(lang_code, landing_t)
128
+
129
+ #############################################################
130
+ #############################################################
131
+ def login_form(lang_code, landing_t):
132
+ with st.form("login_form"):
133
+ username = st.text_input(landing_t['email'])
134
+ password = st.text_input(landing_t['password'], type="password")
135
+ submit_button = st.form_submit_button(landing_t['login_button'])
136
+
137
+ if submit_button:
138
+ success, role = authenticate_user(username, password)
139
+ if success:
140
+ st.session_state.logged_in = True
141
+ st.session_state.username = username
142
+ st.session_state.role = role
143
+ if role == 'Administrador':
144
+ st.session_state.page = 'Admin'
145
+ else:
146
+ st.session_state.page = 'user'
147
+ logger.info(f"Usuario autenticado: {username}, Rol: {role}")
148
+ st.rerun()
149
+ else:
150
+ st.error(landing_t['invalid_credentials'])
151
+
152
+
153
+ #############################################################
154
+ #############################################################
155
+ def register_form(lang_code, landing_t):
156
+ name = st.text_input(landing_t['name'])
157
+ lastname = st.text_input(landing_t['lastname'])
158
+ institution = st.text_input(landing_t['institution'])
159
+ current_role = st.selectbox(landing_t['current_role'],
160
+ [landing_t['professor'], landing_t['student'], landing_t['administrative']])
161
+
162
+ # Definimos el rol por defecto como estudiante
163
+ desired_role = landing_t['student']
164
+
165
+ email = st.text_input(landing_t['institutional_email'])
166
+ reason = st.text_area(landing_t['interest_reason'])
167
+
168
+ if st.button(landing_t['submit_application']):
169
+ logger.info(f"Intentando enviar solicitud para {email}")
170
+ logger.debug(f"Datos del formulario: name={name}, lastname={lastname}, email={email}, institution={institution}, current_role={current_role}, desired_role={desired_role}, reason={reason}")
171
+
172
+ if not name or not lastname or not email or not institution or not reason:
173
+ logger.warning("Env铆o de formulario incompleto")
174
+ st.error(landing_t['complete_all_fields'])
175
+ elif not is_institutional_email(email):
176
+ logger.warning(f"Email no institucional utilizado: {email}")
177
+ st.error(landing_t['use_institutional_email'])
178
+ else:
179
+ logger.info(f"Intentando almacenar solicitud para {email}")
180
+ success = store_application_request(name, lastname, email, institution, current_role, desired_role, reason)
181
+ if success:
182
+ st.success(landing_t['application_sent'])
183
+ logger.info(f"Solicitud almacenada exitosamente para {email}")
184
+ else:
185
+ st.error(landing_t['application_error'])
186
+ logger.error(f"Error al almacenar solicitud para {email}")
187
+
188
+
189
+ #############################################################
190
+ #############################################################
191
+ def is_institutional_email(email):
192
+ forbidden_domains = ['gmail.com', 'hotmail.com', 'yahoo.com', 'outlook.com']
193
+ return not any(domain in email.lower() for domain in forbidden_domains)
194
+
195
+
196
+ #############################################################
197
+ #############################################################
198
+ def display_videos_and_info(lang_code, landing_t):
199
+ # Crear tabs para cada secci贸n
200
+ tab_use_case, tab_videos, tab_events, tab_gallery, tab_news = st.tabs([
201
+ landing_t['use_cases'],
202
+ landing_t['presentation_videos'],
203
+ landing_t['academic_presentations'],
204
+ landing_t['event_photos'],
205
+ landing_t['version_control']
206
+ ])
207
+
208
+ # Tab de Casos de uso
209
+ with tab_use_case:
210
+ use_case_videos = {
211
+ "English - Radar use chart": "https://youtu.be/fFbbtlIewgs",
212
+ "English - Use AI Bot and arcs charts fuctions": "https://youtu.be/XjM-1oOl-ao",
213
+ "English - Arcs use charts, example 1": "https://youtu.be/PdK_bgigVaM",
214
+ "English - Arcs use charts, excample 2": "https://youtu.be/7uaV1njPOng",
215
+ "Espa帽ol - Uso del diagrama radar para verificar redacci贸n": "https://www.youtube.com/watch?v=nJP6xscPLBU",
216
+ "Espa帽ol - Uso de los diagramas de arco, ejemplo 1": "https://www.youtube.com/watch?v=ApBIAr2S-bE",
217
+ "Espa帽ol - Uso de los diagramas de arco, ejemplo 2": "https://www.youtube.com/watch?v=JnP2U1Fm0rc",
218
+ "Espa帽ol - Uso de los diagramas de arco, ejemplo 3": "https://www.youtube.com/watch?v=waWWwPTaI-Y",
219
+ "Espa帽ol - Uso del bot para buscar respuestas" : "https://www.youtube.com/watch?v=GFKDS0K2s7E"
220
+ }
221
+
222
+ selected_title = st.selectbox(landing_t['select_use_case'], list(use_case_videos.keys()))
223
+ if selected_title in use_case_videos:
224
+ try:
225
+ st_player(use_case_videos[selected_title])
226
+ except Exception as e:
227
+ st.error(f"Error al cargar el video: {str(e)}")
228
+
229
+ # Tab de Videos
230
+ with tab_videos:
231
+ videos = {
232
+ "Reel AIdeaText": "https://youtu.be/hXnwUvN1Q9Q",
233
+ "Presentaci贸n en SENDA, UNAM. Ciudad de M茅xico, M茅xico" : "https://www.youtube.com/watch?v=XFLvjST2cE0",
234
+ "Presentaci贸n en PyCon 2024. Colombia, Medell铆n": "https://www.youtube.com/watch?v=Jn545-IKx5Q",
235
+ "Presentaci贸n en Fundaci贸n Ser Maaestro. Lima, Per煤": "https://www.youtube.com/watch?v=imc4TI1q164",
236
+ "Presentaci贸n en Explora del IFE, TEC de Monterrey, Nuevo Le贸n, M茅xico": "https://www.youtube.com/watch?v=Fqi4Di_Rj_s",
237
+ "Entrevista con el Dr. Guillermo Ru铆z. Lima, Per煤": "https://www.youtube.com/watch?v=_ch8cRja3oc",
238
+ "Demo de la versi贸n de escritorio.": "https://www.youtube.com/watch?v=nP6eXbog-ZY"
239
+ }
240
+
241
+ selected_title = st.selectbox(landing_t['select_presentation'], list(videos.keys()))
242
+ if selected_title in videos:
243
+ try:
244
+ st_player(videos[selected_title])
245
+ except Exception as e:
246
+ st.error(f"Error al cargar el video: {str(e)}")
247
+
248
+ # Tab de Eventos
249
+ with tab_events:
250
+ st.markdown("""
251
+ ## 2025
252
+
253
+ **El Agente Cognitivo Vinculante como Innovaci贸n en el Aprendizaje Adaptativo: el caso de AIdeaText**
254
+ IFE CONFERENCE 2025. Organizado por el Instituto para el Futuro de la Educaci贸n del TEC de Monterrey.
255
+ Nuevo Le贸n, M茅xico. Del 28 al 30 enero 2025
256
+
257
+ ## 2024
258
+ [1]
259
+ AIdeaText, AIdeaText, recurso digital que emplea la t茅cnica de An谩lisis de Resonancia Central para perfeccionar textos acad茅micos**
260
+ V Temporada SENDA - Organizado por el Seminario de Entornos y Narrativas Digitales en la Academia del
261
+ Instituto de Investigaciones Antropol贸gicas (IIA) de la Universidad Auton贸ma de M茅xico (UNAM). 22 noviembre 2024
262
+
263
+ [2]
264
+ Aproximaci贸n al Agente Cognitivo Vinculante (ACV) desde la Teor铆a del Actor Red (TAR)**
265
+ Congreso HeETI 2024: Horizontes Expandidos de la Educaci贸n, la Tecnolog铆a y la Innovaci贸n
266
+ Universidad el Claustro de Sor Juana. Del 25 al 27 septiembre 2024
267
+
268
+ [3]
269
+ AIdeaText, visualizaci贸n de mapas sem谩nticos**
270
+ PyCon 2024, Organizado por el grupo de desarrolladores independientes de Python.
271
+ Universidad EAFIT, Medell铆n, Colombia. Del 7 al 9 de junio de 2024.
272
+
273
+ ## 2023
274
+ **Aproximaci贸n al Agente Cognitivo Vinculante (ACV) desde la Teor铆a del Actor Red (TAR)**
275
+ [1]
276
+ XVII Congreso Nacional de Investigaci贸n Educativa - VII Encuentro de Estudiantes de Posgrado Educaci贸n.
277
+ Consejo Mexicano de Investigaci贸n Educativa (COMIE)
278
+ Villahermosa, Tabasco, M茅xico.
279
+ Del 4 al 8 de diciembre 2023
280
+
281
+ [2]
282
+ XXXI Encuentro Internacional de Educaci贸n a Distancia
283
+ Universidad de Guadalajara. Jalisco, M茅xico.
284
+ Del 27 al 30 noviembre 2023
285
+
286
+ [3]
287
+ IV Temporada SENDA - Seminario de Entornos y Narrativas Digitales en la Academia
288
+ Instituto de Investigaciones Antropol贸gicas (IIA), UNAM.
289
+ 22 noviembre 2023
290
+
291
+ [4]
292
+ 1er Congreso Internacional de Educaci贸n Digital
293
+ Instituto Polit茅cnico Nacional, sede Zacatecas. M茅xico.
294
+ Del 23 al 24 de noviembre de 2023
295
+
296
+ [5]
297
+ La cuesti贸n de la centralidad del maestro frente a las tecnolog铆as digitales generativas**
298
+ Innova F贸rum: Ecosistemas de Aprendizaje
299
+ Universidad de Guadalajara. Jalisco, M茅xico.
300
+ Del 16 al 18 de mayo 2023
301
+ """)
302
+
303
+ # Tab de Galer铆a
304
+ with tab_gallery:
305
+ # Contenedor con ancho m谩ximo
306
+ with st.container():
307
+ # Dividimos en dos columnas principales
308
+ col_left, col_right = st.columns(2)
309
+
310
+ # Columna izquierda: Foto 1 grande
311
+ with col_left:
312
+ # Foto 2 arriba
313
+ st.image("src/assets/img/socialmedia/_MG_2845.JPG",
314
+ caption="MakerFaire CDMX 2024",
315
+ width=480) # Ajusta este valor seg煤n necesites
316
+ # use_column_width=True)
317
+
318
+ # Foto 3 abajo
319
+ st.image("src/assets/img/socialmedia/Facebook_CoverPhoto-1_820x312.jpg",
320
+ caption="MakerFaire CDMX 2024",
321
+ width=480) # Ajusta este valor seg煤n necesites
322
+ # use_column_width=True)
323
+
324
+ # Columna derecha: Fotos 2 y 3 una encima de otra
325
+ with col_right:
326
+ st.image("src/assets/img/socialmedia/_MG_2790.jpg",
327
+ caption="MakerFaire CDMX 2024",
328
+ width=540) # Ajusta este valor seg煤n necesites
329
+
330
+
331
+ # Tab de Novedades - Usar contenido traducido
332
+ with tab_news:
333
+ st.markdown(f"### {landing_t['latest_version_title']}")
334
+ for update in landing_t['version_updates']:
335
+ st.markdown(f"- {update}")
336
+
337
+ # Definici贸n de __all__ para especificar qu茅 se exporta
338
+ __all__ = ['main', 'login_register_page', 'initialize_session_state']
339
+
340
+ # Bloque de ejecuci贸n condicional
341
+ if __name__ == "__main__":
342
  main()