# app/routes/platform_pages.py """ Platform public page routes. These routes serve the marketing homepage, pricing page, Letzshop vendor finder, and signup wizard. """ import logging from pathlib import Path from fastapi import APIRouter, Depends, Request from fastapi.responses import HTMLResponse from fastapi.templating import Jinja2Templates from sqlalchemy.orm import Session from app.core.config import settings from app.core.database import get_db from app.utils.i18n import get_jinja2_globals router = APIRouter() logger = logging.getLogger(__name__) # Get the templates directory BASE_DIR = Path(__file__).resolve().parent.parent.parent TEMPLATES_DIR = BASE_DIR / "app" / "templates" templates = Jinja2Templates(directory=str(TEMPLATES_DIR)) def get_platform_context(request: Request, db: Session) -> dict: """Build context for platform pages.""" # Get language from request state (set by middleware) language = getattr(request.state, "language", "fr") # Get translation function i18n_globals = get_jinja2_globals(language) t = i18n_globals["t"] context = { "request": request, "platform_name": "Wizamart", "platform_domain": settings.platform_domain, "stripe_publishable_key": settings.stripe_publishable_key, "trial_days": settings.stripe_trial_days, } # Add i18n globals (_, t, current_language, SUPPORTED_LANGUAGES, etc.) context.update(i18n_globals) # Add footer CMS pages context["footer_pages"] = [ {"slug": "about", "title": t("platform.footer.about")}, {"slug": "faq", "title": t("platform.footer.faq")}, {"slug": "contact", "title": t("platform.footer.contact_us")}, ] return context # ============================================================================= # Homepage # ============================================================================= @router.get("/", response_class=HTMLResponse, name="platform_homepage") async def homepage( request: Request, db: Session = Depends(get_db), ): """ Platform marketing homepage. Displays: - Hero section with value proposition - Pricing tier cards - Add-ons section - Letzshop vendor finder - Call to action for signup """ context = get_platform_context(request, db) # Fetch tiers for display (use API service internally) from models.database.subscription import TIER_LIMITS, TierCode 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, }) context["tiers"] = tiers # 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( "platform/homepage-wizamart.html", context, ) # ============================================================================= # Pricing Page # ============================================================================= @router.get("/pricing", response_class=HTMLResponse, name="platform_pricing") async def pricing_page( request: Request, db: Session = Depends(get_db), ): """ Standalone pricing page with detailed tier comparison. """ context = get_platform_context(request, db) # Reuse tier data from homepage from models.database.subscription import TIER_LIMITS, TierCode 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"), "order_history_months": limits.get("order_history_months"), "features": limits.get("features", []), "is_popular": tier_code == TierCode.PROFESSIONAL, "is_enterprise": tier_code == TierCode.ENTERPRISE, }) context["tiers"] = tiers context["page_title"] = "Pricing" return templates.TemplateResponse( "platform/pricing.html", context, ) # ============================================================================= # Find Your Shop (Letzshop Vendor Browser) # ============================================================================= @router.get("/find-shop", response_class=HTMLResponse, name="platform_find_shop") async def find_shop_page( request: Request, db: Session = Depends(get_db), ): """ Letzshop vendor browser page. Allows vendors to search for and claim their Letzshop shop. """ context = get_platform_context(request, db) context["page_title"] = "Find Your Letzshop Shop" return templates.TemplateResponse( "platform/find-shop.html", context, ) # ============================================================================= # Signup Wizard # ============================================================================= @router.get("/signup", response_class=HTMLResponse, name="platform_signup") async def signup_page( request: Request, tier: str | None = None, annual: bool = False, db: Session = Depends(get_db), ): """ Multi-step signup wizard. Query params: - tier: Pre-selected tier code - annual: Pre-select annual billing """ context = get_platform_context(request, db) context["page_title"] = "Start Your Free Trial" context["selected_tier"] = tier context["is_annual"] = annual # Get tiers for tier selection step from models.database.subscription import TIER_LIMITS, TierCode 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"), "team_members": limits.get("team_members"), "is_enterprise": tier_code == TierCode.ENTERPRISE, }) context["tiers"] = tiers return templates.TemplateResponse( "platform/signup.html", context, ) @router.get("/signup/success", response_class=HTMLResponse, name="platform_signup_success") async def signup_success_page( request: Request, vendor_code: str | None = None, db: Session = Depends(get_db), ): """ Signup success page. Shown after successful account creation. """ context = get_platform_context(request, db) context["page_title"] = "Welcome to Wizamart!" context["vendor_code"] = vendor_code return templates.TemplateResponse( "platform/signup-success.html", context, )