All checks were successful
BCards Deployment Pipeline / Run Tests (push) Successful in 3s
BCards Deployment Pipeline / PR Validation (push) Has been skipped
BCards Deployment Pipeline / Build and Push Image (push) Successful in 15m38s
BCards Deployment Pipeline / Deploy to Production (ARM - OCI) (push) Successful in 1m15s
BCards Deployment Pipeline / Deploy to Staging (x86 - Local) (push) Has been skipped
BCards Deployment Pipeline / Cleanup Old Resources (push) Has been skipped
BCards Deployment Pipeline / Deployment Summary (push) Successful in 1s
141 lines
4.9 KiB
C#
141 lines
4.9 KiB
C#
using BCards.Web.Models;
|
|
using BCards.Web.Services;
|
|
using BCards.Web.Utils;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
|
|
namespace BCards.Web.Controllers;
|
|
|
|
public class UserPageController : Controller
|
|
{
|
|
private readonly IUserPageService _userPageService;
|
|
private readonly ICategoryService _categoryService;
|
|
private readonly ISeoService _seoService;
|
|
private readonly IThemeService _themeService;
|
|
private readonly IModerationService _moderationService;
|
|
private readonly ILogger<UserPageController> _logger;
|
|
|
|
public UserPageController(
|
|
IUserPageService userPageService,
|
|
ICategoryService categoryService,
|
|
ISeoService seoService,
|
|
IThemeService themeService,
|
|
IModerationService moderationService,
|
|
ILogger<UserPageController> logger)
|
|
{
|
|
_userPageService = userPageService;
|
|
_categoryService = categoryService;
|
|
_seoService = seoService;
|
|
_themeService = themeService;
|
|
_moderationService = moderationService;
|
|
_logger = logger;
|
|
}
|
|
|
|
[ResponseCache(Duration = 300, Location = ResponseCacheLocation.Any, VaryByQueryKeys = new[] { "preview" })]
|
|
public async Task<IActionResult> 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
|
|
_logger.LogDebug("View Count - Page: {Slug}, Status: {Status}, IsPreview: {IsPreview}, PreviewToken: {PreviewToken}",
|
|
userPage.Slug, userPage.Status, isPreview, !string.IsNullOrEmpty(previewToken));
|
|
if (!isPreview)
|
|
{
|
|
_logger.LogDebug("Recording view for page {Slug}", userPage.Slug);
|
|
var referrer = Request.Headers["Referer"].FirstOrDefault();
|
|
var userAgent = Request.Headers["User-Agent"].FirstOrDefault();
|
|
_ = _userPageService.RecordPageViewAsync(userPage.Id, referrer, userAgent);
|
|
}
|
|
else
|
|
{
|
|
_logger.LogDebug("NOT recording view - isPreview = true for page {Slug}", userPage.Slug);
|
|
}
|
|
|
|
ViewBag.SeoSettings = seoSettings;
|
|
ViewBag.Category = categoryObj;
|
|
|
|
return View(userPage);
|
|
}
|
|
|
|
[HttpPost]
|
|
[Route("click/{pageId}")]
|
|
public async Task<IActionResult> RecordClick(string pageId, int linkIndex)
|
|
{
|
|
await _userPageService.RecordLinkClickAsync(pageId, linkIndex);
|
|
return Ok();
|
|
}
|
|
|
|
[Route("preview/{category}/{slug}")]
|
|
public async Task<IActionResult> 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);
|
|
}
|
|
|
|
} |