| | import streamlit as st |
| | from datetime import datetime, date |
| |
|
| | |
| | st.set_page_config(page_title="To-Do List Manager", page_icon="β
", layout="centered") |
| |
|
| | |
| | if "tasks" not in st.session_state: |
| | st.session_state.tasks = [] |
| |
|
| | if "edit_mode" not in st.session_state or len(st.session_state.edit_mode) != len(st.session_state.tasks): |
| | st.session_state.edit_mode = [False] * len(st.session_state.tasks) |
| |
|
| | |
| | st.markdown("<h1 style='text-align:center;'>β
To-Do List Manager</h1>", unsafe_allow_html=True) |
| |
|
| | |
| | with st.expander("β Add New Task", expanded=True): |
| | with st.form("add_task_form", clear_on_submit=True): |
| | col1, col2 = st.columns([3, 2]) |
| | task = col1.text_input("Task") |
| | due = col2.date_input("Due Date", value=date.today()) |
| |
|
| | col3, col4 = st.columns([2, 2]) |
| | priority = col3.selectbox("Priority", ["Low", "Medium", "High"]) |
| | category = col4.text_input("Category", placeholder="Work, Study, Personal...") |
| |
|
| | submit = st.form_submit_button("Add Task") |
| | if submit and task.strip(): |
| | st.session_state.tasks.append({ |
| | "task": task.strip(), |
| | "due": due.strftime("%b %d, %Y"), |
| | "priority": priority, |
| | "category": category.strip(), |
| | "completed": False, |
| | "created": datetime.now().strftime("%b %d, %Y") |
| | }) |
| | st.session_state.edit_mode.append(False) |
| |
|
| | st.divider() |
| |
|
| | |
| | st.markdown("### π Filter Tasks") |
| | categories = list({t["category"] for t in st.session_state.tasks if t["category"]}) or ["None"] |
| |
|
| | col1, col2 = st.columns(2) |
| | priority_filter = col1.selectbox("Filter by Priority", ["All", "High", "Medium", "Low"]) |
| | category_filter = col2.selectbox("Filter by Category", ["All"] + categories) |
| |
|
| | def task_matches_filters(task): |
| | pri_match = (priority_filter == "All") or (task["priority"] == priority_filter) |
| | cat_match = (category_filter == "All") or (task["category"] == category_filter) |
| | return pri_match and cat_match |
| |
|
| | filtered_tasks = [t for t in st.session_state.tasks if task_matches_filters(t)] |
| | filtered_tasks_sorted = sorted(filtered_tasks, key=lambda x: not x["completed"]) |
| |
|
| | |
| | st.markdown("### π Your Tasks") |
| | if not filtered_tasks_sorted: |
| | st.info("No tasks match the selected filters.") |
| | else: |
| | for i, task in enumerate(filtered_tasks_sorted): |
| | task_index = st.session_state.tasks.index(task) |
| |
|
| | with st.container(): |
| | st.markdown("---") |
| | cols = st.columns([0.08, 0.6, 0.1, 0.1, 0.1]) |
| |
|
| | |
| | cols[0].checkbox("", value=task["completed"], key=f"complete_{task_index}", |
| | on_change=lambda idx=task_index: st.session_state.tasks.__setitem__(idx, { |
| | **st.session_state.tasks[idx], |
| | "completed": not st.session_state.tasks[idx]["completed"] |
| | })) |
| |
|
| | |
| | if st.session_state.edit_mode[task_index]: |
| | new_task = cols[1].text_input("Edit", value=task["task"], key=f"edit_input_{task_index}") |
| | new_due = cols[1].date_input("Due", value=datetime.strptime(task["due"], "%b %d, %Y").date(), key=f"edit_due_{task_index}") |
| | new_priority = cols[2].selectbox("Priority", ["Low", "Medium", "High"], |
| | index=["Low", "Medium", "High"].index(task["priority"]), key=f"edit_pri_{task_index}") |
| | new_category = cols[3].text_input("Category", value=task["category"], key=f"edit_cat_{task_index}") |
| | cols[4].button("πΎ", key=f"save_{task_index}", on_click=lambda i=task_index, t=new_task, d=new_due, p=new_priority, c=new_category: |
| | ( |
| | st.session_state.tasks.__setitem__(i, { |
| | **st.session_state.tasks[i], |
| | "task": t, |
| | "due": d.strftime("%b %d, %Y"), |
| | "priority": p, |
| | "category": c |
| | }), |
| | st.session_state.edit_mode.__setitem__(i, False) |
| | ) |
| | ) |
| | st.button("β Cancel", key=f"cancel_{task_index}", on_click=lambda i=task_index: st.session_state.edit_mode.__setitem__(i, False)) |
| |
|
| | else: |
| | status = "β
" if task["completed"] else "π²" |
| | task_text = f"~~{task['task']}~~" if task["completed"] else task["task"] |
| | st.markdown(f"**{status} {task_text}**") |
| |
|
| | |
| | if task["completed"]: |
| | st.markdown("<span style='color:green;'>βοΈ Completed</span>", unsafe_allow_html=True) |
| |
|
| | st.markdown(f""" |
| | π
**Due:** {task['due']} |
| | | π― **Priority:** `{task['priority']}` |
| | | ποΈ **Category:** `{task['category'] or 'None'}` |
| | | π **Created:** {task['created']} |
| | """, unsafe_allow_html=True) |
| |
|
| | btn_cols = st.columns([0.2, 0.2]) |
| | btn_cols[0].button("βοΈ Edit", key=f"edit_{task_index}", on_click=lambda i=task_index: st.session_state.edit_mode.__setitem__(i, True)) |
| | btn_cols[1].button("ποΈ Delete", key=f"delete_{task_index}", on_click=lambda i=task_index: ( |
| | st.session_state.tasks.pop(i), |
| | st.session_state.edit_mode.pop(i) |
| | )) |
| |
|
| | st.markdown("---") |
| | st.markdown("<p style='text-align:center; font-size: 13px;'>Built with β€οΈ using Streamlit. Data resets on refresh.</p>", unsafe_allow_html=True) |
| |
|