vanshs055 commited on
Commit
1ea6f43
·
verified ·
1 Parent(s): 2f084f1

Upload 11 files

Browse files
pages/1_Dashboard.py ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import pandas as pd
3
+ from datetime import date, datetime
4
+ from utils import load_data
5
+ from utils.charts import expenses_pie, sleep_line
6
+
7
+ st.title("📊 Daily Overview")
8
+
9
+ # --- Load data ---
10
+ expenses = load_data("expenses.json", [])
11
+ todos = load_data("todos.json", [])
12
+ medicines = load_data("medicines.json", [])
13
+ sleep_records = load_data("sleep.json", [])
14
+ pomodoros = load_data("pomodoro_history.json", [])
15
+
16
+ today = date.today().isoformat()
17
+
18
+ # --- Quick stats ---
19
+ daily_expenses = sum(e['amount'] for e in expenses if e['date'] == today)
20
+ completed_tasks = sum(1 for t in todos if t['done'])
21
+ pending_tasks = len(todos) - completed_tasks
22
+ upcoming_meds = [m for m in medicines if m['date'] == today and not m.get('taken')]
23
+
24
+ col1, col2, col3, col4 = st.columns(4)
25
+ col1.metric("Today's Spend", f"₹{daily_expenses:,.2f}")
26
+ col2.metric("Tasks Pending", pending_tasks)
27
+ col3.metric("Pomodoro Sessions", len(pomodoros))
28
+ col4.metric("Meds Remaining", len(upcoming_meds))
29
+
30
+ # --- Compact charts ---
31
+ st.subheader("Expenses Breakdown")
32
+ st.plotly_chart(expenses_pie(expenses), use_container_width=True)
33
+
34
+ st.subheader("Sleep Trend")
35
+ st.plotly_chart(sleep_line(sleep_records), use_container_width=True)
pages/2_Pomodoro_Timer.py ADDED
@@ -0,0 +1,53 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ from datetime import datetime, timedelta
3
+ from utils import save_data
4
+
5
+ st.title("⏱️ Pomodoro Timer")
6
+
7
+ # --- User settings ---
8
+ work_minutes = st.number_input("Work duration (minutes)", 10, 120, 25)
9
+ break_minutes = st.number_input("Break duration (minutes)", 1, 60, 5)
10
+
11
+ # --- Session state initialisation ---
12
+ if 'pomodoro_running' not in st.session_state:
13
+ st.session_state.pomodoro_running = False
14
+ st.session_state.pomodoro_start = None
15
+ st.session_state.pomodoro_mode = 'Work' # or 'Break'
16
+
17
+ def start_timer():
18
+ st.session_state.pomodoro_running = True
19
+ st.session_state.pomodoro_start = datetime.now()
20
+ st.session_state.pomodoro_mode = 'Work'
21
+
22
+ def stop_timer():
23
+ st.session_state.pomodoro_running = False
24
+ st.session_state.pomodoro_start = None
25
+
26
+ # --- Buttons ---
27
+ col1, col2 = st.columns(2)
28
+ if col1.button("Start" if not st.session_state.pomodoro_running else "Restart"):
29
+ start_timer()
30
+ if col2.button("Stop"):
31
+ stop_timer()
32
+
33
+ # --- Timer display ---
34
+ if st.session_state.pomodoro_running and st.session_state.pomodoro_start:
35
+ elapsed = (datetime.now() - st.session_state.pomodoro_start).total_seconds()
36
+ target = work_minutes * 60 if st.session_state.pomodoro_mode == 'Work' else break_minutes * 60
37
+ remaining = max(0, target - elapsed)
38
+ mins, secs = divmod(int(remaining), 60)
39
+ st.header(f"{st.session_state.pomodoro_mode} — {mins:02d}:{secs:02d}")
40
+ if remaining == 0:
41
+ # switch mode
42
+ st.session_state.pomodoro_mode = 'Break' if st.session_state.pomodoro_mode == 'Work' else 'Work'
43
+ st.session_state.pomodoro_start = datetime.now()
44
+
45
+ # --- History table ---
46
+ if 'pomodoro_history' not in st.session_state:
47
+ st.session_state.pomodoro_history = []
48
+
49
+ st.subheader("Session History")
50
+ st.table(st.session_state.pomodoro_history)
51
+
52
+ # --- Persist history ---
53
+ save_data(st.session_state.pomodoro_history, "pomodoro_history.json")
pages/3_Expenses_Tracker.py ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import pandas as pd
3
+ from utils import load_data, save_data
4
+ from utils.charts import expenses_pie
5
+ from datetime import date
6
+
7
+ st.title("💰 Expenses Tracker")
8
+
9
+ if 'expenses' not in st.session_state:
10
+ st.session_state.expenses = load_data("expenses.json", [])
11
+
12
+ # --- Add / edit form ---
13
+ st.subheader("Add / Edit Expense")
14
+ with st.form("expense_form", clear_on_submit=True):
15
+ amount = st.number_input("Amount", min_value=0.0, step=0.5)
16
+ category_list = list({e['category'] for e in st.session_state.expenses})
17
+ new_category = st.text_input("New category (leave blank to use existing)")
18
+ category = st.selectbox("Category", options=category_list) if not new_category else new_category
19
+ date_input = st.date_input("Date", value=date.today())
20
+ description = st.text_input("Description")
21
+ status = st.selectbox("Status", ["Paid", "Unpaid"])
22
+ submitted = st.form_submit_button("Save")
23
+
24
+ if submitted:
25
+ exp = {
26
+ "amount": amount,
27
+ "category": category,
28
+ "date": date_input.isoformat(),
29
+ "description": description,
30
+ "status": status
31
+ }
32
+ st.session_state.expenses.append(exp)
33
+ save_data(st.session_state.expenses, "expenses.json")
34
+ st.success("Expense saved!")
35
+
36
+ # --- Display table ---
37
+ st.subheader("All Expenses")
38
+ df = pd.DataFrame(st.session_state.expenses)
39
+ if not df.empty:
40
+ st.dataframe(df)
41
+ csv = df.to_csv(index=False).encode('utf-8')
42
+ st.download_button("📥 Download CSV", csv, "expenses.csv", mime="text/csv")
43
+ st.plotly_chart(expenses_pie(st.session_state.expenses), use_container_width=True)
44
+ else:
45
+ st.info("No expenses recorded yet.")
pages/4_ToDo_List.py ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ from utils import load_data, save_data
3
+
4
+ st.title("✅ To‑Do List")
5
+
6
+ if 'todos' not in st.session_state:
7
+ st.session_state.todos = load_data("todos.json", [])
8
+
9
+ # --- Add task ---
10
+ new_task = st.text_input("Add a new task")
11
+ if st.button("Add") and new_task.strip():
12
+ st.session_state.todos.append({"task": new_task, "done": False})
13
+ save_data(st.session_state.todos, "todos.json")
14
+
15
+ # --- Filter ---
16
+ filter_opt = st.radio("Filter", ["All", "Active", "Completed"], horizontal=True)
17
+
18
+ # --- Task list ---
19
+ def task_filter(item):
20
+ if filter_opt == "Active":
21
+ return not item['done']
22
+ if filter_opt == "Completed":
23
+ return item['done']
24
+ return True
25
+
26
+ for i, todo in enumerate(st.session_state.todos):
27
+ if task_filter(todo):
28
+ cols = st.columns([0.1, 0.8, 0.1])
29
+ done = cols[0].checkbox("", value=todo['done'], key=f"todo_{i}")
30
+ if done != todo['done']:
31
+ todo['done'] = done
32
+ save_data(st.session_state.todos, "todos.json")
33
+ cols[1].write(todo['task'])
34
+ if cols[2].button("🗑️", key=f"del_{i}"):
35
+ st.session_state.todos.pop(i)
36
+ save_data(st.session_state.todos, "todos.json")
37
+ st.experimental_rerun()
pages/5_Medicine_Tracker.py ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ from datetime import date, datetime
3
+ from utils import load_data, save_data
4
+
5
+ st.title("💊 Medicine Tracker")
6
+
7
+ if 'medicines' not in st.session_state:
8
+ st.session_state.medicines = load_data("medicines.json", [])
9
+
10
+ with st.form("add_med"):
11
+ name = st.text_input("Medicine Name")
12
+ dosage = st.text_input("Dosage (e.g., 500mg)")
13
+ time_of_day = st.selectbox("Time", ["Morning", "Afternoon", "Evening", "Night"])
14
+ meal = st.selectbox("Meal", ["Before Meal", "After Meal"])
15
+ date_input = st.date_input("Date", date.today())
16
+ submitted = st.form_submit_button("Add")
17
+
18
+ if submitted and name:
19
+ st.session_state.medicines.append({
20
+ "name": name,
21
+ "dosage": dosage,
22
+ "time": time_of_day,
23
+ "meal": meal,
24
+ "date": date_input.isoformat(),
25
+ "taken": False
26
+ })
27
+ save_data(st.session_state.medicines, "medicines.json")
28
+ st.success("Medicine logged.")
29
+
30
+ # --- Upcoming reminders ---
31
+ today = date.today().isoformat()
32
+ upcoming = [m for m in st.session_state.medicines if m['date'] == today and not m['taken']]
33
+ st.subheader("Today's Pending Doses")
34
+ for med in upcoming:
35
+ st.info(f"{med['time']} — {med['name']} {med['dosage']} ({med['meal']})")
36
+ if st.button("Mark Taken", key=f"take_{med['name']}_{med['time']}"):
37
+ med['taken'] = True
38
+ save_data(st.session_state.medicines, "medicines.json")
39
+ st.experimental_rerun()
40
+
41
+ # --- History ---
42
+ st.subheader("All Records")
43
+ if st.session_state.medicines:
44
+ st.dataframe(st.session_state.medicines)
pages/6_Sleep_Tracker.py ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ from datetime import date, datetime, timedelta
3
+ from utils import load_data, save_data
4
+ from utils.charts import sleep_line
5
+
6
+ st.title("🛌 Sleep Tracker")
7
+
8
+ if 'sleep' not in st.session_state:
9
+ st.session_state.sleep = load_data("sleep.json", [])
10
+
11
+ # --- Record sleep ---
12
+ st.subheader("Record Sleep")
13
+ with st.form("sleep_form", clear_on_submit=True):
14
+ sleep_date = st.date_input("Date", date.today())
15
+ bed_time = st.time_input("Bed Time")
16
+ wake_time = st.time_input("Wake Time")
17
+ submitted = st.form_submit_button("Save")
18
+
19
+ if submitted:
20
+ bed_dt = datetime.combine(sleep_date, bed_time)
21
+ wake_dt = datetime.combine(sleep_date + timedelta(days=1 if wake_time < bed_time else 0), wake_time)
22
+ hours = round((wake_dt - bed_dt).total_seconds() / 3600, 2)
23
+ st.session_state.sleep.append({
24
+ "date": sleep_date.isoformat(),
25
+ "hours": hours
26
+ })
27
+ save_data(st.session_state.sleep, "sleep.json")
28
+ st.success(f"Recorded {hours} hrs of sleep.")
29
+
30
+ # --- Display ---
31
+ st.subheader("Last 7 Entries")
32
+ if st.session_state.sleep:
33
+ st.dataframe(st.session_state.sleep[-7:])
34
+ st.plotly_chart(sleep_line(st.session_state.sleep), use_container_width=True)
35
+ else:
36
+ st.info("No sleep data yet.")
requirements.txt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ streamlit>=1.33
2
+ plotly>=5.19
3
+ pandas>=2.2
streamlit_app.py ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ from utils.data_utils import ensure_data_file, load_data, save_data
3
+
4
+ # -------- Page Config -------- #
5
+ st.set_page_config(
6
+ page_title="Life Dashboard",
7
+ page_icon="🌟",
8
+ layout="wide"
9
+ )
10
+
11
+ # -------- Initialise Global Session State -------- #
12
+ default_lists = {
13
+ 'expenses': [],
14
+ 'todos': [],
15
+ 'medicines': [],
16
+ 'sleep': [],
17
+ 'pomodoro_history': []
18
+ }
19
+
20
+ for key, val in default_lists.items():
21
+ if key not in st.session_state:
22
+ st.session_state[key] = load_data(f"{key}.json", val)
23
+
24
+ # -------- Simple landing content -------- #
25
+ st.title("Welcome to Your Life Dashboard ✨")
26
+ st.markdown(
27
+ "This home page just sets things up. Use the sidebar to open the individual tracker pages. "
28
+ "All data you enter is saved locally in **./data/**. Enjoy!")
29
+
30
+ # -------- Persist session data on every run -------- #
31
+ for key in default_lists:
32
+ save_data(st.session_state[key], f"{key}.json")
utils/__init__.py ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ """Re-export utility helpers."""
2
+ from .data_utils import load_data, save_data, ensure_data_file
utils/charts.py ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Chart helper functions."""
2
+ import pandas as pd
3
+ import plotly.express as px
4
+ from typing import List, Dict
5
+
6
+ def expenses_pie(expenses: List[Dict]) -> 'plotly.graph_objs._figure.Figure':
7
+ """Return a pie chart showing paid/unpaid by category."""
8
+ if not expenses:
9
+ return px.pie(title="No expense data yet")
10
+ df = pd.DataFrame(expenses)
11
+ df['status_label'] = df['category'] + ' - ' + df['status']
12
+ return px.pie(
13
+ df,
14
+ names='status_label',
15
+ values='amount',
16
+ title='Expenses: Paid vs Unpaid by Category'
17
+ )
18
+
19
+ def sleep_line(sleep_records: List[Dict]) -> 'plotly.graph_objs._figure.Figure':
20
+ """Return a 7‑day line graph of sleep hours."""
21
+ if not sleep_records:
22
+ return px.line(title="No sleep data yet")
23
+ df = pd.DataFrame(sleep_records)
24
+ df['date'] = pd.to_datetime(df['date'])
25
+ df = df.sort_values('date').tail(7)
26
+ return px.line(df, x='date', y='hours', markers=True, title='Sleep Hours (Last 7 Days)')
utils/data_utils.py ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Utility helpers for data persistence and shared logic."""
2
+ import json
3
+ from pathlib import Path
4
+ from typing import Any
5
+
6
+ DATA_DIR = Path(__file__).resolve().parent.parent / "data"
7
+ DATA_DIR.mkdir(exist_ok=True)
8
+
9
+ def _file_path(filename: str) -> Path:
10
+ """Return path to a data file inside DATA_DIR."""
11
+ return DATA_DIR / filename
12
+
13
+ def ensure_data_file(filename: str, default: Any) -> None:
14
+ """Create a data file with *default* content if it does not exist."""
15
+ fp = _file_path(filename)
16
+ if not fp.exists():
17
+ save_data(default, filename)
18
+
19
+ def load_data(filename: str, default: Any):
20
+ """Load JSON data; create with *default* if missing."""
21
+ ensure_data_file(filename, default)
22
+ with open(_file_path(filename), "r", encoding="utf-8") as f:
23
+ return json.load(f)
24
+
25
+ def save_data(data: Any, filename: str) -> None:
26
+ """Write JSON data atomically."""
27
+ tmp = _file_path(filename).with_suffix(".tmp")
28
+ with open(tmp, "w", encoding="utf-8") as f:
29
+ json.dump(data, f, indent=2, ensure_ascii=False)
30
+ tmp.replace(_file_path(filename))