Spaces:
Runtime error
Runtime error
| import streamlit as st | |
| # Set page config - must be the first Streamlit command | |
| st.set_page_config( | |
| page_title="SlideGator.AI", | |
| page_icon="π", | |
| layout="wide", | |
| initial_sidebar_state="expanded" | |
| ) | |
| import uuid | |
| import os | |
| import json | |
| from updated_components import ( | |
| render_ideation_stage, | |
| render_storyboard_stage, | |
| render_template_stage, | |
| render_slides_stage, | |
| render_export_stage, | |
| render_ai_settings | |
| ) | |
| from multi_llm_provider import get_ai_manager | |
| # Check and display API key status | |
| api_key = os.getenv("ANTHROPIC_API_KEY") | |
| openai_key = os.getenv("OPENAI_API_KEY") | |
| deepseek_key = os.getenv("DEEPSEEK_API_KEY") | |
| perplexity_key = os.getenv("PERPLEXITY_API_KEY") | |
| pexels_key = os.getenv("PEXELS_API_KEY") | |
| # Add custom CSS | |
| st.markdown(""" | |
| <style> | |
| .main .block-container { | |
| padding-top: 2rem; | |
| padding-bottom: 2rem; | |
| } | |
| h1, h2, h3 { | |
| margin-bottom: 1rem; | |
| } | |
| .stButton>button { | |
| width: 100%; | |
| } | |
| .stProgress>div>div>div { | |
| background-color: #4CAF50; | |
| } | |
| .css-18e3th9 { | |
| padding-top: 2rem; | |
| } | |
| /* Progress bar styling */ | |
| .stProgress { | |
| height: 10px !important; | |
| } | |
| /* Custom slide preview styling */ | |
| .slide-preview { | |
| border-radius: 8px !important; | |
| box-shadow: 0 4px 8px rgba(0,0,0,0.1) !important; | |
| transition: transform 0.3s ease, box-shadow 0.3s ease !important; | |
| } | |
| .slide-preview:hover { | |
| transform: translateY(-5px) !important; | |
| box-shadow: 0 6px 12px rgba(0,0,0,0.15) !important; | |
| } | |
| /* SlideGator branding */ | |
| .logo-text { | |
| color: #4CAF50; | |
| font-weight: bold; | |
| font-family: 'Arial', sans-serif; | |
| } | |
| /* Stage icons */ | |
| .stage-icon { | |
| font-size: 1.5rem; | |
| margin-right: 0.5rem; | |
| } | |
| /* Custom button styles */ | |
| .gator-button { | |
| background-color: #4CAF50; | |
| color: white; | |
| border-radius: 5px; | |
| padding: 8px 16px; | |
| font-weight: bold; | |
| transition: all 0.3s; | |
| } | |
| .gator-button:hover { | |
| background-color: #45a049; | |
| box-shadow: 0 4px 8px rgba(0,0,0,0.2); | |
| } | |
| /* AI settings panel */ | |
| .ai-settings { | |
| background-color: #f9f9f9; | |
| border-radius: 8px; | |
| padding: 12px; | |
| margin-top: 15px; | |
| border: 1px solid #eee; | |
| } | |
| /* Enhanced image cards */ | |
| .image-card { | |
| border: 1px solid #ddd; | |
| border-radius: 8px; | |
| overflow: hidden; | |
| transition: transform 0.3s ease; | |
| } | |
| .image-card:hover { | |
| transform: scale(1.03); | |
| box-shadow: 0 4px 8px rgba(0,0,0,0.1); | |
| } | |
| /* Tabs styling */ | |
| .stTabs [data-baseweb="tab-list"] { | |
| gap: 8px; | |
| } | |
| .stTabs [data-baseweb="tab"] { | |
| height: 50px; | |
| white-space: pre-wrap; | |
| background-color: #f0f2f6; | |
| border-radius: 4px 4px 0 0; | |
| padding: 8px 16px; | |
| font-weight: 600; | |
| } | |
| .stTabs [aria-selected="true"] { | |
| background-color: #4CAF50 !important; | |
| color: white !important; | |
| } | |
| </style> | |
| """, unsafe_allow_html=True) | |
| # Initialize session state variables if they don't exist | |
| if "session_id" not in st.session_state: | |
| st.session_state.session_id = str(uuid.uuid4()) | |
| if "current_stage" not in st.session_state: | |
| st.session_state.current_stage = "ideation" | |
| if "presentation_title" not in st.session_state: | |
| st.session_state.presentation_title = "" | |
| if "presentation_purpose" not in st.session_state: | |
| st.session_state.presentation_purpose = "" | |
| if "target_audience" not in st.session_state: | |
| st.session_state.target_audience = "" | |
| if "storyboard" not in st.session_state: | |
| st.session_state.storyboard = [] | |
| if "selected_template" not in st.session_state: | |
| st.session_state.selected_template = "professional" | |
| if "slides_content" not in st.session_state: | |
| st.session_state.slides_content = [] | |
| if "default_model" not in st.session_state: | |
| st.session_state.default_model = "claude-3-sonnet-20250219" | |
| if "ai_temperature" not in st.session_state: | |
| st.session_state.ai_temperature = 0.7 | |
| if "enable_web_search" not in st.session_state: | |
| st.session_state.enable_web_search = False | |
| # Initialize AI provider manager | |
| ai_manager = get_ai_manager() | |
| # Sidebar | |
| with st.sidebar: | |
| # Custom SlideGator logo and title | |
| st.markdown(""" | |
| <div style="display: flex; align-items: center; margin-bottom: 1rem;"> | |
| <div style="font-size: 2.5rem; margin-right: 0.5rem;">π</div> | |
| <div> | |
| <div style="font-size: 1.5rem; font-weight: bold; color: #4CAF50;">SlideGator.AI</div> | |
| <div style="font-size: 0.8rem; color: #666;">Snapping up presentation perfection</div> | |
| </div> | |
| </div> | |
| """, unsafe_allow_html=True) | |
| # Display API information | |
| api_status = [] | |
| if api_key: | |
| api_status.append("π’ Claude AI") | |
| else: | |
| api_status.append("π΄ Claude AI (not connected)") | |
| if openai_key: | |
| api_status.append("π’ OpenAI") | |
| else: | |
| api_status.append("βͺ OpenAI (optional)") | |
| if deepseek_key: | |
| api_status.append("π’ DeepSeek") | |
| else: | |
| api_status.append("βͺ DeepSeek (optional)") | |
| if perplexity_key: | |
| api_status.append("π’ Perplexity") | |
| else: | |
| api_status.append("βͺ Web Search (optional)") | |
| if pexels_key: | |
| api_status.append("π’ Stock Images") | |
| else: | |
| api_status.append("βͺ Stock Images (optional)") | |
| st.info("\n".join(api_status)) | |
| if not api_key: | |
| st.error("β οΈ ANTHROPIC_API_KEY environment variable not found. The app will use fallback content generation.") | |
| # Display current progress | |
| st.write("## Your Journey") | |
| stages = [ | |
| {"name": "Ideation", "icon": "π‘"}, | |
| {"name": "Storyboard", "icon": "π"}, | |
| {"name": "Template", "icon": "π¨"}, | |
| {"name": "Slides", "icon": "πΌοΈ"}, | |
| {"name": "Export", "icon": "π€"} | |
| ] | |
| current_stage_idx = stages.index(next((s for s in stages if s["name"].lower() == st.session_state.current_stage), stages[0])) | |
| progress_value = (current_stage_idx) / (len(stages) - 1) | |
| st.progress(progress_value) | |
| # Display all stages and highlight current | |
| for i, stage in enumerate(stages): | |
| if i == current_stage_idx: | |
| st.markdown(f"### {stage['icon']} {stage['name']} β") | |
| else: | |
| st.markdown(f"### {stage['icon']} {stage['name']}") | |
| st.write("---") | |
| # Settings accordion | |
| with st.expander("βοΈ Settings", expanded=False): | |
| # Show presentation info | |
| if st.session_state.presentation_title: | |
| st.write(f"**Title:** {st.session_state.presentation_title}") | |
| if st.session_state.selected_template: | |
| st.write(f"**Template:** {st.session_state.selected_template.title()}") | |
| # Show slide count | |
| if st.session_state.slides_content: | |
| st.write(f"**Slides:** {len(st.session_state.slides_content)}") | |
| elif st.session_state.storyboard: | |
| st.write(f"**Planned Slides:** {len(st.session_state.storyboard)}") | |
| # Debugging options | |
| show_debug = st.checkbox("Show Debug Info", value=False) | |
| if show_debug: | |
| st.code(json.dumps({k: v for k, v in st.session_state.items() if k not in ["custom_template", "ai_manager", "slides_content", "storyboard"]}, default=str, indent=2)) | |
| st.markdown(""" | |
| <div style="text-align: center;"> | |
| <div>Made with π by SlideGator.AI</div> | |
| <div style="font-size: 0.8rem; color: #666;">Powered by Claude AI</div> | |
| </div> | |
| """, unsafe_allow_html=True) | |
| # Jump to stage buttons (for development/testing) | |
| if st.checkbox("Development Mode", value=False): | |
| st.write("Jump to stage:") | |
| col1, col2 = st.columns(2) | |
| for i, stage in enumerate(stages): | |
| with col1 if i % 2 == 0 else col2: | |
| if st.button(f"{stage['icon']} {stage['name']}", key=f"jump_{stage['name']}"): | |
| st.session_state.current_stage = stage['name'].lower() | |
| st.rerun() | |
| # Main content | |
| st.markdown(""" | |
| <div style="display: flex; align-items: center; margin-bottom: 1rem;"> | |
| <div style="font-size: 3rem; margin-right: 1rem;">π</div> | |
| <div> | |
| <h1 style="margin: 0; color: #4CAF50;">SlideGator.AI</h1> | |
| <div style="font-size: 1.2rem;">Create professional presentations with AI-powered storyboarding and content generation</div> | |
| </div> | |
| </div> | |
| """, unsafe_allow_html=True) | |
| # Display different UI based on current stage | |
| if st.session_state.current_stage == "ideation": | |
| render_ideation_stage() | |
| elif st.session_state.current_stage == "storyboard": | |
| render_storyboard_stage() | |
| elif st.session_state.current_stage == "template": | |
| render_template_stage() | |
| elif st.session_state.current_stage == "slides": | |
| render_slides_stage() | |
| elif st.session_state.current_stage == "export": | |
| render_export_stage() |