iatoolkit 0.8.1__py3-none-any.whl → 0.63.4__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of iatoolkit might be problematic. Click here for more details.

Files changed (159) hide show
  1. iatoolkit/__init__.py +8 -34
  2. iatoolkit/base_company.py +14 -3
  3. iatoolkit/common/routes.py +83 -52
  4. iatoolkit/common/session_manager.py +0 -1
  5. iatoolkit/common/util.py +0 -27
  6. iatoolkit/iatoolkit.py +61 -46
  7. iatoolkit/infra/llm_client.py +7 -8
  8. iatoolkit/infra/openai_adapter.py +1 -1
  9. iatoolkit/infra/redis_session_manager.py +48 -2
  10. iatoolkit/repositories/database_manager.py +17 -2
  11. iatoolkit/repositories/models.py +31 -6
  12. iatoolkit/repositories/profile_repo.py +7 -2
  13. iatoolkit/services/auth_service.py +188 -0
  14. iatoolkit/services/branding_service.py +147 -0
  15. iatoolkit/services/dispatcher_service.py +10 -40
  16. iatoolkit/services/excel_service.py +15 -15
  17. iatoolkit/services/history_service.py +3 -12
  18. iatoolkit/services/jwt_service.py +15 -24
  19. iatoolkit/services/onboarding_service.py +43 -0
  20. iatoolkit/services/profile_service.py +97 -44
  21. iatoolkit/services/query_service.py +124 -81
  22. iatoolkit/services/tasks_service.py +1 -1
  23. iatoolkit/services/user_feedback_service.py +67 -31
  24. iatoolkit/services/user_session_context_service.py +112 -54
  25. iatoolkit/static/images/fernando.jpeg +0 -0
  26. iatoolkit/static/js/{chat_feedback.js → chat_feedback_button.js} +6 -11
  27. iatoolkit/static/js/chat_history_button.js +126 -0
  28. iatoolkit/static/js/chat_logout_button.js +36 -0
  29. iatoolkit/static/js/chat_main.js +130 -220
  30. iatoolkit/static/js/chat_onboarding_button.js +97 -0
  31. iatoolkit/static/js/chat_prompt_manager.js +94 -0
  32. iatoolkit/static/js/chat_reload_button.js +52 -0
  33. iatoolkit/static/styles/chat_iatoolkit.css +329 -507
  34. iatoolkit/static/styles/chat_modal.css +95 -56
  35. iatoolkit/static/styles/landing_page.css +182 -0
  36. iatoolkit/static/styles/onboarding.css +169 -0
  37. iatoolkit/system_prompts/query_main.prompt +3 -12
  38. iatoolkit/templates/_company_header.html +20 -0
  39. iatoolkit/templates/_login_widget.html +40 -0
  40. iatoolkit/templates/base.html +8 -3
  41. iatoolkit/templates/change_password.html +54 -37
  42. iatoolkit/templates/chat.html +149 -66
  43. iatoolkit/templates/chat_modals.html +47 -18
  44. iatoolkit/templates/error.html +41 -8
  45. iatoolkit/templates/forgot_password.html +37 -24
  46. iatoolkit/templates/index.html +140 -0
  47. iatoolkit/templates/login_simulation.html +34 -0
  48. iatoolkit/templates/onboarding_shell.html +105 -0
  49. iatoolkit/templates/signup.html +64 -66
  50. iatoolkit/views/base_login_view.py +81 -0
  51. iatoolkit/views/change_password_view.py +23 -12
  52. iatoolkit/views/external_login_view.py +61 -28
  53. iatoolkit/views/{file_store_view.py → file_store_api_view.py} +9 -2
  54. iatoolkit/views/forgot_password_view.py +23 -13
  55. iatoolkit/views/history_api_view.py +52 -0
  56. iatoolkit/views/home_view.py +58 -25
  57. iatoolkit/views/index_view.py +14 -0
  58. iatoolkit/views/init_context_api_view.py +68 -0
  59. iatoolkit/views/llmquery_api_view.py +45 -0
  60. iatoolkit/views/login_simulation_view.py +81 -0
  61. iatoolkit/views/login_view.py +118 -34
  62. iatoolkit/views/logout_api_view.py +45 -0
  63. iatoolkit/views/{prompt_view.py → prompt_api_view.py} +7 -7
  64. iatoolkit/views/signup_view.py +38 -29
  65. iatoolkit/views/{tasks_view.py → tasks_api_view.py} +10 -36
  66. iatoolkit/views/tasks_review_api_view.py +55 -0
  67. iatoolkit/views/{user_feedback_view.py → user_feedback_api_view.py} +16 -31
  68. iatoolkit/views/verify_user_view.py +13 -8
  69. {iatoolkit-0.8.1.dist-info → iatoolkit-0.63.4.dist-info}/METADATA +2 -2
  70. iatoolkit-0.63.4.dist-info/RECORD +113 -0
  71. {iatoolkit-0.8.1.dist-info → iatoolkit-0.63.4.dist-info}/top_level.txt +0 -1
  72. iatoolkit/common/auth.py +0 -200
  73. iatoolkit/static/images/arrow_up.png +0 -0
  74. iatoolkit/static/images/diagrama_iatoolkit.jpg +0 -0
  75. iatoolkit/static/images/logo_clinica.png +0 -0
  76. iatoolkit/static/images/logo_iatoolkit.png +0 -0
  77. iatoolkit/static/images/logo_maxxa.png +0 -0
  78. iatoolkit/static/images/logo_notaria.png +0 -0
  79. iatoolkit/static/images/logo_tarjeta.png +0 -0
  80. iatoolkit/static/images/logo_umayor.png +0 -0
  81. iatoolkit/static/images/upload.png +0 -0
  82. iatoolkit/static/js/chat_history.js +0 -117
  83. iatoolkit/templates/home.html +0 -201
  84. iatoolkit/templates/login.html +0 -43
  85. iatoolkit/views/chat_token_request_view.py +0 -98
  86. iatoolkit/views/chat_view.py +0 -51
  87. iatoolkit/views/download_file_view.py +0 -58
  88. iatoolkit/views/external_chat_login_view.py +0 -88
  89. iatoolkit/views/history_view.py +0 -57
  90. iatoolkit/views/llmquery_view.py +0 -65
  91. iatoolkit/views/tasks_review_view.py +0 -83
  92. iatoolkit-0.8.1.dist-info/RECORD +0 -175
  93. tests/__init__.py +0 -5
  94. tests/common/__init__.py +0 -0
  95. tests/common/test_auth.py +0 -279
  96. tests/common/test_routes.py +0 -42
  97. tests/common/test_session_manager.py +0 -59
  98. tests/common/test_util.py +0 -444
  99. tests/companies/__init__.py +0 -5
  100. tests/conftest.py +0 -36
  101. tests/infra/__init__.py +0 -5
  102. tests/infra/connectors/__init__.py +0 -5
  103. tests/infra/connectors/test_google_drive_connector.py +0 -107
  104. tests/infra/connectors/test_local_file_connector.py +0 -85
  105. tests/infra/connectors/test_s3_connector.py +0 -95
  106. tests/infra/test_call_service.py +0 -92
  107. tests/infra/test_database_manager.py +0 -59
  108. tests/infra/test_gemini_adapter.py +0 -137
  109. tests/infra/test_google_chat_app.py +0 -68
  110. tests/infra/test_llm_client.py +0 -165
  111. tests/infra/test_llm_proxy.py +0 -122
  112. tests/infra/test_mail_app.py +0 -94
  113. tests/infra/test_openai_adapter.py +0 -105
  114. tests/infra/test_redis_session_manager_service.py +0 -117
  115. tests/repositories/__init__.py +0 -5
  116. tests/repositories/test_database_manager.py +0 -87
  117. tests/repositories/test_document_repo.py +0 -76
  118. tests/repositories/test_llm_query_repo.py +0 -340
  119. tests/repositories/test_models.py +0 -38
  120. tests/repositories/test_profile_repo.py +0 -142
  121. tests/repositories/test_tasks_repo.py +0 -76
  122. tests/repositories/test_vs_repo.py +0 -107
  123. tests/services/__init__.py +0 -5
  124. tests/services/test_dispatcher_service.py +0 -274
  125. tests/services/test_document_service.py +0 -181
  126. tests/services/test_excel_service.py +0 -208
  127. tests/services/test_file_processor_service.py +0 -121
  128. tests/services/test_history_service.py +0 -164
  129. tests/services/test_jwt_service.py +0 -255
  130. tests/services/test_load_documents_service.py +0 -112
  131. tests/services/test_mail_service.py +0 -70
  132. tests/services/test_profile_service.py +0 -379
  133. tests/services/test_prompt_manager_service.py +0 -190
  134. tests/services/test_query_service.py +0 -243
  135. tests/services/test_search_service.py +0 -39
  136. tests/services/test_sql_service.py +0 -160
  137. tests/services/test_tasks_service.py +0 -252
  138. tests/services/test_user_feedback_service.py +0 -389
  139. tests/services/test_user_session_context_service.py +0 -132
  140. tests/views/__init__.py +0 -5
  141. tests/views/test_change_password_view.py +0 -191
  142. tests/views/test_chat_token_request_view.py +0 -188
  143. tests/views/test_chat_view.py +0 -98
  144. tests/views/test_download_file_view.py +0 -149
  145. tests/views/test_external_chat_login_view.py +0 -120
  146. tests/views/test_external_login_view.py +0 -102
  147. tests/views/test_file_store_view.py +0 -128
  148. tests/views/test_forgot_password_view.py +0 -142
  149. tests/views/test_history_view.py +0 -336
  150. tests/views/test_home_view.py +0 -61
  151. tests/views/test_llm_query_view.py +0 -154
  152. tests/views/test_login_view.py +0 -114
  153. tests/views/test_prompt_view.py +0 -111
  154. tests/views/test_signup_view.py +0 -140
  155. tests/views/test_tasks_review_view.py +0 -104
  156. tests/views/test_tasks_view.py +0 -130
  157. tests/views/test_user_feedback_view.py +0 -214
  158. tests/views/test_verify_user_view.py +0 -110
  159. {iatoolkit-0.8.1.dist-info → iatoolkit-0.63.4.dist-info}/WHEEL +0 -0
@@ -1,45 +1,62 @@
1
1
  {% extends "base.html" %}
2
2
 
3
- {% block title %}Cambiar Contraseña{% endblock %}
3
+ {% block title %}Cambiar Contraseña - {{ company.name }}{% endblock %}
4
+
5
+ {% block styles %}
6
+ {# Carga las variables de CSS personalizadas de la empresa #}
7
+ <style>
8
+ {{ branding.css_variables | safe }}
9
+ </style>
10
+ {% endblock %}
4
11
 
5
12
  {% block content %}
6
- <div class="container vh-100 d-flex justify-content-center align-items-center">
7
- <div class="col-11 col-md-8 col-lg-5 border rounded p-3 shadow-sm">
8
- <h4 class="text-muted fw-semibold text-start mb-3">Cambiar Contraseña</h4>
9
- <h6 class="text-muted text-start mb-4">{{ email }}</h6>
10
-
11
- <form action="{{ url_for('change_password', company_short_name=company_short_name, token=token) }}" method="post">
12
- <div class="mb-3">
13
- <label for="temp_code" class="form-label text-muted">Código Temporal recibido</label>
14
- <input type="text" name="temp_code" id="temp_code"
15
- class="form-control text-muted" required
16
- autocomplete="off"
17
- value="{{ form_data.temp_code if form_data else '' }}">
18
- </div>
19
- <div class="mb-3">
20
- <label for="new_password" class="form-label text-muted">Nueva Contraseña</label>
21
- <input type="password" name="new_password" id="new_password"
22
- class="form-control text-muted" required
23
- value="{{ form_data.new_password if form_data else '' }}">
24
- <small class="form-text text-muted">
25
- La contraseña debe contener al menos 8 caracteres, una letra mayúscula, una letra minúscula, un número y un carácter especial.
26
- </small>
13
+ {% include '_company_header.html' %}
27
14
 
28
- </div>
29
- <div class="mb-3">
30
- <label for="confirm_password" class="form-label text-muted">Confirmar Nueva Contraseña</label>
31
- <input type="password" name="confirm_password" id="confirm_password"
32
- class="form-control text-muted" required
33
- value="{{ form_data.password if form_data else '' }}">
34
- </div>
35
- <button type="submit" class="btn btn-primary w-100">Cambiar Contraseña</button>
15
+ <!-- Sección contenedora para centrar el contenido -->
16
+ <section class="hero-section">
17
+ <div class="container">
18
+ <div class="row justify-content-center">
19
+ <div class="col-lg-6 col-md-8">
20
+ <div class="branded-form-container">
21
+ <h4 class="branded-form-title">Crear Nueva Contraseña</h4>
22
+ <p class="text-muted text-center mb-4">
23
+ Estás cambiando la contraseña para <strong>{{ email }}</strong>.
24
+ </p>
25
+
26
+ <form action="{{ url_for('change_password', company_short_name=company_short_name, token=token) }}" method="post">
36
27
 
37
- <p class="text-muted text-start mt-3" style="text-align: justify;">
38
- Ingresa el código de seguridad que recibiste por correo y elige una nueva contraseña.
39
- Asegúrate de que sea segura y fácil de recordar.
40
- </p>
28
+ <div class="mb-3">
29
+ <label for="temp_code" class="form-label text-secondary">Código Temporal</label>
30
+ <input type="text" id="temp_code" name="temp_code" class="form-control"
31
+ required value="{{ form_data.temp_code if form_data else '' }}"
32
+ placeholder="Revisa tu correo electrónico">
33
+ </div>
41
34
 
42
- </form>
43
- </div>
44
- </div>
35
+ <div class="mb-3">
36
+ <label for="new_password" class="form-label text-secondary">Nueva Contraseña</label>
37
+ <input type="password" id="new_password" name="new_password" class="form-control" required>
38
+ <div class="d-flex align-items-start text-muted mt-2" style="font-size: 0.8rem;">
39
+ <i class="bi bi-info-circle me-2" style="font-size: 0.9rem; line-height: 1.4;"></i>
40
+ <span>Debe contener al menos 8 caracteres, mayúscula, minúscula, número y un carácter especial.</span>
41
+ </div>
42
+ </div>
43
+
44
+ <div class="mb-3">
45
+ <label for="confirm_password" class="form-label text-secondary">Confirmar Nueva Contraseña</label>
46
+ <input type="password" id="confirm_password" name="confirm_password" class="form-control" required>
47
+ </div>
48
+
49
+ <button type="submit" class="btn btn-branded-primary w-100 fw-bold py-2 mt-3">Guardar Contraseña</button>
50
+ </form>
51
+
52
+ <div class="text-center mt-4 pt-3" style="border-top: 1px solid #e0e0e0;">
53
+ <a href="{{ url_for('home', company_short_name=company_short_name) }}" class="text-muted text-decoration-none fw-semibold">
54
+ <i class="bi bi-arrow-left me-1"></i>Volver al inicio
55
+ </a>
56
+ </div>
57
+ </div>
58
+ </div>
59
+ </div>
60
+ </div>
61
+ </section>
45
62
  {% endblock %}
@@ -3,50 +3,87 @@
3
3
  {% block title %}IAToolkit{% endblock %}
4
4
 
5
5
  {% block content %}
6
+
7
+ {% block styles %}
8
+ {# Movemos los estilos y los links aquí para que se rendericen en el <head> #}
9
+ <style>
10
+ {{ branding.css_variables | safe }}
11
+ </style>
12
+ <link rel="stylesheet" href="{{ url_for('static', filename='styles/onboarding.css', _external=True) }}">
13
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css">
14
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">
15
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/toastr.js/latest/toastr.min.css">
16
+
17
+ {% endblock %}
18
+
6
19
  <!-- Sección de encabezado con el usuario conectado -->
7
- <div class="company-section d-flex justify-content-between align-items-center">
8
- <!-- Izquierda: Datos del usuario -->
9
- <span class="text-muted small fw-bold">
10
- {{ company_short_name }} - {{ external_user_id or user.email }}
11
- </span>
12
-
13
- <!-- Derecha: Grupo de iconos de acción -->
14
- <div class="d-flex align-items-center">
15
- <!-- "Powered by" -->
16
- <span class="text-muted" style="font-size: 0.75rem;">
17
- Powered by <strong>IAToolkit</strong>
18
- </span>
19
-
20
- <!-- Icono de Historial -->
21
- <a href="javascript:void(0);" id="history-button"
22
- class="ms-3 action-icon-style" title="Historial con mis consultas">
23
- <i class="bi bi-clock-history"></i>
24
- </a>
25
-
26
- <!-- Icono de Feedback -->
27
- <a href="javascript:void(0);" id="send-feedback-button"
28
- class="ms-3 action-icon-style" title="Tu feedback es muy importante">
29
- <i class="bi bi-emoji-smile"></i>
30
- </a>
31
-
32
- <!-- Icono de cerrar sesión -->
33
- {% if user.email %}
34
- <a href="{{ url_for('logout', company_short_name=company_short_name) }}"
35
- class="ms-3 action-icon-style" title="Cerrar sesión">
36
- <i class="bi bi-box-arrow-right"></i>
37
- </a>
38
- {% endif %}
20
+ <div id="company-section"
21
+ class="company-section d-flex flex-column flex-md-row justify-content-md-between align-items-center px-3 py-2"
22
+ style="{{ branding.header_style }}">
23
+
24
+ <!-- Fila 1 (Móvil) / Columna Izquierda (Desktop): Nombre de la Empresa -->
25
+ <div class="d-flex align-items-center mb-2 mb-md-0">
26
+ <span style="{{ branding.primary_text_style }}">
27
+ {{ branding.name }}
28
+ </span>
29
+ <span class="ms-2" data-bs-toggle="tooltip" data-bs-placement="bottom"
30
+ title="Powered by IAToolkit ({{ iatoolkit_version }})">
31
+ <i class="bi bi-info-circle" style="color: {{ branding.header_text_color }}; opacity: 0.7; font-size: 0.9rem;"></i>
32
+ </span>
33
+ </div>
34
+
35
+ <!-- Contenedor para la derecha que agrupa ID de usuario y botones -->
36
+ <div class="d-flex flex-column flex-md-row align-items-center">
37
+
38
+ <!-- Fila 2 (Móvil) / Parte 1 de la Columna Derecha (Desktop): ID de Usuario -->
39
+ <span style="{{ branding.secondary_text_style }}" class="mb-2 mb-md-0">
40
+ {{ user_identifier }}
41
+ </span>
42
+
43
+ <!-- Separador Vertical (Solo visible en Desktop) -->
44
+ <div class="vr mx-3 d-none d-md-block"></div>
45
+
46
+ <!-- Fila 3 (Móvil) / Parte 2 de la Columna Derecha (Desktop): Iconos de Acción -->
47
+ <div class="d-flex align-items-center">
48
+ <a href="javascript:void(0);"
49
+ id="history-button"
50
+ class="action-icon-style" title="Historial con mis consultas" style="color: {{ branding.header_text_color }};">
51
+ <i class="bi bi-clock-history"></i>
52
+ </a>
53
+ <a href="javascript:void(0);"
54
+ id="force-reload-button"
55
+ class="ms-3 action-icon-style"
56
+ title="Forzar Recarga de Contexto"
57
+ style="color: {{ branding.header_text_color }};">
58
+ <i class="bi bi-arrow-clockwise"></i>
59
+ </a>
60
+ <a href="javascript:void(0);"
61
+ id="send-feedback-button"
62
+ class="ms-3 action-icon-style" title="Tu feedback es muy importante" style="color: {{ branding.header_text_color }};">
63
+ <i class="bi bi-emoji-smile"></i>
64
+ </a>
65
+ <a href="javascript:void(0);"
66
+ id="onboarding-button"
67
+ class="ms-3 action-icon-style" title="Ver onboarding"
68
+ style="color: {{ branding.header_text_color }};">
69
+ <i class="bi bi-lightbulb"></i>
70
+ </a>
71
+ <a href="javascript:void(0);"
72
+ id="logout-button"
73
+ class="ms-3 action-icon-style" title="Cerrar sesión"
74
+ style="color: {{ branding.header_text_color }}; !important;">
75
+ <i class="bi bi-box-arrow-right"></i>
76
+ </a>
77
+ </div>
78
+ </div>
39
79
  </div>
40
- </div>
41
80
 
42
81
  <div id="chat-container"
43
- class="mt-2 p-3 border border-2 rounded flex-grow-1"
82
+ class="chat-block mt-2 flex-grow-1"
44
83
  style="overflow-y: auto;">
45
- <div id="chat-messages">
46
- <!-- Mensaje de bienvenida estático -->
47
- <div class="answer-section">
48
- ¡Hola! en que te puedo ayudar hoy?
49
- </div>
84
+ <!-- Mensaje de bienvenida estático -->
85
+ <div class="answer-section">
86
+ ¡Hola! en que te puedo ayudar hoy?
50
87
  </div>
51
88
  </div>
52
89
 
@@ -55,7 +92,7 @@
55
92
  <input type="file" id="file-upload" class="filepond" data-max-files="5" multiple>
56
93
  </div>
57
94
 
58
- <div class="input-area mt-2 mb-2">
95
+ <div id="input-area" class="input-area chat-block mt-2 mb-2">
59
96
 
60
97
  <!-- 1. Contenido Colapsable del Asistente de prompts -->
61
98
  <div class="collapse" id="prompt-assistant-collapse">
@@ -80,8 +117,11 @@
80
117
  data-custom-fields='{{ prompt.custom_fields | tojson }}'>
81
118
  {{ prompt.description }}
82
119
  </a>
83
- </li> {% endfor %}
84
- {% if not loop.last %}<li><hr class="dropdown-divider"></li>{% endif %}
120
+ </li>
121
+ {% endfor %}
122
+ {% if not loop.last %}
123
+ <li><hr class="dropdown-divider"></li>
124
+ {% endif %}
85
125
  {% endfor %}
86
126
  {% endif %}
87
127
  </ul>
@@ -100,11 +140,12 @@
100
140
  </div>
101
141
 
102
142
  <!-- 2. La Barra de Entrada Principal -->
103
- <div class="chat-input-bar d-flex align-items-center">
143
+ <div id="chat-input-bar" class="chat-input-bar d-flex align-items-center">
104
144
  <!-- Iconos de la izquierda -->
105
145
  <div class="d-flex align-items-center">
106
- <!-- BOTÓN PARA CONTROLAR EL COLLAPSE -->
107
- <a class="p-2" href="#prompt-assistant-collapse" data-bs-toggle="collapse" role="button" aria-expanded="false" aria-controls="prompt-assistant-collapse" title="Usar Asistente de Prompts">
146
+ <!-- varita magica -->
147
+ <a class="p-2" href="#prompt-assistant-collapse" data-bs-toggle="collapse" role="button"
148
+ aria-expanded="false" aria-controls="prompt-assistant-collapse" title="Usar Asistente de Prompts">
108
149
  <i class="bi bi-magic"></i>
109
150
  </a>
110
151
  <a class="p-2" href="javascript:void(0);" id="paperclip-button" title="Adjuntar archivos">
@@ -147,34 +188,76 @@
147
188
  <script>
148
189
  // --- Global Configuration from Backend ---
149
190
  window.companyShortName = "{{ company_short_name }}";
191
+ window.user_identifier = "{{ user_identifier }}";
192
+ window.redeemToken = {{ redeem_token | tojson | default('null') }};
150
193
  window.iatoolkit_base_url = "{{ iatoolkit_base_url }}";
151
- window.externalUserId = "{{ external_user_id }}";
152
194
  window.availablePrompts = {{ prompts.message | tojson }};
195
+ window.onboardingCards = {{ onboarding_cards | tojson }};
196
+ window.sendButtonColor = "{{ branding.send_button_color }}";
153
197
 
154
- {% if auth_method == 'jwt' and session_jwt %}
155
- // Store session JWT if it exists, defined in the same global scope
156
- window.sessionJWT = "{{ session_jwt }}";
157
- {% endif %}
158
198
  </script>
159
199
 
160
200
  <!-- Carga de los scripts JS externos después de definir las variables globales -->
161
- <script src="{{ url_for('static', filename='js/chat_filepond.js') }}"></script>
162
- <script src="{{ url_for('static', filename='js/chat_history.js') }}"></script>
163
- <script src="{{ url_for('static', filename='js/chat_feedback.js') }}"></script>
164
- <script src="{{ url_for('static', filename='js/chat_main.js') }}"></script>
201
+ <script src="{{ url_for('static', filename='js/chat_onboarding_button.js', _external=True) }}"></script>
202
+ <script src="{{ url_for('static', filename='js/chat_filepond.js', _external=True) }}"></script>
203
+ <script src="{{ url_for('static', filename='js/chat_history_button.js', _external=True) }}"></script>
204
+ <script src="{{ url_for('static', filename='js/chat_feedback_button.js', _external=True) }}"></script>
205
+ <script src="{{ url_for('static', filename='js/chat_reload_button.js', _external=True) }}"></script>
206
+ <script src="{{ url_for('static', filename='js/chat_main.js', _external=True) }}"></script>
207
+ <script src="{{ url_for('static', filename='js/chat_logout_button.js', _external=True) }}"></script>
208
+ <script src="{{ url_for('static', filename='js/chat_prompt_manager.js', _external=True) }}"></script>
209
+ <script src="{{ url_for('static', filename='js/chat_main.js', _external=True) }}"></script>
165
210
 
166
- <script>
167
- document.addEventListener('DOMContentLoaded', function() {
168
- const promptCollapse = document.getElementById('prompt-assistant-collapse');
169
- if (promptCollapse) {
170
- promptCollapse.addEventListener('shown.bs.collapse', function () {
171
- // Desplazar la ventana al final de la página para mantener visible el área de entrada.
172
- window.scrollTo({
173
- top: document.body.scrollHeight,
174
- behavior: 'smooth'
175
- });
176
- });
177
- }
211
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
212
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/toastr.js/latest/toastr.min.js"></script>
213
+
214
+ <script>
215
+
216
+ document.addEventListener('DOMContentLoaded', function () {
217
+ // Inicializar todos los tooltips de la página
218
+ var tooltipTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"]'))
219
+ var tooltipList = tooltipTriggerList.map(function (tooltipTriggerEl) {
220
+ return new bootstrap.Tooltip(tooltipTriggerEl)
221
+ })
178
222
  });
223
+
224
+ // Inicialización del modal de onboarding
225
+ document.addEventListener('DOMContentLoaded', function () {
226
+ const btn = document.getElementById('onboarding-button');
227
+ if (!btn) return;
228
+
229
+ const modalEl = document.getElementById('onboardingModal');
230
+ const modal = new bootstrap.Modal(modalEl);
231
+
232
+ if (!window.initOnboarding) {
233
+ console.error('initOnboarding no disponible. Verifica chat_onboarding.js');
234
+ return;
235
+ }
236
+
237
+ const onboarding = initOnboarding({
238
+ mode: 'modal',
239
+ cards: Array.isArray(window.onboardingCards) ? window.onboardingCards : [],
240
+ ui: {
241
+ icon: '#ob-icon',
242
+ title: '#ob-title',
243
+ text: '#ob-text',
244
+ dots: '#ob-dots',
245
+ prev: '#ob-prev',
246
+ next: '#ob-next'
247
+ },
248
+ autoRotateMs: 5000
249
+ });
250
+
251
+ modalEl.addEventListener('hidden.bs.modal', () => onboarding.stop());
252
+
253
+ btn.addEventListener('click', () => {
254
+ if (!onboarding.hasCards()) {
255
+ toastr.info('No hay información de onboarding disponible.');
256
+ return;
257
+ }
258
+ onboarding.start();
259
+ modal.show();
260
+ });
261
+ });
179
262
  </script>
180
263
  {% endblock %}
@@ -2,7 +2,7 @@
2
2
  <div class="modal fade" id="uploadedFilesModal" tabindex="-1" aria-labelledby="uploadedFilesModalLabel" aria-hidden="true">
3
3
  <div class="modal-dialog">
4
4
  <div class="modal-content">
5
- <div class="modal-header">
5
+ <div class="modal-header branded">
6
6
  <h5 class="modal-title" id="uploadedFilesModalLabel">Archivos Cargados</h5>
7
7
  <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
8
8
  </div>
@@ -12,7 +12,7 @@
12
12
  </ul>
13
13
  </div>
14
14
  <div class="modal-footer">
15
- <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cerrar</button>
15
+ <button type="button" class="btn btn-branded-secondary" data-bs-dismiss="modal">Cerrar</button>
16
16
  </div>
17
17
  </div>
18
18
  </div>
@@ -22,7 +22,7 @@
22
22
  <div class="modal fade" id="feedbackModal" tabindex="-1" aria-labelledby="feedbackModalLabel" aria-hidden="true">
23
23
  <div class="modal-dialog modal-dialog-centered">
24
24
  <div class="modal-content">
25
- <div class="modal-header">
25
+ <div class="modal-header branded">
26
26
  <h5 class="modal-title" id="feedbackModalLabel">
27
27
  <i class="bi bi-chat-dots me-3"></i>Tu Opinión es Importante
28
28
  </h5>
@@ -31,7 +31,6 @@
31
31
  <div class="modal-body">
32
32
  <p class="text-center mb-2"><strong>¿Qué tan útil fue la respuesta del asistente?</strong></p>
33
33
 
34
- <!-- ▼▼▼ ESTE ES EL BLOQUE DE HTML QUE FALTABA ▼▼▼ -->
35
34
  <div class="rating-stars mb-4">
36
35
  <span class="star" data-rating="1" onclick="gfg(1)"></span>
37
36
  <span class="star" data-rating="2" onclick="gfg(2)"></span>
@@ -52,10 +51,10 @@
52
51
  </div>
53
52
  </div>
54
53
  <div class="modal-footer">
55
- <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">
54
+ <button type="button" class="btn btn-branded-secondary" data-bs-dismiss="modal">
56
55
  <i class="bi bi-x-circle me-1"></i>Cancelar
57
56
  </button>
58
- <button type="button" class="btn btn-primary" id="submit-feedback">
57
+ <button type="button" class="btn btn-branded-primary" id="submit-feedback">
59
58
  <i class="bi bi-send me-1"></i>Enviar
60
59
  </button>
61
60
  </div>
@@ -65,9 +64,9 @@
65
64
 
66
65
  <!-- Modal para historial -->
67
66
  <div class="modal fade" id="historyModal" tabindex="-1" aria-labelledby="historyModalLabel" aria-hidden="true">
68
- <div class="modal-dialog modal-lg modal-dialog-centered">
67
+ <div class="modal-dialog modal-lg modal-dialog-centered modal-dialog-scrollable">
69
68
  <div class="modal-content">
70
- <div class="modal-header">
69
+ <div class="modal-header branded">
71
70
  <h5 class="modal-title" id="historyModalLabel">
72
71
  <i class="bi bi-clock-history me-3"></i>Historial de Consultas
73
72
  </h5>
@@ -80,22 +79,19 @@
80
79
  </div>
81
80
  <p class="mt-2">Cargando historial...</p>
82
81
  </div>
83
- <div id="history-error" style="display: none;" class="alert alert-danger">
82
+ <div id="history-error" style="display: none;">
84
83
  <!-- Los errores se mostrarán aquí -->
85
84
  </div>
86
85
  <div id="history-content" style="display: none;">
87
- <!-- Texto explicativo -->
88
- <div class="alert alert-info mb-3" role="alert">
89
- <i class="bi bi-info-circle me-2"></i>
90
- <strong>Tip:</strong> Haz clic en cualquier pregunta del historial para copiarla automáticamente al área de texto.
91
- </div>
86
+
92
87
  <div class="table-responsive">
93
88
  <table class="table table-striped table-hover">
94
- <thead class="thead-dark">
89
+ <thead class="thead-branded">
95
90
  <tr>
96
- <th scope="col">#</th>
97
- <th scope="col">Fecha</th>
91
+ <th scope="col" class="col-min">Fecha</th>
98
92
  <th scope="col">Consulta</th>
93
+ <th scope="col" class="col-icon"></th>
94
+
99
95
  </tr>
100
96
  </thead>
101
97
  <tbody id="history-table-body">
@@ -106,10 +102,43 @@
106
102
  </div>
107
103
  </div>
108
104
  <div class="modal-footer">
109
- <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">
105
+ <button type="button" class="btn btn-branded-secondary" data-bs-dismiss="modal">
110
106
  <i class="bi bi-x-circle me-1"></i>Cerrar
111
107
  </button>
112
108
  </div>
113
109
  </div>
114
110
  </div>
111
+ </div>
112
+
113
+ <!-- Modal de Onboarding -->
114
+ <div class="modal fade" id="onboardingModal" tabindex="-1" aria-labelledby="onboardingModalLabel" aria-hidden="true">
115
+ <div class="modal-dialog modal-dialog-centered">
116
+ <div class="modal-content" style="border-radius:12px;">
117
+ <div class="modal-header">
118
+ <h5 class="modal-title w-100 text-center" id="onboardingModalLabel" style="color: var(--brand-primary-color, #FF5100);">
119
+ Bienvenido a {{ branding.name }}
120
+ </h5>
121
+ <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Cerrar"></button>
122
+ </div>
123
+
124
+ <div class="modal-body ob-root">
125
+ <div id="ob-card" class="ob-card">
126
+ <div id="ob-icon" class="ob-icon"><i class="bi bi-lightbulb"></i></div>
127
+ <h6 id="ob-title" class="ob-title"></h6>
128
+ <div id="ob-text" class="ob-text"></div>
129
+ <div class="ob-nav">
130
+ <button id="ob-prev" class="ob-btn" aria-label="Anterior"><i class="bi bi-chevron-left"></i></button>
131
+ <div id="ob-dots" class="ob-dots"></div>
132
+ <button id="ob-next" class="ob-btn" aria-label="Siguiente"><i class="bi bi-chevron-right"></i></button>
133
+ </div>
134
+ </div>
135
+ </div>
136
+
137
+ <div class="modal-footer">
138
+ <button id="ob-close" type="button" class="btn btn-branded-primary" data-bs-dismiss="modal">
139
+ Cerrar
140
+ </button>
141
+ </div>
142
+ </div>
143
+ </div>
115
144
  </div>
@@ -1,15 +1,48 @@
1
1
  {% extends "base.html" %}
2
2
 
3
- {% block title %}Error - IAToolkit{% endblock %}
3
+ {% block title %}Error {% endblock %}
4
+
5
+ {% block styles %}
6
+ {# Carga las variables de CSS personalizadas de la empresa #}
7
+ {% if branding %}
8
+ <style>
9
+ {{ branding.css_variables | safe }}
10
+ </style>
11
+ {% endif %}
12
+ {# Enlace a los iconos de Bootstrap para el icono de error #}
13
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">
14
+ {% endblock %}
4
15
 
5
16
  {% block content %}
6
- <div class="container vh-100 d-flex justify-content-center align-items-center">
7
- <div class="text-center col-11 col-md-8 col-lg-6 border rounded p-4 shadow-sm bg-light">
8
- <h1 class="text-danger fw-bold">¡Ups! Ha ocurrido un error</h1>
9
- <p class="mt-3 text-muted">
10
- {{ message }}
11
- </p>
12
- <a href="{{ url_for('home') }}" class="btn btn-primary mt-4">Volver al Inicio</a>
17
+ {% include '_company_header.html' %}
18
+
19
+ {# Contenedor principal para el mensaje de error #}
20
+ <div class="container mt-5">
21
+ <div class="row justify-content-center">
22
+ <div class="col-md-8 col-lg-6">
23
+
24
+ {# Usamos una tarjeta para enmarcar el contenido del error #}
25
+ <div class="card shadow-sm text-center border-danger">
26
+ <div class="card-body p-4 p-md-5">
27
+
28
+ {# Icono de error grande y visible #}
29
+ <i class="bi bi-exclamation-triangle-fill text-danger" style="font-size: 4rem;"></i>
30
+
31
+ <h4 class="card-title mt-4">Ha Ocurrido un Error</h4>
32
+
33
+ {# El mensaje de error dinámico que se pasa desde la vista #}
34
+ <p class="text-muted mt-3 mb-4">
35
+ {{ message | default('Lo sentimos, algo salió mal. Por favor, inténtalo de nuevo más tarde.') }}
36
+ </p>
37
+
38
+ <a href="javascript:history.back()"
39
+ class="btn btn-branded-primary px-4">
40
+ Volver
41
+ </a>
42
+ </div>
43
+ </div>
44
+ </div>
13
45
  </div>
14
46
  </div>
47
+
15
48
  {% endblock %}
@@ -1,33 +1,46 @@
1
1
  {% extends "base.html" %}
2
2
 
3
- {% block title %}Recuperar Contraseña{% endblock %}
3
+ {% block title %}Recuperar Contraseña - {{ branding.name }}{% endblock %}
4
+
5
+ {% block styles %}
6
+ <style>{{ branding.css_variables | safe }}</style>
7
+ <link rel="stylesheet" href="{{ url_for('static', filename='styles/chat_iatoolkit.css') }}">
8
+ {% endblock %}
4
9
 
5
10
  {% block content %}
6
- <div class="container d-flex justify-content-center align-items-center vh-100">
7
- <div class="col-11 col-md-6 col-lg-4 border rounded p-3 shadow-sm">
8
- <h4 class="text-muted fw-semibold text-start mb-3">Recuperar Contraseña</h4>
9
-
10
- <form action="{{ url_for('forgot_password', company_short_name=company_short_name) }}" method="post">
11
- <div class="mb-3">
12
- <label for="email" class="form-label text-muted">Correo Electrónico</label>
13
- <input type="email" id="email" name="email"
14
- class="form-control text-muted"
15
- required value="{{ form_data.email if form_data else '' }}"
16
- style="text-align: justify;">
17
- </div>
11
+ {% include '_company_header.html' %}
12
+
13
+ <!-- 3. Sección contenedora para centrar el contenido -->
14
+ <section class="hero-section">
15
+ <div class="container">
16
+ <div class="row justify-content-center">
17
+ <div class="col-lg-6 col-md-8">
18
+ <div class="branded-form-container">
19
+ <h4 class="branded-form-title">Recuperar Contraseña</h4>
20
+
21
+ <p class="text-muted text-center mb-4">
22
+ Ingresa tu correo electrónico y te enviaremos un enlace para restablecer tu contraseña.
23
+ </p>
18
24
 
19
- <button type="submit" class="btn btn-primary w-100">Enviar Contraseña</button>
25
+ <form action="{{ url_for('forgot_password', company_short_name=company_short_name) }}" method="post">
26
+ <div class="mb-3">
27
+ <label for="email" class="form-label text-secondary">Correo Electrónico</label>
28
+ <input type="email" id="email" name="email"
29
+ class="form-control"
30
+ required value="{{ form_data.email if form_data else '' }}">
31
+ </div>
20
32
 
21
- <!-- Mensaje descriptivo -->
22
- <p class="text-muted text-start mt-3" style="text-align: justify;">
23
- Recibirás un correo con una nueva contraseña temporal junto con un código de seguridad.
24
- Usa este código para cambiar tu contraseña de forma segura y mantener tu cuenta protegida.
25
- </p>
33
+ <button type="submit" class="btn btn-branded-primary w-100 fw-bold py-2 mt-3">Enviar Enlace</button>
34
+ </form>
26
35
 
27
- <div class="text-center mt-3">
28
- <a href="{{ url_for('login', company_short_name=company_short_name) }}" class="text-muted text-decoration-none fw-semibold">Volver al Login</a>
36
+ <div class="text-center mt-4 pt-3" style="border-top: 1px solid #e0e0e0;">
37
+ <a href="{{ url_for('home', company_short_name=company_short_name) }}" class="text-muted text-decoration-none fw-semibold">
38
+ <i class="bi bi-arrow-left me-1"></i>Volver al inicio
39
+ </a>
40
+ </div>
41
+ </div>
42
+ </div>
29
43
  </div>
30
- </form>
31
- </div>
32
- </div>
44
+ </div>
45
+ </section>
33
46
  {% endblock %}