# app/modules/tenancy/routes/pages/vendor.py """ Tenancy Vendor Page Routes (HTML rendering). Vendor pages for authentication and account management: - Root redirect - Login - Team management - Profile - Settings """ from fastapi import APIRouter, Depends, Path, Request from fastapi.responses import HTMLResponse, RedirectResponse from sqlalchemy.orm import Session from app.api.deps import ( get_current_vendor_from_cookie_or_header, get_current_vendor_optional, get_db, ) from app.modules.core.utils.page_context import get_vendor_context from app.templates_config import templates from app.modules.tenancy.models import User router = APIRouter() # ============================================================================ # 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")): """ Redirect /vendor/{code} (no trailing slash) to login page. Handles requests without trailing slash. """ return RedirectResponse(url=f"/vendor/{vendor_code}/login", status_code=302) @router.get( "/{vendor_code}/", response_class=RedirectResponse, include_in_schema=False ) async def vendor_root( vendor_code: str = Path(..., description="Vendor code"), current_user: User | None = Depends(get_current_vendor_optional), ): """ Redirect /vendor/{code}/ based on authentication status. - Authenticated vendor users -> /vendor/{code}/dashboard - Unauthenticated users -> /vendor/{code}/login """ if current_user: return RedirectResponse( url=f"/vendor/{vendor_code}/dashboard", status_code=302 ) return RedirectResponse(url=f"/vendor/{vendor_code}/login", status_code=302) @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: User | None = Depends(get_current_vendor_optional), ): """ Render vendor login page. If user is already authenticated as vendor, redirect to dashboard. Otherwise, show login form. JavaScript will: - Load vendor info via API - Handle login form submission - Redirect to dashboard on success """ if current_user: return RedirectResponse( url=f"/vendor/{vendor_code}/dashboard", status_code=302 ) return templates.TemplateResponse( "tenancy/vendor/login.html", { "request": request, "vendor_code": vendor_code, }, ) # ============================================================================ # AUTHENTICATED ROUTES (Vendor Users Only) # ============================================================================ @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), db: Session = Depends(get_db), ): """ Render team management page. JavaScript loads team members via API. """ return templates.TemplateResponse( "tenancy/vendor/team.html", get_vendor_context(request, db, current_user, vendor_code), ) @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), db: Session = Depends(get_db), ): """ Render vendor profile page. User can manage their personal profile information. """ return templates.TemplateResponse( "tenancy/vendor/profile.html", get_vendor_context(request, db, current_user, vendor_code), ) @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), db: Session = Depends(get_db), ): """ Render vendor settings page. JavaScript loads settings via API. """ return templates.TemplateResponse( "tenancy/vendor/settings.html", get_vendor_context(request, db, current_user, vendor_code), )