"""Scheduler page — list tasks + remove.""" import datetime import flet as ft from gui import services as svc def _fmt_ts(ts) -> str: if not ts: return "—" try: return datetime.datetime.fromtimestamp(int(ts)).strftime("%Y-%m-%d %H:%M:%S") except (TypeError, ValueError, OSError): return "—" def build(page: ft.Page) -> ft.Control: list_view = ft.Column(spacing=8, expand=True, scroll=ft.ScrollMode.AUTO) def render(): list_view.controls.clear() tasks = svc.scheduler_all() if not tasks: list_view.controls.append( ft.Text("Запланированных задач нет. Создавай голосом: «Каждые 30 минут напомни попить воды».", color="#8aa0a8")) for t in sorted(tasks, key=lambda x: x.get("created_at", 0)): list_view.controls.append(_task_card(t, on_delete=lambda tid=t["id"]: do_remove(tid))) page.update() def do_remove(task_id: str): if svc.scheduler_remove(task_id): page.open(ft.SnackBar(content=ft.Text("Задача удалена", color="white"), bgcolor="#33d3a4")) render() render() return ft.Column( [ ft.Row([ ft.Text("Расписание", size=24, weight=ft.FontWeight.W_700), ft.FilledButton(text="Обновить", icon=ft.Icons.REFRESH, on_click=lambda e: render()), ], alignment=ft.MainAxisAlignment.SPACE_BETWEEN), list_view, ], spacing=10, expand=True, ) def _task_card(t: dict, on_delete) -> ft.Control: name = t.get("name", "?") sched_h = t.get("schedule_human") or t.get("schedule_kind") or "?" action = t.get("action") or {} action_text = action.get("text") or action.get("speak") or action.get("phrase") or "(нет текста)" return ft.Container( content=ft.Column([ ft.Row([ ft.Text(name, weight=ft.FontWeight.W_600, size=14), ft.Container( content=ft.Text(sched_h, size=10), bgcolor="#1e3a44", padding=ft.padding.symmetric(horizontal=8, vertical=2), border_radius=10, ), ], alignment=ft.MainAxisAlignment.SPACE_BETWEEN), ft.Text(f"Действие: {action_text}", size=11, color="#a8b8c0"), ft.Row([ ft.Text(f"создана: {_fmt_ts(t.get('created_at'))}", size=10, color="#5a6a72"), ft.Text(f"последний запуск: {_fmt_ts(t.get('last_fired'))}", size=10, color="#5a6a72"), ]), ft.Row([ ft.OutlinedButton(text="Удалить", icon=ft.Icons.DELETE, on_click=lambda e: on_delete()), ]), ], spacing=6), bgcolor="#15252b", border_radius=8, padding=12, )