import streamlit as st import pandas as pd from datetime import datetime import time import os from io import BytesIO from fpdf import FPDF from apscheduler.schedulers.background import BackgroundScheduler from plyer import notification import plotly.express as px # --- PAGE CONFIGURATION --- st.set_page_config(page_title="The Task Tracker", page_icon="โœ…", layout="wide") # --- THEME CSS (Navy, Black, Gold) --- st.markdown(""" """, unsafe_allow_html=True) # --- BACKEND FUNCTIONS --- DATA_FILE = "task_tracker_elite.csv" def load_data(): if os.path.exists(DATA_FILE): df = pd.read_csv(DATA_FILE) if "Category" not in df.columns: df["Category"] = "General" return df else: return pd.DataFrame(columns=["Date", "Category", "Task", "Status"]) def save_data(df): df.to_csv(DATA_FILE, index=False) def trigger_notification(): try: notification.notify( title='The Task Tracker', message='Execution is key. Update your progress.', timeout=10 ) except: pass def to_excel(df): output = BytesIO() with pd.ExcelWriter(output, engine='openpyxl') as writer: df.to_excel(writer, index=False, sheet_name='Sheet1') return output.getvalue() def to_pdf(df, start_date, end_date): pdf = FPDF() pdf.add_page() pdf.set_font("Times", 'B', 20) pdf.set_text_color(0, 31, 63) pdf.cell(200, 15, txt="PERFORMANCE REPORT", ln=1, align='C') pdf.set_font("Times", 'I', 12) pdf.cell(200, 10, txt=f"Period: {start_date} to {end_date}", ln=1, align='C') pdf.set_text_color(0, 0, 0) pdf.set_font("Times", size=11) pdf.ln(10) cols = ["Date", "Category", "Task", "Status"] pdf.set_fill_color(220, 220, 220) for col in cols: pdf.cell(45, 10, col, 1, 0, 'C', True) pdf.ln() for _, row in df.iterrows(): pdf.cell(45, 10, str(row['Date']), 1) pdf.cell(45, 10, str(row['Category']), 1) pdf.cell(45, 10, str(row['Task'])[:20], 1) pdf.cell(45, 10, str(row['Status']), 1) pdf.ln() return pdf.output(dest='S').encode('latin-1') # --- SCHEDULER --- if 'scheduler_active' not in st.session_state: scheduler = BackgroundScheduler() scheduler.add_job(trigger_notification, 'cron', hour=21, minute=0) scheduler.start() st.session_state['scheduler_active'] = True # --- UI LOGIC --- # 1. UPDATED HEADER & TAGLINE st.markdown("""

THE TASK TRACKER

"Planning, Focus, Discipline & Execution โ€“ these are the Mantras of the life."

""", unsafe_allow_html=True) df = load_data() today_str = datetime.now().strftime("%Y-%m-%d") # 2. UPDATED TAB NAMES tab_planner, tab_analytics = st.tabs(["๐Ÿ“ Daily Task", "๐Ÿ“Š Performance Metrics"]) # --- TAB 1: DAILY TASK --- with tab_planner: st.markdown("### ๐Ÿ“‹ Plan Your Execution") with st.container(): c1, c2, c3 = st.columns([2, 1, 1]) with c1: new_task = st.text_input("Task Description", placeholder="What is the next objective?") with c2: category = st.selectbox("Category", ["Work ๐Ÿ’ผ", "Personal ๐Ÿ ", "Finance ๐Ÿ’ฐ", "Health ๐Ÿ’ช", "Priority โšก"]) with c3: st.write("") st.write("") add_btn = st.button("ADD TASK", use_container_width=True) if add_btn and new_task: clean_cat = category.split(" ")[0] new_entry = pd.DataFrame([{"Date": today_str, "Category": clean_cat, "Task": new_task, "Status": "Pending"}]) df = pd.concat([df, new_entry], ignore_index=True) save_data(df) st.toast("Task successfully added.", icon="โœ…") time.sleep(0.5) st.rerun() st.markdown("---") today_tasks = df[df['Date'] == today_str] if not today_tasks.empty: total_today = len(today_tasks) completed_count = len(today_tasks[today_tasks['Status'] == "Completed"]) progress_val = int((completed_count / total_today) * 100) if total_today > 0 else 0 st.write(f"### ๐Ÿ“‰ Daily Discipline: {progress_val}%") st.progress(progress_val) categories = today_tasks['Category'].unique() with st.form("status_update_form"): for cat in categories: st.markdown(f"#### ๐Ÿ”น {cat}") cat_tasks = today_tasks[today_tasks['Category'] == cat] for index, row in cat_tasks.iterrows(): c_task, c_status = st.columns([3, 2]) with c_task: if row['Status'] == "Completed": st.markdown(f"โœ… ~~{row['Task']}~~") elif row['Status'] == "Missed": st.markdown(f"โŒ **{row['Task']}**") else: st.markdown(f"**{row['Task']}**") with c_status: options = ["Pending", "Completed", "Missed"] try: default_ix = options.index(row['Status']) except: default_ix = 0 st.radio("Status", options, key=f"status_{index}", index=default_ix, horizontal=True, label_visibility="collapsed") st.write("") if st.form_submit_button("CONFIRM PROGRESS"): # Save changes for index, row in today_tasks.iterrows(): key = f"status_{index}" if key in st.session_state: df.at[index, 'Status'] = st.session_state[key] save_data(df) # 3. NEW YEAR EVE EFFECT LOGIC # Trigger massive celebration on any update to simulate the "Sky at New Year" st.balloons() # Rising crackers st.snow() # Falling glitter/ash from crackers st.toast("๐ŸŽ† ๐Ÿ’ฅ ๐Ÿงจ BOOM! Progress Recorded! ๐Ÿงจ ๐Ÿ’ฅ ๐ŸŽ†", icon="โœจ") current_completed = len(df[(df['Date'] == today_str) & (df['Status'] == "Completed")]) if current_completed == total_today and total_today > 0: st.success("๐Ÿ† EXECUTION COMPLETE! You mastered the day.") else: st.info("Progress updated. Keep pushing.") time.sleep(2) st.rerun() else: st.info("No tasks defined. Start by planning your day above.") # --- TAB 2: PERFORMANCE METRICS --- with tab_analytics: st.header("๐Ÿ“Š Performance Metrics") st.markdown("##### ๐Ÿ—“๏ธ Select Reporting Period") c_date1, c_date2 = st.columns(2) start_date = c_date1.date_input("Start Date") end_date = c_date2.date_input("End Date") st.markdown("---") if not df.empty: mask = (df['Date'] >= str(start_date)) & (df['Date'] <= str(end_date)) filtered_df = df.loc[mask] if not filtered_df.empty: total_all = len(filtered_df) total_done = len(filtered_df[filtered_df['Status'] == "Completed"]) total_missed = len(filtered_df[filtered_df['Status'] == "Missed"]) c1, c2, c3 = st.columns(3) c1.metric("Total Tasks", total_all) c2.metric("Executed (Done)", total_done) c3.metric("Missed (Failed)", total_missed) st.write("") g1, g2 = st.columns(2) with g1: st.subheader("Consistency Chart") daily_stats = filtered_df.groupby(['Date', 'Status']).size().reset_index(name='Count') color_map = { "Completed": "#001f3f", "Missed": "#000000", "Pending": "#808080" } fig_bar = px.bar( daily_stats, x="Date", y="Count", color="Status", barmode="group", color_discrete_map=color_map, title="Daily Execution" ) fig_bar.update_layout(font_family="Times New Roman") st.plotly_chart(fig_bar, use_container_width=True) with g2: st.subheader("Category Breakdown") cat_counts = filtered_df['Category'].value_counts().reset_index() cat_counts.columns = ['Category', 'Count'] fig_pie = px.pie( cat_counts, values='Count', names='Category', hole=0.4, color_discrete_sequence=px.colors.sequential.Blues_r, title="Focus Distribution" ) fig_pie.update_layout(font_family="Times New Roman") st.plotly_chart(fig_pie, use_container_width=True) st.write("### ๐Ÿ“ฅ Download Reports") d1, d2 = st.columns(2) d1.download_button( "Export Excel Log", data=to_excel(filtered_df), file_name=f"Task_Data_{start_date}_{end_date}.xlsx" ) d2.download_button( "Export PDF Report", data=to_pdf(filtered_df, start_date, end_date), file_name=f"Task_Report_{start_date}_{end_date}.pdf" ) else: st.warning(f"No data found between {start_date} and {end_date}.") else: st.info("No data available in database.")