iatoolkit 0.18.1__py3-none-any.whl → 0.20.0__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.

@@ -0,0 +1,126 @@
1
+ {% extends "base.html" %}
2
+
3
+ {% block title %}IAToolkit - Acelerador de IA para tu Empresa{% endblock %}
4
+
5
+ {% block content %}
6
+
7
+ <!-- Incluimos los estilos de branding reutilizables -->
8
+ {% include '_branding_styles.html' %}
9
+
10
+ <!-- Enlazamos la hoja de estilos de la landing page -->
11
+ <link rel="stylesheet" href="{{ iatoolkit_base_url }}/static/styles/landing_page.css">
12
+
13
+ <!-- 1. Barra de Navegación (sin cambios) -->
14
+ <nav class="navbar landing-navbar">
15
+ <div class="container-fluid">
16
+ <span class="navbar-brand">IAToolkit</span>
17
+ </div>
18
+ </nav>
19
+
20
+ <!-- 2. Sección Principal (sin cambios) -->
21
+ <section class="hero-section">
22
+ <div class="container">
23
+ <div class="row align-items-center">
24
+ <div class="col-lg-7">
25
+ <div class="value-proposition">
26
+ <h1 class="hero-title">El <span class="hero-accelerator">Acelerador</span> de IA para tu Empresa</h1>
27
+ <p class="hero-subtitle">IAToolkit es la plataforma de código abierto que conecta de forma segura tus
28
+ datos internos —bases de datos, documentos y sistemas— para crear un asistente de IA
29
+ que entiende tu negocio desde el primer día.</p>
30
+ <p class="hero-subtitle">
31
+ Es un producto para ingenieros de software que quieren construir aplicaciones de IA
32
+ a gran velocidad. Proveemos la infraestructura fundamental y extensible construida en Python
33
+ para que tú te puedas enfocar en conectar tus datos y crear la lógica de negocio.</p>
34
+ </div>
35
+ </div>
36
+ <div class="col-lg-5">
37
+ {% include '_login_widget.html' %}
38
+ </div>
39
+ </div>
40
+ </div>
41
+ </section>
42
+
43
+ <!-- 3. Sección de Características con 6 recuadros -->
44
+ <section class="features-section">
45
+ <div class="container">
46
+ <!-- Primera Fila de Características -->
47
+ <div class="row g-4">
48
+ <!-- Feature 1: GitHub / Open Source -->
49
+ <div class="col-lg-4 d-flex align-items-stretch">
50
+ <div class="opensource-box">
51
+ <div>
52
+ <div class="opensource-icon"><i class="bi bi-github"></i></div>
53
+ <div class="opensource-content">
54
+ <h3>100% Open Source</h3>
55
+ <p>Construido en Python, IAToolkit te da control total. Audita el código, adáptalo y contribuye a una comunidad en crecimiento.</p>
56
+ <a href="https://github.com/tu-usuario/iatoolkit" target="_blank" class="btn btn-light"><i class="bi bi-github me-2"></i>Ir a GitHub</a>
57
+ </div>
58
+ </div>
59
+
60
+ </div>
61
+ </div>
62
+
63
+ <!-- Feature 4: Conectividad -->
64
+ <div class="col-lg-4 d-flex align-items-stretch">
65
+ <div class="feature-item">
66
+ <div class="feature-icon"><i class="bi bi-hdd-stack"></i></div>
67
+ <h3>Conecta tus Datos</h3>
68
+ <p>Integra tus bases de datos SQL, documentos (PDFs, TXT) y otros sistemas para que el asistente tenga un contexto real de tu negocio.</p>
69
+ </div>
70
+ </div>
71
+
72
+ <!-- Feature 2: Multi-LLM -->
73
+ <div class="col-lg-4 d-flex align-items-stretch">
74
+ <div class="feature-item">
75
+ <div class="feature-icon"><i class="bi bi-gem"></i></div>
76
+ <h3>Multi-LLM</h3>
77
+ <p>No te ates a un solo proveedor. IAToolkit está diseñado para funcionar con diferentes modelos, incluyendo Gemini y OpenAI (GPT).</p>
78
+ </div>
79
+ </div>
80
+
81
+ </div>
82
+
83
+ <!-- Segunda Fila de Características -->
84
+ <div class="row g-4 mt-4">
85
+ <div class="col-lg-4 d-flex align-items-stretch">
86
+ <div class="feature-item">
87
+ <div class="feature-icon"><i class="bi bi-magic"></i></div>
88
+ <h3>Prompt Manager</h3>
89
+ <p>Crea, gestiona y comparte una librería de prompts personalizados para tu empresa, optimizando las tareas repetitivas.</p>
90
+ </div>
91
+ </div>
92
+ <!-- Feature 6: Personalización -->
93
+ <div class="col-lg-4 d-flex align-items-stretch">
94
+ <div class="feature-item">
95
+ <div class="feature-icon"><i class="bi bi-palette"></i></div>
96
+ <h3>100% Personalizable</h3>
97
+ <p>Desde la apariencia visual hasta las capacidades y herramientas del asistente,
98
+ adapta cada aspecto para que se alinee con la identidad de tu marca.</p>
99
+ </div>
100
+ </div>
101
+
102
+ <!-- Feature 5: Seguridad -->
103
+ <div class="col-lg-4 d-flex align-items-stretch">
104
+ <div class="feature-item">
105
+ <div class="feature-icon"><i class="bi bi-shield-lock"></i></div>
106
+ <h3>Privacidad Primero</h3>
107
+ <p>Despliega IAToolkit en tus propios servidores. Tus datos y consultas nunca son compartidos con terceros, garantizando la máxima confidencialidad.</p>
108
+ </div>
109
+ </div>
110
+
111
+ </div>
112
+ </div>
113
+ </section>
114
+
115
+ <!-- 4. Footer (sin cambios) -->
116
+ <footer class="landing-footer">
117
+ <div class="container">
118
+ &copy; IAToolkit - Proyecto Open Source
119
+ </div>
120
+ </footer>
121
+
122
+ {% endblock %}
123
+
124
+ {% block scripts %}
125
+ <!-- No se necesita JavaScript aquí para la funcionalidad de la página -->
126
+ {% endblock %}
@@ -95,7 +95,7 @@
95
95
  <!-- MEJORADO: Texto de estado ahora junto al spinner -->
96
96
  <div id="loading-status">
97
97
  <div class="spinner"></div>
98
- <p>Inicializando el contexto de Maxxa para la IA...</p>
98
+ <p>Inicializando el contexto de {{ branding.name }} para la IA...</p>
99
99
  </div>
100
100
 
101
101
  </div>
@@ -1,78 +1,74 @@
1
1
  {% extends "base.html" %}
2
2
 
3
- {% block title %}Registro de Usuario{% endblock %}
3
+ {% block title %}Registro de Usuario - {{ company.name }}{% endblock %}
4
4
 
5
5
  {% block content %}
6
+ <!-- 1. Incluimos los estilos de branding reutilizables -->
7
+ {% include '_branding_styles.html' %}
6
8
 
9
+ <!-- Enlazamos la hoja de estilos de la landing page para reutilizar estilos -->
10
+ <link rel="stylesheet" href="{{ iatoolkit_base_url }}/static/styles/landing_page.css">
7
11
 
8
- <div class="d-flex align-items-center p-3 border-bottom border-light-subtle">
9
- <div class="col-11 col-md-8 col-lg-5 p-3">
10
- <h4 class="text-muted fw-semibold mb-2 text-start">Crea tu cuenta</h4>
11
- <p class="text-muted mb-3 text-start" style="text-align: justify;">
12
- Regístrate para acceder a todas las funcionalidades de nuestra plataforma.
13
- </p>
14
- <form action="{{ url_for('signup', company_short_name=company_short_name) }}" method="post" >
15
- <div class="mb-3 ">
16
- <label for="email" class="form-label text-secondary">Correo Electrónico</label>
17
- <input type="email" autocomplete="off" id="email" name="email"
18
- class="form-control" required
19
- value="{{ form_data.email if form_data else '' }}">
20
- </div>
12
+ <!-- 2. Incluimos la barra de navegación reutilizable -->
13
+ {% include '_navbar.html' %}
21
14
 
22
- {% if is_mobile %}
23
- <!-- En móvil, cada input ocupa una fila -->
24
- <div class="mb-3">
25
- <label for="first_name" class="form-label text-secondary">Nombre</label>
26
- <input type="text" id="first_name" name="first_name"
27
- class="form-control" required
28
- value="{{ form_data.first_name if form_data else '' }}">
29
- </div>
30
- <div class="mb-3">
31
- <label for="last_name" class="form-label text-secondary">Apellido</label>
32
- <input type="text" id="last_name" name="last_name"
33
- class="form-control" required
34
- value="{{ form_data.last_name if form_data else '' }}">
35
- </div>
36
- {% else %}
37
- <div class="row">
38
- <!-- En escritorio, los inputs están en la misma fila -->
39
- <div class="col-md-6 mb-3">
40
- <label for="first_name" class="form-label text-secondary">Nombre</label>
41
- <input type="text" id="first_name" name="first_name"
42
- class="form-control" required
43
- value="{{ form_data.first_name if form_data else '' }}">
44
- </div>
45
- <div class="col-md-6 mb-3">
46
- <label for="last_name" class="form-label text-secondary">Apellido</label>
47
- <input type="text" id="last_name" name="last_name"
48
- class="form-control" required
49
- value="{{ form_data.last_name if form_data else '' }}">
50
- </div>
51
- </div>
15
+ <!-- 3. Sección contenedora para centrar el contenido -->
16
+ <section class="hero-section">
17
+ <div class="container">
18
+ <div class="row justify-content-center">
19
+ <!-- Se ha reducido el ancho de la columna a lg-6 y md-8 -->
20
+ <div class="col-lg-6 col-md-8">
21
+ <div class="border rounded p-4 p-md-5 shadow-sm bg-light">
22
+ <h4 class="form-title fw-bold mb-3 text-center">Crea tu cuenta en {{ company.name }}</h4>
23
+ <form action="{{ url_for('signup', company_short_name=company_short_name) }}" method="post">
24
+ <div class="mb-3">
25
+ <label for="email" class="form-label text-secondary">Correo Electrónico</label>
26
+ <input type="email" autocomplete="off" id="email" name="email"
27
+ class="form-control" required
28
+ value="{{ form_data.email if form_data else '' }}">
29
+ </div>
52
30
 
53
- {% endif %}
31
+ <div class="row">
32
+ <div class="col-md-6 mb-3">
33
+ <label for="first_name" class="form-label text-secondary">Nombre</label>
34
+ <input type="text" id="first_name" name="first_name"
35
+ class="form-control" required
36
+ value="{{ form_data.first_name if form_data else '' }}">
37
+ </div>
38
+ <div class="col-md-6 mb-3">
39
+ <label for="last_name" class="form-label text-secondary">Apellido</label>
40
+ <input type="text" id="last_name" name="last_name"
41
+ class="form-control" required
42
+ value="{{ form_data.last_name if form_data else '' }}">
43
+ </div>
44
+ </div>
54
45
 
55
- <div class="mb-3">
56
- <label for="password" class="form-label text-secondary">Contraseña</label>
57
- <input type="password" id="password" name="password" class="form-control" required>
58
- <small class="form-text text-muted">
59
- 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.
60
- </small>
46
+ <div class="mb-3">
47
+ <label for="password" class="form-label text-secondary">Contraseña</label>
48
+ <input type="password" id="password" name="password" class="form-control" required>
49
+ <!-- Bloque de ayuda para la contraseña mejorado -->
50
+ <div class="d-flex align-items-start text-muted mt-2" style="font-size: 0.8rem;">
51
+ <i class="bi bi-info-circle me-2" style="font-size: 0.9rem; line-height: 1.4;"></i>
52
+ <span>Debe contener al menos 8 caracteres, mayúscula, minúscula, número y un carácter especial.</span>
53
+ </div>
54
+ </div>
61
55
 
56
+ <div class="mb-3">
57
+ <label for="confirm_password" class="form-label text-secondary">Confirmar Contraseña</label>
58
+ <input type="password" id="confirm_password" name="confirm_password" class="form-control" required>
59
+ </div>
60
+
61
+ <!-- Botón actualizado con la clase de branding -->
62
+ <button type="submit" class="btn btn-branded-primary w-100 fw-bold py-2 mt-3">Registrarse</button>
63
+ </form>
64
+ <!-- Nota de privacidad -->
65
+ <p class="text-muted small mb-0 text-center mt-4">
66
+ 🔒 Valoramos tu privacidad. Tus datos se usarán exclusivamente para el funcionamiento de la plataforma.
67
+ </p>
68
+ </div>
69
+ </div>
62
70
  </div>
63
- <div class="mb-3">
64
- <label for="confirm_password" class="form-label text-secondary">Confirmar Contraseña</label>
65
- <input type="password" id="confirm_password" name="confirm_password" class="form-control" required>
66
- </div>
67
- <button type="submit" class="btn btn-primary w-100">Registrarse</button>
68
- </form>
69
- <!-- Nota sobre privacidad -->
70
- <p class="text-muted small mb-0 text-start mt-3" style="text-align: justify;">
71
- 🔒 Valoramos tu privacidad. Tus datos serán utilizados exclusivamente para brindarte una mejor experiencia
72
- y no serán compartidos con terceros sin tu consentimiento. Para más información, consulta nuestra
73
- <a href="#" class="text-decoration-none fw-semibold">Política de Privacidad</a>.
74
- </p>
75
- </p>
76
- </div>
77
- </div>
71
+ </div>
72
+ </section>
73
+
78
74
  {% endblock %}
@@ -4,8 +4,9 @@
4
4
  # IAToolkit is open source software.
5
5
 
6
6
  from flask.views import MethodView
7
- from flask import render_template, request
7
+ from flask import render_template, request, url_for, session, redirect
8
8
  from iatoolkit.services.profile_service import ProfileService
9
+ from iatoolkit.services.branding_service import BrandingService
9
10
  from itsdangerous import URLSafeTimedSerializer, SignatureExpired
10
11
  from flask_bcrypt import Bcrypt
11
12
  from injector import inject
@@ -14,8 +15,11 @@ import os
14
15
 
15
16
  class ChangePasswordView(MethodView):
16
17
  @inject
17
- def __init__(self, profile_service: ProfileService):
18
+ def __init__(self,
19
+ profile_service: ProfileService,
20
+ branding_service: BrandingService):
18
21
  self.profile_service = profile_service
22
+ self.branding_service = branding_service # 3. Guardar la instancia
19
23
 
20
24
  self.serializer = URLSafeTimedSerializer(os.getenv("PASS_RESET_KEY"))
21
25
  self.bcrypt = Bcrypt()
@@ -26,16 +30,20 @@ class ChangePasswordView(MethodView):
26
30
  if not company:
27
31
  return render_template('error.html', message=f"Empresa no encontrada: {company_short_name}"), 404
28
32
 
33
+ branding_data = self.branding_service.get_company_branding(company)
34
+
29
35
  try:
30
36
  # Decodificar el token
31
37
  email = self.serializer.loads(token, salt='password-reset', max_age=3600)
32
38
  except SignatureExpired as e:
33
39
  return render_template('forgot_password.html',
40
+ branding=branding_data,
34
41
  alert_message="El enlace de cambio de contraseña ha expirado. Por favor, solicita uno nuevo.")
35
42
 
36
43
  return render_template('change_password.html',
37
44
  company_short_name=company_short_name,
38
45
  company=company,
46
+ branding=branding_data,
39
47
  token=token, email=email)
40
48
 
41
49
  def post(self, company_short_name: str, token: str):
@@ -44,6 +52,7 @@ class ChangePasswordView(MethodView):
44
52
  if not company:
45
53
  return render_template('error.html', message=f"Empresa no encontrada: {company_short_name}"), 404
46
54
 
55
+ branding_data = self.branding_service.get_company_branding(company)
47
56
  try:
48
57
  # Decodificar el token
49
58
  email = self.serializer.loads(token, salt='password-reset', max_age=3600)
@@ -51,6 +60,7 @@ class ChangePasswordView(MethodView):
51
60
  return render_template('forgot_password.html',
52
61
  company_short_name=company_short_name,
53
62
  company=company,
63
+ branding=branding_data,
54
64
  alert_message="El enlace de cambio de contraseña ha expirado. Por favor, solicita uno nuevo.")
55
65
 
56
66
  try:
@@ -72,17 +82,16 @@ class ChangePasswordView(MethodView):
72
82
  token=token,
73
83
  company_short_name=company_short_name,
74
84
  company=company,
85
+ branding=branding_data,
75
86
  form_data={"temp_code": temp_code,
76
87
  "new_password": new_password,
77
88
  "confirm_password": confirm_password},
78
89
  alert_message=response["error"]), 400
79
90
 
80
-
81
- return render_template('login.html',
82
- company_short_name=company_short_name,
83
- company=company,
84
- alert_icon='success',
85
- alert_message="Tu contraseña ha sido restablecida exitosamente. Ahora puedes iniciar sesión.")
91
+ # Éxito: Guardar mensaje en sesión y redirigir
92
+ session['alert_message'] = "Tu contraseña ha sido restablecida exitosamente. Ahora puedes iniciar sesión."
93
+ session['alert_icon'] = 'success'
94
+ return redirect(url_for('index', company_short_name=company_short_name))
86
95
 
87
96
  except Exception as e:
88
97
  return render_template("error.html",
@@ -4,16 +4,19 @@
4
4
  # IAToolkit is open source software.
5
5
 
6
6
  from flask.views import MethodView
7
- from flask import render_template, request, url_for
7
+ from flask import render_template, request, url_for, redirect, session
8
8
  from injector import inject
9
9
  from iatoolkit.services.profile_service import ProfileService
10
+ from iatoolkit.services.branding_service import BrandingService
10
11
  from itsdangerous import URLSafeTimedSerializer
11
12
  import os
12
13
 
13
14
  class ForgotPasswordView(MethodView):
14
15
  @inject
15
- def __init__(self, profile_service: ProfileService):
16
+ def __init__(self, profile_service: ProfileService,
17
+ branding_service: BrandingService):
16
18
  self.profile_service = profile_service
19
+ self.branding_service = branding_service # 3. Guardar la instancia
17
20
  self.serializer = URLSafeTimedSerializer(os.getenv("PASS_RESET_KEY"))
18
21
 
19
22
  def get(self, company_short_name: str):
@@ -22,9 +25,11 @@ class ForgotPasswordView(MethodView):
22
25
  if not company:
23
26
  return render_template('error.html', message="Empresa no encontrada"), 404
24
27
 
28
+ branding_data = self.branding_service.get_company_branding(company)
25
29
  return render_template('forgot_password.html',
26
30
  company=company,
27
- company_short_name=company_short_name
31
+ company_short_name=company_short_name,
32
+ branding=branding_data
28
33
  )
29
34
 
30
35
  def post(self, company_short_name: str):
@@ -43,19 +48,20 @@ class ForgotPasswordView(MethodView):
43
48
 
44
49
  response = self.profile_service.forgot_password(email=email, reset_url=reset_url)
45
50
  if "error" in response:
51
+ branding_data = self.branding_service.get_company_branding(company)
46
52
  return render_template(
47
53
  'forgot_password.html',
48
54
  company=company,
49
55
  company_short_name=company_short_name,
50
- form_data={"email": email },
56
+ branding=branding_data,
57
+ form_data={"email": email},
51
58
  alert_message=response["error"]), 400
52
59
 
60
+ # Guardamos el mensaje y el icono en la sesión manualmente
61
+ session['alert_message'] = "Si tu correo está registrado, recibirás un enlace para restablecer tu contraseña."
62
+ session['alert_icon'] = "success"
63
+ return redirect(url_for('index', company_short_name=company_short_name))
53
64
 
54
- return render_template('login.html',
55
- company=company,
56
- company_short_name=company_short_name,
57
- alert_icon='success',
58
- alert_message="Hemos enviado un enlace a tu correo para restablecer la contraseña.")
59
65
  except Exception as e:
60
66
  return render_template("error.html",
61
67
  company=company,
@@ -0,0 +1,43 @@
1
+ # iatoolkit/views/index_view.py
2
+
3
+ from flask import render_template, abort, session
4
+ from flask.views import MethodView
5
+ from injector import inject
6
+ from iatoolkit.services.profile_service import ProfileService
7
+ from iatoolkit.services.branding_service import BrandingService
8
+
9
+
10
+ class IndexView(MethodView):
11
+ """
12
+ Handles the rendering of the company-specific landing page.
13
+ """
14
+
15
+ @inject
16
+ def __init__(self,
17
+ profile_service: ProfileService,
18
+ branding_service: BrandingService):
19
+ self.profile_service = profile_service
20
+ self.branding_service = branding_service
21
+
22
+ def get(self, company_short_name: str):
23
+ # La vista ahora recibe el company_short_name desde la URL
24
+ company = self.profile_service.get_company_by_short_name(company_short_name)
25
+
26
+ if not company:
27
+ abort(404, description=f"La empresa '{company_short_name}' no fue encontrada.")
28
+
29
+ # Obtenemos los datos de branding para la plantilla
30
+ branding_data = self.branding_service.get_company_branding(company)
31
+
32
+ alert_message = session.pop('alert_message', None)
33
+ alert_icon = session.pop('alert_icon', 'error')
34
+
35
+ # 2. Pasamos las variables a la plantilla. Si no hay mensaje, serán None.
36
+ return render_template(
37
+ 'index.html',
38
+ company=company,
39
+ company_short_name=company_short_name,
40
+ branding=branding_data,
41
+ alert_message=alert_message,
42
+ alert_icon=alert_icon
43
+ )
@@ -0,0 +1,35 @@
1
+ from flask.views import MethodView
2
+ from injector import inject
3
+ from iatoolkit.common.auth import IAuthentication
4
+ from iatoolkit.services.query_service import QueryService
5
+ from flask import jsonify
6
+ import logging
7
+
8
+ class InitContextView(MethodView):
9
+
10
+ @inject
11
+ def __init__(self,
12
+ iauthentication: IAuthentication,
13
+ query_service: QueryService
14
+ ):
15
+ self.iauthentication = iauthentication
16
+ self.query_service = query_service
17
+
18
+ def get(self, company_short_name: str, external_user_id: str):
19
+ # 1. get access credentials
20
+ iaut = self.iauthentication.verify(company_short_name, external_user_id)
21
+ if not iaut.get("success"):
22
+ return jsonify(iaut), 401
23
+
24
+ try:
25
+ # initialize the context
26
+ self.query_service.llm_init_context(
27
+ company_short_name=company_short_name,
28
+ external_user_id=external_user_id
29
+ )
30
+
31
+ return {'status': 'OK'}, 200
32
+ except Exception as e:
33
+ logging.exception(
34
+ f"Error inesperado al inicializar el contexto durante el login para company {company_short_name}: {e}")
35
+ return jsonify({"error_message": str(e)}), 500
@@ -55,7 +55,7 @@ class InitiateLoginView(MethodView):
55
55
  "email": email,
56
56
  "password": password,
57
57
  },
58
- alert_message=response["error"]), 400
58
+ alert_message=response["message"]), 400
59
59
 
60
60
  # 2. Get branding and onboarding data for the shell page
61
61
  branding_data = self.branding_service.get_company_branding(company)
@@ -4,18 +4,20 @@
4
4
  # IAToolkit is open source software.
5
5
 
6
6
  from flask.views import MethodView
7
- from flask import render_template
7
+ from flask import render_template, request, url_for, session, redirect
8
8
  from iatoolkit.services.profile_service import ProfileService
9
+ from iatoolkit.services.branding_service import BrandingService # 1. Importar BrandingService
9
10
  from injector import inject
10
11
  from itsdangerous import URLSafeTimedSerializer
11
- from flask import url_for, request
12
12
  import os
13
13
 
14
14
 
15
15
  class SignupView(MethodView):
16
16
  @inject
17
- def __init__(self, profile_service: ProfileService):
17
+ def __init__(self, profile_service: ProfileService,
18
+ branding_service: BrandingService):
18
19
  self.profile_service = profile_service
20
+ self.branding_service = branding_service # 3. Guardar la instancia
19
21
  self.serializer = URLSafeTimedSerializer(os.getenv("USER_VERIF_KEY"))
20
22
 
21
23
 
@@ -25,12 +27,13 @@ class SignupView(MethodView):
25
27
  if not company:
26
28
  return render_template('error.html', message="Empresa no encontrada"), 404
27
29
 
28
- user_agent = request.user_agent
29
- is_mobile = user_agent.platform in ["android", "iphone", "ipad"] or "mobile" in user_agent.string.lower()
30
+ # Obtener los datos de branding
31
+ branding_data = self.branding_service.get_company_branding(company)
32
+
30
33
  return render_template('signup.html',
31
34
  company=company,
32
35
  company_short_name=company_short_name,
33
- is_mobile=is_mobile)
36
+ branding=branding_data)
34
37
 
35
38
  def post(self, company_short_name: str):
36
39
  # get company info
@@ -59,26 +62,28 @@ class SignupView(MethodView):
59
62
  verification_url=verification_url)
60
63
 
61
64
  if "error" in response:
65
+ branding_data = self.branding_service.get_company_branding(company)
62
66
  return render_template(
63
- 'signup.html',
64
- company=company,
65
- company_short_name=company_short_name,
66
- form_data={
67
- "first_name": first_name,
68
- "last_name": last_name,
69
- "email": email,
70
- "password": password,
71
- "confirm_password": confirm_password
72
- },
73
- alert_message=response["error"]), 400
74
-
75
- # all is OK
76
- return render_template(
77
- 'login.html',
78
- company=company,
79
- company_short_name=company_short_name,
80
- alert_icon='success',
81
- alert_message=response["message"]), 200
67
+ 'signup.html',
68
+ company=company,
69
+ company_short_name=company_short_name,
70
+ branding=branding_data,
71
+ form_data={
72
+ "first_name": first_name,
73
+ "last_name": last_name,
74
+ "email": email,
75
+ "password": password,
76
+ "confirm_password": confirm_password
77
+ },
78
+ alert_message=response["error"]), 400
79
+
80
+ # Guardamos el mensaje de éxito en la sesión
81
+ session['alert_message'] = response["message"]
82
+ session['alert_icon'] = 'success'
83
+
84
+ # Redirigimos al usuario a la página de login
85
+ return redirect(url_for('index', company_short_name=company_short_name))
86
+
82
87
  except Exception as e:
83
88
  return render_template("error.html",
84
89
  company=company,
@@ -4,7 +4,7 @@
4
4
  # IAToolkit is open source software.
5
5
 
6
6
  from flask.views import MethodView
7
- from flask import render_template
7
+ from flask import render_template, url_for, redirect, session
8
8
  from iatoolkit.services.profile_service import ProfileService
9
9
  from itsdangerous import URLSafeTimedSerializer, SignatureExpired
10
10
  from injector import inject
@@ -43,11 +43,11 @@ class VerifyAccountView(MethodView):
43
43
  token=token,
44
44
  alert_message=response["error"]), 400
45
45
 
46
- return render_template('login.html',
47
- company=company,
48
- company_short_name=company_short_name,
49
- alert_icon='success',
50
- alert_message=response['message'])
46
+ # Guardamos el mensaje y el icono en la sesión manualmente
47
+ session['alert_message'] = response['message']
48
+ session['alert_icon'] = "success"
49
+ return redirect(url_for('index', company_short_name=company_short_name))
50
+
51
51
  except Exception as e:
52
52
  return render_template("error.html",
53
53
  company=company,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: iatoolkit
3
- Version: 0.18.1
3
+ Version: 0.20.0
4
4
  Summary: IAToolkit
5
5
  Author: Fernando Libedinsky
6
6
  License-Expression: MIT