from fastapi import APIRouter, Request from fastapi.responses import HTMLResponse from fastapi.templating import Jinja2Templates from sqlalchemy import func, select from app.database import async_session_factory from app.models.payment import Payment, PaymentStatus from app.models.server import Server from app.models.tariff import Tariff from app.models.user import User from app.repositories.payment import PaymentRepository from app.repositories.server import ServerRepository from app.repositories.tariff import TariffRepository from app.repositories.user import UserRepository router = APIRouter(prefix="/admin", tags=["admin"]) templates = Jinja2Templates(directory="app/templates") router = APIRouter(prefix="/admin", tags=["admin"]) templates = Jinja2Templates(directory="app/templates") @router.get("/", response_class=HTMLResponse) async def dashboard(request: Request): async with async_session_factory() as session: async def _count(model, *filters): stmt = select(func.count(model.id)) for f in filters: stmt = stmt.where(f) return (await session.execute(stmt)).scalar_one() total_users = await _count(User) active_users = await _count(User, User.is_active.is_(True)) total_tariffs = await _count(Tariff) total_servers = await _count(Server) active_servers = await _count(Server, Server.is_active.is_(True)) total_payments = await _count(Payment) confirmed_payments = await _count( Payment, Payment.status == PaymentStatus.CONFIRMED ) rev_stmt = select(func.coalesce(func.sum(Payment.amount), 0)).where( Payment.status == PaymentStatus.CONFIRMED ) total_revenue = float((await session.execute(rev_stmt)).scalar_one()) return templates.TemplateResponse( "dashboard.html", { "request": request, "total_users": total_users, "active_users": active_users, "total_tariffs": total_tariffs, "total_servers": total_servers, "active_servers": active_servers, "total_payments": total_payments, "confirmed_payments": confirmed_payments, "total_revenue": total_revenue, }, ) @router.get("/users", response_class=HTMLResponse) async def users_page(request: Request): async with async_session_factory() as session: repo = UserRepository(session) users = await repo.get_all() return templates.TemplateResponse( "users.html", {"request": request, "users": users}, ) @router.get("/payments", response_class=HTMLResponse) async def payments_page(request: Request): async with async_session_factory() as session: tariff_repo = TariffRepository(session) stmt = select(Payment).order_by(Payment.created_at.desc()) result = await session.execute(stmt) payments = list(result.scalars().all()) tariffs_map = {} for p in payments: if p.tariff_id not in tariffs_map: t = await tariff_repo.get(p.tariff_id) tariffs_map[p.tariff_id] = t.name if t else "—" return templates.TemplateResponse( "payments.html", {"request": request, "payments": payments, "tariffs_map": tariffs_map}, ) @router.get("/servers", response_class=HTMLResponse) async def servers_page(request: Request): async with async_session_factory() as session: repo = ServerRepository(session) servers = await repo.get_all() return templates.TemplateResponse( "servers.html", {"request": request, "servers": servers}, ) @router.get("/tariffs", response_class=HTMLResponse) async def tariffs_page(request: Request): async with async_session_factory() as session: repo = TariffRepository(session) tariffs = await repo.get_all() return templates.TemplateResponse( "tariffs.html", {"request": request, "tariffs": tariffs}, )