Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
@@ -1,513 +1,255 @@
|
|
1 |
-
|
2 |
-
|
3 |
-
|
4 |
-
|
5 |
-
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
-
|
208 |
-
|
209 |
-
|
210 |
-
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
|
219 |
-
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
""
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
|
233 |
-
|
234 |
-
|
235 |
-
|
236 |
-
|
237 |
-
|
238 |
-
|
239 |
-
|
240 |
-
|
241 |
-
|
242 |
-
|
243 |
-
|
244 |
-
|
245 |
-
|
246 |
-
|
247 |
-
|
248 |
-
|
249 |
-
|
250 |
-
|
251 |
-
|
252 |
-
|
253 |
-
|
254 |
-
|
255 |
-
|
256 |
-
**PERFIL SIMPLIFICADO**
|
257 |
-
|
258 |
-
**Nombre:**
|
259 |
-
[Nombre del avatar]
|
260 |
-
|
261 |
-
**Demografía:**
|
262 |
-
[Edad, género, ubicación, ocupación]
|
263 |
-
|
264 |
-
**Problema principal:**
|
265 |
-
[Descripción del problema principal que enfrenta]
|
266 |
-
|
267 |
-
**Nivel de conciencia:**
|
268 |
-
[Nivel de conciencia sobre su problema]
|
269 |
-
|
270 |
-
**Deseo principal:**
|
271 |
-
[Lo que realmente desea conseguir]
|
272 |
-
""",
|
273 |
-
|
274 |
-
# También actualizar los ejemplos para mantener la consistencia - Removed "Lo que realmente quiere" section
|
275 |
-
"story_example": """
|
276 |
-
**HISTORIA DEL CLIENTE IDEAL**
|
277 |
-
|
278 |
-
**Protagonista:**
|
279 |
-
Ana es una emprendedora de 35 años que dirige su propio estudio de diseño gráfico desde hace tres años. Es creativa, perfeccionista y apasionada por su trabajo.
|
280 |
-
|
281 |
-
**Situación actual:**
|
282 |
-
Ana trabaja más de 12 horas diarias intentando equilibrar la parte creativa de su negocio con las tareas administrativas. Tiene cinco clientes recurrentes, pero le cuesta conseguir nuevos proyectos. Cada mes es una lucha para cubrir todos los gastos y se siente constantemente estresada por la inestabilidad financiera.
|
283 |
-
|
284 |
-
**El problema:**
|
285 |
-
Aunque Ana es excelente en su trabajo creativo, no tiene estrategia de marketing definida. Publica ocasionalmente en redes sociales cuando recuerda hacerlo, pero sin un plan coherente. Ha perdido oportunidades porque potenciales clientes no la encuentran o no entienden claramente el valor de sus servicios. Se siente invisible en un mercado saturado.
|
286 |
-
|
287 |
-
**Intentos fallidos:**
|
288 |
-
Ha probado crear perfiles en todas las redes sociales populares, pero no mantiene ninguno actualizado. Contrató a un freelancer para que le hiciera una página web, pero quedó abandonada sin tráfico. Intentó hacer networking en eventos locales, pero no logró convertir esos contactos en clientes. Cada intento le ha costado tiempo y dinero sin resultados tangibles.
|
289 |
-
|
290 |
-
**Momento de descubrimiento:**
|
291 |
-
Un día, mientras busca desesperadamente soluciones en internet, Ana encuentra un webinar sobre estrategias de marketing específicas para estudios creativos. Por primera vez, escucha consejos que realmente entienden su situación y ofrecen un camino claro y estructurado para atraer clientes ideales sin sacrificar su tiempo creativo.
|
292 |
-
|
293 |
-
**Transformación:**
|
294 |
-
Ana implementa el sistema de marketing aprendido, creando contenido estratégico que muestra su expertise. Establece un embudo de ventas simple pero efectivo que convierte visitantes en clientes. Aprende a comunicar el valor de su trabajo de manera que resuena con quienes realmente valoran el diseño de calidad.
|
295 |
-
|
296 |
-
**Nuevo estado:**
|
297 |
-
Seis meses después, Ana ha duplicado su cartera de clientes y puede ser selectiva con los proyectos que acepta. Ha aumentado sus tarifas un 30% y los clientes pagan sin cuestionar porque entienden el valor que aporta. Trabaja menos horas pero genera más ingresos. El estrés ha disminuido considerablemente y ha recuperado la pasión por su trabajo al poder enfocarse en la parte creativa que realmente ama.
|
298 |
-
""",
|
299 |
-
|
300 |
-
# Simplified example - No "Lo que realmente quiere" section needed
|
301 |
-
"simple_example": """
|
302 |
-
**PERFIL SIMPLIFICADO**
|
303 |
-
|
304 |
-
**Nombre:**
|
305 |
-
Carlos Emprendedor
|
306 |
-
|
307 |
-
**Demografía:**
|
308 |
-
35 años, hombre, Madrid, dueño de pequeña empresa de tecnología
|
309 |
-
|
310 |
-
**Problema principal:**
|
311 |
-
No logra escalar su negocio más allá de los clientes locales y siente que ha alcanzado un techo en su crecimiento.
|
312 |
-
|
313 |
-
**Nivel de conciencia:**
|
314 |
-
Consciente del problema - Sabe que necesita expandirse pero no tiene claro qué estrategias implementar para lograrlo.
|
315 |
-
|
316 |
-
**Deseo principal:**
|
317 |
-
Convertir su pequeña empresa local en una compañía reconocida a nivel nacional con procesos automatizados que le permitan tener más tiempo libre.
|
318 |
-
"""
|
319 |
-
}
|
320 |
-
|
321 |
-
# Asegúrate de que la clave "example" exista y apunte al mismo contenido que "junguiano_example"
|
322 |
-
buyer_persona_formats["example"] = buyer_persona_formats["junguiano_example"]
|
323 |
-
|
324 |
-
# Instrucciones para formato de listas con viñetas
|
325 |
-
bullet_format_instructions = """
|
326 |
-
\n\nIMPORTANT - LIST FORMAT:
|
327 |
-
For the sections of Fears, Insecurities, Guilt, Problems, and Frustrations, use BULLET POINTS (•) with PROPER PARAGRAPH BREAKS after each item.
|
328 |
-
|
329 |
-
Example:
|
330 |
-
Miedos:
|
331 |
-
• Miedo a quedarse atrás en el mercado por no dominar nuevas tecnologías.
|
332 |
-
|
333 |
-
• Temor a perder oportunidades de negocio por barreras de comunicación.
|
334 |
-
|
335 |
-
• Preocupación por no poder expandir su empresa internacionalmente.
|
336 |
-
|
337 |
-
The correct format is (note the empty line between each bullet point):
|
338 |
-
Culpa:
|
339 |
-
• Se siente culpable por no pasar suficiente tiempo con su hijo debido al trabajo.
|
340 |
-
|
341 |
-
• Siente remordimiento por no haber aprendido inglés antes y ahora tener que hacerlo a la fuerza.
|
342 |
-
|
343 |
-
• Experimenta culpa al gastar dinero en un curso de inglés en lugar de en otras necesidades de su hijo.
|
344 |
-
|
345 |
-
• Se siente mal por no poder ayudar a su hijo con sus tareas de inglés.
|
346 |
-
|
347 |
-
DO NOT use this incorrect format (without paragraph breaks):
|
348 |
-
Inseguridades: • Primera inseguridad • Segunda inseguridad • Tercera inseguridad
|
349 |
-
|
350 |
-
ALSO DO NOT use this incorrect format (without empty lines between items):
|
351 |
-
Problemas:
|
352 |
-
• Tiene dificultades para encontrar tiempo para estudiar inglés debido a su trabajo y responsabilidades familiares.
|
353 |
-
• Se siente abrumado por la cantidad de información y recursos disponibles para aprender inglés.
|
354 |
-
• Le resulta difícil concentrarse y mantenerse motivado para estudiar después de un largo día de trabajo.
|
355 |
-
|
356 |
-
ENSURE there is an EMPTY LINE between each bullet point to create proper paragraph separation.
|
357 |
-
DO NOT use hyphens (-) or numbers for these lists.
|
358 |
-
"""
|
359 |
-
|
360 |
-
# Instrucciones para niveles de conciencia
|
361 |
-
consciousness_level_instructions = """
|
362 |
-
\n\nABSOLUTELY CRITICAL - CONSCIOUSNESS LEVEL MAPPING:
|
363 |
-
You MUST use the EXACT consciousness level from this mapping:
|
364 |
-
|
365 |
-
- If user selects "Desconocido" → Use "Desconocido" in your response
|
366 |
-
- If user selects "Consciente del problema" → Use "Consciente del problema" in your response
|
367 |
-
- If user selects "Consciente de la solución" → Use "Consciente de la solución" in your response
|
368 |
-
- If user selects "Consciente del producto" → Use "Consciente del producto" in your response
|
369 |
-
- If user selects "Consciente de la compra" → Use "Consciente de la compra" in your response
|
370 |
-
|
371 |
-
DO NOT DEVIATE from this mapping under any circumstances.
|
372 |
-
|
373 |
-
For "Desconocido" level:
|
374 |
-
- The person is completely unaware they have a problem
|
375 |
-
- They don't recognize any need for change
|
376 |
-
- They are not actively looking for solutions
|
377 |
-
- Their fears and frustrations exist but they don't connect them to this specific problem
|
378 |
-
|
379 |
-
For "Consciente del problema" level:
|
380 |
-
- The person knows they have a problem
|
381 |
-
- They feel the pain and recognize the issue
|
382 |
-
- They don't yet know what solutions exist
|
383 |
-
- They are beginning to research and understand their problem
|
384 |
-
|
385 |
-
For "Consciente de la solución" level:
|
386 |
-
- The person knows what type of solution they need
|
387 |
-
- They are actively comparing different options
|
388 |
-
- They understand how solutions work but haven't chosen one
|
389 |
-
- They are evaluating features, benefits, and pricing
|
390 |
-
|
391 |
-
For "Consciente del producto" level:
|
392 |
-
- The person knows about your specific product/service
|
393 |
-
- They are considering it but haven't decided to purchase
|
394 |
-
- They may have objections or concerns about your offering
|
395 |
-
- They need convincing about your specific solution
|
396 |
-
|
397 |
-
For "Consciente de la compra" level:
|
398 |
-
- The person is ready to buy
|
399 |
-
- They need a final push or incentive
|
400 |
-
- They are looking for validation of their decision
|
401 |
-
- They may need help with the purchasing process
|
402 |
-
|
403 |
-
The "Nivel de conciencia" section in your response MUST follow this exact format:
|
404 |
-
**Nivel de conciencia**: [EXACT MAPPED LEVEL] - [explanation consistent with that level]
|
405 |
-
|
406 |
-
ALL other aspects of the persona (fears, problems, etc.) MUST be consistent with the specified consciousness level.
|
407 |
-
"""
|
408 |
-
|
409 |
-
# Lo que realmente queremos (motivaciones profundas)
|
410 |
-
what_we_really_want = {
|
411 |
-
"list": [
|
412 |
-
"Increase our potential",
|
413 |
-
"Escape danger",
|
414 |
-
"Free ourselves from fear and guilt",
|
415 |
-
"Silence those who doubt us",
|
416 |
-
"Validate our feelings",
|
417 |
-
"Power over others",
|
418 |
-
"Advantages over our rivals",
|
419 |
-
"Be free from the consequences",
|
420 |
-
"Have more time dedicated to what we love",
|
421 |
-
"Less time dedicated to what we hate",
|
422 |
-
"Happiness and satisfaction",
|
423 |
-
"Prove we are right",
|
424 |
-
"Prove our detractors wrong",
|
425 |
-
"Be attractive and charming to others",
|
426 |
-
"Leave a lasting legacy",
|
427 |
-
"Higher status among our peers",
|
428 |
-
"Have a life full of comforts and luxuries",
|
429 |
-
"Be accepted by a social group or community",
|
430 |
-
"Be respected and admired for our intelligence, skills, or talents",
|
431 |
-
"Be true to ourselves and reach our full potential",
|
432 |
-
"Climb the social hierarchy",
|
433 |
-
"Establish close and lasting relationships with friends and family",
|
434 |
-
"Feel part of a group or community and be valued and appreciated by others",
|
435 |
-
"Be appreciated for our actions and receive gratitude from others"
|
436 |
-
],
|
437 |
-
"format": """
|
438 |
-
**[WHAT WE REALLY WANT]**
|
439 |
-
- Increase our potential
|
440 |
-
- Escape danger
|
441 |
-
- Free ourselves from fear and guilt
|
442 |
-
- Silence those who doubt us
|
443 |
-
- Validate our feelings
|
444 |
-
- Power over others
|
445 |
-
- Advantages over our rivals
|
446 |
-
- Be free from the consequences
|
447 |
-
- Have more time dedicated to what we love
|
448 |
-
- Less time dedicated to what we hate
|
449 |
-
- Happiness and satisfaction
|
450 |
-
- Prove we are right
|
451 |
-
- Prove our detractors wrong
|
452 |
-
- Be attractive and charming to others
|
453 |
-
- Leave a lasting legacy
|
454 |
-
- Higher status among our peers
|
455 |
-
- Have a life full of comforts and luxuries
|
456 |
-
- Be accepted by a social group or community
|
457 |
-
- Be respected and admired for our intelligence, skills, or talents
|
458 |
-
- Be true to ourselves and reach our full potential
|
459 |
-
- Climb the social hierarchy
|
460 |
-
- Establish close and lasting relationships with friends and family
|
461 |
-
- Feel part of a group or community and be valued and appreciated by others
|
462 |
-
- Be appreciated for our actions and receive gratitude from others
|
463 |
-
"""
|
464 |
-
}
|
465 |
-
|
466 |
-
validation_questions = {
|
467 |
-
"buyer_persona": """
|
468 |
-
---
|
469 |
-
**Validation Questions for Your Ideal Customer Profile:**
|
470 |
-
|
471 |
-
Have you addressed these essential aspects in your buyer persona?
|
472 |
-
|
473 |
-
1. **Demographics and Background:**
|
474 |
-
- Have you defined their age, gender, education level, and location?
|
475 |
-
- What is their current occupation and professional background?
|
476 |
-
- What is their socioeconomic status and lifestyle?
|
477 |
-
|
478 |
-
2. **Psychographics and Values:**
|
479 |
-
- What are their core values and beliefs?
|
480 |
-
- What aspirations drive their decisions?
|
481 |
-
- Which activities and interests align with your offering?
|
482 |
-
- How do their interests overlap with your expertise?
|
483 |
-
|
484 |
-
3. **Problems and Needs:**
|
485 |
-
- What specific problems are they trying to solve?
|
486 |
-
- Which pain points are most urgent for them?
|
487 |
-
- What frustrations are driving them to seek a solution?
|
488 |
-
- How does your solution address their specific challenges?
|
489 |
-
|
490 |
-
4. **Purchase Behavior:**
|
491 |
-
- What is their typical budget for similar solutions?
|
492 |
-
- How do they evaluate purchase decisions?
|
493 |
-
- What factors influence their buying choices?
|
494 |
-
- Are they willing to invest in premium solutions?
|
495 |
-
|
496 |
-
5. **Decision-Making Process:**
|
497 |
-
- Do they research thoroughly before buying?
|
498 |
-
- What information sources do they trust?
|
499 |
-
- How do reviews and recommendations influence them?
|
500 |
-
- What convinces them of a product's value?
|
501 |
-
|
502 |
-
6. **Consciousness Level:**
|
503 |
-
- Does the avatar clearly reflect one of the five consciousness levels?
|
504 |
-
- Are their fears, problems, and frustrations consistent with their consciousness level?
|
505 |
-
- Does their language and way of expressing themselves correspond to their consciousness level about the problem?
|
506 |
-
- Are their objections and doubts appropriate for their consciousness level?
|
507 |
-
- Is the type of information they seek consistent with their consciousness level?
|
508 |
-
- Do their decision criteria adequately reflect their consciousness level?
|
509 |
-
|
510 |
-
Ensure your buyer persona thoroughly addresses these questions to create an accurate profile of someone who will value and invest in your offering.
|
511 |
-
---
|
512 |
-
"""
|
513 |
-
}
|
|
|
1 |
+
import streamlit as st
|
2 |
+
# Configurar la interfaz de usuario con Streamlit - MUST BE FIRST!
|
3 |
+
st.set_page_config(page_title="Generador de Cliente Ideal", page_icon="👤", layout="wide")
|
4 |
+
|
5 |
+
from dotenv import load_dotenv
|
6 |
+
import os
|
7 |
+
import google.generativeai as genai
|
8 |
+
from style import styles
|
9 |
+
from prompts import create_instruction
|
10 |
+
from consciousness_levels import CONSCIOUSNESS_LEVELS
|
11 |
+
|
12 |
+
# Cargar las variables de entorno
|
13 |
+
load_dotenv()
|
14 |
+
|
15 |
+
# Configurar la API de Google
|
16 |
+
genai.configure(api_key=os.getenv("GOOGLE_API_KEY"))
|
17 |
+
|
18 |
+
# Inicializar variables de estado en session_state si no existen
|
19 |
+
if 'perfil_cliente' not in st.session_state:
|
20 |
+
st.session_state.perfil_cliente = None
|
21 |
+
if 'producto' not in st.session_state:
|
22 |
+
st.session_state.producto = ""
|
23 |
+
if 'habilidades' not in st.session_state:
|
24 |
+
st.session_state.habilidades = ""
|
25 |
+
if 'creatividad' not in st.session_state:
|
26 |
+
st.session_state.creatividad = 1.0
|
27 |
+
# Update the default format in session state
|
28 |
+
if 'formato' not in st.session_state:
|
29 |
+
st.session_state.formato = "Jung's_Avatar" # Changed from previous format name
|
30 |
+
if 'nivel_conciencia' not in st.session_state:
|
31 |
+
# Usar el primer nivel del diccionario como valor predeterminado
|
32 |
+
first_key = list(CONSCIOUSNESS_LEVELS.keys())[0]
|
33 |
+
st.session_state.nivel_conciencia = first_key.replace("_", " ")
|
34 |
+
|
35 |
+
# Función para generar el perfil de cliente ideal
|
36 |
+
@st.cache_resource
|
37 |
+
def get_model(temperature):
|
38 |
+
generation_config = {
|
39 |
+
"temperature": temperature,
|
40 |
+
}
|
41 |
+
return genai.GenerativeModel('gemini-2.0-flash', generation_config=generation_config)
|
42 |
+
|
43 |
+
# REMOVED: The format selection dropdown that was here
|
44 |
+
|
45 |
+
def generate_buyer_persona(product, skills, target_audience, temperature, consciousness_level="Ninguno", format_type="Jung's_Avatar"):
|
46 |
+
if not product or not skills:
|
47 |
+
return "Por favor, completa los campos de producto y habilidades."
|
48 |
+
|
49 |
+
try:
|
50 |
+
model = get_model(temperature)
|
51 |
+
instruction = create_instruction(
|
52 |
+
product_service=product,
|
53 |
+
skills=skills,
|
54 |
+
target_audience=target_audience,
|
55 |
+
consciousness_level=consciousness_level,
|
56 |
+
format_type=format_type
|
57 |
+
)
|
58 |
+
|
59 |
+
# Añadir instrucción explícita para respuesta en español
|
60 |
+
instruction += "\n\nIMPORTANTE: La respuesta debe estar completamente en español."
|
61 |
+
|
62 |
+
response = model.generate_content([instruction], generation_config={"temperature": temperature})
|
63 |
+
return response.parts[0].text if response and response.parts else "Error generando el perfil de cliente ideal."
|
64 |
+
except Exception as e:
|
65 |
+
return f"Error al generar el perfil: {str(e)}"
|
66 |
+
|
67 |
+
# Modificar la función update_profile para que no use spinner
|
68 |
+
def update_profile():
|
69 |
+
# Solo actualizar la variable de sesión
|
70 |
+
st.session_state.submitted = True
|
71 |
+
|
72 |
+
# Leer el contenido del archivo manual.md si existe
|
73 |
+
try:
|
74 |
+
with open("manual.md", "r", encoding="utf-8") as file:
|
75 |
+
manual_content = file.read()
|
76 |
+
# Mostrar el contenido del manual en el sidebar
|
77 |
+
st.sidebar.markdown(manual_content)
|
78 |
+
except FileNotFoundError:
|
79 |
+
st.sidebar.warning("Manual not found. Please create a manual.md file.")
|
80 |
+
except Exception as e:
|
81 |
+
st.sidebar.error(f"Error loading manual: {str(e)}")
|
82 |
+
|
83 |
+
# Ocultar elementos de la interfaz
|
84 |
+
st.markdown(styles["main_layout"], unsafe_allow_html=True)
|
85 |
+
|
86 |
+
# Centrar el título y el subtítulo
|
87 |
+
st.markdown("<h1 style='text-align: center;'>Generador de Perfil de Cliente Ideal</h1>", unsafe_allow_html=True)
|
88 |
+
st.markdown("<h4 style='text-align: center;'>Crea un perfil detallado de tu cliente ideal basado en tu producto y habilidades.</h4>", unsafe_allow_html=True)
|
89 |
+
|
90 |
+
# Añadir CSS personalizado para el botón
|
91 |
+
st.markdown(styles["button"], unsafe_allow_html=True)
|
92 |
+
# Añadir CSS personalizado para el botón de descarga
|
93 |
+
st.markdown(styles["download_button"], unsafe_allow_html=True)
|
94 |
+
|
95 |
+
# Crear columnas
|
96 |
+
col1, col2 = st.columns([1, 2])
|
97 |
+
|
98 |
+
# Columna de entrada
|
99 |
+
with col1:
|
100 |
+
producto = st.text_area("¿Qué producto o servicio ofreces?",
|
101 |
+
value=st.session_state.producto,
|
102 |
+
placeholder="Ejemplo: Curso de Inglés",
|
103 |
+
key="producto_input",
|
104 |
+
height=70)
|
105 |
+
st.session_state.producto = producto
|
106 |
+
|
107 |
+
habilidades = st.text_area("¿Cuáles son tus habilidades principales?",
|
108 |
+
value=st.session_state.habilidades,
|
109 |
+
placeholder="Ejemplo: Enseñanza, comunicación, diseño de contenidos",
|
110 |
+
key="habilidades_input",
|
111 |
+
height=70)
|
112 |
+
st.session_state.habilidades = habilidades
|
113 |
+
|
114 |
+
# Botón para generar - Movido arriba del acordeón
|
115 |
+
submit = st.button("CREAR MI CLIENTE IDEAL SOÑADO ➤➤", on_click=update_profile)
|
116 |
+
|
117 |
+
# Crear un acordeón para las opciones de personalización
|
118 |
+
with st.expander("Personaliza Tu Cliente Ideal Soñado"):
|
119 |
+
# Nuevo campo para público objetivo
|
120 |
+
if 'publico_objetivo' not in st.session_state:
|
121 |
+
st.session_state.publico_objetivo = ""
|
122 |
+
|
123 |
+
publico_objetivo = st.text_area("¿Cuál es tu público objetivo? (opcional)",
|
124 |
+
value=st.session_state.publico_objetivo,
|
125 |
+
placeholder="Ejemplo: Profesionales entre 25-40 años interesados en desarrollo personal",
|
126 |
+
key="publico_objetivo_input",
|
127 |
+
height=70)
|
128 |
+
st.session_state.publico_objetivo = publico_objetivo
|
129 |
+
|
130 |
+
# Selector de formato
|
131 |
+
from format.format import buyer_persona_formats
|
132 |
+
|
133 |
+
# Obtener solo las claves que terminan en "_format" del diccionario
|
134 |
+
format_keys = [key for key in buyer_persona_formats.keys() if key.endswith("_format")]
|
135 |
+
|
136 |
+
formato = st.selectbox(
|
137 |
+
"Formato del perfil",
|
138 |
+
options=format_keys,
|
139 |
+
format_func=lambda x: x.replace("_format", "").capitalize(),
|
140 |
+
index=format_keys.index(st.session_state.formato) if st.session_state.formato in format_keys else 0,
|
141 |
+
help="Selecciona el formato en el que se presentará el perfil del cliente ideal"
|
142 |
+
)
|
143 |
+
st.session_state.formato = formato
|
144 |
+
|
145 |
+
# Nivel de creatividad con slider
|
146 |
+
creatividad = st.slider("Nivel de creatividad",
|
147 |
+
min_value=0.0,
|
148 |
+
max_value=2.0,
|
149 |
+
value=st.session_state.creatividad,
|
150 |
+
step=0.1,
|
151 |
+
key="creatividad_slider")
|
152 |
+
st.session_state.creatividad = creatividad
|
153 |
+
|
154 |
+
# Selector de nivel de conciencia
|
155 |
+
consciousness_options = []
|
156 |
+
for i, key in enumerate(CONSCIOUSNESS_LEVELS.keys(), 1):
|
157 |
+
# Replace underscores with spaces in the key
|
158 |
+
display_name = key.replace("_", " ")
|
159 |
+
consciousness_options.append(f"Nivel {i} - {display_name}")
|
160 |
+
|
161 |
+
nivel_conciencia_display = st.selectbox(
|
162 |
+
"Nivel de conciencia del cliente ideal",
|
163 |
+
consciousness_options,
|
164 |
+
index=0,
|
165 |
+
help="Selecciona el nivel de conciencia en el que se encuentra tu cliente ideal"
|
166 |
+
)
|
167 |
+
|
168 |
+
# Extract the original key from the display name
|
169 |
+
level_number = nivel_conciencia_display.split(" - ")[0].replace("Nivel ", "")
|
170 |
+
original_key = list(CONSCIOUSNESS_LEVELS.keys())[int(level_number) - 1]
|
171 |
+
nivel_conciencia = original_key.replace("_", " ")
|
172 |
+
|
173 |
+
# Get the description from the CONSCIOUSNESS_LEVELS dictionary
|
174 |
+
if original_key in CONSCIOUSNESS_LEVELS:
|
175 |
+
nivel_info = CONSCIOUSNESS_LEVELS[original_key]["estado_mental"]
|
176 |
+
st.info(f"**{nivel_conciencia}**: {nivel_info}")
|
177 |
+
|
178 |
+
st.session_state.nivel_conciencia = nivel_conciencia
|
179 |
+
|
180 |
+
# Columna de resultados
|
181 |
+
with col2:
|
182 |
+
# Verificar si se ha enviado el formulario
|
183 |
+
if 'submitted' in st.session_state and st.session_state.submitted:
|
184 |
+
if st.session_state.producto and st.session_state.habilidades:
|
185 |
+
with st.spinner("Creando tu Cliente Ideal Soñado..."):
|
186 |
+
# Generar el perfil del cliente
|
187 |
+
perfil_cliente = generate_buyer_persona(
|
188 |
+
st.session_state.producto,
|
189 |
+
st.session_state.habilidades,
|
190 |
+
st.session_state.publico_objetivo,
|
191 |
+
st.session_state.creatividad,
|
192 |
+
st.session_state.nivel_conciencia,
|
193 |
+
st.session_state.formato
|
194 |
+
)
|
195 |
+
# Guardar en session_state
|
196 |
+
st.session_state.perfil_cliente = perfil_cliente
|
197 |
+
# Resetear el estado de envío
|
198 |
+
st.session_state.submitted = False
|
199 |
+
|
200 |
+
# Mostrar resultados
|
201 |
+
if not isinstance(st.session_state.perfil_cliente, str):
|
202 |
+
st.error("Error al generar el perfil de cliente ideal")
|
203 |
+
else:
|
204 |
+
# Crear un contenedor con estilo personalizado
|
205 |
+
st.markdown(f"""
|
206 |
+
<style>
|
207 |
+
.results-box {{
|
208 |
+
padding: 15px;
|
209 |
+
border: 1px solid #ddd;
|
210 |
+
border-radius: 8px;
|
211 |
+
margin-bottom: 20px;
|
212 |
+
}}
|
213 |
+
</style>
|
214 |
+
""", unsafe_allow_html=True)
|
215 |
+
|
216 |
+
# Usar un expander sin título para contener todo el resultado
|
217 |
+
with st.expander("", expanded=True):
|
218 |
+
st.markdown("<h3>Tu Cliente Ideal</h3>", unsafe_allow_html=True)
|
219 |
+
st.markdown(st.session_state.perfil_cliente)
|
220 |
+
|
221 |
+
# Opción para descargar
|
222 |
+
st.download_button(
|
223 |
+
label="DESCARGAR MI CLIENTE SOÑADO ➤➤",
|
224 |
+
data=st.session_state.perfil_cliente,
|
225 |
+
file_name="cliente_ideal.txt",
|
226 |
+
mime="text/plain"
|
227 |
+
)
|
228 |
+
else:
|
229 |
+
st.warning("Por favor, completa los campos de producto y habilidades antes de generar el perfil.")
|
230 |
+
# Mostrar resultados anteriores si existen
|
231 |
+
elif st.session_state.perfil_cliente:
|
232 |
+
# Crear un contenedor con estilo personalizado
|
233 |
+
st.markdown(f"""
|
234 |
+
<style>
|
235 |
+
.results-box {{
|
236 |
+
padding: 15px;
|
237 |
+
border: 1px solid #ddd;
|
238 |
+
border-radius: 8px;
|
239 |
+
margin-bottom: 20px;
|
240 |
+
}}
|
241 |
+
</style>
|
242 |
+
""", unsafe_allow_html=True)
|
243 |
+
|
244 |
+
# Usar un expander sin título para contener todo el resultado
|
245 |
+
with st.expander("", expanded=True):
|
246 |
+
st.markdown("<h3>Tu Cliente Ideal</h3>", unsafe_allow_html=True)
|
247 |
+
st.markdown(st.session_state.perfil_cliente)
|
248 |
+
|
249 |
+
# Opción para descargar
|
250 |
+
st.download_button(
|
251 |
+
label="DESCARGAR MI CLIENTE SOÑADO ➤➤",
|
252 |
+
data=st.session_state.perfil_cliente,
|
253 |
+
file_name="cliente_ideal.txt",
|
254 |
+
mime="text/plain"
|
255 |
+
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|