import gradio as gr from datetime import datetime # In-memory storage for todos todos = [] def add_todo(task, priority): if not task.strip(): return todos_to_dataframe(), "❌ Please enter a task!" todos.append({ "id": len(todos) + 1, "task": task.strip(), "priority": priority, "completed": False, "created": datetime.now().strftime("%Y-%m-%d %H:%M") }) return todos_to_dataframe(), f"✅ Added: {task}" def toggle_complete(todo_id): if not todo_id: return todos_to_dataframe(), "❌ Please enter a valid ID" try: idx = int(todo_id) - 1 if 0 <= idx < len(todos): todos[idx]["completed"] = not todos[idx]["completed"] status = "completed" if todos[idx]["completed"] else "uncompleted" return todos_to_dataframe(), f"✅ Task marked as {status}" return todos_to_dataframe(), "❌ Invalid ID" except ValueError: return todos_to_dataframe(), "❌ Please enter a valid number" def delete_todo(todo_id): if not todo_id: return todos_to_dataframe(), "❌ Please enter a valid ID" try: idx = int(todo_id) - 1 if 0 <= idx < len(todos): removed = todos.pop(idx) for i, t in enumerate(todos): t["id"] = i + 1 return todos_to_dataframe(), f"🗑️ Deleted: {removed['task']}" return todos_to_dataframe(), "❌ Invalid ID" except ValueError: return todos_to_dataframe(), "❌ Please enter a valid number" def clear_completed(): global todos count = len([t for t in todos if t["completed"]]) todos = [t for t in todos if not t["completed"]] for i, t in enumerate(todos): t["id"] = i + 1 return todos_to_dataframe(), f"🧹 Cleared {count} completed tasks" def todos_to_dataframe(): if not todos: return [["No tasks yet!", "", "", "", ""]] return [[ t["id"], "✅" if t["completed"] else "⬜", t["task"], {"High": "🔴", "Medium": "🟡", "Low": "🟢"}[t["priority"]], t["created"] ] for t in todos] def get_stats(): total = len(todos) completed = len([t for t in todos if t["completed"]]) pending = total - completed return f"📊 Total: {total} | ✅ Completed: {completed} | ⏳ Pending: {pending}" with gr.Blocks(title="Todo App", theme=gr.themes.Soft()) as demo: gr.Markdown(""" # ✨ Simple Todo App *[Built with anycoder](https://huggingface.co/spaces/akhaliq/anycoder)* """) stats = gr.Markdown(get_stats()) with gr.Row(): task_input = gr.Textbox(label="New Task", placeholder="Enter your task...", scale=3) priority = gr.Dropdown(["High", "Medium", "Low"], value="Medium", label="Priority", scale=1) add_btn = gr.Button("➕ Add", variant="primary", scale=1) todo_table = gr.Dataframe( headers=["ID", "Status", "Task", "Priority", "Created"], value=todos_to_dataframe(), interactive=False, wrap=True ) status_msg = gr.Textbox(label="Status", interactive=False) with gr.Row(): todo_id = gr.Number(label="Task ID", precision=0) toggle_btn = gr.Button("🔄 Toggle Complete") delete_btn = gr.Button("🗑️ Delete", variant="stop") clear_btn = gr.Button("🧹 Clear Completed") def update_all(table, msg): return table, msg, get_stats() add_btn.click(add_todo, [task_input, priority], [todo_table, status_msg]).then( lambda: ("", get_stats()), None, [task_input, stats]) task_input.submit(add_todo, [task_input, priority], [todo_table, status_msg]).then( lambda: ("", get_stats()), None, [task_input, stats]) toggle_btn.click(toggle_complete, todo_id, [todo_table, status_msg]).then( get_stats, None, stats) delete_btn.click(delete_todo, todo_id, [todo_table, status_msg]).then( get_stats, None, stats) clear_btn.click(clear_completed, None, [todo_table, status_msg]).then( get_stats, None, stats) demo.launch()