import streamlit as st import os import json from datetime import datetime, timedelta import base64 import pandas as pd from travel import ( destination_research_task, accommodation_task, transportation_task, activities_task, dining_task, itinerary_task, run_task ) # Set page configuration with modern theme st.set_page_config( page_title="BlockX Travel Itinerary Generator", page_icon="✈️", layout="wide", initial_sidebar_state="expanded" ) # Modern CSS with refined color scheme and sleek animations st.markdown(""" """, unsafe_allow_html=True) # Helper function to download HTML file def get_download_link(text_content, filename): b64 = base64.b64encode(text_content.encode()).decode() href = f'πŸ“₯ Download Itinerary as Text' return href # Updated helper function to display modern progress with a single UI element def display_modern_progress(current_step, total_steps=6): if 'progress_steps' not in st.session_state: st.session_state.progress_steps = { 0: {'status': 'pending', 'name': 'Destination Research'}, 1: {'status': 'pending', 'name': 'Accommodation'}, 2: {'status': 'pending', 'name': 'Transportation'}, 3: {'status': 'pending', 'name': 'Activities'}, 4: {'status': 'pending', 'name': 'Dining'}, 5: {'status': 'pending', 'name': 'Itinerary Creation'} } # Update the current step status for i in range(total_steps): if i < current_step: st.session_state.progress_steps[i]['status'] = 'complete' elif i == current_step: st.session_state.progress_steps[i]['status'] = 'active' else: st.session_state.progress_steps[i]['status'] = 'pending' # Calculate overall progress percentage progress_percentage = (current_step / total_steps) * 100 # Show overall progress bar st.progress(progress_percentage / 100) # Create a modern, compact, inline progress tracker st.markdown('''
''', unsafe_allow_html=True) # Create grid layout st.markdown('
', unsafe_allow_html=True) # Display each step in a compact grid for i, step_info in st.session_state.progress_steps.items(): status = step_info['status'] name = step_info['name'] if status == 'complete': icon = "βœ…" status_class = "complete" elif status == 'active': icon = "πŸ”„" status_class = "active" else: icon = "β­•" status_class = "pending" st.markdown(f'''
{icon} {name}
''', unsafe_allow_html=True) st.markdown('
', unsafe_allow_html=True) return progress_percentage # Function to update the status of a specific step def update_step_status(step_index, status): if 'progress_steps' in st.session_state and step_index in st.session_state.progress_steps: st.session_state.progress_steps[step_index]['status'] = status # Custom run_task function that updates the UI with logs and shows live agent outputs def run_task_with_logs(task, input_text, log_container, output_container, results_key=None): # Add log message log_message = f"πŸ€– Starting {task.agent.role}..." st.session_state.log_messages.append(log_message) # Update the log container with log_container: st.markdown("### Agent Activity") for msg in st.session_state.log_messages: st.markdown(msg) # Run the actual task result = run_task(task, input_text) # Store result if needed if results_key: st.session_state.results[results_key] = result # Add completion log message log_message = f"βœ… {task.agent.role} completed!" st.session_state.log_messages.append(log_message) # Update the log container again with log_container: st.markdown("### Agent Activity") for msg in st.session_state.log_messages: st.markdown(msg) # Display the agent's output in the output container with output_container: st.markdown(f"### {task.agent.role} Output") st.markdown("""
""" + result + """
""", unsafe_allow_html=True) return result # Initialize session state if 'generated_itinerary' not in st.session_state: st.session_state.generated_itinerary = None if 'generation_complete' not in st.session_state: st.session_state.generation_complete = False if 'current_step' not in st.session_state: st.session_state.current_step = 0 if 'results' not in st.session_state: st.session_state.results = { "destination_info": "", "accommodation_info": "", "transportation_info": "", "activities_info": "", "dining_info": "", "itinerary": "", "final_itinerary": "" } if 'log_messages' not in st.session_state: st.session_state.log_messages = [] if 'current_output' not in st.session_state: st.session_state.current_output = None if 'form_submitted' not in st.session_state: st.session_state.form_submitted = False # Modern animated header st.markdown('''

BlockX Travel Itinerary Generator

✨ Create your personalized AI-powered travel itinerary in minutes! ✨

''', unsafe_allow_html=True) # Add a nice separator st.markdown('
', unsafe_allow_html=True) # Enhanced sidebar with modern design with st.sidebar: # Add a profile/brand area at the top st.markdown('''

BlockX Travel

AI-Powered Travel Planning

''', unsafe_allow_html=True) # About section with modern container st.markdown('
', unsafe_allow_html=True) st.markdown("### 🌟 About") st.info( "This AI-powered tool creates a personalized travel itinerary based on your preferences. " "Fill in the form and let our specialized travel agents plan your perfect trip!" ) st.markdown('
', unsafe_allow_html=True) # How it works with steps and icons st.markdown('
', unsafe_allow_html=True) st.markdown("### πŸ” How it works") st.markdown("""
  1. πŸ–ŠοΈ Enter your travel details
  2. 🧠 AI analysis of your preferences
  3. πŸ“‹ Generate comprehensive itinerary
  4. πŸ“₯ Download and enjoy your trip!
""", unsafe_allow_html=True) st.markdown('
', unsafe_allow_html=True) # Travel Agents section with icons st.markdown('
', unsafe_allow_html=True) st.markdown("### πŸ€– Travel Agents") agents = [ ("πŸ”­ Research Specialist", "Finds the best destinations based on your preferences"), ("🏨 Accommodation Expert", "Suggests suitable hotels and stays"), ("πŸš† Transportation Planner", "Plans efficient travel routes"), ("🎯 Activities Curator", "Recommends activities tailored to your interests"), ("🍽️ Dining Connoisseur", "Finds the best dining experiences"), ("πŸ“… Itinerary Creator", "Puts everything together in a daily plan") ] for name, desc in agents: st.markdown(f"**{name}**") st.markdown(f"{desc}", unsafe_allow_html=True) st.markdown('
', unsafe_allow_html=True) # Main content area if not st.session_state.generation_complete: # Sleek form with minimal design st.markdown('
', unsafe_allow_html=True) st.markdown("

✈️ Create Your Itinerary

", unsafe_allow_html=True) # Minimalist description st.markdown("""

Complete the form below for a personalized travel plan.

""", unsafe_allow_html=True) # Form with improved layout and visual cues with st.form("travel_form"): col1, col2 = st.columns(2) with col1: st.markdown('

Trip Details

', unsafe_allow_html=True) origin = st.text_input("Origin", placeholder="e.g., New York, USA") destination = st.text_input("Destination", placeholder="e.g., Paris, France") # Minimalist date picker st.markdown('

Travel Dates

', unsafe_allow_html=True) start_date = st.date_input("Start Date", min_value=datetime.now(), label_visibility="collapsed") end_date = start_date + timedelta(days=7) duration = st.slider("Duration (days)", min_value=1, max_value=30, value=7) end_date = start_date + timedelta(days=duration-1) st.markdown(f'

{start_date.strftime("%b %d")} - {end_date.strftime("%b %d, %Y")}

', unsafe_allow_html=True) with col2: st.markdown('

Preferences

', unsafe_allow_html=True) travelers = st.number_input("Travelers", min_value=1, max_value=15, value=2) budget_options = ["Budget", "Moderate", "Luxury"] budget = st.selectbox("Budget", budget_options, help="Budget: Economy options | Moderate: Mid-range | Luxury: High-end experiences") # Travel style with visual selection travel_style = st.multiselect("🌈 Travel Style", options=["Culture", "Adventure", "Relaxation", "Food & Dining", "Nature", "Shopping", "Nightlife", "Family-friendly"], default=["Culture", "Food & Dining"]) # Additional information in an expander with st.expander("🌟 Additional Preferences & Requirements", expanded=False): preferences = st.text_area("Specific Interests", placeholder="e.g., I love history museums, local cuisine, hiking, contemporary art...") special_requirements = st.text_area("Special Requirements", placeholder="e.g., dietary restrictions, accessibility needs, traveling with children...") # Submit button with enhanced styling submit_button = st.form_submit_button("πŸš€ Create My Personal Travel Itinerary") st.markdown('
', unsafe_allow_html=True) # Process form submission if submit_button: if not origin or not destination: st.error("Please enter both origin and destination.") else: st.session_state.form_submitted = True user_input = { "origin": origin, "destination": destination, "duration": str(duration), "travel_dates": f"{start_date.strftime('%Y-%m-%d')} to {end_date.strftime('%Y-%m-%d')}", "travelers": str(travelers), "budget": budget.lower(), "travel_style": ", ".join(travel_style), "preferences": preferences, "special_requirements": special_requirements } # Format the user input for tasks with enhanced details input_context = f"""Travel Request Details: Origin: {user_input['origin']} Destination: {user_input['destination']} Duration: {user_input['duration']} days Travel Dates: {user_input['travel_dates']} Travelers: {user_input['travelers']} Budget Level: {user_input['budget']} Travel Style: {user_input['travel_style']} Preferences/Interests: {user_input['preferences']} Special Requirements: {user_input['special_requirements']} """ # Display a minimal, sleek processing animation st.markdown("""
""", unsafe_allow_html=True) # Create modern containers for progress, logs, and live output st.markdown('
', unsafe_allow_html=True) # Create tabs for better organization progress_tab, logs_tab, details_tab = st.tabs(["πŸ“Š Progress", "πŸ”„ Live Activity", "πŸ“‹ Request Details"]) # Show request details in the details tab with details_tab: st.markdown("#### Your Travel Request") st.markdown(f"**Destination:** {user_input['destination']}") st.markdown(f"**From:** {user_input['origin']}") st.markdown(f"**When:** {user_input['travel_dates']} ({user_input['duration']} days)") st.markdown(f"**Budget:** {user_input['budget'].title()}") st.markdown(f"**Travel Style:** {user_input['travel_style']}") if user_input['preferences']: st.markdown(f"**Interests:** {user_input['preferences']}") if user_input['special_requirements']: st.markdown(f"**Special Requirements:** {user_input['special_requirements']}") with progress_tab: # Create a persistent placeholder for progress display to avoid duplication if 'progress_placeholder' not in st.session_state: st.session_state.progress_placeholder = st.empty() with st.session_state.progress_placeholder.container(): display_modern_progress(0) with logs_tab: log_container = st.container() st.session_state.log_messages = [] # Create a container for output that spans the full width st.markdown('
', unsafe_allow_html=True) # Close the progress card output_container = st.container() with output_container: st.markdown('
', unsafe_allow_html=True) st.markdown("### 🌟 Live Agent Outputs") st.info("Our AI agents will show their work here as they create your itinerary") st.markdown('
', unsafe_allow_html=True) # Initialize progress tracking st.session_state.current_step = 0 # Display initial progress - using the session state placeholder # Step 1: Destination Research update_step_status(0, 'active') # Mark step 1 as active with st.session_state.progress_placeholder.container(): display_modern_progress(st.session_state.current_step) destination_info = run_task_with_logs( destination_research_task, input_context.format( destination=user_input['destination'], preferences=user_input['preferences'] ), log_container, output_container, "destination_info" ) # Update progress after step 1 completes update_step_status(0, 'complete') # Mark step 1 as complete st.session_state.current_step = 1 update_step_status(1, 'active') # Mark step 2 as active with st.session_state.progress_placeholder.container(): display_modern_progress(st.session_state.current_step) # Step 2: Accommodation Recommendations accommodation_info = run_task_with_logs( accommodation_task, input_context.format( destination=user_input['destination'], budget=user_input['budget'], preferences=user_input['preferences'] ), log_container, output_container, "accommodation_info" ) # Update progress after step 2 completes update_step_status(1, 'complete') # Mark step 2 as complete st.session_state.current_step = 2 update_step_status(2, 'active') # Mark step 3 as active with st.session_state.progress_placeholder.container(): display_modern_progress(st.session_state.current_step) # Step 3: Transportation Planning transportation_info = run_task_with_logs( transportation_task, input_context.format( origin=user_input['origin'], destination=user_input['destination'] ), log_container, output_container, "transportation_info" ) # Update progress after step 3 completes update_step_status(2, 'complete') # Mark step 3 as complete st.session_state.current_step = 3 update_step_status(3, 'active') # Mark step 4 as active with st.session_state.progress_placeholder.container(): display_modern_progress(st.session_state.current_step) # Step 4: Activities & Attractions activities_info = run_task_with_logs( activities_task, input_context.format( destination=user_input['destination'], preferences=user_input['preferences'] ), log_container, output_container, "activities_info" ) # Update progress after step 4 completes update_step_status(3, 'complete') # Mark step 4 as complete st.session_state.current_step = 4 update_step_status(4, 'active') # Mark step 5 as active with st.session_state.progress_placeholder.container(): display_modern_progress(st.session_state.current_step) # Step 5: Dining Recommendations dining_info = run_task_with_logs( dining_task, input_context.format( destination=user_input['destination'], preferences=user_input['preferences'] ), log_container, output_container, "dining_info" ) # Update progress after step 5 completes update_step_status(4, 'complete') # Mark step 5 as complete st.session_state.current_step = 5 update_step_status(5, 'active') # Mark step 6 as active with st.session_state.progress_placeholder.container(): display_modern_progress(st.session_state.current_step) # Step 6: Create Day-by-Day Itinerary combined_info = f"""{input_context} Destination Information: {destination_info} Accommodation Options: {accommodation_info} Transportation Plan: {transportation_info} Recommended Activities: {activities_info} Dining Recommendations: {dining_info} """ itinerary = run_task_with_logs( itinerary_task, combined_info.format( duration=user_input['duration'], origin=user_input['origin'], destination=user_input['destination'] ), log_container, output_container, "itinerary" ) # Update final step status to complete update_step_status(5, 'complete') # Mark final step as complete st.session_state.current_step = 6 with st.session_state.progress_placeholder.container(): display_modern_progress(st.session_state.current_step) # Save the generated itinerary to session state st.session_state.generated_itinerary = itinerary st.session_state.generation_complete = True # Create a filename based on the destination and date date_str = datetime.now().strftime("%Y-%m-%d") st.session_state.filename = f"{user_input['destination'].replace(' ', '_')}_{date_str}_itinerary.txt" # No need to rerun, we'll update the UI directly # Display results if generation is complete if st.session_state.generation_complete: # Success animation and header st.markdown("""

Your Travel Itinerary is Ready! πŸŽ‰

We've created a personalized travel experience just for you. Explore your itinerary below.

""", unsafe_allow_html=True) # Main container for itinerary content st.markdown('
', unsafe_allow_html=True) # Modern tabs for different views itinerary_tab, details_tab, download_tab = st.tabs(["πŸ—’οΈ Full Itinerary", "πŸ’ΌDetails", "πŸ’Ύ Download & Share"]) with itinerary_tab: # Preview the itinerary as text st.text_area("Your Itinerary", st.session_state.generated_itinerary, height=600) with details_tab: # More detailed view with agent outputs in a nested tab structure agent_tabs = st.tabs([ "🌎 Destination", "🏨 Accommodation", "πŸš— Transportation", "🎭 Activities", "🍽️ Dining" ]) with agent_tabs[0]: st.markdown("### 🌎 Destination Research") st.markdown(st.session_state.results["destination_info"]) with agent_tabs[1]: st.markdown("### 🏨 Accommodation Options") st.markdown(st.session_state.results["accommodation_info"]) with agent_tabs[2]: st.markdown("### πŸš— Transportation Plan") st.markdown(st.session_state.results["transportation_info"]) with agent_tabs[3]: st.markdown("### 🎭 Recommended Activities") st.markdown(st.session_state.results["activities_info"]) with agent_tabs[4]: st.markdown("### 🍽️ Dining Recommendations") st.markdown(st.session_state.results["dining_info"]) with download_tab: col1, col2 = st.columns([2, 1]) with col1: st.markdown("### Save Your Itinerary") st.markdown("Download your personalized travel plan to access it offline or share with your travel companions.") # Display stylized download button st.markdown("""

Your Itinerary File

Text format - Can be opened in any text editor

""", unsafe_allow_html=True) # Enhanced download link st.markdown( f"""
{ get_download_link(st.session_state.generated_itinerary, st.session_state.filename) }
""", unsafe_allow_html=True ) st.markdown("
", unsafe_allow_html=True) # Share options st.markdown("### Share Your Itinerary") st.markdown("*Coming soon: Email your itinerary or share via social media.*") with col2: # QR code placeholder for future implementation st.markdown("### Save for Mobile") st.markdown("*Coming soon: QR code for easy access on your phone*") st.markdown('
', unsafe_allow_html=True) # Add a reset button to create a new itinerary if st.button("πŸ”„ Plan Another Trip", key="reset_button"): # Reset the session state st.session_state.generated_itinerary = None st.session_state.generation_complete = False st.session_state.current_step = 0 st.session_state.form_submitted = False st.session_state.results = {} st.experimental_rerun() # Footer for the app st.markdown("""

© 2023 AI Travel Planner | Built with ❀️ using Streamlit and advanced AI

""", unsafe_allow_html=True) # End of app # Modern footer with more information st.markdown("""

BlockX Travel

AI-powered travel planning made easy. Create personalized itineraries for your dream destinations.

Quick Links

  • About
  • Travel Guides
  • FAQs
  • Contact Us

Connect

Stay updated with our latest travel guides and features.

🐰 🐿 🐸 πŸ¦‰

© 2025 BlockX AI Travel | All rights reserved | Built with ❀️ from the team of BlockX AI Ltd https://blockxint.com.

""", unsafe_allow_html=True)