Spaces:
Runtime error
Runtime error
| """ | |
| FocusTrack - Streamlit Dashboard Entry Point | |
| Run with: streamlit run app.py | |
| """ | |
| import sys | |
| from pathlib import Path | |
| sys.path.insert(0, str(Path(__file__).parent)) | |
| import streamlit as st | |
| from ui_utils import DARK_CSS, LIGHT_CSS, get_db | |
| # βββ Page Config (must be first Streamlit call) βββββββββββββββββββββββββββββββ | |
| st.set_page_config( | |
| page_title="FocusTrack", | |
| page_icon="π―", | |
| layout="wide", | |
| initial_sidebar_state="expanded", | |
| ) | |
| # βββ Theme ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| db = get_db() | |
| theme = db.get_setting("theme", "dark") | |
| st.markdown(DARK_CSS if theme == "dark" else LIGHT_CSS, unsafe_allow_html=True) | |
| # βββ Sidebar ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| with st.sidebar: | |
| # Logo | |
| st.markdown(""" | |
| <div style="padding: 1rem 0 1.5rem; border-bottom: 1px solid #2a2a3a; margin-bottom: 1rem;"> | |
| <div style="display:flex; align-items:center; gap:10px;"> | |
| <div style=" | |
| width:36px; height:36px; border-radius:10px; | |
| background: linear-gradient(135deg, #6366f1, #22d3ee); | |
| display:flex; align-items:center; justify-content:center; | |
| font-size:1.1rem; box-shadow: 0 4px 12px #6366f144; | |
| ">π―</div> | |
| <div> | |
| <div style="font-family:'Syne',sans-serif; font-weight:800; font-size:1.1rem; color:#f0f0ff; letter-spacing:-0.02em;">FocusTrack</div> | |
| <div style="font-size:0.68rem; color:#5a5a7a; letter-spacing:0.08em; text-transform:uppercase;">Productivity Tracker</div> | |
| </div> | |
| </div> | |
| </div> | |
| """, unsafe_allow_html=True) | |
| # Navigation | |
| nav_items = { | |
| "π Live Dashboard": "dashboard", | |
| "π Analytics": "analytics", | |
| "π Activity Log": "activity_log", | |
| "βοΈ Settings": "settings", | |
| } | |
| if "page" not in st.session_state: | |
| st.session_state.page = "dashboard" | |
| for label, key in nav_items.items(): | |
| is_active = st.session_state.page == key | |
| if st.button( | |
| label, | |
| key=f"nav_{key}", | |
| use_container_width=True, | |
| ): | |
| st.session_state.page = key | |
| st.rerun() | |
| # Tracker status badge | |
| st.markdown("<div style='margin-top:1rem; border-top:1px solid #2a2a3a; padding-top:1rem;'></div>", | |
| unsafe_allow_html=True) | |
| tracker_status = db.get_setting("tracker_running", "true") | |
| status_map = { | |
| "true": ("β Tracking", "#10b981"), | |
| "paused": ("β Paused", "#f59e0b"), | |
| "false": ("β Stopped", "#f43f5e"), | |
| } | |
| s_label, s_color = status_map.get(tracker_status, ("β Unknown", "#6366f1")) | |
| st.markdown( | |
| f"<div style='font-size:0.78rem; font-weight:600; color:{s_color}; " | |
| f"padding:6px 12px; background:{s_color}11; border-radius:8px; " | |
| f"border:1px solid {s_color}33; text-align:center;'>{s_label}</div>", | |
| unsafe_allow_html=True, | |
| ) | |
| # Privacy badge in sidebar | |
| st.markdown(""" | |
| <div style="margin-top:auto; padding-top:2rem; font-size:0.7rem; color:#5a5a7a; text-align:center; line-height:1.5;"> | |
| π 100% private<br>All data stays on your device | |
| </div> | |
| """, unsafe_allow_html=True) | |
| # βββ Main Content βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| page = st.session_state.get("page", "dashboard") | |
| if page == "dashboard": | |
| from ui_pages.dashboard import render | |
| render() | |
| elif page == "analytics": | |
| from ui_pages.analytics import render | |
| render() | |
| elif page == "activity_log": | |
| from ui_pages.activity_log import render | |
| render() | |
| elif page == "settings": | |
| from ui_pages.settings import render | |
| render() | |