Files
draletaha/DrSousan.Api/Pages/Blog/Post.cshtml.cs
T
soroush.asadi b3c4615bc7
CI/CD / CI · dotnet build (push) Successful in 51s
CI/CD / Deploy · drsousan (push) Failing after 5m40s
fix: replace emoji with hero image in blog sidebar doctor card
- Post.cshtml.cs: load hero image, tag from SiteSettings in SetViewDataAsync
- Post.cshtml: show <img> with hero image in .doc-avatar when set,
  fall back to emoji only if no image is configured
- .doc-avatar: circular crop with object-fit:cover, gold border
- doc-title now uses HeroTag from settings (not hardcoded)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-06-02 15:15:06 +03:30

157 lines
5.6 KiB
C#

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.EntityFrameworkCore;
using System.ComponentModel.DataAnnotations;
using DrSousan.Api.Data;
using DrSousan.Api.Models;
namespace DrSousan.Api.Pages.Blog;
public class PostModel : PageModel
{
private readonly AppDbContext _db;
public PostModel(AppDbContext db) => _db = db;
public BlogPost? Post { get; private set; }
public List<CommentVm> Comments { get; private set; } = new();
public bool CommentSent { get; private set; } = false;
// Comment form binding
[BindProperty]
[Required(ErrorMessage = "نام الزامی است.")]
[MaxLength(100)]
public string CommentAuthor { get; set; } = "";
[BindProperty]
[MaxLength(200)]
[EmailAddress]
public string CommentEmail { get; set; } = "";
[BindProperty]
[Required(ErrorMessage = "متن نظر الزامی است.")]
public string CommentBody { get; set; } = "";
public async Task<IActionResult> OnGetAsync(string slug)
{
var post = await _db.BlogPosts
.Include(p => p.Category)
.FirstOrDefaultAsync(p => p.Slug == slug && p.IsPublished);
if (post is null) return NotFound();
// Increment view count
post.ViewCount++;
await _db.SaveChangesAsync();
Post = post;
await LoadCommentsAsync(post.Id);
await SetViewDataAsync(post);
return Page();
}
public async Task<IActionResult> OnPostAsync(string slug)
{
var post = await _db.BlogPosts
.Include(p => p.Category)
.FirstOrDefaultAsync(p => p.Slug == slug && p.IsPublished);
if (post is null) return NotFound();
Post = post;
await LoadCommentsAsync(post.Id);
await SetViewDataAsync(post);
if (!ModelState.IsValid) return Page();
// Sanitise
var body = System.Text.RegularExpressions.Regex.Replace(CommentBody ?? "", "<[^>]*>", "").Trim();
var authorName = System.Text.RegularExpressions.Regex.Replace(CommentAuthor ?? "", "<[^>]*>", "").Trim();
if (string.IsNullOrWhiteSpace(body) || string.IsNullOrWhiteSpace(authorName))
{
ModelState.AddModelError("", "نام و متن نظر الزامی است.");
return Page();
}
_db.Comments.Add(new Comment
{
BlogPostId = post.Id,
AuthorName = authorName,
AuthorEmail = CommentEmail ?? "",
Body = body,
IsApproved = false,
CreatedAt = DateTime.UtcNow
});
await _db.SaveChangesAsync();
CommentSent = true;
// Clear form
CommentAuthor = "";
CommentEmail = "";
CommentBody = "";
ModelState.Clear();
return Page();
}
private async Task LoadCommentsAsync(int postId)
{
var raw = await _db.Comments
.Where(c => c.BlogPostId == postId && c.IsApproved && c.ParentId == null)
.OrderBy(c => c.CreatedAt)
.Select(c => new
{
c.Id, c.AuthorName, c.Body, c.CreatedAt, c.IsAdminReply,
Replies = _db.Comments
.Where(r => r.ParentId == c.Id && r.IsApproved)
.OrderBy(r => r.CreatedAt)
.Select(r => new { r.Id, r.AuthorName, r.Body, r.CreatedAt, r.IsAdminReply })
.ToList()
}).ToListAsync();
Comments = raw.Select(c => new CommentVm
{
Id = c.Id, AuthorName = c.AuthorName, Body = c.Body,
CreatedAt = c.CreatedAt, IsAdminReply = c.IsAdminReply,
Replies = c.Replies.Select(r => new CommentVm
{
Id = r.Id, AuthorName = r.AuthorName, Body = r.Body,
CreatedAt = r.CreatedAt, IsAdminReply = r.IsAdminReply
}).ToList()
}).ToList();
}
private async Task SetViewDataAsync(BlogPost post)
{
var metaTitle = string.IsNullOrEmpty(post.MetaTitle) ? post.Title : post.MetaTitle;
var metaDesc = string.IsNullOrEmpty(post.MetaDescription) ? post.Excerpt : post.MetaDescription;
// Avoid duplicating the site name if MetaTitle already contains it
var suffix = " | دکتر سوسن آل‌طه";
ViewData["Title"] = metaTitle.Contains("دکتر سوسن") ? metaTitle : metaTitle + suffix;
ViewData["MetaDesc"] = metaDesc;
ViewData["Keywords"] = post.Keywords;
ViewData["OgImage"] = string.IsNullOrEmpty(post.OgImage) ? post.FeaturedImage : post.OgImage;
ViewData["ArticleType"] = post.ArticleType;
ViewData["Slug"] = post.Slug;
var heroSettings = await _db.SiteSettings
.Where(x => x.Section == "hero" && (x.Key == "name" || x.Key == "image" || x.Key == "tag"))
.ToListAsync();
ViewData["SiteName"] = heroSettings.FirstOrDefault(x => x.Key == "name")?.Value ?? "دکتر سوسن آل‌طه";
ViewData["HeroImage"] = heroSettings.FirstOrDefault(x => x.Key == "image")?.Value ?? "";
ViewData["HeroTag"] = heroSettings.FirstOrDefault(x => x.Key == "tag")?.Value ?? "پزشک عمومی و متخصص زیبایی پوست";
}
// View model for comments
public class CommentVm
{
public int Id { get; set; }
public string AuthorName { get; set; } = "";
public string Body { get; set; } = "";
public DateTime CreatedAt { get; set; }
public bool IsAdminReply { get; set; }
public List<CommentVm> Replies { get; set; } = new();
}
}