Spaces:
Runtime error
Runtime error
| import streamlit as st | |
| from datetime import datetime, date | |
| import utils | |
| import json | |
| # Set page config | |
| st.set_page_config( | |
| page_title="Todo App", | |
| page_icon="β ", | |
| layout="wide", | |
| initial_sidebar_state="expanded" | |
| ) | |
| # Initialize session state | |
| if 'todos' not in st.session_state: | |
| st.session_state.todos = [] | |
| if 'filter' not in st.session_state: | |
| st.session_state.filter = 'all' | |
| if 'editing_id' not in st.session_state: | |
| st.session_state.editing_id = None | |
| def main(): | |
| # Header with link | |
| col1, col2, col3 = st.columns([1, 2, 1]) | |
| with col2: | |
| st.markdown(""" | |
| <div style='text-align: center; padding: 20px;'> | |
| <h1>π Todo App</h1> | |
| <p style='font-size: 14px; color: #666;'>Built with <a href='https://huggingface.co/spaces/akhaliq/anycoder' target='_blank'>anycoder</a></p> | |
| </div> | |
| """, unsafe_allow_html=True) | |
| # Sidebar for filters and stats | |
| with st.sidebar: | |
| st.header("π Statistics") | |
| stats = utils.get_todo_stats(st.session_state.todos) | |
| st.metric("Total Tasks", stats['total']) | |
| st.metric("Completed", stats['completed']) | |
| st.metric("Pending", stats['pending']) | |
| completion_rate = (stats['completed'] / stats['total'] * 100) if stats['total'] > 0 else 0 | |
| st.metric("Completion Rate", f"{completion_rate:.1f}%") | |
| st.divider() | |
| st.header("π Filter Tasks") | |
| filter_option = st.radio( | |
| "Show:", | |
| ['All Tasks', 'Active Tasks', 'Completed Tasks'], | |
| index=['all', 'active', 'completed'].index(st.session_state.filter) | |
| ) | |
| st.session_state.filter = ['all', 'active', 'completed'][['All Tasks', 'Active Tasks', 'Completed Tasks'].index(filter_option)] | |
| st.divider() | |
| st.header("π― Priority") | |
| priority_filter = st.multiselect( | |
| "Filter by priority:", | |
| ['High', 'Medium', 'Low'], | |
| default=['High', 'Medium', 'Low'] | |
| ) | |
| st.divider() | |
| if st.button("ποΈ Clear Completed", type="secondary"): | |
| st.session_state.todos = utils.clear_completed_todos(st.session_state.todos) | |
| st.rerun() | |
| # Main content area | |
| col1, col2 = st.columns([2, 1]) | |
| with col1: | |
| st.header("π Task List") | |
| # Search bar | |
| search_query = st.text_input("π Search tasks...", placeholder="Type to search...") | |
| # Filter and search todos | |
| filtered_todos = utils.filter_todos(st.session_state.todos, st.session_state.filter, search_query, priority_filter) | |
| if not filtered_todos: | |
| st.info("No tasks found. Add a new task to get started!") | |
| else: | |
| for todo in filtered_todos: | |
| with st.container(): | |
| col_task, col_actions = st.columns([4, 1]) | |
| with col_task: | |
| # Create a unique key for each todo | |
| key = f"todo_{todo['id']}" | |
| # Display todo based on whether it's being edited | |
| if st.session_state.editing_id == todo['id']: | |
| # Edit mode | |
| edited_text = st.text_input( | |
| "Edit task:", | |
| value=todo['text'], | |
| key=f"edit_{todo['id']}" | |
| ) | |
| edited_priority = st.selectbox( | |
| "Priority:", | |
| ['High', 'Medium', 'Low'], | |
| index=['High', 'Medium', 'Low'].index(todo['priority']), | |
| key=f"priority_{todo['id']}" | |
| ) | |
| edited_date = st.date_input( | |
| "Due date:", | |
| value=datetime.strptime(todo['due_date'], '%Y-%m-%d').date(), | |
| key=f"date_{todo['id']}" | |
| ) | |
| col_save, col_cancel = st.columns(2) | |
| with col_save: | |
| if st.button("πΎ Save", key=f"save_{todo['id']}", type="primary"): | |
| st.session_state.todos = utils.update_todo( | |
| st.session_state.todos, | |
| todo['id'], | |
| edited_text, | |
| edited_priority, | |
| edited_date.strftime('%Y-%m-%d') | |
| ) | |
| st.session_state.editing_id = None | |
| st.rerun() | |
| with col_cancel: | |
| if st.button("β Cancel", key=f"cancel_{todo['id']}"): | |
| st.session_state.editing_id = None | |
| st.rerun() | |
| else: | |
| # Display mode | |
| completed = st.checkbox( | |
| todo['text'], | |
| value=todo['completed'], | |
| key=f"check_{todo['id']}", | |
| help=f"Priority: {todo['priority']} | Due: {todo['due_date']}" | |
| ) | |
| if completed != todo['completed']: | |
| st.session_state.todos = utils.toggle_todo(st.session_state.todos, todo['id']) | |
| st.rerun() | |
| # Show priority and due date | |
| priority_color = {'High': 'π΄', 'Medium': 'π‘', 'Low': 'π’'} | |
| st.markdown( | |
| f"<small style='color: #666;'>{priority_color[todo['priority']]} {todo['priority']} Priority | π Due: {todo['due_date']}</small>", | |
| unsafe_allow_html=True | |
| ) | |
| with col_actions: | |
| if not todo['completed'] and st.session_state.editing_id != todo['id']: | |
| if st.button("βοΈ", key=f"edit_btn_{todo['id']}", help="Edit task"): | |
| st.session_state.editing_id = todo['id'] | |
| st.rerun() | |
| if st.button("ποΈ", key=f"delete_{todo['id']}", help="Delete task"): | |
| st.session_state.todos = utils.delete_todo(st.session_state.todos, todo['id']) | |
| st.rerun() | |
| st.divider() | |
| with col2: | |
| st.header("β Add New Task") | |
| with st.form("add_todo_form"): | |
| task_text = st.text_area( | |
| "Task description:", | |
| placeholder="Enter your task here...", | |
| height=100 | |
| ) | |
| priority = st.selectbox( | |
| "Priority:", | |
| ['High', 'Medium', 'Low'], | |
| index=1 | |
| ) | |
| due_date = st.date_input( | |
| "Due date:", | |
| value=date.today() | |
| ) | |
| submit_button = st.form_submit_button("Add Task", type="primary") | |
| if submit_button and task_text.strip(): | |
| new_todo = utils.create_todo( | |
| task_text.strip(), | |
| priority, | |
| due_date.strftime('%Y-%m-%d') | |
| ) | |
| st.session_state.todos.append(new_todo) | |
| st.rerun() | |
| st.success("Task added successfully!") | |
| st.divider() | |
| st.header("π Progress") | |
| if stats['total'] > 0: | |
| # Progress bar | |
| progress_value = stats['completed'] / stats['total'] | |
| st.progress(progress_value) | |
| st.caption(f"{stats['completed']} of {stats['total']} tasks completed") | |
| # Priority breakdown | |
| st.subheader("Priority Breakdown") | |
| priority_stats = utils.get_priority_stats(st.session_state.todos) | |
| for priority in ['High', 'Medium', 'Low']: | |
| if priority_stats[priority] > 0: | |
| st.write(f"π΄ {priority}: {priority_stats[priority]} tasks") | |
| # Footer | |
| st.markdown("---") | |
| st.markdown( | |
| "<div style='text-align: center; color: #666; font-size: 12px;'>" | |
| "π‘ Tip: Click on a task to mark it complete, use the edit button to modify, or delete when done!" | |
| "</div>", | |
| unsafe_allow_html=True | |
| ) | |
| if __name__ == "__main__": | |
| main() |