""" Musora Sentiment Analysis Dashboard Main Streamlit Application Run with: streamlit run app.py """ import streamlit as st import sys from pathlib import Path import json # Add parent directory to path parent_dir = Path(__file__).resolve().parent sys.path.append(str(parent_dir)) from data.data_loader import SentimentDataLoader from components.dashboard import render_dashboard from components.sentiment_analysis import render_sentiment_analysis from components.reply_required import render_reply_required # Load configuration config_path = parent_dir / "config" / "viz_config.json" with open(config_path, 'r') as f: config = json.load(f) # Page configuration st.set_page_config( page_title=config['page_config']['page_title'], page_icon=config['page_config']['page_icon'], layout=config['page_config']['layout'], initial_sidebar_state=config['page_config']['initial_sidebar_state'] ) def main(): """ Main application function """ # Sidebar with st.sidebar: st.image("visualization/img/musora.png", use_container_width=True) st.title("Navigation") # Page selection page = st.radio( "Select Page", ["đ Dashboard", "đ Sentiment Analysis", "đŦ Reply Required"], index=0 ) st.markdown("---") # Filters section st.markdown("### đ Global Filters") # Initialize session state for filters if 'filters_applied' not in st.session_state: st.session_state.filters_applied = False # Load data first to get filter options with st.spinner("Loading data..."): data_loader = SentimentDataLoader() df = data_loader.load_data() if df.empty: st.error("No data available. Please check your Snowflake connection.") return # Get filter options filter_options = data_loader.get_filter_options(df) # Platform filter selected_platforms = st.multiselect( "Platforms", options=filter_options['platforms'], default=[] ) # Brand filter selected_brands = st.multiselect( "Brands", options=filter_options['brands'], default=[] ) # Sentiment filter selected_sentiments = st.multiselect( "Sentiments", options=filter_options['sentiments'], default=[] ) # Date range filter (if available) if 'comment_timestamp' in df.columns and not df.empty: min_date = df['comment_timestamp'].min().date() max_date = df['comment_timestamp'].max().date() date_range = st.date_input( "Date Range", value=(min_date, max_date), min_value=min_date, max_value=max_date ) else: date_range = None # Apply filters button if st.button("đ Apply Filters", use_container_width=True): st.session_state.filters_applied = True # Reset filters button if st.button("đ Reset Filters", use_container_width=True): st.session_state.filters_applied = False st.rerun() st.markdown("---") # Data refresh st.markdown("### đ Data Management") if st.button("âģī¸ Reload Data", use_container_width=True): st.cache_data.clear() st.rerun() # Display data info st.markdown("---") st.markdown("### âšī¸ Data Info") st.info(f"**Total Records:** {len(df):,}") if 'processed_at' in df.columns and not df.empty: last_update = df['processed_at'].max() st.info(f"**Last Updated:** {last_update.strftime('%Y-%m-%d %H:%M')}") # Apply filters if needed if st.session_state.filters_applied: df = data_loader.apply_filters( df, platforms=selected_platforms if selected_platforms else None, brands=selected_brands if selected_brands else None, sentiments=selected_sentiments if selected_sentiments else None, date_range=date_range if date_range and len(date_range) == 2 else None ) # Show filter summary if df.empty: st.warning("No data matches the selected filters. Please adjust your filters.") return else: st.info(f"Showing {len(df):,} records after applying filters") # Main content area - render selected page if page == "đ Dashboard": render_dashboard(df) elif page == "đ Sentiment Analysis": render_sentiment_analysis(df) elif page == "đŦ Reply Required": render_reply_required(df) # Footer st.markdown("---") st.markdown( """
Musora Sentiment Analysis Dashboard v1.0
Powered by Streamlit | Data from Snowflake