"""Areas: grouping within domains.""" from fastapi import APIRouter, Request, Form, Depends from fastapi.templating import Jinja2Templates from fastapi.responses import RedirectResponse from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy import text from typing import Optional from core.database import get_db from core.base_repository import BaseRepository from core.sidebar import get_sidebar_data router = APIRouter(prefix="/areas", tags=["areas"]) templates = Jinja2Templates(directory="templates") @router.get("/") async def list_areas( request: Request, domain_id: Optional[str] = None, db: AsyncSession = Depends(get_db), ): repo = BaseRepository("areas", db) sidebar = await get_sidebar_data(db) filters = {} if domain_id: filters["domain_id"] = domain_id result = await db.execute(text(""" SELECT a.*, d.name as domain_name, d.color as domain_color FROM areas a JOIN domains d ON a.domain_id = d.id WHERE a.is_deleted = false ORDER BY d.sort_order, d.name, a.sort_order, a.name """)) items = [dict(r._mapping) for r in result] if domain_id: items = [i for i in items if str(i["domain_id"]) == domain_id] # Get domains for filter/form domains_repo = BaseRepository("domains", db) domains = await domains_repo.list() return templates.TemplateResponse("areas.html", { "request": request, "sidebar": sidebar, "items": items, "domains": domains, "current_domain_id": domain_id or "", "page_title": "Areas", "active_nav": "areas", }) @router.get("/create") async def create_form( request: Request, domain_id: Optional[str] = None, db: AsyncSession = Depends(get_db), ): sidebar = await get_sidebar_data(db) domains_repo = BaseRepository("domains", db) domains = await domains_repo.list() return templates.TemplateResponse("area_form.html", { "request": request, "sidebar": sidebar, "domains": domains, "page_title": "New Area", "active_nav": "areas", "item": None, "prefill_domain_id": domain_id or "", }) @router.post("/create") async def create_area( request: Request, name: str = Form(...), domain_id: str = Form(...), description: Optional[str] = Form(None), status: str = Form("active"), db: AsyncSession = Depends(get_db), ): repo = BaseRepository("areas", db) await repo.create({ "name": name, "domain_id": domain_id, "description": description, "status": status, }) return RedirectResponse(url="/areas", status_code=303) @router.get("/{area_id}/edit") async def edit_form(area_id: str, request: Request, db: AsyncSession = Depends(get_db)): repo = BaseRepository("areas", db) sidebar = await get_sidebar_data(db) item = await repo.get(area_id) if not item: return RedirectResponse(url="/areas", status_code=303) domains_repo = BaseRepository("domains", db) domains = await domains_repo.list() return templates.TemplateResponse("area_form.html", { "request": request, "sidebar": sidebar, "domains": domains, "page_title": f"Edit {item['name']}", "active_nav": "areas", "item": item, "prefill_domain_id": "", }) @router.post("/{area_id}/edit") async def update_area( area_id: str, name: str = Form(...), domain_id: str = Form(...), description: Optional[str] = Form(None), status: str = Form("active"), db: AsyncSession = Depends(get_db), ): repo = BaseRepository("areas", db) await repo.update(area_id, { "name": name, "domain_id": domain_id, "description": description, "status": status, }) return RedirectResponse(url="/areas", status_code=303) @router.post("/{area_id}/delete") async def delete_area(area_id: str, db: AsyncSession = Depends(get_db)): repo = BaseRepository("areas", db) await repo.soft_delete(area_id) return RedirectResponse(url="/areas", status_code=303)