File size: 10,243 Bytes
c1dbcb8
 
 
 
c50c598
 
 
 
 
 
 
 
c1dbcb8
 
c50c598
c1dbcb8
 
c50c598
 
 
 
 
 
c1dbcb8
c50c598
 
c1dbcb8
c50c598
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6ae03b9
c50c598
 
6ae03b9
c50c598
c1dbcb8
c50c598
 
 
 
c1dbcb8
c50c598
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
c1dbcb8
c50c598
 
 
 
 
c1dbcb8
c50c598
 
 
 
 
c1dbcb8
c50c598
 
 
 
c1dbcb8
c50c598
 
c1dbcb8
c50c598
 
 
 
 
c1dbcb8
 
 
 
c50c598
 
c1dbcb8
c50c598
c1dbcb8
c50c598
 
 
 
c1dbcb8
c50c598
 
 
 
c1dbcb8
c50c598
 
 
 
 
 
 
c1dbcb8
 
c50c598
c1dbcb8
 
 
 
 
 
 
 
 
5785f6b
c1dbcb8
 
 
 
 
 
 
 
c50c598
c1dbcb8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5785f6b
c1dbcb8
 
 
 
 
 
 
 
 
 
 
c50c598
c1dbcb8
c50c598
 
 
 
 
 
 
 
 
 
 
 
 
c1dbcb8
c50c598
 
 
 
 
 
 
 
 
 
 
 
 
78c550d
c50c598
 
 
 
 
 
 
 
 
c1dbcb8
c50c598
 
 
 
 
 
 
 
 
 
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
from dotenv import load_dotenv
import streamlit as st
import os
import google.generativeai as genai
from puv_formulas import puv_formulas
from styles import apply_styles
import PyPDF2
import docx
from PIL import Image
import datetime  # Add this import for timestamp

# Cargar variables de entorno
load_dotenv()

# Configurar API de Google Gemini
genai.configure(api_key=os.getenv("GOOGLE_API_KEY"))

# Función para obtener la respuesta del modelo Gemini
def get_gemini_response(product_service, target_audience, skills, formula_type, temperature, file_content="", image_parts=None):
    # Check if we have at least one source of information
    has_file_content = bool(file_content.strip())
    has_image = image_parts is not None
    has_text_input = target_audience or product_service or skills
    
    if not (has_file_content or has_image or has_text_input):
        return "Debes proporcionar al menos un tipo de información: público objetivo, producto/servicio, habilidades o un archivo de referencia."
    
    # If we only have file content but no other inputs, we can proceed
    if (has_file_content or has_image) and not has_text_input:
        # File-only mode
        business_info = "Analyze the provided reference material to extract business information.\n"
    else:
        # Regular mode with validation
        if not target_audience:
            return "El campo de público objetivo es obligatorio cuando no se proporciona un archivo de referencia completo."
        
        if not product_service and not skills:
            return "Debes proporcionar al menos tu producto/servicio o tus habilidades cuando no se proporciona un archivo de referencia completo."
        
        # Adjust prompt based on what's provided
        business_info = f"Target Audience: {target_audience}\n"
        
        if product_service:
            business_info += f"Product/Service: {product_service}\n"
        
        if skills:
            business_info += f"My Skills/Expertise: {skills}\n"
    
    formula = puv_formulas[formula_type]
    
    # Add file content if available
    reference_info = ""
    if file_content:
        reference_info = f"\nREFERENCE MATERIAL:\n{file_content}\n"
    
    model = genai.GenerativeModel('gemini-2.0-flash')
    full_prompt = f"""
    You are a UVP (Unique Value Proposition) expert. Analyze (internally only, do not output the analysis) the following information:
    BUSINESS INFORMATION:
    {business_info}
    Formula Type: {formula_type}
    {formula["description"]}
    {reference_info}

    EXAMPLE TO FOLLOW:
    {formula["examples"]}

    First, analyze (but don't output) these points:
    1. TARGET AUDIENCE ANALYSIS - Pain Points:
       - What specific frustrations does this audience experience?
       - What are their biggest daily challenges?
       - What emotional problems do they face?
       - What have they tried before that didn't work?
       - What's stopping them from achieving their goals?

    2. PRODUCT/SERVICE ANALYSIS - Benefits:
       - What tangible results do clients get?
       - What specific transformation does it offer?
       - What's the unique method or differentiator?
       - What competitive advantages does it have?
       - What emotional benefits does it provide?
       
    3. SKILLS/EXPERTISE ANALYSIS - Credibility:
       - How do these skills directly address the audience's pain points?
       - What unique perspective do these skills bring to the solution?
       - How do these skills enhance the product/service delivery?
       - What credibility elements can be highlighted?
       - How do these skills differentiate from competitors?

    Based on your internal analysis of the target audience pain points and product benefits (do not include this analysis in the output), create THREE different UVPs in Spanish language following the formula structure provided.
    CRITICAL INSTRUCTIONS:
    - Each UVP must be specific and measurable
    - Focus on the transformation journey
    - Use natural, conversational language
    - Avoid generic phrases and buzzwords
    - Maximum 2 lines per UVP
    - DO NOT include any analysis in the output
    - ONLY output the three UVPs
    
    Output EXACTLY in this format (no additional text) in Spanish language:
    1. [First UVP]
    2. [Second UVP]
    3. [Third UVP]
    """
    
    # Handle text-only or text+image requests
    if image_parts:
        response = model.generate_content([full_prompt, image_parts], generation_config={"temperature": temperature})
    else:
        response = model.generate_content([full_prompt], generation_config={"temperature": temperature})
    
    return response.parts[0].text if response and response.parts else "Error generating content."

# Configurar la aplicación Streamlit
st.set_page_config(page_title="UVP Generator", page_icon="💡", layout="wide")

# Aplicar estilos
st.markdown(apply_styles(), unsafe_allow_html=True)

# Título de la app
st.markdown("<h1>Generador de PUV</h1>", unsafe_allow_html=True)
st.markdown("<h3>Crea Propuestas Únicas de Valor poderosas que atraigan a tus clientes ideales y comuniquen tu valor de manera efectiva.</h3>", unsafe_allow_html=True)

# Sidebar manual
with open("manual.md", "r", encoding="utf-8") as file:
    manual_content = file.read()
st.sidebar.markdown(manual_content)

# Crear dos columnas
col1, col2 = st.columns([1, 1])

# Columna izquierda para inputs
with col1:
    product_service = st.text_area(
        "¿Cuál es tu producto o servicio?",
        placeholder="Ejemplo: Curso de copywriting con IA, Programa de coaching..."
    )
    
    skills = st.text_area(
        "Mis habilidades:",
        placeholder="Ejemplo: Experiencia en marketing digital, certificación en SEO..."
    )
    
    # Move the generate button here, right after skills
    generate_button = st.button("Generar PUV")
    
    with st.expander("Opciones avanzadas"):
        target_audience = st.text_area(
            "¿Cuál es tu público objetivo?",
            placeholder="Ejemplo: Coaches que quieren atraer más clientes..."
        )
        
        # Añadir cargador de archivos
        uploaded_file = st.file_uploader("📄 Archivo o imagen de referencia", 
                                        type=['txt', 'pdf', 'docx', 'jpg', 'jpeg', 'png'])
        
        file_content = ""
        is_image = False
        image_parts = None
        
        if uploaded_file is not None:
            file_type = uploaded_file.name.split('.')[-1].lower()
            
            # Manejar archivos de texto
            if file_type in ['txt', 'pdf', 'docx']:
                if file_type == 'txt':
                    try:
                        file_content = uploaded_file.read().decode('utf-8')
                    except Exception as e:
                        st.error(f"Error al leer el archivo TXT: {str(e)}")
                        file_content = ""
                    
                elif file_type == 'pdf':
                    try:
                        pdf_reader = PyPDF2.PdfReader(uploaded_file)
                        file_content = ""
                        for page in pdf_reader.pages:
                            file_content += page.extract_text() + "\n"
                    except Exception as e:
                        st.error(f"Error al leer el archivo PDF: {str(e)}")
                        file_content = ""
                        
                elif file_type == 'docx':
                    try:
                        doc = docx.Document(uploaded_file)
                        file_content = "\n".join([para.text for para in doc.paragraphs])
                    except Exception as e:
                        st.error(f"Error al leer el archivo DOCX: {str(e)}")
                        file_content = ""
            
            # Manejar archivos de imagen
            elif file_type in ['jpg', 'jpeg', 'png']:
                try:
                    image = Image.open(uploaded_file)
                    image_bytes = uploaded_file.getvalue()
                    image_parts = {
                        "mime_type": uploaded_file.type,
                        "data": image_bytes
                    }
                    is_image = True
                except Exception as e:
                    st.error(f"Error al procesar la imagen: {str(e)}")
                    is_image = False
        
        formula_type = st.selectbox(
            "Fórmula PUV:",
            options=list(puv_formulas.keys())
        )
        temperature = st.slider(
            "Nivel de creatividad:",
            min_value=0.0,
            max_value=2.0,
            value=1.0,
            step=0.1,
            help="Valores más altos generan propuestas más creativas pero menos predecibles."
        )

with col2:
    if generate_button:
        # Store the response in session state so it persists across reruns
        with st.spinner("Creando tu PUV..."):
            st.session_state.puv_response = get_gemini_response(
                product_service,
                target_audience,
                skills,
                formula_type,
                temperature,
                file_content,
                image_parts
            )
    
    # Display the response if it exists in session state (separate from the generate button condition)
    if 'puv_response' in st.session_state:
        st.write("### Propuestas Únicas de Valor")
        st.write(st.session_state.puv_response)
        
        # Add download button if we have a valid response
        if st.session_state.puv_response and not st.session_state.puv_response.startswith("Error") and not st.session_state.puv_response.startswith("Debes"):
            # Get current timestamp for the filename
            timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
            
            # Prepare content for download
            download_content = st.session_state.puv_response
            
            # Download button
            st.download_button(
                label="DESCARGAR PUV",
                data=download_content,
                file_name=f"propuestas_unicas_valor_{timestamp}.txt",
                mime="text/plain"
            )