"""Eisenhower Matrix: read-only 2x2 priority/urgency grid of open tasks.""" from fastapi import APIRouter, Request, Depends from fastapi.templating import Jinja2Templates from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy import text from core.database import get_db from core.sidebar import get_sidebar_data router = APIRouter(prefix="/eisenhower", tags=["eisenhower"]) templates = Jinja2Templates(directory="templates") @router.get("/") async def eisenhower_matrix( request: Request, db: AsyncSession = Depends(get_db), ): sidebar = await get_sidebar_data(db) result = await db.execute(text(""" SELECT t.id, t.title, t.priority, t.status, t.due_date, t.context, t.estimated_minutes, p.name as project_name, d.name as domain_name, d.color as domain_color FROM tasks t LEFT JOIN projects p ON t.project_id = p.id LEFT JOIN domains d ON t.domain_id = d.id WHERE t.is_deleted = false AND t.status IN ('open', 'in_progress', 'blocked') ORDER BY t.priority, t.due_date NULLS LAST, t.title """)) tasks = [dict(r._mapping) for r in result] # Classify into quadrants from datetime import date, timedelta today = date.today() urgent_cutoff = today + timedelta(days=7) quadrants = { "do_first": [], # Urgent + Important "schedule": [], # Not Urgent + Important "delegate": [], # Urgent + Not Important "eliminate": [], # Not Urgent + Not Important } for t in tasks: important = t["priority"] in (1, 2) urgent = ( t["due_date"] is not None and t["due_date"] <= urgent_cutoff ) if important and urgent: quadrants["do_first"].append(t) elif important and not urgent: quadrants["schedule"].append(t) elif not important and urgent: quadrants["delegate"].append(t) else: quadrants["eliminate"].append(t) counts = {k: len(v) for k, v in quadrants.items()} total = sum(counts.values()) return templates.TemplateResponse("eisenhower.html", { "request": request, "sidebar": sidebar, "quadrants": quadrants, "counts": counts, "total": total, "today": today, "page_title": "Eisenhower Matrix", "active_nav": "eisenhower", })