Spaces:
Sleeping
Sleeping
| # app.py | |
| import streamlit as st | |
| import json | |
| from pathlib import Path | |
| from datetime import datetime | |
| import uuid | |
| DATA_FILE = Path("tasks.json") | |
| def load_tasks(): | |
| if DATA_FILE.exists(): | |
| try: | |
| return json.loads(DATA_FILE.read_text()) | |
| except Exception: | |
| return [] | |
| return [] | |
| def save_tasks(tasks): | |
| try: | |
| DATA_FILE.write_text(json.dumps(tasks, indent=2)) | |
| except Exception: | |
| pass | |
| if "tasks" not in st.session_state: | |
| st.session_state.tasks = load_tasks() | |
| st.set_page_config(page_title="Simple Todo", layout="centered") | |
| st.title("π Simple Todo App") | |
| # Add task form | |
| with st.form("add_task", clear_on_submit=True): | |
| new_task = st.text_input("New task") | |
| submitted = st.form_submit_button("Add") | |
| if submitted and new_task.strip(): | |
| st.session_state.tasks.append({ | |
| "id": str(uuid.uuid4()), | |
| "text": new_task.strip(), | |
| "done": False, | |
| "created": datetime.utcnow().isoformat() | |
| }) | |
| save_tasks(st.session_state.tasks) | |
| st.success("Added") | |
| # Summary | |
| col1, col2, col3 = st.columns([1,1,1]) | |
| total = len(st.session_state.tasks) | |
| done = sum(1 for t in st.session_state.tasks if t["done"]) | |
| col1.metric("Total", total) | |
| col2.metric("Completed", done) | |
| if col3.button("Clear completed"): | |
| st.session_state.tasks = [t for t in st.session_state.tasks if not t["done"]] | |
| save_tasks(st.session_state.tasks) | |
| st.markdown("---") | |
| # Filter | |
| filter_opt = st.radio("Show", ("All", "Active", "Completed"), horizontal=True) | |
| # Display tasks (with per-row actions) | |
| if total == 0: | |
| st.info("No tasks yet β add one above!") | |
| else: | |
| for idx, task in enumerate(list(st.session_state.tasks)): | |
| if filter_opt == "Active" and task["done"]: | |
| continue | |
| if filter_opt == "Completed" and not task["done"]: | |
| continue | |
| cols = st.columns([0.05, 0.7, 0.15, 0.1]) | |
| checked = cols[0].checkbox("", value=task["done"], key=f"chk_{task['id']}") | |
| if checked != task["done"]: | |
| st.session_state.tasks[idx]["done"] = checked | |
| save_tasks(st.session_state.tasks) | |
| txt = task["text"] | |
| if task["done"]: | |
| cols[1].markdown(f"~~{txt}~~") | |
| else: | |
| cols[1].markdown(txt) | |
| cols[2].markdown(task["created"][:10]) | |
| if cols[3].button("Delete", key=f"del_{task['id']}"): | |
| st.session_state.tasks.pop(idx) | |
| save_tasks(st.session_state.tasks) | |
| st.experimental_rerun() | |
| st.markdown("---") | |
| c1, c2 = st.columns(2) | |
| if c1.button("Save to file"): | |
| save_tasks(st.session_state.tasks) | |
| st.success("Saved") | |
| if c2.button("Reload from file"): | |
| st.session_state.tasks = load_tasks() | |
| st.success("Reloaded") |