Ajout liste des commentaires d'un lien / ajout commentaire
This commit is contained in:
parent
d930693b58
commit
c2d1abe808
47
Apps/HackerNet.Web/Controllers/CommentsController.cs
Normal file
47
Apps/HackerNet.Web/Controllers/CommentsController.cs
Normal file
@ -0,0 +1,47 @@
|
||||
using HackerNet.Application;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace HackerNet.Web.Controllers;
|
||||
|
||||
public class CommentsController : HackerController
|
||||
{
|
||||
private readonly LinkService _linkService;
|
||||
|
||||
public CommentsController(LinkService linkService)
|
||||
{
|
||||
_linkService = linkService;
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public IActionResult New(Guid id)
|
||||
{
|
||||
var link = _linkService.GetLinkDetail(id);
|
||||
ViewData["LinkUrl"] = link.Url;
|
||||
|
||||
return View(new PublishCommentCommand
|
||||
{
|
||||
LinkId = id
|
||||
});
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[ValidateAntiForgeryToken]
|
||||
public IActionResult New(PublishCommentCommand cmd)
|
||||
{
|
||||
if (!ModelState.IsValid)
|
||||
{
|
||||
var link = _linkService.GetLinkDetail(cmd.LinkId);
|
||||
ViewData["LinkUrl"] = link.Url;
|
||||
return View(cmd);
|
||||
}
|
||||
|
||||
_linkService.PublishComment(cmd);
|
||||
|
||||
SetFlashMessage("Votre commentaire a été publié !");
|
||||
|
||||
// asp-controller="Links" asp-action="Detail"
|
||||
// asp-route-id="@Model.Id"
|
||||
|
||||
return RedirectToAction("Detail", "Links", new { id = cmd.LinkId });
|
||||
}
|
||||
}
|
||||
@ -1,4 +1,5 @@
|
||||
using HackerNet.Application;
|
||||
using HackerNet.Web.Models;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace HackerNet.Web.Controllers;
|
||||
@ -20,12 +21,13 @@ public class LinksController : HackerController
|
||||
// return View(_linkRepository.GetAll());// retourne Link[]
|
||||
}
|
||||
|
||||
// TODO: Page de détail d'un lien
|
||||
|
||||
[HttpGet]
|
||||
public IActionResult Detail(Guid id)
|
||||
{
|
||||
return View(_linkService.GetLinkDetail(id));
|
||||
var link = _linkService.GetLinkDetail(id);
|
||||
var comments = _linkService.GetLinkComments(id);
|
||||
|
||||
return View(new LinkDetailViewModel(link, comments));
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
|
||||
15
Apps/HackerNet.Web/Models/LinkDetailViewModel.cs
Normal file
15
Apps/HackerNet.Web/Models/LinkDetailViewModel.cs
Normal file
@ -0,0 +1,15 @@
|
||||
using HackerNet.Application;
|
||||
|
||||
namespace HackerNet.Web.Models;
|
||||
|
||||
public class LinkDetailViewModel
|
||||
{
|
||||
public LinkHomePage Link { get; set; }
|
||||
public LinkComment[] Comments { get; set; }
|
||||
|
||||
public LinkDetailViewModel(LinkHomePage link, LinkComment[] comments)
|
||||
{
|
||||
Link = link;
|
||||
Comments = comments;
|
||||
}
|
||||
}
|
||||
@ -5,10 +5,14 @@ using HackerNet.Infrastructure.Repositories.Memory;
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
|
||||
// Add services to the container.
|
||||
var linksRepository = new MemoryLinkRepository(new Link("https://localhost:7050/", "Youhouuu"));
|
||||
var link = new Link("https://localhost:7050/", "Youhouuu");
|
||||
var comment = new Comment(link.Id, "Wow!");
|
||||
var linksRepository = new MemoryLinkRepository(link);
|
||||
var commentsRepository = new MemoryCommentRepository(comment);
|
||||
|
||||
builder.Services.AddSingleton<ILinkRepository>(linksRepository);
|
||||
builder.Services.AddSingleton<IReadStore>(linksRepository);
|
||||
builder.Services.AddSingleton<ICommentRepository>(commentsRepository);
|
||||
builder.Services.AddSingleton<IReadStore>(new MemoryReadStore(linksRepository, commentsRepository));
|
||||
|
||||
builder.Services.AddSingleton<LinkService>();
|
||||
builder.Services.AddControllersWithViews();
|
||||
|
||||
21
Apps/HackerNet.Web/Views/Comments/New.cshtml
Normal file
21
Apps/HackerNet.Web/Views/Comments/New.cshtml
Normal file
@ -0,0 +1,21 @@
|
||||
@model HackerNet.Application.PublishCommentCommand
|
||||
@{
|
||||
ViewData["Title"] = $"Ajouter un commentaire sur {ViewData["LinkUrl"]}";
|
||||
}
|
||||
|
||||
<div class="shadow-xl p-6">
|
||||
<h1 class="font-semibold text-xl text-indigo-500">@ViewData["Title"]</h1>
|
||||
|
||||
<form asp-action="New" method="post">
|
||||
<input type="hidden" asp-for="@Model.LinkId" />
|
||||
|
||||
<label asp-for="@Model.Content"></label>
|
||||
<textarea class="mt-4 bg-gray-100 rounded-xl px-2 py-4 block w-full" asp-for="@Model.Content">
|
||||
</textarea>
|
||||
<span class="text-red-700 text-sm block" asp-validation-for="@Model.Content"></span>
|
||||
|
||||
<div class="mt-4 flex justify-end">
|
||||
<button type="submit" class="px-4 py-2 text-indigo-500 font-semibold rounded-xl bg-indigo-100">Publier un lien</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
@ -1,6 +1,20 @@
|
||||
@model HackerNet.Application.LinkHomePage
|
||||
@model HackerNet.Web.Models.LinkDetailViewModel
|
||||
@{
|
||||
ViewData["Title"] = $"Détail du lien {Model.Url}";
|
||||
ViewData["Title"] = $"Détail du lien {Model.Link.Url}";
|
||||
}
|
||||
|
||||
<partial name="_LinkCard" model="@Model" />
|
||||
<partial name="_LinkCard" model="@Model.Link" />
|
||||
|
||||
@if(Model.Comments.Length == 0)
|
||||
{
|
||||
<p>Aucun commentaire pour le moment.</p>
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var comment in Model.Comments)
|
||||
{
|
||||
<p class="mb-6 shadow p-6">
|
||||
@comment.Content
|
||||
</p>
|
||||
}
|
||||
}
|
||||
@ -5,7 +5,9 @@
|
||||
|
||||
<p>@Model.Description</p>
|
||||
|
||||
<div class="mt-4">
|
||||
<div class="flex gap-4 mt-4">
|
||||
<a class="text-indigo-500 hover:underline" asp-controller="Links" asp-action="Detail" asp-route-id="@Model.Id">Détail du lien</a>
|
||||
<a class="text-indigo-500 hover:underline" asp-controller="Comments" asp-action="New" asp-route-id="@Model.Id">Ajouter un commentaire</a>
|
||||
<p>@Model.CommentsCount commentaire@(Model.CommentsCount > 1 ? "s" : "")</p>
|
||||
</div>
|
||||
</article>
|
||||
@ -5,11 +5,16 @@ namespace HackerNet.Application;
|
||||
public class LinkService
|
||||
{
|
||||
private readonly ILinkRepository _repository;
|
||||
private readonly ICommentRepository _commentRepository;
|
||||
private readonly IReadStore _readStore;
|
||||
|
||||
public LinkService(ILinkRepository repository, IReadStore readStore)
|
||||
public LinkService(
|
||||
ILinkRepository repository,
|
||||
ICommentRepository commentRepository,
|
||||
IReadStore readStore)
|
||||
{
|
||||
_repository = repository;
|
||||
_commentRepository = commentRepository;
|
||||
_readStore = readStore;
|
||||
}
|
||||
|
||||
@ -22,17 +27,30 @@ public class LinkService
|
||||
return link.Id;
|
||||
}
|
||||
|
||||
public Guid PublishComment(PublishCommentCommand cmd)
|
||||
{
|
||||
var comment = new Comment(cmd.LinkId, cmd.Content);
|
||||
|
||||
_commentRepository.Add(comment);
|
||||
|
||||
return comment.Id;
|
||||
}
|
||||
|
||||
public LinkHomePage[] GetPublishedLinks()
|
||||
=> _readStore.GetPublishedLinks();
|
||||
|
||||
public LinkHomePage GetLinkDetail(Guid id)
|
||||
=> _readStore.GetLinkDetail(id);
|
||||
|
||||
public LinkComment[] GetLinkComments(Guid linkId)
|
||||
=> _readStore.GetLinkComments(linkId);
|
||||
}
|
||||
|
||||
public interface IReadStore
|
||||
{
|
||||
LinkHomePage[] GetPublishedLinks();
|
||||
LinkHomePage GetLinkDetail(Guid id);
|
||||
LinkComment[] GetLinkComments(Guid linkId);
|
||||
}
|
||||
|
||||
public class LinkHomePage
|
||||
@ -43,6 +61,11 @@ public class LinkHomePage
|
||||
public int CommentsCount { get; set; }
|
||||
}
|
||||
|
||||
public class LinkComment
|
||||
{
|
||||
public string Content { get; set; }
|
||||
}
|
||||
|
||||
public class PublishLinkCommand
|
||||
{
|
||||
[Required(ErrorMessage = "L'url est requise")]
|
||||
@ -53,3 +76,11 @@ public class PublishLinkCommand
|
||||
[Required(ErrorMessage = "La description est obligatoire")]
|
||||
public string Description { get; set; }
|
||||
}
|
||||
|
||||
public class PublishCommentCommand
|
||||
{
|
||||
public Guid LinkId { get; set; }
|
||||
|
||||
[Required]
|
||||
public string Content { get; set; }
|
||||
}
|
||||
@ -0,0 +1,20 @@
|
||||
using HackerNet.Domain;
|
||||
|
||||
namespace HackerNet.Infrastructure.Repositories.Memory;
|
||||
|
||||
public class MemoryCommentRepository : ICommentRepository
|
||||
{
|
||||
private List<Comment> _comments;
|
||||
|
||||
internal List<Comment> Comments => _comments;
|
||||
|
||||
public MemoryCommentRepository(params Comment[] comments)
|
||||
{
|
||||
_comments = comments.ToList();
|
||||
}
|
||||
|
||||
public void Add(Comment comment)
|
||||
{
|
||||
_comments.Add(comment);
|
||||
}
|
||||
}
|
||||
@ -5,10 +5,12 @@ namespace HackerNet.Infrastructure.Repositories.Memory;
|
||||
|
||||
|
||||
|
||||
public class MemoryLinkRepository : ILinkRepository, IReadStore
|
||||
public class MemoryLinkRepository : ILinkRepository
|
||||
{
|
||||
private List<Link> _links;
|
||||
|
||||
internal List<Link> Links => _links;
|
||||
|
||||
public MemoryLinkRepository(params Link[] links)
|
||||
{
|
||||
_links = links.ToList();
|
||||
@ -18,36 +20,4 @@ public class MemoryLinkRepository : ILinkRepository, IReadStore
|
||||
{
|
||||
_links.Add(link);
|
||||
}
|
||||
|
||||
public LinkHomePage GetLinkDetail(Guid id)
|
||||
=> GetLinks(id).Single();
|
||||
|
||||
public LinkHomePage[] GetPublishedLinks()
|
||||
{
|
||||
// return (from l in _links
|
||||
// orderby l.CreatedAt descending
|
||||
// select new LinkHomePage
|
||||
// {
|
||||
// Id = l.Id,
|
||||
// Url = l.Url,
|
||||
// Description = l.Description,
|
||||
// CommentsCount = 0,
|
||||
// }).ToArray();
|
||||
|
||||
return GetLinks().ToArray();
|
||||
}
|
||||
|
||||
private IEnumerable<LinkHomePage> GetLinks(Guid? id = null)
|
||||
{
|
||||
return _links
|
||||
.Where(l => !id.HasValue || l.Id == id)
|
||||
.OrderByDescending(l => l.CreatedAt)
|
||||
.Select(l => new LinkHomePage
|
||||
{
|
||||
Id = l.Id,
|
||||
Url = l.Url,
|
||||
Description = l.Description,
|
||||
CommentsCount = 0,
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,56 @@
|
||||
using HackerNet.Application;
|
||||
|
||||
namespace HackerNet.Infrastructure.Repositories.Memory;
|
||||
|
||||
public class MemoryReadStore : IReadStore
|
||||
{
|
||||
private readonly MemoryLinkRepository _linkRepository;
|
||||
private readonly MemoryCommentRepository _commentRepository;
|
||||
|
||||
public MemoryReadStore(MemoryLinkRepository linkRepository, MemoryCommentRepository commentRepository)
|
||||
{
|
||||
_linkRepository = linkRepository;
|
||||
_commentRepository = commentRepository;
|
||||
}
|
||||
|
||||
public LinkComment[] GetLinkComments(Guid linkId)
|
||||
=> _commentRepository.Comments
|
||||
.OrderByDescending(c => c.CreatedAt)
|
||||
.Select(c => new LinkComment
|
||||
{
|
||||
Content = c.Content
|
||||
}).ToArray();
|
||||
|
||||
public LinkHomePage GetLinkDetail(Guid id)
|
||||
=> GetLinks(id).Single();
|
||||
|
||||
public LinkHomePage[] GetPublishedLinks()
|
||||
{
|
||||
// return (from l in _links
|
||||
// orderby l.CreatedAt descending
|
||||
// select new LinkHomePage
|
||||
// {
|
||||
// Id = l.Id,
|
||||
// Url = l.Url,
|
||||
// Description = l.Description,
|
||||
// CommentsCount = 0,
|
||||
// }).ToArray();
|
||||
|
||||
return GetLinks().ToArray();
|
||||
}
|
||||
|
||||
private IEnumerable<LinkHomePage> GetLinks(Guid? id = null)
|
||||
{
|
||||
return _linkRepository.Links
|
||||
.Where(l => !id.HasValue || l.Id == id)
|
||||
.OrderByDescending(l => l.CreatedAt)
|
||||
.Select(l => new LinkHomePage
|
||||
{
|
||||
Id = l.Id,
|
||||
Url = l.Url,
|
||||
Description = l.Description,
|
||||
CommentsCount = _commentRepository.Comments
|
||||
.Count(c => c.LinkId == l.Id),
|
||||
});
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user