File size: 8,743 Bytes
c2f9118
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
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()