style: apply black and isort formatting across entire codebase
- Standardize quote style (single to double quotes) - Reorder and group imports alphabetically - Fix line breaks and indentation for consistency - Apply PEP 8 formatting standards Also updated Makefile to exclude both venv and .venv from code quality checks. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -30,17 +30,15 @@ Routes:
|
||||
- GET /code-quality/violations/{violation_id} → Violation details (auth required)
|
||||
"""
|
||||
|
||||
from fastapi import APIRouter, Request, Depends, Path
|
||||
from typing import Optional
|
||||
|
||||
from fastapi import APIRouter, Depends, Path, Request
|
||||
from fastapi.responses import HTMLResponse, RedirectResponse
|
||||
from fastapi.templating import Jinja2Templates
|
||||
from sqlalchemy.orm import Session
|
||||
from typing import Optional
|
||||
|
||||
from app.api.deps import (
|
||||
get_current_admin_from_cookie_or_header,
|
||||
get_current_admin_optional,
|
||||
get_db
|
||||
)
|
||||
from app.api.deps import (get_current_admin_from_cookie_or_header,
|
||||
get_current_admin_optional, get_db)
|
||||
from models.database.user import User
|
||||
|
||||
router = APIRouter()
|
||||
@@ -51,9 +49,10 @@ templates = Jinja2Templates(directory="app/templates")
|
||||
# PUBLIC ROUTES (No Authentication Required)
|
||||
# ============================================================================
|
||||
|
||||
|
||||
@router.get("/", response_class=RedirectResponse, include_in_schema=False)
|
||||
async def admin_root(
|
||||
current_user: Optional[User] = Depends(get_current_admin_optional)
|
||||
current_user: Optional[User] = Depends(get_current_admin_optional),
|
||||
):
|
||||
"""
|
||||
Redirect /admin/ based on authentication status.
|
||||
@@ -70,8 +69,7 @@ async def admin_root(
|
||||
|
||||
@router.get("/login", response_class=HTMLResponse, include_in_schema=False)
|
||||
async def admin_login_page(
|
||||
request: Request,
|
||||
current_user: Optional[User] = Depends(get_current_admin_optional)
|
||||
request: Request, current_user: Optional[User] = Depends(get_current_admin_optional)
|
||||
):
|
||||
"""
|
||||
Render admin login page.
|
||||
@@ -83,21 +81,19 @@ async def admin_login_page(
|
||||
# User is already logged in as admin, redirect to dashboard
|
||||
return RedirectResponse(url="/admin/dashboard", status_code=302)
|
||||
|
||||
return templates.TemplateResponse(
|
||||
"admin/login.html",
|
||||
{"request": request}
|
||||
)
|
||||
return templates.TemplateResponse("admin/login.html", {"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_from_cookie_or_header),
|
||||
db: Session = Depends(get_db)
|
||||
request: Request,
|
||||
current_user: User = Depends(get_current_admin_from_cookie_or_header),
|
||||
db: Session = Depends(get_db),
|
||||
):
|
||||
"""
|
||||
Render admin dashboard page.
|
||||
@@ -108,7 +104,7 @@ async def admin_dashboard_page(
|
||||
{
|
||||
"request": request,
|
||||
"user": current_user,
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
@@ -116,11 +112,12 @@ async def admin_dashboard_page(
|
||||
# VENDOR MANAGEMENT ROUTES
|
||||
# ============================================================================
|
||||
|
||||
|
||||
@router.get("/vendors", response_class=HTMLResponse, include_in_schema=False)
|
||||
async def admin_vendors_list_page(
|
||||
request: Request,
|
||||
current_user: User = Depends(get_current_admin_from_cookie_or_header),
|
||||
db: Session = Depends(get_db)
|
||||
request: Request,
|
||||
current_user: User = Depends(get_current_admin_from_cookie_or_header),
|
||||
db: Session = Depends(get_db),
|
||||
):
|
||||
"""
|
||||
Render vendors management page.
|
||||
@@ -131,15 +128,15 @@ async def admin_vendors_list_page(
|
||||
{
|
||||
"request": request,
|
||||
"user": current_user,
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
@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_from_cookie_or_header),
|
||||
db: Session = Depends(get_db)
|
||||
request: Request,
|
||||
current_user: User = Depends(get_current_admin_from_cookie_or_header),
|
||||
db: Session = Depends(get_db),
|
||||
):
|
||||
"""
|
||||
Render vendor creation form.
|
||||
@@ -149,16 +146,18 @@ async def admin_vendor_create_page(
|
||||
{
|
||||
"request": request,
|
||||
"user": current_user,
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
@router.get("/vendors/{vendor_code}", response_class=HTMLResponse, include_in_schema=False)
|
||||
@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_from_cookie_or_header),
|
||||
db: Session = Depends(get_db)
|
||||
request: Request,
|
||||
vendor_code: str = Path(..., description="Vendor code"),
|
||||
current_user: User = Depends(get_current_admin_from_cookie_or_header),
|
||||
db: Session = Depends(get_db),
|
||||
):
|
||||
"""
|
||||
Render vendor detail page.
|
||||
@@ -170,16 +169,18 @@ async def admin_vendor_detail_page(
|
||||
"request": request,
|
||||
"user": current_user,
|
||||
"vendor_code": vendor_code,
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
@router.get("/vendors/{vendor_code}/edit", response_class=HTMLResponse, include_in_schema=False)
|
||||
@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_from_cookie_or_header),
|
||||
db: Session = Depends(get_db)
|
||||
request: Request,
|
||||
vendor_code: str = Path(..., description="Vendor code"),
|
||||
current_user: User = Depends(get_current_admin_from_cookie_or_header),
|
||||
db: Session = Depends(get_db),
|
||||
):
|
||||
"""
|
||||
Render vendor edit form.
|
||||
@@ -190,7 +191,7 @@ async def admin_vendor_edit_page(
|
||||
"request": request,
|
||||
"user": current_user,
|
||||
"vendor_code": vendor_code,
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
@@ -198,12 +199,17 @@ async def admin_vendor_edit_page(
|
||||
# VENDOR DOMAINS ROUTES
|
||||
# ============================================================================
|
||||
|
||||
@router.get("/vendors/{vendor_code}/domains", response_class=HTMLResponse, include_in_schema=False)
|
||||
|
||||
@router.get(
|
||||
"/vendors/{vendor_code}/domains",
|
||||
response_class=HTMLResponse,
|
||||
include_in_schema=False,
|
||||
)
|
||||
async def admin_vendor_domains_page(
|
||||
request: Request,
|
||||
vendor_code: str = Path(..., description="Vendor code"),
|
||||
current_user: User = Depends(get_current_admin_from_cookie_or_header),
|
||||
db: Session = Depends(get_db)
|
||||
request: Request,
|
||||
vendor_code: str = Path(..., description="Vendor code"),
|
||||
current_user: User = Depends(get_current_admin_from_cookie_or_header),
|
||||
db: Session = Depends(get_db),
|
||||
):
|
||||
"""
|
||||
Render vendor domains management page.
|
||||
@@ -215,7 +221,7 @@ async def admin_vendor_domains_page(
|
||||
"request": request,
|
||||
"user": current_user,
|
||||
"vendor_code": vendor_code,
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
@@ -223,12 +229,15 @@ async def admin_vendor_domains_page(
|
||||
# VENDOR THEMES ROUTES
|
||||
# ============================================================================
|
||||
|
||||
@router.get("/vendors/{vendor_code}/theme", response_class=HTMLResponse, include_in_schema=False)
|
||||
|
||||
@router.get(
|
||||
"/vendors/{vendor_code}/theme", response_class=HTMLResponse, include_in_schema=False
|
||||
)
|
||||
async def admin_vendor_theme_page(
|
||||
request: Request,
|
||||
vendor_code: str = Path(..., description="Vendor code"),
|
||||
current_user: User = Depends(get_current_admin_from_cookie_or_header),
|
||||
db: Session = Depends(get_db)
|
||||
request: Request,
|
||||
vendor_code: str = Path(..., description="Vendor code"),
|
||||
current_user: User = Depends(get_current_admin_from_cookie_or_header),
|
||||
db: Session = Depends(get_db),
|
||||
):
|
||||
"""
|
||||
Render vendor theme customization page.
|
||||
@@ -240,7 +249,7 @@ async def admin_vendor_theme_page(
|
||||
"request": request,
|
||||
"user": current_user,
|
||||
"vendor_code": vendor_code,
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
@@ -248,11 +257,12 @@ async def admin_vendor_theme_page(
|
||||
# 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_from_cookie_or_header),
|
||||
db: Session = Depends(get_db)
|
||||
request: Request,
|
||||
current_user: User = Depends(get_current_admin_from_cookie_or_header),
|
||||
db: Session = Depends(get_db),
|
||||
):
|
||||
"""
|
||||
Render users management page.
|
||||
@@ -263,7 +273,7 @@ async def admin_users_page(
|
||||
{
|
||||
"request": request,
|
||||
"user": current_user,
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
@@ -271,11 +281,12 @@ async def admin_users_page(
|
||||
# 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_from_cookie_or_header),
|
||||
db: Session = Depends(get_db)
|
||||
request: Request,
|
||||
current_user: User = Depends(get_current_admin_from_cookie_or_header),
|
||||
db: Session = Depends(get_db),
|
||||
):
|
||||
"""
|
||||
Render imports management page.
|
||||
@@ -286,7 +297,7 @@ async def admin_imports_page(
|
||||
{
|
||||
"request": request,
|
||||
"user": current_user,
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
@@ -294,11 +305,12 @@ async def admin_imports_page(
|
||||
# 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_from_cookie_or_header),
|
||||
db: Session = Depends(get_db)
|
||||
request: Request,
|
||||
current_user: User = Depends(get_current_admin_from_cookie_or_header),
|
||||
db: Session = Depends(get_db),
|
||||
):
|
||||
"""
|
||||
Render admin settings page.
|
||||
@@ -309,7 +321,7 @@ async def admin_settings_page(
|
||||
{
|
||||
"request": request,
|
||||
"user": current_user,
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
@@ -317,11 +329,12 @@ async def admin_settings_page(
|
||||
# CONTENT MANAGEMENT SYSTEM (CMS) ROUTES
|
||||
# ============================================================================
|
||||
|
||||
|
||||
@router.get("/platform-homepage", response_class=HTMLResponse, include_in_schema=False)
|
||||
async def admin_platform_homepage_manager(
|
||||
request: Request,
|
||||
current_user: User = Depends(get_current_admin_from_cookie_or_header),
|
||||
db: Session = Depends(get_db)
|
||||
request: Request,
|
||||
current_user: User = Depends(get_current_admin_from_cookie_or_header),
|
||||
db: Session = Depends(get_db),
|
||||
):
|
||||
"""
|
||||
Render platform homepage manager.
|
||||
@@ -332,15 +345,15 @@ async def admin_platform_homepage_manager(
|
||||
{
|
||||
"request": request,
|
||||
"user": current_user,
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
@router.get("/content-pages", response_class=HTMLResponse, include_in_schema=False)
|
||||
async def admin_content_pages_list(
|
||||
request: Request,
|
||||
current_user: User = Depends(get_current_admin_from_cookie_or_header),
|
||||
db: Session = Depends(get_db)
|
||||
request: Request,
|
||||
current_user: User = Depends(get_current_admin_from_cookie_or_header),
|
||||
db: Session = Depends(get_db),
|
||||
):
|
||||
"""
|
||||
Render content pages list.
|
||||
@@ -351,15 +364,17 @@ async def admin_content_pages_list(
|
||||
{
|
||||
"request": request,
|
||||
"user": current_user,
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
@router.get("/content-pages/create", response_class=HTMLResponse, include_in_schema=False)
|
||||
@router.get(
|
||||
"/content-pages/create", response_class=HTMLResponse, include_in_schema=False
|
||||
)
|
||||
async def admin_content_page_create(
|
||||
request: Request,
|
||||
current_user: User = Depends(get_current_admin_from_cookie_or_header),
|
||||
db: Session = Depends(get_db)
|
||||
request: Request,
|
||||
current_user: User = Depends(get_current_admin_from_cookie_or_header),
|
||||
db: Session = Depends(get_db),
|
||||
):
|
||||
"""
|
||||
Render create content page form.
|
||||
@@ -371,16 +386,20 @@ async def admin_content_page_create(
|
||||
"request": request,
|
||||
"user": current_user,
|
||||
"page_id": None, # Indicates this is a create operation
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
@router.get("/content-pages/{page_id}/edit", response_class=HTMLResponse, include_in_schema=False)
|
||||
@router.get(
|
||||
"/content-pages/{page_id}/edit",
|
||||
response_class=HTMLResponse,
|
||||
include_in_schema=False,
|
||||
)
|
||||
async def admin_content_page_edit(
|
||||
request: Request,
|
||||
page_id: int = Path(..., description="Content page ID"),
|
||||
current_user: User = Depends(get_current_admin_from_cookie_or_header),
|
||||
db: Session = Depends(get_db)
|
||||
request: Request,
|
||||
page_id: int = Path(..., description="Content page ID"),
|
||||
current_user: User = Depends(get_current_admin_from_cookie_or_header),
|
||||
db: Session = Depends(get_db),
|
||||
):
|
||||
"""
|
||||
Render edit content page form.
|
||||
@@ -392,7 +411,7 @@ async def admin_content_page_edit(
|
||||
"request": request,
|
||||
"user": current_user,
|
||||
"page_id": page_id,
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
@@ -400,11 +419,12 @@ async def admin_content_page_edit(
|
||||
# DEVELOPER TOOLS - COMPONENTS & TESTING
|
||||
# ============================================================================
|
||||
|
||||
|
||||
@router.get("/components", response_class=HTMLResponse, include_in_schema=False)
|
||||
async def admin_components_page(
|
||||
request: Request,
|
||||
current_user: User = Depends(get_current_admin_from_cookie_or_header),
|
||||
db: Session = Depends(get_db)
|
||||
request: Request,
|
||||
current_user: User = Depends(get_current_admin_from_cookie_or_header),
|
||||
db: Session = Depends(get_db),
|
||||
):
|
||||
"""
|
||||
Render UI components library page.
|
||||
@@ -415,7 +435,7 @@ async def admin_components_page(
|
||||
{
|
||||
"request": request,
|
||||
"user": current_user,
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
@@ -423,7 +443,7 @@ async def admin_components_page(
|
||||
async def admin_icons_page(
|
||||
request: Request,
|
||||
current_user: User = Depends(get_current_admin_from_cookie_or_header),
|
||||
db: Session = Depends(get_db)
|
||||
db: Session = Depends(get_db),
|
||||
):
|
||||
"""
|
||||
Render icons browser page.
|
||||
@@ -434,15 +454,15 @@ async def admin_icons_page(
|
||||
{
|
||||
"request": request,
|
||||
"user": current_user,
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
@router.get("/testing", response_class=HTMLResponse, include_in_schema=False)
|
||||
async def admin_testing_hub(
|
||||
request: Request,
|
||||
current_user: User = Depends(get_current_admin_from_cookie_or_header),
|
||||
db: Session = Depends(get_db)
|
||||
request: Request,
|
||||
current_user: User = Depends(get_current_admin_from_cookie_or_header),
|
||||
db: Session = Depends(get_db),
|
||||
):
|
||||
"""
|
||||
Render testing hub page.
|
||||
@@ -453,15 +473,15 @@ async def admin_testing_hub(
|
||||
{
|
||||
"request": request,
|
||||
"user": current_user,
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
@router.get("/test/auth-flow", response_class=HTMLResponse, include_in_schema=False)
|
||||
async def admin_test_auth_flow(
|
||||
request: Request,
|
||||
current_user: User = Depends(get_current_admin_from_cookie_or_header),
|
||||
db: Session = Depends(get_db)
|
||||
request: Request,
|
||||
current_user: User = Depends(get_current_admin_from_cookie_or_header),
|
||||
db: Session = Depends(get_db),
|
||||
):
|
||||
"""
|
||||
Render authentication flow testing page.
|
||||
@@ -472,15 +492,19 @@ async def admin_test_auth_flow(
|
||||
{
|
||||
"request": request,
|
||||
"user": current_user,
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
@router.get("/test/vendors-users-migration", response_class=HTMLResponse, include_in_schema=False)
|
||||
@router.get(
|
||||
"/test/vendors-users-migration",
|
||||
response_class=HTMLResponse,
|
||||
include_in_schema=False,
|
||||
)
|
||||
async def admin_test_vendors_users_migration(
|
||||
request: Request,
|
||||
current_user: User = Depends(get_current_admin_from_cookie_or_header),
|
||||
db: Session = Depends(get_db)
|
||||
request: Request,
|
||||
current_user: User = Depends(get_current_admin_from_cookie_or_header),
|
||||
db: Session = Depends(get_db),
|
||||
):
|
||||
"""
|
||||
Render vendors and users migration testing page.
|
||||
@@ -491,7 +515,7 @@ async def admin_test_vendors_users_migration(
|
||||
{
|
||||
"request": request,
|
||||
"user": current_user,
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
@@ -499,11 +523,12 @@ async def admin_test_vendors_users_migration(
|
||||
# CODE QUALITY & ARCHITECTURE ROUTES
|
||||
# ============================================================================
|
||||
|
||||
|
||||
@router.get("/code-quality", response_class=HTMLResponse, include_in_schema=False)
|
||||
async def admin_code_quality_dashboard(
|
||||
request: Request,
|
||||
current_user: User = Depends(get_current_admin_from_cookie_or_header),
|
||||
db: Session = Depends(get_db)
|
||||
request: Request,
|
||||
current_user: User = Depends(get_current_admin_from_cookie_or_header),
|
||||
db: Session = Depends(get_db),
|
||||
):
|
||||
"""
|
||||
Render code quality dashboard.
|
||||
@@ -514,15 +539,17 @@ async def admin_code_quality_dashboard(
|
||||
{
|
||||
"request": request,
|
||||
"user": current_user,
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
@router.get("/code-quality/violations", response_class=HTMLResponse, include_in_schema=False)
|
||||
@router.get(
|
||||
"/code-quality/violations", response_class=HTMLResponse, include_in_schema=False
|
||||
)
|
||||
async def admin_code_quality_violations(
|
||||
request: Request,
|
||||
current_user: User = Depends(get_current_admin_from_cookie_or_header),
|
||||
db: Session = Depends(get_db)
|
||||
request: Request,
|
||||
current_user: User = Depends(get_current_admin_from_cookie_or_header),
|
||||
db: Session = Depends(get_db),
|
||||
):
|
||||
"""
|
||||
Render violations list page.
|
||||
@@ -533,16 +560,20 @@ async def admin_code_quality_violations(
|
||||
{
|
||||
"request": request,
|
||||
"user": current_user,
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
@router.get("/code-quality/violations/{violation_id}", response_class=HTMLResponse, include_in_schema=False)
|
||||
@router.get(
|
||||
"/code-quality/violations/{violation_id}",
|
||||
response_class=HTMLResponse,
|
||||
include_in_schema=False,
|
||||
)
|
||||
async def admin_code_quality_violation_detail(
|
||||
request: Request,
|
||||
violation_id: int = Path(..., description="Violation ID"),
|
||||
current_user: User = Depends(get_current_admin_from_cookie_or_header),
|
||||
db: Session = Depends(get_db)
|
||||
request: Request,
|
||||
violation_id: int = Path(..., description="Violation ID"),
|
||||
current_user: User = Depends(get_current_admin_from_cookie_or_header),
|
||||
db: Session = Depends(get_db),
|
||||
):
|
||||
"""
|
||||
Render violation detail page.
|
||||
@@ -554,5 +585,5 @@ async def admin_code_quality_violation_detail(
|
||||
"request": request,
|
||||
"user": current_user,
|
||||
"violation_id": violation_id,
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
@@ -31,7 +31,8 @@ Routes (all mounted at /shop/* or /vendors/{code}/shop/* prefix):
|
||||
"""
|
||||
|
||||
import logging
|
||||
from fastapi import APIRouter, Request, Depends, Path
|
||||
|
||||
from fastapi import APIRouter, Depends, Path, Request
|
||||
from fastapi.responses import HTMLResponse, RedirectResponse
|
||||
from fastapi.templating import Jinja2Templates
|
||||
from sqlalchemy.orm import Session
|
||||
@@ -50,6 +51,7 @@ logger = logging.getLogger(__name__)
|
||||
# HELPER: Build Shop Template Context
|
||||
# ============================================================================
|
||||
|
||||
|
||||
def get_shop_context(request: Request, db: Session = None, **extra_context) -> dict:
|
||||
"""
|
||||
Build template context for shop pages.
|
||||
@@ -76,13 +78,17 @@ def get_shop_context(request: Request, db: Session = None, **extra_context) -> d
|
||||
get_shop_context(request, db=db, user=current_user, product_id=123)
|
||||
"""
|
||||
# Extract from middleware state
|
||||
vendor = getattr(request.state, 'vendor', None)
|
||||
theme = getattr(request.state, 'theme', None)
|
||||
clean_path = getattr(request.state, 'clean_path', request.url.path)
|
||||
vendor_context = getattr(request.state, 'vendor_context', None)
|
||||
vendor = getattr(request.state, "vendor", None)
|
||||
theme = getattr(request.state, "theme", None)
|
||||
clean_path = getattr(request.state, "clean_path", request.url.path)
|
||||
vendor_context = getattr(request.state, "vendor_context", None)
|
||||
|
||||
# Get detection method from vendor_context
|
||||
access_method = vendor_context.get('detection_method', 'unknown') if vendor_context else 'unknown'
|
||||
access_method = (
|
||||
vendor_context.get("detection_method", "unknown")
|
||||
if vendor_context
|
||||
else "unknown"
|
||||
)
|
||||
|
||||
if vendor is None:
|
||||
logger.warning(
|
||||
@@ -91,7 +97,7 @@ def get_shop_context(request: Request, db: Session = None, **extra_context) -> d
|
||||
"path": request.url.path,
|
||||
"host": request.headers.get("host", ""),
|
||||
"has_vendor": False,
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
# Calculate base URL for links
|
||||
@@ -100,7 +106,11 @@ def get_shop_context(request: Request, db: Session = None, **extra_context) -> d
|
||||
base_url = "/"
|
||||
if access_method == "path" and vendor:
|
||||
# Use the full_prefix from vendor_context to determine which pattern was used
|
||||
full_prefix = vendor_context.get('full_prefix', '/vendor/') if vendor_context else '/vendor/'
|
||||
full_prefix = (
|
||||
vendor_context.get("full_prefix", "/vendor/")
|
||||
if vendor_context
|
||||
else "/vendor/"
|
||||
)
|
||||
base_url = f"{full_prefix}{vendor.subdomain}/"
|
||||
|
||||
# Load footer navigation pages from CMS if db session provided
|
||||
@@ -111,22 +121,16 @@ def get_shop_context(request: Request, db: Session = None, **extra_context) -> d
|
||||
vendor_id = vendor.id
|
||||
# Get pages configured to show in footer
|
||||
footer_pages = content_page_service.list_pages_for_vendor(
|
||||
db,
|
||||
vendor_id=vendor_id,
|
||||
footer_only=True,
|
||||
include_unpublished=False
|
||||
db, vendor_id=vendor_id, footer_only=True, include_unpublished=False
|
||||
)
|
||||
# Get pages configured to show in header
|
||||
header_pages = content_page_service.list_pages_for_vendor(
|
||||
db,
|
||||
vendor_id=vendor_id,
|
||||
header_only=True,
|
||||
include_unpublished=False
|
||||
db, vendor_id=vendor_id, header_only=True, include_unpublished=False
|
||||
)
|
||||
except Exception as e:
|
||||
logger.error(
|
||||
f"[SHOP_CONTEXT] Failed to load navigation pages",
|
||||
extra={"error": str(e), "vendor_id": vendor.id if vendor else None}
|
||||
extra={"error": str(e), "vendor_id": vendor.id if vendor else None},
|
||||
)
|
||||
|
||||
context = {
|
||||
@@ -156,7 +160,7 @@ def get_shop_context(request: Request, db: Session = None, **extra_context) -> d
|
||||
"footer_pages_count": len(footer_pages),
|
||||
"header_pages_count": len(header_pages),
|
||||
"extra_keys": list(extra_context.keys()) if extra_context else [],
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
return context
|
||||
@@ -166,6 +170,7 @@ def get_shop_context(request: Request, db: Session = None, **extra_context) -> d
|
||||
# PUBLIC SHOP ROUTES (No Authentication Required)
|
||||
# ============================================================================
|
||||
|
||||
|
||||
@router.get("/", response_class=HTMLResponse, include_in_schema=False)
|
||||
@router.get("/products", response_class=HTMLResponse, include_in_schema=False)
|
||||
async def shop_products_page(request: Request, db: Session = Depends(get_db)):
|
||||
@@ -177,21 +182,21 @@ async def shop_products_page(request: Request, db: Session = Depends(get_db)):
|
||||
f"[SHOP_HANDLER] shop_products_page REACHED",
|
||||
extra={
|
||||
"path": request.url.path,
|
||||
"vendor": getattr(request.state, 'vendor', 'NOT SET'),
|
||||
"context": getattr(request.state, 'context_type', 'NOT SET'),
|
||||
}
|
||||
"vendor": getattr(request.state, "vendor", "NOT SET"),
|
||||
"context": getattr(request.state, "context_type", "NOT SET"),
|
||||
},
|
||||
)
|
||||
|
||||
return templates.TemplateResponse(
|
||||
"shop/products.html",
|
||||
get_shop_context(request, db=db)
|
||||
"shop/products.html", get_shop_context(request, db=db)
|
||||
)
|
||||
|
||||
|
||||
@router.get("/products/{product_id}", response_class=HTMLResponse, include_in_schema=False)
|
||||
@router.get(
|
||||
"/products/{product_id}", response_class=HTMLResponse, include_in_schema=False
|
||||
)
|
||||
async def shop_product_detail_page(
|
||||
request: Request,
|
||||
product_id: int = Path(..., description="Product ID")
|
||||
request: Request, product_id: int = Path(..., description="Product ID")
|
||||
):
|
||||
"""
|
||||
Render product detail page.
|
||||
@@ -201,21 +206,21 @@ async def shop_product_detail_page(
|
||||
f"[SHOP_HANDLER] shop_products_page REACHED",
|
||||
extra={
|
||||
"path": request.url.path,
|
||||
"vendor": getattr(request.state, 'vendor', 'NOT SET'),
|
||||
"context": getattr(request.state, 'context_type', 'NOT SET'),
|
||||
}
|
||||
"vendor": getattr(request.state, "vendor", "NOT SET"),
|
||||
"context": getattr(request.state, "context_type", "NOT SET"),
|
||||
},
|
||||
)
|
||||
|
||||
return templates.TemplateResponse(
|
||||
"shop/product.html",
|
||||
get_shop_context(request, product_id=product_id)
|
||||
"shop/product.html", get_shop_context(request, product_id=product_id)
|
||||
)
|
||||
|
||||
|
||||
@router.get("/categories/{category_slug}", response_class=HTMLResponse, include_in_schema=False)
|
||||
@router.get(
|
||||
"/categories/{category_slug}", response_class=HTMLResponse, include_in_schema=False
|
||||
)
|
||||
async def shop_category_page(
|
||||
request: Request,
|
||||
category_slug: str = Path(..., description="Category slug")
|
||||
request: Request, category_slug: str = Path(..., description="Category slug")
|
||||
):
|
||||
"""
|
||||
Render category products page.
|
||||
@@ -225,14 +230,13 @@ async def shop_category_page(
|
||||
f"[SHOP_HANDLER] shop_products_page REACHED",
|
||||
extra={
|
||||
"path": request.url.path,
|
||||
"vendor": getattr(request.state, 'vendor', 'NOT SET'),
|
||||
"context": getattr(request.state, 'context_type', 'NOT SET'),
|
||||
}
|
||||
"vendor": getattr(request.state, "vendor", "NOT SET"),
|
||||
"context": getattr(request.state, "context_type", "NOT SET"),
|
||||
},
|
||||
)
|
||||
|
||||
return templates.TemplateResponse(
|
||||
"shop/category.html",
|
||||
get_shop_context(request, category_slug=category_slug)
|
||||
"shop/category.html", get_shop_context(request, category_slug=category_slug)
|
||||
)
|
||||
|
||||
|
||||
@@ -246,15 +250,12 @@ async def shop_cart_page(request: Request):
|
||||
f"[SHOP_HANDLER] shop_products_page REACHED",
|
||||
extra={
|
||||
"path": request.url.path,
|
||||
"vendor": getattr(request.state, 'vendor', 'NOT SET'),
|
||||
"context": getattr(request.state, 'context_type', 'NOT SET'),
|
||||
}
|
||||
"vendor": getattr(request.state, "vendor", "NOT SET"),
|
||||
"context": getattr(request.state, "context_type", "NOT SET"),
|
||||
},
|
||||
)
|
||||
|
||||
return templates.TemplateResponse(
|
||||
"shop/cart.html",
|
||||
get_shop_context(request)
|
||||
)
|
||||
return templates.TemplateResponse("shop/cart.html", get_shop_context(request))
|
||||
|
||||
|
||||
@router.get("/checkout", response_class=HTMLResponse, include_in_schema=False)
|
||||
@@ -267,15 +268,12 @@ async def shop_checkout_page(request: Request):
|
||||
f"[SHOP_HANDLER] shop_products_page REACHED",
|
||||
extra={
|
||||
"path": request.url.path,
|
||||
"vendor": getattr(request.state, 'vendor', 'NOT SET'),
|
||||
"context": getattr(request.state, 'context_type', 'NOT SET'),
|
||||
}
|
||||
"vendor": getattr(request.state, "vendor", "NOT SET"),
|
||||
"context": getattr(request.state, "context_type", "NOT SET"),
|
||||
},
|
||||
)
|
||||
|
||||
return templates.TemplateResponse(
|
||||
"shop/checkout.html",
|
||||
get_shop_context(request)
|
||||
)
|
||||
return templates.TemplateResponse("shop/checkout.html", get_shop_context(request))
|
||||
|
||||
|
||||
@router.get("/search", response_class=HTMLResponse, include_in_schema=False)
|
||||
@@ -288,21 +286,19 @@ async def shop_search_page(request: Request):
|
||||
f"[SHOP_HANDLER] shop_products_page REACHED",
|
||||
extra={
|
||||
"path": request.url.path,
|
||||
"vendor": getattr(request.state, 'vendor', 'NOT SET'),
|
||||
"context": getattr(request.state, 'context_type', 'NOT SET'),
|
||||
}
|
||||
"vendor": getattr(request.state, "vendor", "NOT SET"),
|
||||
"context": getattr(request.state, "context_type", "NOT SET"),
|
||||
},
|
||||
)
|
||||
|
||||
return templates.TemplateResponse(
|
||||
"shop/search.html",
|
||||
get_shop_context(request)
|
||||
)
|
||||
return templates.TemplateResponse("shop/search.html", get_shop_context(request))
|
||||
|
||||
|
||||
# ============================================================================
|
||||
# CUSTOMER ACCOUNT - PUBLIC ROUTES (No Authentication)
|
||||
# ============================================================================
|
||||
|
||||
|
||||
@router.get("/account/register", response_class=HTMLResponse, include_in_schema=False)
|
||||
async def shop_register_page(request: Request):
|
||||
"""
|
||||
@@ -313,14 +309,13 @@ async def shop_register_page(request: Request):
|
||||
f"[SHOP_HANDLER] shop_products_page REACHED",
|
||||
extra={
|
||||
"path": request.url.path,
|
||||
"vendor": getattr(request.state, 'vendor', 'NOT SET'),
|
||||
"context": getattr(request.state, 'context_type', 'NOT SET'),
|
||||
}
|
||||
"vendor": getattr(request.state, "vendor", "NOT SET"),
|
||||
"context": getattr(request.state, "context_type", "NOT SET"),
|
||||
},
|
||||
)
|
||||
|
||||
return templates.TemplateResponse(
|
||||
"shop/account/register.html",
|
||||
get_shop_context(request)
|
||||
"shop/account/register.html", get_shop_context(request)
|
||||
)
|
||||
|
||||
|
||||
@@ -334,18 +329,19 @@ async def shop_login_page(request: Request):
|
||||
f"[SHOP_HANDLER] shop_products_page REACHED",
|
||||
extra={
|
||||
"path": request.url.path,
|
||||
"vendor": getattr(request.state, 'vendor', 'NOT SET'),
|
||||
"context": getattr(request.state, 'context_type', 'NOT SET'),
|
||||
}
|
||||
"vendor": getattr(request.state, "vendor", "NOT SET"),
|
||||
"context": getattr(request.state, "context_type", "NOT SET"),
|
||||
},
|
||||
)
|
||||
|
||||
return templates.TemplateResponse(
|
||||
"shop/account/login.html",
|
||||
get_shop_context(request)
|
||||
"shop/account/login.html", get_shop_context(request)
|
||||
)
|
||||
|
||||
|
||||
@router.get("/account/forgot-password", response_class=HTMLResponse, include_in_schema=False)
|
||||
@router.get(
|
||||
"/account/forgot-password", response_class=HTMLResponse, include_in_schema=False
|
||||
)
|
||||
async def shop_forgot_password_page(request: Request):
|
||||
"""
|
||||
Render forgot password page.
|
||||
@@ -355,14 +351,13 @@ async def shop_forgot_password_page(request: Request):
|
||||
f"[SHOP_HANDLER] shop_products_page REACHED",
|
||||
extra={
|
||||
"path": request.url.path,
|
||||
"vendor": getattr(request.state, 'vendor', 'NOT SET'),
|
||||
"context": getattr(request.state, 'context_type', 'NOT SET'),
|
||||
}
|
||||
"vendor": getattr(request.state, "vendor", "NOT SET"),
|
||||
"context": getattr(request.state, "context_type", "NOT SET"),
|
||||
},
|
||||
)
|
||||
|
||||
return templates.TemplateResponse(
|
||||
"shop/account/forgot-password.html",
|
||||
get_shop_context(request)
|
||||
"shop/account/forgot-password.html", get_shop_context(request)
|
||||
)
|
||||
|
||||
|
||||
@@ -370,6 +365,7 @@ async def shop_forgot_password_page(request: Request):
|
||||
# CUSTOMER ACCOUNT - AUTHENTICATED ROUTES
|
||||
# ============================================================================
|
||||
|
||||
|
||||
@router.get("/account", response_class=RedirectResponse, include_in_schema=False)
|
||||
@router.get("/account/", response_class=RedirectResponse, include_in_schema=False)
|
||||
async def shop_account_root(request: Request):
|
||||
@@ -380,19 +376,27 @@ async def shop_account_root(request: Request):
|
||||
f"[SHOP_HANDLER] shop_products_page REACHED",
|
||||
extra={
|
||||
"path": request.url.path,
|
||||
"vendor": getattr(request.state, 'vendor', 'NOT SET'),
|
||||
"context": getattr(request.state, 'context_type', 'NOT SET'),
|
||||
}
|
||||
"vendor": getattr(request.state, "vendor", "NOT SET"),
|
||||
"context": getattr(request.state, "context_type", "NOT SET"),
|
||||
},
|
||||
)
|
||||
|
||||
# Get base_url from context for proper redirect
|
||||
vendor = getattr(request.state, 'vendor', None)
|
||||
vendor_context = getattr(request.state, 'vendor_context', None)
|
||||
access_method = vendor_context.get('detection_method', 'unknown') if vendor_context else 'unknown'
|
||||
vendor = getattr(request.state, "vendor", None)
|
||||
vendor_context = getattr(request.state, "vendor_context", None)
|
||||
access_method = (
|
||||
vendor_context.get("detection_method", "unknown")
|
||||
if vendor_context
|
||||
else "unknown"
|
||||
)
|
||||
|
||||
base_url = "/"
|
||||
if access_method == "path" and vendor:
|
||||
full_prefix = vendor_context.get('full_prefix', '/vendor/') if vendor_context else '/vendor/'
|
||||
full_prefix = (
|
||||
vendor_context.get("full_prefix", "/vendor/")
|
||||
if vendor_context
|
||||
else "/vendor/"
|
||||
)
|
||||
base_url = f"{full_prefix}{vendor.subdomain}/"
|
||||
|
||||
return RedirectResponse(url=f"{base_url}shop/account/dashboard", status_code=302)
|
||||
@@ -400,9 +404,9 @@ async def shop_account_root(request: Request):
|
||||
|
||||
@router.get("/account/dashboard", response_class=HTMLResponse, include_in_schema=False)
|
||||
async def shop_account_dashboard_page(
|
||||
request: Request,
|
||||
current_customer: Customer = Depends(get_current_customer_from_cookie_or_header),
|
||||
db: Session = Depends(get_db)
|
||||
request: Request,
|
||||
current_customer: Customer = Depends(get_current_customer_from_cookie_or_header),
|
||||
db: Session = Depends(get_db),
|
||||
):
|
||||
"""
|
||||
Render customer account dashboard.
|
||||
@@ -413,22 +417,21 @@ async def shop_account_dashboard_page(
|
||||
f"[SHOP_HANDLER] shop_products_page REACHED",
|
||||
extra={
|
||||
"path": request.url.path,
|
||||
"vendor": getattr(request.state, 'vendor', 'NOT SET'),
|
||||
"context": getattr(request.state, 'context_type', 'NOT SET'),
|
||||
}
|
||||
"vendor": getattr(request.state, "vendor", "NOT SET"),
|
||||
"context": getattr(request.state, "context_type", "NOT SET"),
|
||||
},
|
||||
)
|
||||
|
||||
return templates.TemplateResponse(
|
||||
"shop/account/dashboard.html",
|
||||
get_shop_context(request, user=current_customer)
|
||||
"shop/account/dashboard.html", get_shop_context(request, user=current_customer)
|
||||
)
|
||||
|
||||
|
||||
@router.get("/account/orders", response_class=HTMLResponse, include_in_schema=False)
|
||||
async def shop_orders_page(
|
||||
request: Request,
|
||||
current_customer: Customer = Depends(get_current_customer_from_cookie_or_header),
|
||||
db: Session = Depends(get_db)
|
||||
request: Request,
|
||||
current_customer: Customer = Depends(get_current_customer_from_cookie_or_header),
|
||||
db: Session = Depends(get_db),
|
||||
):
|
||||
"""
|
||||
Render customer orders history page.
|
||||
@@ -439,23 +442,24 @@ async def shop_orders_page(
|
||||
f"[SHOP_HANDLER] shop_products_page REACHED",
|
||||
extra={
|
||||
"path": request.url.path,
|
||||
"vendor": getattr(request.state, 'vendor', 'NOT SET'),
|
||||
"context": getattr(request.state, 'context_type', 'NOT SET'),
|
||||
}
|
||||
"vendor": getattr(request.state, "vendor", "NOT SET"),
|
||||
"context": getattr(request.state, "context_type", "NOT SET"),
|
||||
},
|
||||
)
|
||||
|
||||
return templates.TemplateResponse(
|
||||
"shop/account/orders.html",
|
||||
get_shop_context(request, user=current_customer)
|
||||
"shop/account/orders.html", get_shop_context(request, user=current_customer)
|
||||
)
|
||||
|
||||
|
||||
@router.get("/account/orders/{order_id}", response_class=HTMLResponse, include_in_schema=False)
|
||||
@router.get(
|
||||
"/account/orders/{order_id}", response_class=HTMLResponse, include_in_schema=False
|
||||
)
|
||||
async def shop_order_detail_page(
|
||||
request: Request,
|
||||
order_id: int = Path(..., description="Order ID"),
|
||||
current_customer: Customer = Depends(get_current_customer_from_cookie_or_header),
|
||||
db: Session = Depends(get_db)
|
||||
request: Request,
|
||||
order_id: int = Path(..., description="Order ID"),
|
||||
current_customer: Customer = Depends(get_current_customer_from_cookie_or_header),
|
||||
db: Session = Depends(get_db),
|
||||
):
|
||||
"""
|
||||
Render customer order detail page.
|
||||
@@ -466,22 +470,22 @@ async def shop_order_detail_page(
|
||||
f"[SHOP_HANDLER] shop_products_page REACHED",
|
||||
extra={
|
||||
"path": request.url.path,
|
||||
"vendor": getattr(request.state, 'vendor', 'NOT SET'),
|
||||
"context": getattr(request.state, 'context_type', 'NOT SET'),
|
||||
}
|
||||
"vendor": getattr(request.state, "vendor", "NOT SET"),
|
||||
"context": getattr(request.state, "context_type", "NOT SET"),
|
||||
},
|
||||
)
|
||||
|
||||
return templates.TemplateResponse(
|
||||
"shop/account/order-detail.html",
|
||||
get_shop_context(request, user=current_customer, order_id=order_id)
|
||||
get_shop_context(request, user=current_customer, order_id=order_id),
|
||||
)
|
||||
|
||||
|
||||
@router.get("/account/profile", response_class=HTMLResponse, include_in_schema=False)
|
||||
async def shop_profile_page(
|
||||
request: Request,
|
||||
current_customer: Customer = Depends(get_current_customer_from_cookie_or_header),
|
||||
db: Session = Depends(get_db)
|
||||
request: Request,
|
||||
current_customer: Customer = Depends(get_current_customer_from_cookie_or_header),
|
||||
db: Session = Depends(get_db),
|
||||
):
|
||||
"""
|
||||
Render customer profile page.
|
||||
@@ -492,22 +496,21 @@ async def shop_profile_page(
|
||||
f"[SHOP_HANDLER] shop_products_page REACHED",
|
||||
extra={
|
||||
"path": request.url.path,
|
||||
"vendor": getattr(request.state, 'vendor', 'NOT SET'),
|
||||
"context": getattr(request.state, 'context_type', 'NOT SET'),
|
||||
}
|
||||
"vendor": getattr(request.state, "vendor", "NOT SET"),
|
||||
"context": getattr(request.state, "context_type", "NOT SET"),
|
||||
},
|
||||
)
|
||||
|
||||
return templates.TemplateResponse(
|
||||
"shop/account/profile.html",
|
||||
get_shop_context(request, user=current_customer)
|
||||
"shop/account/profile.html", get_shop_context(request, user=current_customer)
|
||||
)
|
||||
|
||||
|
||||
@router.get("/account/addresses", response_class=HTMLResponse, include_in_schema=False)
|
||||
async def shop_addresses_page(
|
||||
request: Request,
|
||||
current_customer: Customer = Depends(get_current_customer_from_cookie_or_header),
|
||||
db: Session = Depends(get_db)
|
||||
request: Request,
|
||||
current_customer: Customer = Depends(get_current_customer_from_cookie_or_header),
|
||||
db: Session = Depends(get_db),
|
||||
):
|
||||
"""
|
||||
Render customer addresses management page.
|
||||
@@ -518,22 +521,21 @@ async def shop_addresses_page(
|
||||
f"[SHOP_HANDLER] shop_products_page REACHED",
|
||||
extra={
|
||||
"path": request.url.path,
|
||||
"vendor": getattr(request.state, 'vendor', 'NOT SET'),
|
||||
"context": getattr(request.state, 'context_type', 'NOT SET'),
|
||||
}
|
||||
"vendor": getattr(request.state, "vendor", "NOT SET"),
|
||||
"context": getattr(request.state, "context_type", "NOT SET"),
|
||||
},
|
||||
)
|
||||
|
||||
return templates.TemplateResponse(
|
||||
"shop/account/addresses.html",
|
||||
get_shop_context(request, user=current_customer)
|
||||
"shop/account/addresses.html", get_shop_context(request, user=current_customer)
|
||||
)
|
||||
|
||||
|
||||
@router.get("/account/wishlist", response_class=HTMLResponse, include_in_schema=False)
|
||||
async def shop_wishlist_page(
|
||||
request: Request,
|
||||
current_customer: Customer = Depends(get_current_customer_from_cookie_or_header),
|
||||
db: Session = Depends(get_db)
|
||||
request: Request,
|
||||
current_customer: Customer = Depends(get_current_customer_from_cookie_or_header),
|
||||
db: Session = Depends(get_db),
|
||||
):
|
||||
"""
|
||||
Render customer wishlist page.
|
||||
@@ -544,22 +546,21 @@ async def shop_wishlist_page(
|
||||
f"[SHOP_HANDLER] shop_products_page REACHED",
|
||||
extra={
|
||||
"path": request.url.path,
|
||||
"vendor": getattr(request.state, 'vendor', 'NOT SET'),
|
||||
"context": getattr(request.state, 'context_type', 'NOT SET'),
|
||||
}
|
||||
"vendor": getattr(request.state, "vendor", "NOT SET"),
|
||||
"context": getattr(request.state, "context_type", "NOT SET"),
|
||||
},
|
||||
)
|
||||
|
||||
return templates.TemplateResponse(
|
||||
"shop/account/wishlist.html",
|
||||
get_shop_context(request, user=current_customer)
|
||||
"shop/account/wishlist.html", get_shop_context(request, user=current_customer)
|
||||
)
|
||||
|
||||
|
||||
@router.get("/account/settings", response_class=HTMLResponse, include_in_schema=False)
|
||||
async def shop_settings_page(
|
||||
request: Request,
|
||||
current_customer: Customer = Depends(get_current_customer_from_cookie_or_header),
|
||||
db: Session = Depends(get_db)
|
||||
request: Request,
|
||||
current_customer: Customer = Depends(get_current_customer_from_cookie_or_header),
|
||||
db: Session = Depends(get_db),
|
||||
):
|
||||
"""
|
||||
Render customer account settings page.
|
||||
@@ -570,14 +571,13 @@ async def shop_settings_page(
|
||||
f"[SHOP_HANDLER] shop_products_page REACHED",
|
||||
extra={
|
||||
"path": request.url.path,
|
||||
"vendor": getattr(request.state, 'vendor', 'NOT SET'),
|
||||
"context": getattr(request.state, 'context_type', 'NOT SET'),
|
||||
}
|
||||
"vendor": getattr(request.state, "vendor", "NOT SET"),
|
||||
"context": getattr(request.state, "context_type", "NOT SET"),
|
||||
},
|
||||
)
|
||||
|
||||
return templates.TemplateResponse(
|
||||
"shop/account/settings.html",
|
||||
get_shop_context(request, user=current_customer)
|
||||
"shop/account/settings.html", get_shop_context(request, user=current_customer)
|
||||
)
|
||||
|
||||
|
||||
@@ -585,11 +585,12 @@ async def shop_settings_page(
|
||||
# DYNAMIC CONTENT PAGES (CMS)
|
||||
# ============================================================================
|
||||
|
||||
|
||||
@router.get("/{slug}", response_class=HTMLResponse, include_in_schema=False)
|
||||
async def generic_content_page(
|
||||
request: Request,
|
||||
slug: str = Path(..., description="Content page slug"),
|
||||
db: Session = Depends(get_db)
|
||||
db: Session = Depends(get_db),
|
||||
):
|
||||
"""
|
||||
Generic content page handler (CMS).
|
||||
@@ -612,20 +613,17 @@ async def generic_content_page(
|
||||
extra={
|
||||
"path": request.url.path,
|
||||
"slug": slug,
|
||||
"vendor": getattr(request.state, 'vendor', 'NOT SET'),
|
||||
"context": getattr(request.state, 'context_type', 'NOT SET'),
|
||||
}
|
||||
"vendor": getattr(request.state, "vendor", "NOT SET"),
|
||||
"context": getattr(request.state, "context_type", "NOT SET"),
|
||||
},
|
||||
)
|
||||
|
||||
vendor = getattr(request.state, 'vendor', None)
|
||||
vendor = getattr(request.state, "vendor", None)
|
||||
vendor_id = vendor.id if vendor else None
|
||||
|
||||
# Load content page from database (vendor override → platform default)
|
||||
page = content_page_service.get_page_for_vendor(
|
||||
db,
|
||||
slug=slug,
|
||||
vendor_id=vendor_id,
|
||||
include_unpublished=False
|
||||
db, slug=slug, vendor_id=vendor_id, include_unpublished=False
|
||||
)
|
||||
|
||||
if not page:
|
||||
@@ -635,7 +633,7 @@ async def generic_content_page(
|
||||
"slug": slug,
|
||||
"vendor_id": vendor_id,
|
||||
"vendor_name": vendor.name if vendor else None,
|
||||
}
|
||||
},
|
||||
)
|
||||
raise HTTPException(status_code=404, detail=f"Page not found: {slug}")
|
||||
|
||||
@@ -647,12 +645,11 @@ async def generic_content_page(
|
||||
"page_title": page.title,
|
||||
"is_vendor_override": page.vendor_id is not None,
|
||||
"vendor_id": vendor_id,
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
return templates.TemplateResponse(
|
||||
"shop/content-page.html",
|
||||
get_shop_context(request, page=page)
|
||||
"shop/content-page.html", get_shop_context(request, page=page)
|
||||
)
|
||||
|
||||
|
||||
@@ -660,6 +657,7 @@ async def generic_content_page(
|
||||
# DEBUG ENDPOINTS - For troubleshooting context issues
|
||||
# ============================================================================
|
||||
|
||||
|
||||
@router.get("/debug/context", response_class=HTMLResponse, include_in_schema=False)
|
||||
async def debug_context(request: Request):
|
||||
"""
|
||||
@@ -670,8 +668,8 @@ async def debug_context(request: Request):
|
||||
|
||||
URL: /shop/debug/context
|
||||
"""
|
||||
vendor = getattr(request.state, 'vendor', None)
|
||||
theme = getattr(request.state, 'theme', None)
|
||||
vendor = getattr(request.state, "vendor", None)
|
||||
theme = getattr(request.state, "theme", None)
|
||||
|
||||
debug_info = {
|
||||
"path": request.url.path,
|
||||
@@ -687,12 +685,13 @@ async def debug_context(request: Request):
|
||||
"found": theme is not None,
|
||||
"name": theme.get("theme_name") if theme else None,
|
||||
},
|
||||
"clean_path": getattr(request.state, 'clean_path', 'NOT SET'),
|
||||
"context_type": str(getattr(request.state, 'context_type', 'NOT SET')),
|
||||
"clean_path": getattr(request.state, "clean_path", "NOT SET"),
|
||||
"context_type": str(getattr(request.state, "context_type", "NOT SET")),
|
||||
}
|
||||
|
||||
# Return as JSON-like HTML for easy reading
|
||||
import json
|
||||
|
||||
html_content = f"""
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
@@ -21,18 +21,16 @@ Routes:
|
||||
- GET /vendor/{vendor_code}/settings → Vendor settings
|
||||
"""
|
||||
|
||||
from fastapi import APIRouter, Request, Depends, Path, HTTPException
|
||||
import logging
|
||||
from typing import Optional
|
||||
|
||||
from fastapi import APIRouter, Depends, HTTPException, Path, Request
|
||||
from fastapi.responses import HTMLResponse, RedirectResponse
|
||||
from fastapi.templating import Jinja2Templates
|
||||
from sqlalchemy.orm import Session
|
||||
from typing import Optional
|
||||
import logging
|
||||
|
||||
from app.api.deps import (
|
||||
get_current_vendor_from_cookie_or_header,
|
||||
get_current_vendor_optional,
|
||||
get_db
|
||||
)
|
||||
from app.api.deps import (get_current_vendor_from_cookie_or_header,
|
||||
get_current_vendor_optional, get_db)
|
||||
from app.services.content_page_service import content_page_service
|
||||
from models.database.user import User
|
||||
|
||||
@@ -46,6 +44,7 @@ templates = Jinja2Templates(directory="app/templates")
|
||||
# PUBLIC ROUTES (No Authentication Required)
|
||||
# ============================================================================
|
||||
|
||||
|
||||
@router.get("/{vendor_code}", response_class=RedirectResponse, include_in_schema=False)
|
||||
async def vendor_root_no_slash(vendor_code: str = Path(..., description="Vendor code")):
|
||||
"""
|
||||
@@ -57,8 +56,8 @@ async def vendor_root_no_slash(vendor_code: str = Path(..., description="Vendor
|
||||
|
||||
@router.get("/{vendor_code}/", response_class=RedirectResponse, include_in_schema=False)
|
||||
async def vendor_root(
|
||||
vendor_code: str = Path(..., description="Vendor code"),
|
||||
current_user: Optional[User] = Depends(get_current_vendor_optional)
|
||||
vendor_code: str = Path(..., description="Vendor code"),
|
||||
current_user: Optional[User] = Depends(get_current_vendor_optional),
|
||||
):
|
||||
"""
|
||||
Redirect /vendor/{code}/ based on authentication status.
|
||||
@@ -73,11 +72,13 @@ async def vendor_root(
|
||||
return RedirectResponse(url=f"/vendor/{vendor_code}/login", status_code=302)
|
||||
|
||||
|
||||
@router.get("/{vendor_code}/login", response_class=HTMLResponse, include_in_schema=False)
|
||||
@router.get(
|
||||
"/{vendor_code}/login", response_class=HTMLResponse, include_in_schema=False
|
||||
)
|
||||
async def vendor_login_page(
|
||||
request: Request,
|
||||
vendor_code: str = Path(..., description="Vendor code"),
|
||||
current_user: Optional[User] = Depends(get_current_vendor_optional)
|
||||
request: Request,
|
||||
vendor_code: str = Path(..., description="Vendor code"),
|
||||
current_user: Optional[User] = Depends(get_current_vendor_optional),
|
||||
):
|
||||
"""
|
||||
Render vendor login page.
|
||||
@@ -99,7 +100,7 @@ async def vendor_login_page(
|
||||
{
|
||||
"request": request,
|
||||
"vendor_code": vendor_code,
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
@@ -107,11 +108,14 @@ async def vendor_login_page(
|
||||
# AUTHENTICATED ROUTES (Vendor Users Only)
|
||||
# ============================================================================
|
||||
|
||||
@router.get("/{vendor_code}/dashboard", response_class=HTMLResponse, include_in_schema=False)
|
||||
|
||||
@router.get(
|
||||
"/{vendor_code}/dashboard", response_class=HTMLResponse, include_in_schema=False
|
||||
)
|
||||
async def vendor_dashboard_page(
|
||||
request: Request,
|
||||
vendor_code: str = Path(..., description="Vendor code"),
|
||||
current_user: User = Depends(get_current_vendor_from_cookie_or_header)
|
||||
request: Request,
|
||||
vendor_code: str = Path(..., description="Vendor code"),
|
||||
current_user: User = Depends(get_current_vendor_from_cookie_or_header),
|
||||
):
|
||||
"""
|
||||
Render vendor dashboard.
|
||||
@@ -128,7 +132,7 @@ async def vendor_dashboard_page(
|
||||
"request": request,
|
||||
"user": current_user,
|
||||
"vendor_code": vendor_code,
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
@@ -136,11 +140,14 @@ async def vendor_dashboard_page(
|
||||
# PRODUCT MANAGEMENT
|
||||
# ============================================================================
|
||||
|
||||
@router.get("/{vendor_code}/products", response_class=HTMLResponse, include_in_schema=False)
|
||||
|
||||
@router.get(
|
||||
"/{vendor_code}/products", response_class=HTMLResponse, include_in_schema=False
|
||||
)
|
||||
async def vendor_products_page(
|
||||
request: Request,
|
||||
vendor_code: str = Path(..., description="Vendor code"),
|
||||
current_user: User = Depends(get_current_vendor_from_cookie_or_header)
|
||||
request: Request,
|
||||
vendor_code: str = Path(..., description="Vendor code"),
|
||||
current_user: User = Depends(get_current_vendor_from_cookie_or_header),
|
||||
):
|
||||
"""
|
||||
Render products management page.
|
||||
@@ -152,7 +159,7 @@ async def vendor_products_page(
|
||||
"request": request,
|
||||
"user": current_user,
|
||||
"vendor_code": vendor_code,
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
@@ -160,11 +167,14 @@ async def vendor_products_page(
|
||||
# ORDER MANAGEMENT
|
||||
# ============================================================================
|
||||
|
||||
@router.get("/{vendor_code}/orders", response_class=HTMLResponse, include_in_schema=False)
|
||||
|
||||
@router.get(
|
||||
"/{vendor_code}/orders", response_class=HTMLResponse, include_in_schema=False
|
||||
)
|
||||
async def vendor_orders_page(
|
||||
request: Request,
|
||||
vendor_code: str = Path(..., description="Vendor code"),
|
||||
current_user: User = Depends(get_current_vendor_from_cookie_or_header)
|
||||
request: Request,
|
||||
vendor_code: str = Path(..., description="Vendor code"),
|
||||
current_user: User = Depends(get_current_vendor_from_cookie_or_header),
|
||||
):
|
||||
"""
|
||||
Render orders management page.
|
||||
@@ -176,7 +186,7 @@ async def vendor_orders_page(
|
||||
"request": request,
|
||||
"user": current_user,
|
||||
"vendor_code": vendor_code,
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
@@ -184,11 +194,14 @@ async def vendor_orders_page(
|
||||
# CUSTOMER MANAGEMENT
|
||||
# ============================================================================
|
||||
|
||||
@router.get("/{vendor_code}/customers", response_class=HTMLResponse, include_in_schema=False)
|
||||
|
||||
@router.get(
|
||||
"/{vendor_code}/customers", response_class=HTMLResponse, include_in_schema=False
|
||||
)
|
||||
async def vendor_customers_page(
|
||||
request: Request,
|
||||
vendor_code: str = Path(..., description="Vendor code"),
|
||||
current_user: User = Depends(get_current_vendor_from_cookie_or_header)
|
||||
request: Request,
|
||||
vendor_code: str = Path(..., description="Vendor code"),
|
||||
current_user: User = Depends(get_current_vendor_from_cookie_or_header),
|
||||
):
|
||||
"""
|
||||
Render customers management page.
|
||||
@@ -200,7 +213,7 @@ async def vendor_customers_page(
|
||||
"request": request,
|
||||
"user": current_user,
|
||||
"vendor_code": vendor_code,
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
@@ -208,11 +221,14 @@ async def vendor_customers_page(
|
||||
# INVENTORY MANAGEMENT
|
||||
# ============================================================================
|
||||
|
||||
@router.get("/{vendor_code}/inventory", response_class=HTMLResponse, include_in_schema=False)
|
||||
|
||||
@router.get(
|
||||
"/{vendor_code}/inventory", response_class=HTMLResponse, include_in_schema=False
|
||||
)
|
||||
async def vendor_inventory_page(
|
||||
request: Request,
|
||||
vendor_code: str = Path(..., description="Vendor code"),
|
||||
current_user: User = Depends(get_current_vendor_from_cookie_or_header)
|
||||
request: Request,
|
||||
vendor_code: str = Path(..., description="Vendor code"),
|
||||
current_user: User = Depends(get_current_vendor_from_cookie_or_header),
|
||||
):
|
||||
"""
|
||||
Render inventory management page.
|
||||
@@ -224,7 +240,7 @@ async def vendor_inventory_page(
|
||||
"request": request,
|
||||
"user": current_user,
|
||||
"vendor_code": vendor_code,
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
@@ -232,11 +248,14 @@ async def vendor_inventory_page(
|
||||
# MARKETPLACE IMPORTS
|
||||
# ============================================================================
|
||||
|
||||
@router.get("/{vendor_code}/marketplace", response_class=HTMLResponse, include_in_schema=False)
|
||||
|
||||
@router.get(
|
||||
"/{vendor_code}/marketplace", response_class=HTMLResponse, include_in_schema=False
|
||||
)
|
||||
async def vendor_marketplace_page(
|
||||
request: Request,
|
||||
vendor_code: str = Path(..., description="Vendor code"),
|
||||
current_user: User = Depends(get_current_vendor_from_cookie_or_header)
|
||||
request: Request,
|
||||
vendor_code: str = Path(..., description="Vendor code"),
|
||||
current_user: User = Depends(get_current_vendor_from_cookie_or_header),
|
||||
):
|
||||
"""
|
||||
Render marketplace import page.
|
||||
@@ -248,7 +267,7 @@ async def vendor_marketplace_page(
|
||||
"request": request,
|
||||
"user": current_user,
|
||||
"vendor_code": vendor_code,
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
@@ -256,11 +275,12 @@ async def vendor_marketplace_page(
|
||||
# TEAM MANAGEMENT
|
||||
# ============================================================================
|
||||
|
||||
|
||||
@router.get("/{vendor_code}/team", response_class=HTMLResponse, include_in_schema=False)
|
||||
async def vendor_team_page(
|
||||
request: Request,
|
||||
vendor_code: str = Path(..., description="Vendor code"),
|
||||
current_user: User = Depends(get_current_vendor_from_cookie_or_header)
|
||||
request: Request,
|
||||
vendor_code: str = Path(..., description="Vendor code"),
|
||||
current_user: User = Depends(get_current_vendor_from_cookie_or_header),
|
||||
):
|
||||
"""
|
||||
Render team management page.
|
||||
@@ -272,7 +292,7 @@ async def vendor_team_page(
|
||||
"request": request,
|
||||
"user": current_user,
|
||||
"vendor_code": vendor_code,
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
@@ -280,11 +300,14 @@ async def vendor_team_page(
|
||||
# PROFILE & SETTINGS
|
||||
# ============================================================================
|
||||
|
||||
@router.get("/{vendor_code}/profile", response_class=HTMLResponse, include_in_schema=False)
|
||||
|
||||
@router.get(
|
||||
"/{vendor_code}/profile", response_class=HTMLResponse, include_in_schema=False
|
||||
)
|
||||
async def vendor_profile_page(
|
||||
request: Request,
|
||||
vendor_code: str = Path(..., description="Vendor code"),
|
||||
current_user: User = Depends(get_current_vendor_from_cookie_or_header)
|
||||
request: Request,
|
||||
vendor_code: str = Path(..., description="Vendor code"),
|
||||
current_user: User = Depends(get_current_vendor_from_cookie_or_header),
|
||||
):
|
||||
"""
|
||||
Render vendor profile page.
|
||||
@@ -296,15 +319,17 @@ async def vendor_profile_page(
|
||||
"request": request,
|
||||
"user": current_user,
|
||||
"vendor_code": vendor_code,
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
@router.get("/{vendor_code}/settings", response_class=HTMLResponse, include_in_schema=False)
|
||||
@router.get(
|
||||
"/{vendor_code}/settings", response_class=HTMLResponse, include_in_schema=False
|
||||
)
|
||||
async def vendor_settings_page(
|
||||
request: Request,
|
||||
vendor_code: str = Path(..., description="Vendor code"),
|
||||
current_user: User = Depends(get_current_vendor_from_cookie_or_header)
|
||||
request: Request,
|
||||
vendor_code: str = Path(..., description="Vendor code"),
|
||||
current_user: User = Depends(get_current_vendor_from_cookie_or_header),
|
||||
):
|
||||
"""
|
||||
Render vendor settings page.
|
||||
@@ -316,7 +341,7 @@ async def vendor_settings_page(
|
||||
"request": request,
|
||||
"user": current_user,
|
||||
"vendor_code": vendor_code,
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
@@ -324,12 +349,15 @@ async def vendor_settings_page(
|
||||
# DYNAMIC CONTENT PAGES (CMS)
|
||||
# ============================================================================
|
||||
|
||||
@router.get("/{vendor_code}/{slug}", response_class=HTMLResponse, include_in_schema=False)
|
||||
|
||||
@router.get(
|
||||
"/{vendor_code}/{slug}", response_class=HTMLResponse, include_in_schema=False
|
||||
)
|
||||
async def vendor_content_page(
|
||||
request: Request,
|
||||
vendor_code: str = Path(..., description="Vendor code"),
|
||||
slug: str = Path(..., description="Content page slug"),
|
||||
db: Session = Depends(get_db)
|
||||
db: Session = Depends(get_db),
|
||||
):
|
||||
"""
|
||||
Generic content page handler for vendor shop (CMS).
|
||||
@@ -351,20 +379,17 @@ async def vendor_content_page(
|
||||
"path": request.url.path,
|
||||
"vendor_code": vendor_code,
|
||||
"slug": slug,
|
||||
"vendor": getattr(request.state, 'vendor', 'NOT SET'),
|
||||
"context": getattr(request.state, 'context_type', 'NOT SET'),
|
||||
}
|
||||
"vendor": getattr(request.state, "vendor", "NOT SET"),
|
||||
"context": getattr(request.state, "context_type", "NOT SET"),
|
||||
},
|
||||
)
|
||||
|
||||
vendor = getattr(request.state, 'vendor', None)
|
||||
vendor = getattr(request.state, "vendor", None)
|
||||
vendor_id = vendor.id if vendor else None
|
||||
|
||||
# Load content page from database (vendor override → platform default)
|
||||
page = content_page_service.get_page_for_vendor(
|
||||
db,
|
||||
slug=slug,
|
||||
vendor_id=vendor_id,
|
||||
include_unpublished=False
|
||||
db, slug=slug, vendor_id=vendor_id, include_unpublished=False
|
||||
)
|
||||
|
||||
if not page:
|
||||
@@ -374,7 +399,7 @@ async def vendor_content_page(
|
||||
"slug": slug,
|
||||
"vendor_code": vendor_code,
|
||||
"vendor_id": vendor_id,
|
||||
}
|
||||
},
|
||||
)
|
||||
raise HTTPException(status_code=404, detail="Page not found")
|
||||
|
||||
@@ -385,7 +410,7 @@ async def vendor_content_page(
|
||||
"page_id": page.id,
|
||||
"is_vendor_override": page.vendor_id is not None,
|
||||
"vendor_id": vendor_id,
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
return templates.TemplateResponse(
|
||||
@@ -394,5 +419,5 @@ async def vendor_content_page(
|
||||
"request": request,
|
||||
"page": page,
|
||||
"vendor_code": vendor_code,
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user