using BCards.Web.Models; using BCards.Web.Services; using BCards.Web.Utils; using Microsoft.AspNetCore.Mvc; namespace BCards.Web.Controllers; //[Route("[controller]")] public class UserPageController : Controller { private readonly IUserPageService _userPageService; private readonly ICategoryService _categoryService; private readonly ISeoService _seoService; private readonly IThemeService _themeService; private readonly IModerationService _moderationService; public UserPageController( IUserPageService userPageService, ICategoryService categoryService, ISeoService seoService, IThemeService themeService, IModerationService moderationService) { _userPageService = userPageService; _categoryService = categoryService; _seoService = seoService; _themeService = themeService; _moderationService = moderationService; } //[Route("{category}/{slug}")] //VOltar a linha abaixo em prod //[ResponseCache(Duration = 300, VaryByQueryKeys = new[] { "category", "slug" })] public async Task Display(string category, string slug) { var userPage = await _userPageService.GetPageAsync(category, slug); if (userPage == null) return NotFound(); var categoryObj = await _categoryService.GetCategoryBySlugAsync(category); if (categoryObj == null) return NotFound(); // Check if it's a preview request var isPreview = HttpContext.Items.ContainsKey("IsPreview") && (bool)HttpContext.Items["IsPreview"]; var previewToken = Request.Query["preview"].FirstOrDefault(); if (!string.IsNullOrEmpty(previewToken)) { // Handle preview request var isValidPreview = await _moderationService.ValidatePreviewTokenAsync(userPage.Id, previewToken); if (!isValidPreview) { return View("PreviewExpired"); } // Set preview flag ViewBag.IsPreview = true; ViewBag.PreviewToken = previewToken; } else { // Regular request - check if page is active if (userPage.Status == ViewModels.PageStatus.PendingModeration) { return View("PendingModeration"); } if (userPage.Status == ViewModels.PageStatus.Rejected) { return View("PageRejected"); } if (userPage.Status == ViewModels.PageStatus.Inactive || !userPage.IsActive) { return NotFound(); } } // Ensure theme is loaded - critical fix for theme display issue if (userPage.Theme?.Id == null || string.IsNullOrEmpty(userPage.Theme.PrimaryColor)) { userPage.Theme = _themeService.GetDefaultTheme(); } // Generate SEO settings var seoSettings = _seoService.GenerateSeoSettings(userPage, categoryObj); // Record page view (async, don't wait) - only for non-preview requests if (!isPreview) { var referrer = Request.Headers["Referer"].FirstOrDefault(); var userAgent = Request.Headers["User-Agent"].FirstOrDefault(); _ = Task.Run(() => _userPageService.RecordPageViewAsync(userPage.Id, referrer, userAgent)); } ViewBag.SeoSettings = seoSettings; ViewBag.Category = categoryObj; return View(userPage); } [HttpPost] [Route("click/{pageId}")] public async Task RecordClick(string pageId, int linkIndex) { await _userPageService.RecordLinkClickAsync(pageId, linkIndex); return Ok(); } [Route("preview/{category}/{slug}")] public async Task Preview(string category, string slug) { var userPage = await _userPageService.GetPageAsync(category, slug); if (userPage == null) return NotFound(); var categoryObj = await _categoryService.GetCategoryBySlugAsync(category); if (categoryObj == null) return NotFound(); // Ensure theme is loaded for preview too if (userPage.Theme?.Id == null || string.IsNullOrEmpty(userPage.Theme.PrimaryColor)) { userPage.Theme = _themeService.GetDefaultTheme(); } ViewBag.Category = categoryObj; ViewBag.IsPreview = true; return View("Display", userPage); } }