Nakvi commited on
Commit
9ffd375
Β·
verified Β·
1 Parent(s): 3f4def8

Upload 2 files

Browse files
Files changed (2) hide show
  1. app.py +106 -0
  2. requirements.txt +29 -0
app.py ADDED
@@ -0,0 +1,106 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ FocusTrack - Streamlit Dashboard Entry Point
3
+ Run with: streamlit run app.py
4
+ """
5
+
6
+ import sys
7
+ from pathlib import Path
8
+ sys.path.insert(0, str(Path(__file__).parent))
9
+
10
+ import streamlit as st
11
+ from ui_utils import DARK_CSS, LIGHT_CSS, get_db
12
+
13
+ # ─── Page Config (must be first Streamlit call) ───────────────────────────────
14
+ st.set_page_config(
15
+ page_title="FocusTrack",
16
+ page_icon="🎯",
17
+ layout="wide",
18
+ initial_sidebar_state="expanded",
19
+ )
20
+
21
+ # ─── Theme ────────────────────────────────────────────────────────────────────
22
+ db = get_db()
23
+ theme = db.get_setting("theme", "dark")
24
+ st.markdown(DARK_CSS if theme == "dark" else LIGHT_CSS, unsafe_allow_html=True)
25
+
26
+ # ─── Sidebar ──────────────────────────────────────────────────────────────────
27
+ with st.sidebar:
28
+ # Logo
29
+ st.markdown("""
30
+ <div style="padding: 1rem 0 1.5rem; border-bottom: 1px solid #2a2a3a; margin-bottom: 1rem;">
31
+ <div style="display:flex; align-items:center; gap:10px;">
32
+ <div style="
33
+ width:36px; height:36px; border-radius:10px;
34
+ background: linear-gradient(135deg, #6366f1, #22d3ee);
35
+ display:flex; align-items:center; justify-content:center;
36
+ font-size:1.1rem; box-shadow: 0 4px 12px #6366f144;
37
+ ">🎯</div>
38
+ <div>
39
+ <div style="font-family:'Syne',sans-serif; font-weight:800; font-size:1.1rem; color:#f0f0ff; letter-spacing:-0.02em;">FocusTrack</div>
40
+ <div style="font-size:0.68rem; color:#5a5a7a; letter-spacing:0.08em; text-transform:uppercase;">Productivity Tracker</div>
41
+ </div>
42
+ </div>
43
+ </div>
44
+ """, unsafe_allow_html=True)
45
+
46
+ # Navigation
47
+ nav_items = {
48
+ "🏠 Live Dashboard": "dashboard",
49
+ "πŸ“Š Analytics": "analytics",
50
+ "πŸ“‹ Activity Log": "activity_log",
51
+ "βš™οΈ Settings": "settings",
52
+ }
53
+
54
+ if "page" not in st.session_state:
55
+ st.session_state.page = "dashboard"
56
+
57
+ for label, key in nav_items.items():
58
+ is_active = st.session_state.page == key
59
+ if st.button(
60
+ label,
61
+ key=f"nav_{key}",
62
+ use_container_width=True,
63
+ ):
64
+ st.session_state.page = key
65
+ st.rerun()
66
+
67
+ # Tracker status badge
68
+ st.markdown("<div style='margin-top:1rem; border-top:1px solid #2a2a3a; padding-top:1rem;'></div>",
69
+ unsafe_allow_html=True)
70
+
71
+ tracker_status = db.get_setting("tracker_running", "true")
72
+ status_map = {
73
+ "true": ("● Tracking", "#10b981"),
74
+ "paused": ("● Paused", "#f59e0b"),
75
+ "false": ("● Stopped", "#f43f5e"),
76
+ }
77
+ s_label, s_color = status_map.get(tracker_status, ("● Unknown", "#6366f1"))
78
+ st.markdown(
79
+ f"<div style='font-size:0.78rem; font-weight:600; color:{s_color}; "
80
+ f"padding:6px 12px; background:{s_color}11; border-radius:8px; "
81
+ f"border:1px solid {s_color}33; text-align:center;'>{s_label}</div>",
82
+ unsafe_allow_html=True,
83
+ )
84
+
85
+ # Privacy badge in sidebar
86
+ st.markdown("""
87
+ <div style="margin-top:auto; padding-top:2rem; font-size:0.7rem; color:#5a5a7a; text-align:center; line-height:1.5;">
88
+ πŸ”’ 100% private<br>All data stays on your device
89
+ </div>
90
+ """, unsafe_allow_html=True)
91
+
92
+ # ─── Main Content ─────────────────────────────────────────────────────────────
93
+ page = st.session_state.get("page", "dashboard")
94
+
95
+ if page == "dashboard":
96
+ from ui_pages.dashboard import render
97
+ render()
98
+ elif page == "analytics":
99
+ from ui_pages.analytics import render
100
+ render()
101
+ elif page == "activity_log":
102
+ from ui_pages.activity_log import render
103
+ render()
104
+ elif page == "settings":
105
+ from ui_pages.settings import render
106
+ render()
requirements.txt ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # FocusTrack - Python Dependencies
2
+ # Install: pip install -r requirements.txt
3
+
4
+ # ─── Core Dashboard ───────────────────────────────────────────────────────────
5
+ streamlit>=1.35.0
6
+ plotly>=5.22.0
7
+ pandas>=2.2.0
8
+ altair>=5.3.0
9
+
10
+ # ─── Tracker Engine ───────────────────────────────────────────────────────────
11
+ pynput>=1.7.7 # Mouse + keyboard idle detection
12
+ psutil>=5.9.8 # Process/app name lookup
13
+
14
+ # ─── System Tray (optional but recommended) ──────────────────────────────────
15
+ pystray>=0.19.5
16
+ Pillow>=10.3.0 # For tray icon rendering
17
+
18
+ # ─── macOS window detection (optional) ───────────────────────────────────────
19
+ # pyobjc-framework-AppKit # Uncomment on macOS
20
+
21
+ # ─── Linux window detection (install via system package manager) ──────────────
22
+ # xdotool β†’ sudo apt install xdotool (Ubuntu/Debian)
23
+ # wmctrl β†’ sudo apt install wmctrl
24
+
25
+ # ─── Packaging (optional, for .exe build) ────────────────────────────────────
26
+ # pyinstaller>=6.6.0
27
+
28
+ # ─── Standard Library (no install needed) ────────────────────────────────────
29
+ # sqlite3, threading, platform, json, logging, subprocess, pathlib