admin panel migration to jinja

This commit is contained in:
2025-10-25 07:31:44 +02:00
parent 13ae656a49
commit 1a43a4250c
21 changed files with 1788 additions and 1599 deletions

View File

@@ -113,6 +113,44 @@ def get_current_admin_user(current_user: User = Depends(get_current_user)):
return auth_manager.require_admin(current_user)
def get_current_vendor_user(current_user: User = Depends(get_current_user)):
"""
Require vendor user (vendor owner or vendor staff).
This dependency ensures the current user has vendor role.
Used for protecting vendor-only routes.
Args:
current_user: User object from get_current_user dependency
Returns:
User: Vendor user object
Raises:
InsufficientPermissionsException: If user is not a vendor user
"""
return auth_manager.require_vendor(current_user)
def get_current_customer_user(current_user: User = Depends(get_current_user)):
"""
Require customer user.
This dependency ensures the current user has customer role.
Used for protecting customer account routes.
Args:
current_user: User object from get_current_user dependency
Returns:
User: Customer user object
Raises:
InsufficientPermissionsException: If user is not a customer
"""
return auth_manager.require_customer(current_user)
def get_user_vendor(
vendor_code: str,
current_user: User = Depends(get_current_user),

View File

@@ -3,17 +3,25 @@
Admin HTML page routes using Jinja2 templates.
These routes return rendered HTML pages (response_class=HTMLResponse).
Separate from other admin routes which return JSON data.
Separate from admin API routes which return JSON data.
All routes require admin authentication except /login.
Authentication failures redirect to /admin/login.
Routes:
- GET / - Admin root (redirects to login)
- GET /login - Admin login page (no auth required)
- GET /dashboard - Admin dashboard (requires auth)
- GET /vendors - Vendor management page (requires auth)
- GET /users - User management page (requires auth)
- GET / → Redirect to /admin/login
- GET /login Admin login page (no auth)
- GET /dashboard Admin dashboard (auth required)
- GET /vendors Vendor list page (auth required)
- GET /vendors/create → Create vendor form (auth required)
- GET /vendors/{vendor_code} → Vendor details (auth required)
- GET /vendors/{vendor_code}/edit → Edit vendor form (auth required)
- GET /users → User management page (auth required)
- GET /imports → Import history page (auth required)
- GET /settings → Settings page (auth required)
"""
from fastapi import APIRouter, Request, Depends
from fastapi import APIRouter, Request, Depends, Path
from fastapi.responses import HTMLResponse, RedirectResponse
from fastapi.templating import Jinja2Templates
from sqlalchemy.orm import Session
@@ -25,18 +33,18 @@ router = APIRouter()
templates = Jinja2Templates(directory="app/templates")
# ============================================================================
# PUBLIC ROUTES (No Authentication Required)
# ============================================================================
@router.get("/", response_class=RedirectResponse, include_in_schema=False)
async def admin_root():
"""
Redirect /admin/ to /admin/login.
This is the simplest approach:
- Unauthenticated users: see login form
- Authenticated users: login page clears token and shows form
(they can manually navigate to dashboard if needed)
Alternative: Could redirect to /admin/dashboard and let auth
dependency handle the redirect, but that's an extra hop.
Simple approach:
- Unauthenticated users see login form
- Authenticated users login page shows form (they can navigate to dashboard)
"""
return RedirectResponse(url="/admin/login", status_code=302)
@@ -53,15 +61,19 @@ async def admin_login_page(request: Request):
)
# ============================================================================
# AUTHENTICATED ROUTES (Admin Only)
# ============================================================================
@router.get("/dashboard", response_class=HTMLResponse, include_in_schema=False)
async def admin_dashboard_page(
request: Request,
current_user: User = Depends(get_current_admin_user),
db: Session = Depends(get_db)
request: Request,
current_user: User = Depends(get_current_admin_user),
db: Session = Depends(get_db)
):
"""
Render admin dashboard page.
Requires admin authentication - will redirect to login if not authenticated.
Shows platform statistics and recent activity.
"""
return templates.TemplateResponse(
"admin/dashboard.html",
@@ -72,15 +84,19 @@ async def admin_dashboard_page(
)
# ============================================================================
# VENDOR MANAGEMENT ROUTES
# ============================================================================
@router.get("/vendors", response_class=HTMLResponse, include_in_schema=False)
async def admin_vendors_page(
request: Request,
current_user: User = Depends(get_current_admin_user),
db: Session = Depends(get_db)
async def admin_vendors_list_page(
request: Request,
current_user: User = Depends(get_current_admin_user),
db: Session = Depends(get_db)
):
"""
Render vendors management page.
Requires admin authentication.
Shows list of all vendors with stats.
"""
return templates.TemplateResponse(
"admin/vendors.html",
@@ -91,15 +107,78 @@ async def admin_vendors_page(
)
@router.get("/vendors/create", response_class=HTMLResponse, include_in_schema=False)
async def admin_vendor_create_page(
request: Request,
current_user: User = Depends(get_current_admin_user),
db: Session = Depends(get_db)
):
"""
Render vendor creation form.
"""
return templates.TemplateResponse(
"admin/vendor-create.html",
{
"request": request,
"user": current_user,
}
)
@router.get("/vendors/{vendor_code}", response_class=HTMLResponse, include_in_schema=False)
async def admin_vendor_detail_page(
request: Request,
vendor_code: str = Path(..., description="Vendor code"),
current_user: User = Depends(get_current_admin_user),
db: Session = Depends(get_db)
):
"""
Render vendor detail page.
Shows full vendor information.
"""
return templates.TemplateResponse(
"admin/vendor-detail.html",
{
"request": request,
"user": current_user,
"vendor_code": vendor_code,
}
)
@router.get("/vendors/{vendor_code}/edit", response_class=HTMLResponse, include_in_schema=False)
async def admin_vendor_edit_page(
request: Request,
vendor_code: str = Path(..., description="Vendor code"),
current_user: User = Depends(get_current_admin_user),
db: Session = Depends(get_db)
):
"""
Render vendor edit form.
"""
return templates.TemplateResponse(
"admin/vendor-edit.html",
{
"request": request,
"user": current_user,
"vendor_code": vendor_code,
}
)
# ============================================================================
# USER MANAGEMENT ROUTES
# ============================================================================
@router.get("/users", response_class=HTMLResponse, include_in_schema=False)
async def admin_users_page(
request: Request,
current_user: User = Depends(get_current_admin_user),
db: Session = Depends(get_db)
request: Request,
current_user: User = Depends(get_current_admin_user),
db: Session = Depends(get_db)
):
"""
Render users management page.
Requires admin authentication.
Shows list of all platform users.
"""
return templates.TemplateResponse(
"admin/users.html",
@@ -108,3 +187,49 @@ async def admin_users_page(
"user": current_user,
}
)
# ============================================================================
# IMPORT MANAGEMENT ROUTES
# ============================================================================
@router.get("/imports", response_class=HTMLResponse, include_in_schema=False)
async def admin_imports_page(
request: Request,
current_user: User = Depends(get_current_admin_user),
db: Session = Depends(get_db)
):
"""
Render imports management page.
Shows import history and status.
"""
return templates.TemplateResponse(
"admin/imports.html",
{
"request": request,
"user": current_user,
}
)
# ============================================================================
# SETTINGS ROUTES
# ============================================================================
@router.get("/settings", response_class=HTMLResponse, include_in_schema=False)
async def admin_settings_page(
request: Request,
current_user: User = Depends(get_current_admin_user),
db: Session = Depends(get_db)
):
"""
Render admin settings page.
Platform configuration and preferences.
"""
return templates.TemplateResponse(
"admin/settings.html",
{
"request": request,
"user": current_user,
}
)