diff --git a/routers/contacts.py b/routers/contacts.py index 56927ff..33bed75 100644 --- a/routers/contacts.py +++ b/routers/contacts.py @@ -32,10 +32,14 @@ async def list_contacts(request: Request, db: AsyncSession = Depends(get_db)): @router.get("/create") async def create_form(request: Request, db: AsyncSession = Depends(get_db)): sidebar = await get_sidebar_data(db) + result = await db.execute(text( + "SELECT id, label, url FROM links WHERE is_deleted = false ORDER BY label" + )) + all_links = [dict(r._mapping) for r in result] return templates.TemplateResponse("contact_form.html", { "request": request, "sidebar": sidebar, "page_title": "New Contact", "active_nav": "contacts", - "item": None, + "item": None, "all_links": all_links, }) @@ -60,8 +64,22 @@ async def create_contact( } if tags and tags.strip(): data["tags"] = [t.strip() for t in tags.split(",") if t.strip()] - await repo.create(data) - return RedirectResponse(url="/contacts", status_code=303) + contact = await repo.create(data) + + # Process link attachments from form + form_data = await request.form() + link_ids = form_data.getlist("link_ids") + link_roles = form_data.getlist("link_roles") + for i, lid in enumerate(link_ids): + if lid and lid.strip(): + lr = link_roles[i] if i < len(link_roles) else None + await db.execute(text(""" + INSERT INTO contact_links (contact_id, link_id, role) + VALUES (:cid, :lid, :role) ON CONFLICT DO NOTHING + """), {"cid": contact["id"], "lid": lid, "role": lr if lr and lr.strip() else None}) + await db.commit() + + return RedirectResponse(url=f"/contacts/{contact['id']}", status_code=303) @router.get("/{contact_id}") @@ -104,16 +122,28 @@ async def edit_form(contact_id: str, request: Request, db: AsyncSession = Depend item = await repo.get(contact_id) if not item: return RedirectResponse(url="/contacts", status_code=303) + result = await db.execute(text( + "SELECT id, label, url FROM links WHERE is_deleted = false ORDER BY label" + )) + all_links = [dict(r._mapping) for r in result] + # Existing linked links + result = await db.execute(text(""" + SELECT l.id, l.label, l.url, cl.role + FROM links l JOIN contact_links cl ON cl.link_id = l.id + WHERE cl.contact_id = :cid AND l.is_deleted = false + """), {"cid": contact_id}) + linked_links = [dict(r._mapping) for r in result] return templates.TemplateResponse("contact_form.html", { "request": request, "sidebar": sidebar, "page_title": "Edit Contact", "active_nav": "contacts", - "item": item, + "item": item, "all_links": all_links, "linked_links": linked_links, }) @router.post("/{contact_id}/edit") async def update_contact( contact_id: str, + request: Request, first_name: str = Form(...), last_name: Optional[str] = Form(None), company: Optional[str] = Form(None), @@ -135,6 +165,22 @@ async def update_contact( else: data["tags"] = None await repo.update(contact_id, data) + + # Sync link attachments + form_data = await request.form() + link_ids = form_data.getlist("link_ids") + link_roles = form_data.getlist("link_roles") + # Clear existing and re-insert + await db.execute(text("DELETE FROM contact_links WHERE contact_id = :cid"), {"cid": contact_id}) + for i, lid in enumerate(link_ids): + if lid and lid.strip(): + lr = link_roles[i] if i < len(link_roles) else None + await db.execute(text(""" + INSERT INTO contact_links (contact_id, link_id, role) + VALUES (:cid, :lid, :role) ON CONFLICT DO NOTHING + """), {"cid": contact_id, "lid": lid, "role": lr if lr and lr.strip() else None}) + await db.commit() + return RedirectResponse(url=f"/contacts/{contact_id}", status_code=303) diff --git a/templates/contact_form.html b/templates/contact_form.html index 36db2f7..0155c29 100644 --- a/templates/contact_form.html +++ b/templates/contact_form.html @@ -13,7 +13,58 @@
-
Cancel
+ + +
+ + + + + +
+ +
Cancel
+ + {% endblock %}