akhaliq HF Staff commited on
Commit
3004372
Β·
verified Β·
1 Parent(s): f82b788

Deploy from anycoder

Browse files
Files changed (3) hide show
  1. app.py +184 -0
  2. requirements.txt +1 -0
  3. utils.py +3 -0
app.py ADDED
@@ -0,0 +1,184 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import json
3
+ import os
4
+ from datetime import datetime
5
+ from typing import List, Dict
6
+
7
+ # File to persist todos
8
+ TODO_FILE = "todos.json"
9
+
10
+ def load_todos() -> List[Dict]:
11
+ """Load todos from JSON file"""
12
+ if os.path.exists(TODO_FILE):
13
+ try:
14
+ with open(TODO_FILE, 'r') as f:
15
+ return json.load(f)
16
+ except:
17
+ return []
18
+ return []
19
+
20
+ def save_todos(todos: List[Dict]):
21
+ """Save todos to JSON file"""
22
+ try:
23
+ with open(TODO_FILE, 'w') as f:
24
+ json.dump(todos, f, indent=2)
25
+ except Exception:
26
+ pass # Silently fail on save issues
27
+
28
+ def add_todo(task: str, priority: int) -> tuple[List[Dict], str]:
29
+ """Add a new todo item"""
30
+ if not task.strip():
31
+ return load_todos(), "Please enter a task!"
32
+
33
+ todos = load_todos()
34
+ new_todo = {
35
+ "id": len(todos) + 1,
36
+ "task": task.strip(),
37
+ "priority": priority,
38
+ "completed": False,
39
+ "created": datetime.now().isoformat()
40
+ }
41
+ todos.insert(0, new_todo) # Add to top
42
+ save_todos(todos)
43
+ return todos, f"Added: '{task}'"
44
+
45
+ def toggle_todo(todo_id: int) -> List[Dict]:
46
+ """Toggle todo completion status"""
47
+ todos = load_todos()
48
+ for todo in todos:
49
+ if todo["id"] == todo_id:
50
+ todo["completed"] = not todo["completed"]
51
+ break
52
+ save_todos(todos)
53
+ return todos
54
+
55
+ def delete_todo(todo_id: int) -> List[Dict]:
56
+ """Delete a todo item"""
57
+ todos = load_todos()
58
+ todos = [todo for todo in todos if todo["id"] != todo_id]
59
+ save_todos(todos)
60
+ return todos
61
+
62
+ def get_todos_display(todos: List[Dict]) -> str:
63
+ """Format todos for display"""
64
+ if not todos:
65
+ return "πŸŽ‰ No todos! Great job!"
66
+
67
+ lines = []
68
+ for todo in todos:
69
+ status = "βœ…" if todo["completed"] else "⏳"
70
+ priority_emoji = "πŸ”₯" if todo["priority"] == 3 else "⚑" if todo["priority"] == 2 else "πŸ“"
71
+ lines.append(f"{status} {priority_emoji} {todo['task']}")
72
+
73
+ return "\n".join(lines)
74
+
75
+ def clear_completed() -> List[Dict]:
76
+ """Remove all completed todos"""
77
+ todos = [todo for todo in load_todos() if not todo["completed"]]
78
+ save_todos(todos)
79
+ return todos
80
+
81
+ # Load initial todos
82
+ initial_todos = load_todos()
83
+
84
+ with gr.Blocks(
85
+ title="πŸš€ Todo App",
86
+ theme=gr.themes.Soft(),
87
+ css="""
88
+ .todo-item { margin: 8px 0; padding: 12px; border-radius: 8px; background: var(--neutral-100); }
89
+ .priority-high { border-left: 4px solid #ef4444; }
90
+ .priority-medium { border-left: 4px solid #f59e0b; }
91
+ .priority-low { border-left: 4px solid #10b981; }
92
+ """
93
+ ) as demo:
94
+
95
+ gr.Markdown(
96
+ """
97
+ # πŸš€ My Todo App
98
+ Add, complete, and manage your tasks with priority levels!
99
+
100
+ <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px;">
101
+ <span></span>
102
+ <a href="https://huggingface.co/spaces/akhaliq/anycoder" target="_blank" style="color: #666; font-size: 12px;">
103
+ Built with anycoder
104
+ </a>
105
+ </div>
106
+ """,
107
+ elem_id="header"
108
+ )
109
+
110
+ with gr.Row():
111
+ with gr.Column(scale=1):
112
+ task_input = gr.Textbox(
113
+ label="New Task",
114
+ placeholder="What needs to be done?",
115
+ lines=2,
116
+ max_lines=3
117
+ )
118
+
119
+ priority_slider = gr.Slider(
120
+ minimum=1,
121
+ maximum=3,
122
+ value=2,
123
+ step=1,
124
+ label="Priority",
125
+ info="1=Low πŸ“, 2=Medium ⚑, 3=High πŸ”₯"
126
+ )
127
+
128
+ with gr.Row():
129
+ add_btn = gr.Button("βž• Add Task", variant="primary", scale=1)
130
+ clear_btn = gr.Button("πŸ—‘οΈ Clear Completed", scale=1)
131
+
132
+ status_msg = gr.Textbox(
133
+ label="Status",
134
+ interactive=False,
135
+ scale=1
136
+ )
137
+
138
+ with gr.Column(scale=2):
139
+ todos_display = gr.Markdown(
140
+ get_todos_display(initial_todos),
141
+ label="Your Todos"
142
+ )
143
+
144
+ # Examples
145
+ gr.Examples(
146
+ examples=[
147
+ ["Buy groceries", 2],
148
+ ["Finish project report", 3],
149
+ ["Call mom", 1]
150
+ ],
151
+ inputs=[task_input, priority_slider],
152
+ label="Quick Examples"
153
+ )
154
+
155
+ # Event handlers
156
+ add_btn.click(
157
+ add_todo,
158
+ inputs=[task_input, priority_slider],
159
+ outputs=[todos_display, status_msg]
160
+ ).then(
161
+ lambda: gr.update(value=""),
162
+ outputs=[task_input]
163
+ )
164
+
165
+ clear_btn.click(
166
+ clear_completed,
167
+ outputs=[todos_display, status_msg]
168
+ ).then(
169
+ lambda: gr.update(value=""),
170
+ outputs=[status_msg]
171
+ )
172
+
173
+ # Clear status after 3 seconds
174
+ def clear_status():
175
+ return gr.update(value="")
176
+
177
+ status_msg.change(
178
+ clear_status,
179
+ outputs=[status_msg],
180
+ show_progress=False
181
+ )
182
+
183
+ if __name__ == "__main__":
184
+ demo.launch()
requirements.txt ADDED
@@ -0,0 +1 @@
 
 
1
+ gradio>=4.0.0
utils.py ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ # No additional utility functions needed for this simple todo app
2
+ # All logic is contained in app.py for simplicity
3
+ pass