Initial commit
This commit is contained in:
126
routers/contacts.py
Normal file
126
routers/contacts.py
Normal file
@@ -0,0 +1,126 @@
|
||||
"""Contacts: people directory for CRM."""
|
||||
|
||||
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="/contacts", tags=["contacts"])
|
||||
templates = Jinja2Templates(directory="templates")
|
||||
|
||||
|
||||
@router.get("/")
|
||||
async def list_contacts(request: Request, db: AsyncSession = Depends(get_db)):
|
||||
sidebar = await get_sidebar_data(db)
|
||||
result = await db.execute(text("""
|
||||
SELECT * FROM contacts WHERE is_deleted = false
|
||||
ORDER BY sort_order, first_name, last_name
|
||||
"""))
|
||||
items = [dict(r._mapping) for r in result]
|
||||
return templates.TemplateResponse("contacts.html", {
|
||||
"request": request, "sidebar": sidebar, "items": items,
|
||||
"page_title": "Contacts", "active_nav": "contacts",
|
||||
})
|
||||
|
||||
|
||||
@router.get("/create")
|
||||
async def create_form(request: Request, db: AsyncSession = Depends(get_db)):
|
||||
sidebar = await get_sidebar_data(db)
|
||||
return templates.TemplateResponse("contact_form.html", {
|
||||
"request": request, "sidebar": sidebar,
|
||||
"page_title": "New Contact", "active_nav": "contacts",
|
||||
"item": None,
|
||||
})
|
||||
|
||||
|
||||
@router.post("/create")
|
||||
async def create_contact(
|
||||
request: Request,
|
||||
first_name: str = Form(...),
|
||||
last_name: Optional[str] = Form(None),
|
||||
company: Optional[str] = Form(None),
|
||||
role: Optional[str] = Form(None),
|
||||
email: Optional[str] = Form(None),
|
||||
phone: Optional[str] = Form(None),
|
||||
notes: Optional[str] = Form(None),
|
||||
tags: Optional[str] = Form(None),
|
||||
db: AsyncSession = Depends(get_db),
|
||||
):
|
||||
repo = BaseRepository("contacts", db)
|
||||
data = {
|
||||
"first_name": first_name, "last_name": last_name,
|
||||
"company": company, "role": role, "email": email,
|
||||
"phone": phone, "notes": notes,
|
||||
}
|
||||
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)
|
||||
|
||||
|
||||
@router.get("/{contact_id}")
|
||||
async def contact_detail(contact_id: str, request: Request, db: AsyncSession = Depends(get_db)):
|
||||
repo = BaseRepository("contacts", db)
|
||||
sidebar = await get_sidebar_data(db)
|
||||
item = await repo.get(contact_id)
|
||||
if not item:
|
||||
return RedirectResponse(url="/contacts", status_code=303)
|
||||
return templates.TemplateResponse("contact_detail.html", {
|
||||
"request": request, "sidebar": sidebar, "item": item,
|
||||
"page_title": f"{item['first_name']} {item.get('last_name', '')}".strip(),
|
||||
"active_nav": "contacts",
|
||||
})
|
||||
|
||||
|
||||
@router.get("/{contact_id}/edit")
|
||||
async def edit_form(contact_id: str, request: Request, db: AsyncSession = Depends(get_db)):
|
||||
repo = BaseRepository("contacts", db)
|
||||
sidebar = await get_sidebar_data(db)
|
||||
item = await repo.get(contact_id)
|
||||
if not item:
|
||||
return RedirectResponse(url="/contacts", status_code=303)
|
||||
return templates.TemplateResponse("contact_form.html", {
|
||||
"request": request, "sidebar": sidebar,
|
||||
"page_title": "Edit Contact", "active_nav": "contacts",
|
||||
"item": item,
|
||||
})
|
||||
|
||||
|
||||
@router.post("/{contact_id}/edit")
|
||||
async def update_contact(
|
||||
contact_id: str,
|
||||
first_name: str = Form(...),
|
||||
last_name: Optional[str] = Form(None),
|
||||
company: Optional[str] = Form(None),
|
||||
role: Optional[str] = Form(None),
|
||||
email: Optional[str] = Form(None),
|
||||
phone: Optional[str] = Form(None),
|
||||
notes: Optional[str] = Form(None),
|
||||
tags: Optional[str] = Form(None),
|
||||
db: AsyncSession = Depends(get_db),
|
||||
):
|
||||
repo = BaseRepository("contacts", db)
|
||||
data = {
|
||||
"first_name": first_name, "last_name": last_name,
|
||||
"company": company, "role": role, "email": email,
|
||||
"phone": phone, "notes": notes,
|
||||
}
|
||||
if tags and tags.strip():
|
||||
data["tags"] = [t.strip() for t in tags.split(",") if t.strip()]
|
||||
else:
|
||||
data["tags"] = None
|
||||
await repo.update(contact_id, data)
|
||||
return RedirectResponse(url=f"/contacts/{contact_id}", status_code=303)
|
||||
|
||||
|
||||
@router.post("/{contact_id}/delete")
|
||||
async def delete_contact(contact_id: str, db: AsyncSession = Depends(get_db)):
|
||||
repo = BaseRepository("contacts", db)
|
||||
await repo.soft_delete(contact_id)
|
||||
return RedirectResponse(url="/contacts", status_code=303)
|
||||
Reference in New Issue
Block a user