mirror of https://github.com/abpframework/abp
Merge pull request #16313 from abpframework/Onur/blogging-module-add-profile
Blog Module - Member page createdpull/16378/head
commit
664788516e
@ -0,0 +1,5 @@
|
||||
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
|
||||
@addTagHelper *, Volo.Abp.AspNetCore.Mvc.UI
|
||||
@addTagHelper *, Volo.Abp.AspNetCore.Mvc.UI.Bootstrap
|
||||
@addTagHelper *, Volo.Abp.AspNetCore.Mvc.UI.Bundling
|
||||
@addTagHelper *, Volo.Blogging.Web
|
||||
@ -0,0 +1,10 @@
|
||||
using System.Threading.Tasks;
|
||||
using Volo.Abp.Application.Services;
|
||||
using Volo.Blogging.Posts;
|
||||
|
||||
namespace Volo.Blogging.Members;
|
||||
|
||||
public interface IMemberAppService : IApplicationService
|
||||
{
|
||||
Task<BlogUserDto> FindAsync(string username);
|
||||
}
|
||||
@ -0,0 +1,29 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Volo.Abp.Domain.Repositories;
|
||||
using Volo.Blogging.Posts;
|
||||
using Volo.Blogging.Users;
|
||||
|
||||
namespace Volo.Blogging.Members;
|
||||
|
||||
public class MemberAppService : BloggingAppServiceBase, IMemberAppService
|
||||
{
|
||||
private readonly IRepository<BlogUser, Guid> _userRepository;
|
||||
|
||||
public MemberAppService(IRepository<BlogUser, Guid> userRepository)
|
||||
{
|
||||
_userRepository = userRepository;
|
||||
}
|
||||
|
||||
public async Task<BlogUserDto> FindAsync(string username)
|
||||
{
|
||||
var user = await _userRepository.FindAsync(x => x.UserName == username);
|
||||
|
||||
if (user == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return ObjectMapper.Map<BlogUser, BlogUserDto>(user);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,28 @@
|
||||
// This file is automatically generated by ABP framework to use MVC Controllers from CSharp
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Volo.Abp.Application.Dtos;
|
||||
using Volo.Abp.Http.Client;
|
||||
using Volo.Abp.Http.Modeling;
|
||||
using Volo.Abp.DependencyInjection;
|
||||
using Volo.Abp.Http.Client.ClientProxying;
|
||||
using Volo.Blogging.Blogs;
|
||||
using Volo.Blogging.Blogs.Dtos;
|
||||
using Volo.Blogging.Members;
|
||||
using Volo.Blogging.Posts;
|
||||
|
||||
// ReSharper disable once CheckNamespace
|
||||
namespace Volo.Blogging.ClientProxies;
|
||||
|
||||
[Dependency(ReplaceServices = true)]
|
||||
[ExposeServices(typeof(IMemberAppService), typeof(MembersClientProxy))]
|
||||
public partial class MembersClientProxy : ClientProxyBase<IMemberAppService>, IMemberAppService
|
||||
{
|
||||
public Task<BlogUserDto> FindAsync(string username)
|
||||
{
|
||||
return RequestAsync<BlogUserDto>(nameof(FindAsync), new ClientProxyRequestTypeValue
|
||||
{
|
||||
{ typeof(string), username }
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,7 @@
|
||||
// This file is part of MembersClientProxy, you can customize it here
|
||||
// ReSharper disable once CheckNamespace
|
||||
namespace Volo.Blogging.ClientProxies;
|
||||
|
||||
public partial class MembersClientProxy
|
||||
{
|
||||
}
|
||||
@ -0,0 +1,96 @@
|
||||
@page
|
||||
@using Microsoft.Extensions.Localization
|
||||
@using Volo.Abp.AspNetCore.Mvc.UI.Bundling.TagHelpers
|
||||
@using Volo.Abp.Users
|
||||
@using Volo.Blogging.Localization
|
||||
@model Volo.Blogging.Pages.Members.IndexModel
|
||||
@inject IStringLocalizer<BloggingResource> L
|
||||
@inject ICurrentUser CurrentUser
|
||||
@{
|
||||
ViewBag.Title = @Model.User.UserName.ToUpper() + " - " + L["Blogs"].Value;
|
||||
}
|
||||
|
||||
@section styles {
|
||||
<abp-style src="/Pages/Members/Index.css"/>
|
||||
}
|
||||
|
||||
<main>
|
||||
<div class="container">
|
||||
<div class="row gx-lg-5">
|
||||
<div class="col-md-4 mb-5 mb-md-0">
|
||||
<div class="card h-auto member-profile-info">
|
||||
<div class="card-body">
|
||||
<div class="d-inline-block position-relative">
|
||||
<img gravatar-email="@Model.User.Email" default-image="Identicon" class="post-member-img rounded-circle d-block"/>
|
||||
</div>
|
||||
@if (Model.User.UserName != null)
|
||||
{
|
||||
<h2 class="m-0">@Model.User.UserName</h2>
|
||||
}
|
||||
<small class="d-block mt-4">@L["UserName"].Value.ToUpper()</small>
|
||||
<h5>@Model.User.UserName</h5>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@if (Model.Posts is not null && Model.Posts.Any())
|
||||
{
|
||||
<div class="col-md-8">
|
||||
<abp-tabs>
|
||||
<abp-tab name="all-posts" title="All Blog Posts">
|
||||
<div class="mt-4 pt-3">
|
||||
@foreach (var post in Model.Posts)
|
||||
{
|
||||
<div class="post-item">
|
||||
<div class="post-type-cont">
|
||||
|
||||
<a href="@Model.GetMemberProfileUrl(Model.User)" class="text-decoration-none">
|
||||
<img gravatar-email="@Model.User.Email" default-image="Identicon" class="post-member-img rounded-circle d-block"/>
|
||||
</a>
|
||||
<span class="post-type">
|
||||
<i class="fas fa-pen-nib"></i>
|
||||
@L["Blog"].Value.ToUpper()
|
||||
</span>
|
||||
</div>
|
||||
<div class="post-detail-cont">
|
||||
<div class="post-info fs-12 mb-2">
|
||||
<a href="@Model.GetMemberProfileUrl(Model.User)" class="text-decoration-none">
|
||||
<span class="text-dark dot">@Model.User.UserName</span>
|
||||
</a>
|
||||
<span class="text-dark-200 dot">@post.CreationTime.ToString("MMMM yyyy")</span>
|
||||
<span class="text-dark-200">@post.ReadCount.ToString() @L["Views"]</span>
|
||||
</div>
|
||||
<h3 class="post-title mb-3">
|
||||
<a href="@Model.GetBlogPostUrl(post)">
|
||||
@post.Title
|
||||
</a>
|
||||
</h3>
|
||||
<p class="post-desc">
|
||||
<a href="@Model.GetBlogPostUrl(post)">
|
||||
@post.Description.TruncateWithPostfix(150)
|
||||
</a>
|
||||
<a href="@Model.GetBlogPostUrl(post)" class="readMore">@L["ReadMore"]</a>
|
||||
</p>
|
||||
</div>
|
||||
<div class="post-img-cont">
|
||||
<div class="post-list-span text-center post">
|
||||
<img src="@post.CoverImage" class="box-articles">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</abp-tab>
|
||||
</abp-tabs>
|
||||
</div>
|
||||
}
|
||||
else
|
||||
{
|
||||
<div class="col-md-8">
|
||||
<div class="mt-5 pt-6">
|
||||
<p>@L["MemberNotPublishedPostYet"]</p>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
@ -0,0 +1,66 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Volo.Abp.AspNetCore.Mvc.UI.RazorPages;
|
||||
using Volo.Blogging.Blogs;
|
||||
using Volo.Blogging.Members;
|
||||
using Volo.Blogging.Posts;
|
||||
|
||||
namespace Volo.Blogging.Pages.Members;
|
||||
|
||||
public class IndexModel : AbpPageModel
|
||||
{
|
||||
private readonly IPostAppService _postAppService;
|
||||
|
||||
private readonly IMemberAppService _memberAppService;
|
||||
|
||||
private readonly IBlogAppService _blogAppService;
|
||||
|
||||
public BlogUserDto User { get; set; }
|
||||
public List<PostWithDetailsDto> Posts { get; set; }
|
||||
|
||||
public Dictionary<Guid, string> BlogShortNameMap { get; set; }
|
||||
|
||||
public IndexModel(IPostAppService postAppService, IMemberAppService memberAppService, IBlogAppService blogAppService)
|
||||
{
|
||||
_postAppService = postAppService;
|
||||
_memberAppService = memberAppService;
|
||||
_blogAppService = blogAppService;
|
||||
}
|
||||
|
||||
public async Task<IActionResult> OnGetAsync(string userName)
|
||||
{
|
||||
User = await _memberAppService.FindAsync(userName);
|
||||
|
||||
if (User is null)
|
||||
{
|
||||
return Redirect("/");
|
||||
}
|
||||
|
||||
Posts = await _postAppService.GetListByUserIdAsync(User.Id);
|
||||
|
||||
var blogIds = Posts.Select(x => x.BlogId).Distinct();
|
||||
BlogShortNameMap = new Dictionary<Guid, string>();
|
||||
|
||||
foreach (var blogId in blogIds)
|
||||
{
|
||||
BlogShortNameMap[blogId] = (await _blogAppService.GetAsync(blogId)).ShortName;
|
||||
}
|
||||
|
||||
return Page();
|
||||
}
|
||||
public string GetBlogPostUrl(PostWithDetailsDto post)
|
||||
{
|
||||
var blogShortName = BlogShortNameMap[post.BlogId];
|
||||
|
||||
return "/" + blogShortName + "/" + post.Url;
|
||||
}
|
||||
|
||||
public string GetMemberProfileUrl(BlogUserDto user)
|
||||
{
|
||||
return "/members/" + user.UserName;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
.post-desc {
|
||||
overflow-wrap: break-word;
|
||||
}
|
||||
Loading…
Reference in new issue