diff --git a/BlogPlatform/BlogPlatform.csproj b/BlogPlatform/BlogPlatform.csproj
index 15a03ab..eefd7b6 100644
--- a/BlogPlatform/BlogPlatform.csproj
+++ b/BlogPlatform/BlogPlatform.csproj
@@ -18,13 +18,12 @@
+
-
-
diff --git a/BlogPlatform/DTO/Comment/Response/GetCommentDto.cs b/BlogPlatform/DTO/Comment/Response/GetCommentDto.cs
index e341d71..9170bad 100644
--- a/BlogPlatform/DTO/Comment/Response/GetCommentDto.cs
+++ b/BlogPlatform/DTO/Comment/Response/GetCommentDto.cs
@@ -5,6 +5,6 @@ public class GetCommentDto
public int Id { get; set; }
public string? Content { get; set; }
public DateOnly CreatedAt { get; set; }
- public int PostId { get; set; }
+ public int? PostId { get; set; }
public int UserId { get; set; }
}
\ No newline at end of file
diff --git a/BlogPlatform/DTO/Post/Request/PatchPostDecrementLikeDto.cs b/BlogPlatform/DTO/Post/Request/PatchPostDecrementLikeDto.cs
index 07cab01..2c53f7e 100644
--- a/BlogPlatform/DTO/Post/Request/PatchPostDecrementLikeDto.cs
+++ b/BlogPlatform/DTO/Post/Request/PatchPostDecrementLikeDto.cs
@@ -3,5 +3,4 @@ namespace BlogPlatform.DTO.Post.Request;
public class PatchPostDecrementLikeDto
{
public int Id { get; set; }
- public int Likes { get; set; }
}
\ No newline at end of file
diff --git a/BlogPlatform/DTO/Post/Request/PatchPostIncrementLikeDto.cs b/BlogPlatform/DTO/Post/Request/PatchPostIncrementLikeDto.cs
index d1e85e4..c597ec0 100644
--- a/BlogPlatform/DTO/Post/Request/PatchPostIncrementLikeDto.cs
+++ b/BlogPlatform/DTO/Post/Request/PatchPostIncrementLikeDto.cs
@@ -3,5 +3,4 @@ namespace BlogPlatform.DTO.Post.Request;
public class PatchPostIncrementLikeDto
{
public int Id { get; set; }
- public int Likes { get; set; }
}
\ No newline at end of file
diff --git a/BlogPlatform/Endpoints/Post/CreatePostEndpoint.cs b/BlogPlatform/Endpoints/Post/CreatePostEndpoint.cs
new file mode 100644
index 0000000..b64f71c
--- /dev/null
+++ b/BlogPlatform/Endpoints/Post/CreatePostEndpoint.cs
@@ -0,0 +1,41 @@
+using BlogPlatform.DTO.Post.Request;
+using BlogPlatform.DTO.Post.Response;
+using FastEndpoints;
+
+namespace BlogPlatform.Endpoints.Post;
+
+public class CreatePostEndpoint(BlogPlatformDbContext database) : Endpoint
+{
+ public override void Configure()
+ {
+ Post("/api/posts");
+ AllowAnonymous();
+ }
+
+ public override async Task HandleAsync(CreatePostDto req, CancellationToken ct)
+ {
+ var post = new Models.Post()
+ {
+ Title = req.Title,
+ Content = req.Content,
+ Likes = req.Likes,
+ CreatedAt = DateOnly.FromDateTime(DateTime.Now),
+ UserId = req.UserId
+ };
+
+ database.Posts.Add(post);
+ await database.SaveChangesAsync(ct);
+
+ GetPostDto responseDto = new()
+ {
+ Id = post.Id,
+ Title = post.Title,
+ Content = post.Content,
+ Likes = post.Likes,
+ CreatedAt = post.CreatedAt,
+ UserId = post.UserId
+ };
+
+ await Send.OkAsync(responseDto, ct);
+ }
+}
\ No newline at end of file
diff --git a/BlogPlatform/Endpoints/Post/GetAllPostsEndpoint.cs b/BlogPlatform/Endpoints/Post/GetAllPostsEndpoint.cs
new file mode 100644
index 0000000..6f48d54
--- /dev/null
+++ b/BlogPlatform/Endpoints/Post/GetAllPostsEndpoint.cs
@@ -0,0 +1,6 @@
+namespace BlogPlatform.Endpoints.Post;
+
+public class GetAllPostsEndpoint
+{
+
+}
\ No newline at end of file
diff --git a/BlogPlatform/Endpoints/Post/GetPostEndpoint.cs b/BlogPlatform/Endpoints/Post/GetPostEndpoint.cs
new file mode 100644
index 0000000..e514dbb
--- /dev/null
+++ b/BlogPlatform/Endpoints/Post/GetPostEndpoint.cs
@@ -0,0 +1,6 @@
+namespace BlogPlatform.Endpoints.Post;
+
+public class GetPostEndpoint
+{
+
+}
\ No newline at end of file
diff --git a/BlogPlatform/Endpoints/Post/PatchPostDecrementLikeEndpoint.cs b/BlogPlatform/Endpoints/Post/PatchPostDecrementLikeEndpoint.cs
new file mode 100644
index 0000000..de65147
--- /dev/null
+++ b/BlogPlatform/Endpoints/Post/PatchPostDecrementLikeEndpoint.cs
@@ -0,0 +1,53 @@
+using BlogPlatform.DTO.Comment.Response;
+using BlogPlatform.DTO.Post.Request;
+using BlogPlatform.DTO.Post.Response;
+using FastEndpoints;
+using Microsoft.EntityFrameworkCore;
+
+namespace BlogPlatform.Endpoints.Post;
+
+public class PatchPostDecrementLikeEndpoint(BlogPlatformDbContext database) : Endpoint
+{
+ public override void Configure()
+ {
+ Patch("/api/posts/{@Id}/DecrementLikes", x => new {x.Id});
+ AllowAnonymous();
+ }
+
+ public override async Task HandleAsync(PatchPostDecrementLikeDto req, CancellationToken ct)
+ {
+ var post = await database.Posts.SingleOrDefaultAsync(x => x.Id == req.Id, ct);
+
+ if (post == null)
+ {
+ await Send.NotFoundAsync(ct);
+ return;
+ }
+
+ if (post.Likes > 0)
+ {
+ post.Likes = post.Likes--;
+ }
+ else post.Likes = 0;
+ await database.SaveChangesAsync(ct);
+
+ GetPostDto responseDto = new()
+ {
+ Id = post.Id,
+ Title = post.Title,
+ Content = post.Content,
+ Likes = post.Likes,
+ CreatedAt = post.CreatedAt,
+ UserId = post.UserId,
+ Comments = post.Comments.Select(c => new GetCommentDto()
+ {
+ Id = c.Id,
+ Content = c.Content,
+ CreatedAt = c.CreatedAt,
+ UserId = c.UserId
+ }).ToList()
+ };
+
+ await Send.OkAsync(responseDto, ct);
+ }
+}
\ No newline at end of file
diff --git a/BlogPlatform/Endpoints/Post/PatchPostIncrementLikeEndpoint.cs b/BlogPlatform/Endpoints/Post/PatchPostIncrementLikeEndpoint.cs
new file mode 100644
index 0000000..44079db
--- /dev/null
+++ b/BlogPlatform/Endpoints/Post/PatchPostIncrementLikeEndpoint.cs
@@ -0,0 +1,49 @@
+using BlogPlatform.DTO.Comment.Response;
+using BlogPlatform.DTO.Post.Request;
+using BlogPlatform.DTO.Post.Response;
+using FastEndpoints;
+using Microsoft.EntityFrameworkCore;
+
+namespace BlogPlatform.Endpoints.Post;
+
+public class PatchPostIncrementLikeEndpoint(BlogPlatformDbContext database) : Endpoint
+{
+ public override void Configure()
+ {
+ Patch("/api/posts/{@Id}/IncrementLikes", x => new {x.Id});
+ AllowAnonymous();
+ }
+
+ public override async Task HandleAsync(PatchPostIncrementLikeDto req, CancellationToken ct)
+ {
+ var post = await database.Posts.SingleOrDefaultAsync(x => x.Id == req.Id, ct);
+
+ if (post == null)
+ {
+ await Send.NotFoundAsync(ct);
+ return;
+ }
+
+ post.Likes = post.Likes++;
+ await database.SaveChangesAsync(ct);
+
+ GetPostDto responseDto = new()
+ {
+ Id = post.Id,
+ Title = post.Title,
+ Content = post.Content,
+ Likes = post.Likes,
+ CreatedAt = post.CreatedAt,
+ UserId = post.UserId,
+ Comments = post.Comments.Select(c => new GetCommentDto()
+ {
+ Id = c.Id,
+ Content = c.Content,
+ CreatedAt = c.CreatedAt,
+ UserId = c.UserId
+ }).ToList()
+ };
+
+ await Send.OkAsync(responseDto, ct);
+ }
+}
\ No newline at end of file
diff --git a/BlogPlatform/Endpoints/Post/UpdatePostEndpoint.cs b/BlogPlatform/Endpoints/Post/UpdatePostEndpoint.cs
new file mode 100644
index 0000000..45be386
--- /dev/null
+++ b/BlogPlatform/Endpoints/Post/UpdatePostEndpoint.cs
@@ -0,0 +1,53 @@
+using BlogPlatform.DTO.Post.Request;
+using BlogPlatform.DTO.Post.Response;
+using FastEndpoints;
+using Microsoft.EntityFrameworkCore;
+
+namespace BlogPlatform.Endpoints.Post;
+
+public class UpdatePostEndpoint(BlogPlatformDbContext database) : Endpoint
+{
+ public override void Configure()
+ {
+ Put("/api/posts/{@Id}", x => new {x.Id});
+ AllowAnonymous();
+ }
+
+ public override async Task HandleAsync(UpdatePostDto req, CancellationToken ct)
+ {
+ var post = await database.Posts.SingleOrDefaultAsync(x => x.Id == req.Id, ct);
+
+ if (post == null)
+ {
+ await Send.NotFoundAsync(ct);
+ return;
+ }
+
+ var checkUser = await database.Users.SingleOrDefaultAsync(x => x.Id == req.UserId, ct);
+
+ if (checkUser == null)
+ {
+ await Send.NotFoundAsync(ct);
+ return;
+ }
+
+ post.Title = post.Title;
+ post.Content = post.Content;
+ post.Likes = post.Likes;
+ post.CreatedAt = DateOnly.FromDateTime(DateTime.Now);
+ post.UserId = post.UserId;
+ await database.SaveChangesAsync(ct);
+
+ GetPostDto responseDto = new()
+ {
+ Id = post.Id,
+ Title = post.Title,
+ Content = post.Content,
+ Likes = post.Likes,
+ CreatedAt = post.CreatedAt,
+ UserId = post.UserId
+ };
+
+ await Send.OkAsync(responseDto, ct);
+ }
+}
\ No newline at end of file
diff --git a/BlogPlatform/Endpoints/User/UserLoginEndpoint.cs b/BlogPlatform/Endpoints/User/UserLoginEndpoint.cs
new file mode 100644
index 0000000..b8ade14
--- /dev/null
+++ b/BlogPlatform/Endpoints/User/UserLoginEndpoint.cs
@@ -0,0 +1,47 @@
+using BlogPlatform.DTO.User.Request;
+using BlogPlatform.DTO.User.Response;
+using FastEndpoints;
+using FastEndpoints.Security;
+using Microsoft.EntityFrameworkCore;
+
+namespace BlogPlatform.Endpoints.User;
+
+public class UserLoginEndpoint(BlogPlatformDbContext database) : Endpoint
+{
+ public override void Configure()
+ {
+ Post("/api/user");
+ AllowAnonymous();
+ }
+
+ public override async Task HandleAsync(CreateUserDto req, CancellationToken ct)
+ {
+ var user = await database.Users.SingleOrDefaultAsync(x => x.Username == req.Username, ct);
+
+ if (user == null)
+ {
+ await Send.UnauthorizedAsync(ct);
+ return;
+ }
+
+ if (BCrypt.Net.BCrypt.Verify(req.Password + user.Salt, user.Password))
+ {
+ var jwtToken = JwtBearer.CreateToken(
+ o =>
+ {
+ o.SigningKey = "ThisIsASuperSecretJwtKeyThatIsAtLeast32CharsLong";
+ o.ExpireAt = DateTime.UtcNow.AddMinutes(15);
+ o.User.Claims.Add(("Username", user.Username)!);
+ o.User["UserId"] = "001";
+ });
+
+ GetUserDto responseDto = new()
+ {
+ Token = jwtToken
+ };
+
+ await Send.OkAsync(responseDto, ct);
+ }
+ else await Send.UnauthorizedAsync(ct);
+ }
+}
\ No newline at end of file