"""Prism — Financial Analysis Dashboard""" import streamlit as st from dotenv import load_dotenv load_dotenv() st.set_page_config( page_title="Prism", page_icon="🔷", layout="wide", initial_sidebar_state="expanded", ) # ── Global CSS ──────────────────────────────────────────────────────────────── st.markdown(""" """, unsafe_allow_html=True) from components.market_bar import render_market_bar from components.overview import render_overview from components.financials import render_financials from components.valuation import render_valuation from components.insiders import render_insiders from components.filings import render_filings from components.news import render_news from components.options import render_options from services.data_service import get_company_info, search_tickers if "ticker" not in st.session_state: st.session_state["ticker"] = None # ── Sidebar ────────────────────────────────────────────────────────────────── with st.sidebar: col_logo, col_title = st.columns([1, 2]) with col_logo: st.image("assets/logo.png", width=60) with col_title: st.markdown("### Prism") st.caption("Financial Analysis Dashboard") st.divider() with st.form("ticker_search_form", clear_on_submit=False): query = st.text_input( "Search company or ticker", placeholder="e.g. Apple, AAPL, MSFT…", key="search_query", ).strip() results = search_tickers(query) if query else [] selected_symbol = None if results: options = {f"{r['symbol']} — {r['name']} ({r['exchange']})": r["symbol"] for r in results} choice = st.selectbox( "Matches", options=list(options.keys()), label_visibility="collapsed", ) selected_symbol = options[choice] elif query: selected_symbol = query.upper() submitted = st.form_submit_button("Open", use_container_width=True, type="primary") if submitted and selected_symbol: st.session_state["ticker"] = selected_symbol if st.session_state["ticker"]: st.caption(f"Currently viewing: **{st.session_state['ticker']}**") ticker = st.session_state["ticker"] # Quick company info in sidebar st.divider() if ticker: info = get_company_info(ticker) if ticker and info: st.caption(info.get("longName", ticker)) st.caption(f"Exchange: {info.get('exchange', '—')}") st.caption(f"Currency: {info.get('currency', 'USD')}") st.caption(f"Sector: {info.get('sector', '—')}") employees = info.get("fullTimeEmployees") st.caption(f"Employees: {employees:,}" if isinstance(employees, int) else "Employees: —") website = info.get("website") if website: st.markdown(f"[🌐 Website]({website})") # ── Market Bar ──────────────────────────────────────────────────────────────── with st.container(): render_market_bar() st.divider() # ── Main Content ────────────────────────────────────────────────────────────── if not ticker: st.info("Search for a company or ticker in the sidebar to get started.") st.stop() tab_overview, tab_financials, tab_valuation, tab_options, tab_insiders, tab_filings, tab_news = st.tabs([ "📈 Overview", "📊 Financials", "💰 Valuation", "🎯 Options", "👤 Insiders", "📁 Filings", "📰 News", ]) with tab_overview: try: render_overview(ticker) except Exception as e: st.error(f"Overview failed to load: {e}") with tab_financials: try: render_financials(ticker) except Exception as e: st.error(f"Financials failed to load: {e}") with tab_valuation: try: render_valuation(ticker) except Exception as e: st.error(f"Valuation failed to load: {e}") with tab_options: try: render_options(ticker) except Exception as e: st.error(f"Options data failed to load: {e}") with tab_insiders: try: render_insiders(ticker) except Exception as e: st.error(f"Insider data failed to load: {e}") with tab_filings: try: render_filings(ticker) except Exception as e: st.error(f"Filings failed to load: {e}") with tab_news: try: render_news(ticker) except Exception as e: st.error(f"News failed to load: {e}")