Almost finish implementing client side
This commit is contained in:
@@ -328,15 +328,15 @@ public class PostController(
|
||||
/// Get a paginated list of posts.
|
||||
/// </summary>
|
||||
/// <param name="query">Query to filter posts by tags. Use +tag-name to require a tag, -tag-name to exclude a tag.</param>
|
||||
/// <param name="pageNumber">The page number.</param>
|
||||
/// <param name="page">The page number.</param>
|
||||
/// <response code="200">The paginated list</response>
|
||||
/// <response code="400">If request is malformed</response>
|
||||
[HttpGet]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
||||
public async Task<ActionResult<PagedList<PostDto>>> GetAll(string? query, [Range(1, int.MaxValue)] int pageNumber = 1)
|
||||
public async Task<ActionResult<PagedList<PostDto>>> GetAll(string? query, [Range(1, int.MaxValue)] int page = 1)
|
||||
{
|
||||
var list = await postService.FindAll(query, pageNumber);
|
||||
var list = await postService.FindAll(query, page);
|
||||
var newItems = list.Items.Select(i =>
|
||||
{
|
||||
var fileUrl = Url.Action(nameof(PatchFileContent), "Post",
|
||||
@@ -494,7 +494,7 @@ public class PostController(
|
||||
/// Get paginated list of specific post comments.
|
||||
/// </summary>
|
||||
/// <param name="postId">Post ID</param>
|
||||
/// <param name="pageNumber">Page number</param>
|
||||
/// <param name="page">Page number</param>
|
||||
/// <response code="200">Paginated list of comments</response>
|
||||
/// <response code="400">If request is malformed</response>
|
||||
/// <response code="404">If post is not found</response>
|
||||
@@ -504,13 +504,13 @@ public class PostController(
|
||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||
public async Task<ActionResult<PagedList<CommentDto>>> GetAllComments(
|
||||
int postId,
|
||||
[Range(1, int.MaxValue)] int pageNumber = 1
|
||||
[Range(1, int.MaxValue)] int page = 1
|
||||
)
|
||||
{
|
||||
var post = await postService.GetById(postId);
|
||||
if (post == null) return NotFound();
|
||||
|
||||
var list = await commentService.GetAll(postId, pageNumber);
|
||||
var list = await commentService.GetAll(postId, page);
|
||||
var newItems = list.Items.Select(CommentDto.FromComment).ToList();
|
||||
return Ok(new PagedList<CommentDto>(newItems, list.CurrentPage, list.PageSize, list.TotalCount));
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ public class TagController(
|
||||
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
|
||||
[ProducesResponseType(StatusCodes.Status403Forbidden)]
|
||||
[ProducesResponseType(StatusCodes.Status409Conflict)]
|
||||
public async Task<ActionResult<Tag>> Create(CreateTagDto dto)
|
||||
public async Task<ActionResult<TagDto>> Create(CreateTagDto dto)
|
||||
{
|
||||
// Check if tag exists, if it does, throw a conflict
|
||||
var existingTag = await tagService.GetByName(dto.Name);
|
||||
@@ -44,21 +44,23 @@ public class TagController(
|
||||
}
|
||||
|
||||
var createdTag = await tagService.Create(dto.Type, dto.Name);
|
||||
return CreatedAtAction(nameof(Get), new { name = createdTag.Name }, createdTag);
|
||||
return CreatedAtAction(nameof(Get), new { name = createdTag.Name }, TagDto.FromTag(createdTag));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get a paginated list of tags.
|
||||
/// </summary>
|
||||
/// <param name="pageNumber">The page number</param>
|
||||
/// <param name="page">The page number</param>
|
||||
/// <response code="200">Returns paginated list</response>
|
||||
/// <response code="400">If request is malformed</response>
|
||||
[HttpGet]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
||||
public async Task<ActionResult<PagedList<Tag>>> GetAll(int pageNumber = 1)
|
||||
public async Task<ActionResult<PagedList<TagDto>>> GetAll(int page = 1)
|
||||
{
|
||||
return Ok(await tagService.GetAll(pageNumber));
|
||||
var list = await tagService.GetAll(page);
|
||||
var newItems = list.Items.Select(TagDto.FromTag).ToList();
|
||||
return Ok(new PagedList<TagDto>(newItems, list.CurrentPage, list.PageSize, list.TotalCount));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -72,14 +74,14 @@ public class TagController(
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||
public async Task<ActionResult<Tag>> Get(string name)
|
||||
public async Task<ActionResult<TagDto>> Get(string name)
|
||||
{
|
||||
var tag = await tagService.GetByName(name);
|
||||
if (tag == null)
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
return Ok(tag);
|
||||
return Ok(TagDto.FromTag(tag));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -122,12 +124,12 @@ public class TagController(
|
||||
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
|
||||
[ProducesResponseType(StatusCodes.Status403Forbidden)]
|
||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||
public async Task<ActionResult<Tag>> Update(string name, EditTagDto dto)
|
||||
public async Task<ActionResult<TagDto>> Update(string name, EditTagDto dto)
|
||||
{
|
||||
var tag = await tagService.GetByName(name);
|
||||
if (tag == null) return NotFound();
|
||||
var updatedTag = await tagService.Update(tag, dto.Type);
|
||||
return Ok(updatedTag);
|
||||
return Ok(TagDto.FromTag(updatedTag));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
namespace T120B165_ImgBoard.Dtos.Comment;
|
||||
|
||||
public record CommentDto(int Id, string Text, SlimUserDto Author)
|
||||
public record CommentDto(int Id, string Text, SlimUserDto Author, DateTime CreatedAt)
|
||||
{
|
||||
public static CommentDto FromComment(Models.Comment comment)
|
||||
{
|
||||
return new CommentDto(
|
||||
Id: comment.Id,
|
||||
Text: comment.Text,
|
||||
Author: SlimUserDto.FromUser(comment.Author)
|
||||
Author: SlimUserDto.FromUser(comment.Author),
|
||||
CreatedAt: comment.Created
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using T120B165_ImgBoard.Dtos.Tag;
|
||||
using File = T120B165_ImgBoard.Models.File;
|
||||
|
||||
namespace T120B165_ImgBoard.Dtos.Post;
|
||||
@@ -7,8 +8,9 @@ public record PostDto(
|
||||
string Title,
|
||||
string Description,
|
||||
SlimUserDto Author,
|
||||
List<Models.Tag> Tags,
|
||||
string? FileUrl
|
||||
List<TagDto> Tags,
|
||||
string? FileUrl,
|
||||
DateTime CreatedAt
|
||||
)
|
||||
{
|
||||
public static PostDto FromPost(Models.Post post, string? fileUrl)
|
||||
@@ -18,8 +20,9 @@ public record PostDto(
|
||||
Title: post.Title,
|
||||
Description: post.Description,
|
||||
Author: SlimUserDto.FromUser(post.Author),
|
||||
Tags: post.Tags,
|
||||
FileUrl: fileUrl
|
||||
Tags: post.Tags.Select(TagDto.FromTag).ToList(),
|
||||
FileUrl: fileUrl,
|
||||
CreatedAt: post.Created
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ public record CreateTagDto(
|
||||
TagType Type,
|
||||
[Required]
|
||||
[StringLength(64)]
|
||||
[RegularExpression(@"^[a-zA-Z0-9-]+$", ErrorMessage = "The name must only contain alphanumeric characters and hyphens.")]
|
||||
string Name
|
||||
);
|
||||
|
||||
|
||||
14
T120B165-ImgBoard/Dtos/Tag/TagDto.cs
Normal file
14
T120B165-ImgBoard/Dtos/Tag/TagDto.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
using T120B165_ImgBoard.Models;
|
||||
|
||||
namespace T120B165_ImgBoard.Dtos.Tag;
|
||||
|
||||
public record TagDto(string Name, TagType Type)
|
||||
{
|
||||
public static TagDto FromTag(Models.Tag tag)
|
||||
{
|
||||
return new TagDto(
|
||||
Name: tag.Name,
|
||||
Type: tag.Type
|
||||
);
|
||||
}
|
||||
};
|
||||
@@ -14,4 +14,6 @@ public class Tag
|
||||
public required string Name { get; init; }
|
||||
|
||||
public required TagType Type { get; set; }
|
||||
|
||||
public List<Post> Posts { get; set; }
|
||||
}
|
||||
|
||||
@@ -63,7 +63,8 @@ public class Program
|
||||
BearerFormat = "jwt"
|
||||
}));
|
||||
});
|
||||
|
||||
|
||||
builder.Services.AddCors();
|
||||
|
||||
builder.Services.AddIdentity<User, IdentityRole>()
|
||||
.AddEntityFrameworkStores<ImgBoardContext>()
|
||||
@@ -143,6 +144,13 @@ public class Program
|
||||
app.UseAuthentication();
|
||||
app.UseAuthorization();
|
||||
|
||||
app.UseCors(x => x
|
||||
.AllowAnyMethod()
|
||||
.AllowAnyHeader()
|
||||
.SetIsOriginAllowed(origin => true) // allow any origin
|
||||
//.WithOrigins("https://localhost:44351")); // Allow only this origin can also have multiple origins separated with comma
|
||||
.AllowCredentials()); // allow credentials
|
||||
|
||||
app.MapControllers();
|
||||
app.Run();
|
||||
}
|
||||
|
||||
@@ -13,7 +13,6 @@ public interface IPostService
|
||||
string title, string description, List<Tag> tags, User author,
|
||||
string fileName, string fileContentType, long fileSize);
|
||||
Task<Post?> GetById(int postId, bool includeUnfinished = false);
|
||||
Task<PagedList<Post>> GetAll(int pageNumber = 1);
|
||||
public Task<PagedList<Post>> FindAll(string? query, int pageNumber = 1);
|
||||
Task<bool> Delete(Post post);
|
||||
Task<Post> Update(Post post);
|
||||
@@ -23,7 +22,7 @@ public record CreatedPost(Post Post, File File);
|
||||
|
||||
public class PostService(ImgBoardContext context): IPostService
|
||||
{
|
||||
private const int PageSize = 20;
|
||||
private const int PageSize = 8;
|
||||
public async Task<CreatedPost> Create(
|
||||
string title,
|
||||
string description,
|
||||
@@ -71,20 +70,6 @@ public class PostService(ImgBoardContext context): IPostService
|
||||
.Include(b => b.File)
|
||||
.FirstOrDefaultAsync();
|
||||
}
|
||||
|
||||
public async Task<PagedList<Post>> GetAll(int pageNumber = 1)
|
||||
{
|
||||
var totalCount = await context.Posts.Where(p => p.File.FinishedDate != null).CountAsync();
|
||||
var items = await context.Posts
|
||||
.Skip((pageNumber - 1) * PageSize)
|
||||
.Take(PageSize)
|
||||
.Where(p => p.File.FinishedDate != null)
|
||||
.Include(b => b.Author)
|
||||
.Include(b => b.Tags)
|
||||
.Include(b => b.File)
|
||||
.ToListAsync();
|
||||
return new PagedList<Post>(items, pageNumber, PageSize, totalCount);
|
||||
}
|
||||
|
||||
public async Task<PagedList<Post>> FindAll(string? query, int pageNumber = 1)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user