import streamlit as st import google.generativeai as genai import os from dotenv import load_dotenv from styles import get_custom_css from formulas import offer_formulas import PyPDF2 import docx # Set page to wide mode to use full width st.set_page_config(layout="wide") # Load environment variables load_dotenv() # Configure Google Gemini API genai.configure(api_key=os.getenv('GOOGLE_API_KEY')) model = genai.GenerativeModel('gemini-2.0-flash') # Initialize session state variables if they don't exist if 'submitted' not in st.session_state: st.session_state.submitted = False if 'offer_result' not in st.session_state: st.session_state.offer_result = "" # Hide Streamlit menu and footer st.markdown(""" """, unsafe_allow_html=True) # Custom CSS st.markdown(get_custom_css(), unsafe_allow_html=True) # App title and description - centered and without emoji st.markdown('

Great Offer Generator

', unsafe_allow_html=True) st.markdown('

Transform your skills into compelling offers!

', unsafe_allow_html=True) # Create two columns for layout - left column 40%, right column 60% col1, col2 = st.columns([4, 6]) # Main input section in left column with col1: # Add tabs for different input methods input_tab1, input_tab2 = st.tabs(["Entrada Manual", "Subir Archivo"]) with input_tab1: skills = st.text_area('💪 Tus Habilidades', height=70, help='Lista tus habilidades y experiencia clave') product_service = st.text_area('🎯 Producto/Servicio', height=70, help='Describe tu producto o servicio') with input_tab2: uploaded_file = st.file_uploader("Sube un archivo con tu información", type=['txt', 'pdf', 'docx']) if uploaded_file is not None: # Handle different file types file_type = uploaded_file.name.split('.')[-1].lower() if file_type == 'txt': # Read text file file_content = uploaded_file.read().decode('utf-8') st.success(f"Archivo cargado correctamente: {uploaded_file.name}") elif file_type == 'pdf': try: import PyPDF2 pdf_reader = PyPDF2.PdfReader(uploaded_file) file_content = "" for page in pdf_reader.pages: file_content += page.extract_text() + "\n" st.success(f"Archivo PDF cargado correctamente: {uploaded_file.name}") except Exception as e: st.error(f"Error al leer el archivo PDF: {str(e)}") file_content = "" elif file_type == 'docx': try: import docx doc = docx.Document(uploaded_file) file_content = "\n".join([para.text for para in doc.paragraphs]) st.success(f"Archivo DOCX cargado correctamente: {uploaded_file.name}") except Exception as e: st.error(f"Error al leer el archivo DOCX: {str(e)}") file_content = "" # Display preview of file content with st.expander("Vista previa del contenido"): st.write(file_content[:500] + "..." if len(file_content) > 500 else file_content) # Accordion for additional settings with st.expander('⚙️ Configuración Avanzada'): target_audience = st.text_area('👥 Público Objetivo', height=70, help='Describe tu cliente o público ideal') # Selector de fórmula formula_type = st.selectbox( '📋 Tipo de Fórmula', options=list(offer_formulas.keys()), help='Selecciona el tipo de fórmula para tu oferta' ) # Removed the "Ver detalles de la fórmula" expander section temperature = st.slider('🌡️ Nivel de Creatividad', min_value=0.0, max_value=2.0, value=0.7, help='Valores más altos hacen que el resultado sea más creativo pero menos enfocado') # Generate button with callback def generate_offer(): has_manual_input = bool(skills and product_service) has_file_input = bool(uploaded_file is not None) # Handle all three scenarios if not has_manual_input and not has_file_input: st.error('Por favor ingresa texto o sube un archivo') return st.session_state.submitted = True # Store inputs based on what's available if has_manual_input: st.session_state.skills = skills st.session_state.product_service = product_service if has_file_input: st.session_state.file_content = file_content # Set input type if has_manual_input and has_file_input: st.session_state.input_type = "both" elif has_manual_input: st.session_state.input_type = "manual" else: st.session_state.input_type = "file" # Store common settings st.session_state.target_audience = target_audience st.session_state.temperature = temperature st.session_state.formula_type = formula_type st.button('Generar Oferta 🎉', on_click=generate_offer) # Results column with col2: # Check if form has been submitted if st.session_state.submitted: with st.spinner('Creando tu oferta perfecta...'): # Determine which input source to use if st.session_state.input_type == "manual": prompt = f"""Based on the following information, create a compelling offer using the {st.session_state.formula_type} formula: Skills: {st.session_state.skills} Product/Service: {st.session_state.product_service} Target Audience: {st.session_state.target_audience if st.session_state.target_audience else 'General audience'} """ elif st.session_state.input_type == "file": prompt = f"""Based on the following information from the uploaded file, create a compelling offer using the {st.session_state.formula_type} formula: File Content: {st.session_state.file_content} Target Audience: {st.session_state.target_audience if st.session_state.target_audience else 'General audience'} """ else: # both inputs prompt = f"""Based on the following combined information, create a compelling offer using the {st.session_state.formula_type} formula: Skills: {st.session_state.skills} Product/Service: {st.session_state.product_service} Additional Information from File: {st.session_state.file_content} Target Audience: {st.session_state.target_audience if st.session_state.target_audience else 'General audience'} Please consider both the manual input and file content to create a comprehensive offer. """ prompt += f""" Formula Description: {offer_formulas[st.session_state.formula_type]["description"]} Please create a professional and engaging offer that highlights the value proposition. IMPORTANT: Provide ONLY the final offer text. Do not include any explanations, labels, formatting instructions, brackets, or call to action at the end.""" try: # Create generation config with temperature generation_config = genai.GenerationConfig(temperature=st.session_state.temperature) # Pass the generation config to generate_content response = model.generate_content(prompt, generation_config=generation_config) st.session_state.offer_result = response.text # Display result - without emoji st.markdown('### Oferta Generada') st.markdown(st.session_state.offer_result) # Add download button below the result with 80% width col_download, col_empty = st.columns([8, 2]) with col_download: st.download_button( label="Descargar Oferta", data=st.session_state.offer_result, file_name="oferta_generada.txt", mime="text/plain" ) except Exception as e: st.error(f'Ocurrió un error: {str(e)}') st.session_state.submitted = False # Footer st.markdown('---') st.markdown('Made with ❤️ by Jesús Cabrera')