# app/modules/cms/routes/pages/platform.py """ CMS Platform Page Routes (HTML rendering). Platform (unauthenticated) pages for platform content: - Homepage - Generic content pages (/{slug} catch-all) """ import logging from fastapi import APIRouter, Depends, HTTPException, Request from fastapi.responses import HTMLResponse, RedirectResponse from sqlalchemy.orm import Session from app.core.database import get_db from app.modules.billing.models import TIER_LIMITS, TierCode from app.modules.cms.services import content_page_service from app.modules.core.utils.page_context import get_platform_context from app.templates_config import templates logger = logging.getLogger(__name__) router = APIRouter() # Route configuration - high priority so catch-all is registered last ROUTE_CONFIG = { "priority": 100, } def _get_tiers_data() -> list[dict]: """Build tier data for display in templates.""" tiers = [] for tier_code, limits in TIER_LIMITS.items(): tiers.append( { "code": tier_code.value, "name": limits["name"], "price_monthly": limits["price_monthly_cents"] / 100, "price_annual": (limits["price_annual_cents"] / 100) if limits.get("price_annual_cents") else None, "orders_per_month": limits.get("orders_per_month"), "products_limit": limits.get("products_limit"), "team_members": limits.get("team_members"), "features": limits.get("features", []), "is_popular": tier_code == TierCode.PROFESSIONAL, "is_enterprise": tier_code == TierCode.ENTERPRISE, } ) return tiers # ============================================================================ # HOMEPAGE # ============================================================================ @router.get("/", response_class=HTMLResponse, name="platform_homepage") async def homepage( request: Request, db: Session = Depends(get_db), ): """ Homepage handler. Handles two scenarios: 1. Vendor on custom domain (vendor.com) -> Show vendor landing page or redirect to shop 2. Platform marketing site -> Show platform homepage from CMS or default template URL routing: - localhost:9999/ -> Main marketing site ('main' platform) - localhost:9999/platforms/oms/ -> OMS platform (middleware rewrites to /) - oms.lu/ -> OMS platform (domain-based) - shop.mycompany.com/ -> Vendor landing page (custom domain) """ # Get platform and vendor from middleware platform = getattr(request.state, "platform", None) vendor = getattr(request.state, "vendor", None) # Scenario 1: Vendor detected (custom domain like vendor.com) if vendor: logger.debug(f"[HOMEPAGE] Vendor detected: {vendor.subdomain}") # Get platform_id (use platform from context or default to 1 for OMS) platform_id = platform.id if platform else 1 # Try to find vendor landing page (slug='landing' or 'home') landing_page = content_page_service.get_page_for_vendor( db, platform_id=platform_id, slug="landing", vendor_id=vendor.id, include_unpublished=False, ) if not landing_page: landing_page = content_page_service.get_page_for_vendor( db, platform_id=platform_id, slug="home", vendor_id=vendor.id, include_unpublished=False, ) if landing_page: # Render landing page with selected template from app.modules.core.utils.page_context import get_storefront_context template_name = landing_page.template or "default" template_path = f"cms/storefront/landing-{template_name}.html" logger.info(f"[HOMEPAGE] Rendering vendor landing page: {template_path}") return templates.TemplateResponse( template_path, get_storefront_context(request, db=db, page=landing_page), ) # No landing page - redirect to shop vendor_context = getattr(request.state, "vendor_context", None) access_method = ( vendor_context.get("detection_method", "unknown") if vendor_context else "unknown" ) if access_method == "path": full_prefix = ( vendor_context.get("full_prefix", "/vendor/") if vendor_context else "/vendor/" ) return RedirectResponse( url=f"{full_prefix}{vendor.subdomain}/storefront/", status_code=302 ) # Domain/subdomain - redirect to /storefront/ return RedirectResponse(url="/storefront/", status_code=302) # Scenario 2: Platform marketing site (no vendor) # Load platform homepage from CMS (slug='home') platform_id = platform.id if platform else 1 cms_homepage = content_page_service.get_platform_page( db, platform_id=platform_id, slug="home", include_unpublished=False ) if cms_homepage: # Use CMS-based homepage with template selection context = get_platform_context(request, db) context["page"] = cms_homepage context["tiers"] = _get_tiers_data() template_name = cms_homepage.template or "default" template_path = f"cms/platform/homepage-{template_name}.html" logger.info(f"[HOMEPAGE] Rendering CMS homepage with template: {template_path}") return templates.TemplateResponse(template_path, context) # Fallback: Default wizamart homepage (no CMS content) logger.info("[HOMEPAGE] No CMS homepage found, using default wizamart template") context = get_platform_context(request, db) context["tiers"] = _get_tiers_data() # Add-ons (hardcoded for now, will come from DB) context["addons"] = [ { "code": "domain", "name": "Custom Domain", "description": "Use your own domain (mydomain.com)", "price": 15, "billing_period": "year", "icon": "globe", }, { "code": "ssl_premium", "name": "Premium SSL", "description": "EV certificate for trust badges", "price": 49, "billing_period": "year", "icon": "shield-check", }, { "code": "email", "name": "Email Package", "description": "Professional email addresses", "price": 5, "billing_period": "month", "icon": "mail", "options": [ {"quantity": 5, "price": 5}, {"quantity": 10, "price": 9}, {"quantity": 25, "price": 19}, ], }, ] return templates.TemplateResponse( "cms/platform/homepage-wizamart.html", context, ) # ============================================================================ # GENERIC CONTENT PAGES (CMS) # ============================================================================ # IMPORTANT: This route must be LAST as it catches all /{slug} URLs @router.get("/{slug}", response_class=HTMLResponse, name="platform_content_page") async def content_page( request: Request, slug: str, db: Session = Depends(get_db), ): """ Serve CMS content pages (about, contact, faq, privacy, terms, etc.). This is a catch-all route for dynamic content pages managed via the admin CMS. Platform pages have vendor_id=None and is_platform_page=True. """ # Get platform from middleware (default to OMS platform_id=1) platform = getattr(request.state, "platform", None) platform_id = platform.id if platform else 1 # Load platform marketing page from database page = content_page_service.get_platform_page( db, platform_id=platform_id, slug=slug, include_unpublished=False ) if not page: raise HTTPException(status_code=404, detail=f"Page not found: {slug}") context = get_platform_context(request, db) context["page"] = page context["page_title"] = page.title return templates.TemplateResponse( "cms/platform/content-page.html", context, )