| import gradio as gr |
| import uuid |
|
|
| |
| def new_item(text): |
| return {"id": str(uuid.uuid4()), "text": text.strip(), "done": False} |
|
|
| def build_choices(items): |
| return [f"{i}:{'β
' if it['done'] else 'β»οΈ '}{it['text']}" for i, it in enumerate(items)] |
|
|
| def parse_idx(choice): |
| return int(choice.split(":", 1)[0]) if choice else None |
|
|
| def progress_html(done, total): |
| pct = int(done / total * 100) if total else 0 |
| return f"<progress value='{done}' max='{total}' style='width:100%'></progress><br>{done}/{total} done ({pct}%)" |
|
|
| def render_ui(state): |
| """Returns CheckboxGroup + HTML for a given state""" |
| ch = build_choices(state) |
| html = "<ul>" |
| for it in state: |
| t = f"<s>{it['text']}</s>" if it["done"] else it["text"] |
| html += f"<li>{t}</li>" |
| html += "</ul>" if state else "<i>No items yet</i>" |
| done = sum(i["done"] for i in state) |
| prog = progress_html(done, len(state)) |
| return gr.update(choices=ch, value=[]), gr.update(value=html + "<br>" + prog) |
|
|
| |
| def add_item(txt, state): |
| if txt.strip(): |
| state.append(new_item(txt)) |
| cbx_update, html_update = render_ui(state) |
| return cbx_update, html_update, gr.update(value=""), state |
|
|
| def toggle_item(selected, state): |
| for s in selected: |
| idx = parse_idx(s) |
| if 0 <= idx < len(state): |
| state[idx]["done"] = not state[idx]["done"] |
| cbx_update, html_update = render_ui(state) |
| return cbx_update, html_update, state |
|
|
| def delete_item(selected, state): |
| idxs = sorted([parse_idx(s) for s in selected], reverse=True) |
| for i in idxs: |
| if 0 <= i < len(state): |
| state.pop(i) |
| cbx_update, html_update = render_ui(state) |
| return cbx_update, html_update, state |
|
|
|
|
| |
| with gr.Blocks(title="To-Do & Habit Tracker") as demo: |
| gr.Markdown("# β
To-Do & Habit Tracker\nKeep your daily routine organized!") |
|
|
| with gr.Row(): |
| |
| with gr.Column(): |
| gr.Markdown("### π To-Do Tasks") |
| task_input = gr.Textbox(label="Add a new task") |
| add_task_btn = gr.Button("β Add Task") |
| todo_box = gr.CheckboxGroup(label="Tasks") |
| toggle_task_btn = gr.Button("βοΈ Toggle Complete") |
| del_task_btn = gr.Button("ποΈ Delete Selected") |
| todo_html = gr.HTML() |
| todo_state = gr.State([]) |
|
|
| |
| with gr.Column(): |
| gr.Markdown("### π Daily Habits") |
| habit_input = gr.Textbox(label="Add a new habit") |
| add_habit_btn = gr.Button("β Add Habit") |
| habit_box = gr.CheckboxGroup(label="Habits") |
| toggle_habit_btn = gr.Button("βοΈ Toggle Complete") |
| del_habit_btn = gr.Button("ποΈ Delete Selected") |
| habit_html = gr.HTML() |
| habit_state = gr.State([]) |
|
|
| |
| add_task_btn.click(add_item, [task_input, todo_state], [todo_box, todo_html, task_input, todo_state]) |
| toggle_task_btn.click(toggle_item, [todo_box, todo_state], [todo_box, todo_html, todo_state]) |
| del_task_btn.click(delete_item, [todo_box, todo_state], [todo_box, todo_html, todo_state]) |
|
|
| |
| add_habit_btn.click(add_item, [habit_input, habit_state], [habit_box, habit_html, habit_input, habit_state]) |
| toggle_habit_btn.click(toggle_item, [habit_box, habit_state], [habit_box, habit_html, habit_state]) |
| del_habit_btn.click(delete_item, [habit_box, habit_state], [habit_box, habit_html, habit_state]) |
|
|
| |
| def init(): |
| cbx1, html1 = render_ui([]) |
| cbx2, html2 = render_ui([]) |
| return cbx1, html1, cbx2, html2, [], [] |
|
|
| demo.load(init, None, [todo_box, todo_html, habit_box, habit_html, todo_state, habit_state]) |
|
|
| demo.launch() |
|
|