using FastBlog.Core.Models; using FastBlog.Core.Models.Blogs; using FastBlog.Core.Services; using FastBlog.Web.Middlewares; using FastBlog.Web.Models; using Microsoft.AspNetCore.Mvc; namespace FastBlog.Web.Controllers; [Route("")] [Route("blogs")] public class BlogsController(BlogService service) : Controller { [HttpGet] [Route("{*slug}")] public async Task Index(string? slug) { if (string.IsNullOrWhiteSpace(slug)) slug = null; var blog = await service.GetPublished(slug); if (blog is null) return NotFound(); return View(blog); } [HttpGet] [Route("")] public async Task Index() { var blog = await service.GetPublished(null); if (blog is null) return NotFound(); return View(blog); } [SimpleAuth] [HttpGet] [Route("unpublished/{*slug}")] public async Task Unpublished(string? slug) { if (string.IsNullOrWhiteSpace(slug)) slug = null; var blog = await service.Get(slug); if (blog is null) return NotFound(); return View(blog); } [SimpleAuth] [HttpGet("list/edit")] public async Task ListEdit( [FromQuery(Name = "amount")] int amount = 25, [FromQuery(Name = "offset")] int offset = 0, [FromQuery(Name = "query")] string? query = null, [FromQuery(Name = "from")] DateTime? from = null, [FromQuery(Name = "to")] DateTime? to = null) { if(amount is < 1 or > 100) return BadRequest("Amount must be between 1 and 100"); if(offset < 0) return BadRequest("Offset must be greater than 0"); return View(await service.ListMetas(new BlogFilter(from,to, query), new PagedRequest(amount, offset))); } [SimpleAuth] [HttpGet] [Route("edit/{id:int?}")] public async ValueTask Edit(int? id) { if (!id.HasValue) { var date = DateTime.UtcNow; return View( new EditBlog { Text = "# My new blog", Title = "Blog from " + DateTime.UtcNow.ToString("g"), SourceLocation = $"{date:yyyy-MM-dd-HH-mm}_blog.md", CreatedAt = date, ModifiedAt = date, FullWidth = false, ShowDetails = true, Slug = "blog-" + date.ToString("yyyy-MM-dd-HH-mm"), Visible = false } ); } var blog = await service.GetForEdit(id.Value); if (blog is null) return NotFound(); return View(new EditBlog { Id = blog.Metadata.Id, Text = blog.Text, Title = blog.Metadata.Title, SourceLocation = blog.Metadata.SourceLocation, CreatedAt = blog.Metadata.CreatedAt, ModifiedAt = blog.Metadata.ModifiedAt, FullWidth = blog.Metadata.FullWidth, ShowDetails = blog.Metadata.ShowDetails, Slug = blog.Metadata.Slug, Visible = blog.Metadata.Visible, ImageUrl = blog.Metadata.ImageUrl, Signature = blog.Metadata.Signature }); } [SimpleAuth] [HttpPost] [Route("edit")] public async Task Edit([FromForm] EditBlog editBlog) { var result = await service.Update(new() { Text = editBlog.Text, Metadata = new() { Id = editBlog.Id, Title = editBlog.Title, Slug = editBlog.Slug, ShowDetails = editBlog.ShowDetailsStr is not null, ImageUrl = editBlog.ImageUrl, CreatedAt = editBlog.CreatedAt, ModifiedAt = editBlog.ModifiedAt, Signature = editBlog.Signature, FullWidth = editBlog.FullWidthStr is not null, Visible = editBlog.VisibleStr is not null, SourceLocation = editBlog.SourceLocation } }); if (result.IsError) { return result.AsError.ShortCode switch { "already_exists" => Conflict(), "not_found" => NotFound(), _ => throw result.AsError }; } return Redirect($"/blogs/{editBlog.Slug}"); } [SimpleAuth] [HttpPost] [Route("preview")] public IActionResult Preview([FromForm] EditBlog editBlog) { return View("Preview", new Blog { Text = editBlog.Text, Metadata = new() { Title = editBlog.Title, Slug = editBlog.Slug, ShowDetails = editBlog.ShowDetailsStr is not null, ImageUrl = editBlog.ImageUrl, CreatedAt = editBlog.CreatedAt, ModifiedAt = editBlog.ModifiedAt, Signature = editBlog.Signature, FullWidth = editBlog.FullWidthStr is not null, Visible = editBlog.VisibleStr is not null, SourceLocation = editBlog.SourceLocation } }); } [SimpleAuth] [HttpDelete] [Route("{id:int}")] public async Task Delete(int id) { var result = await service.Delete(id); if (!result) return NotFound(); HttpContext.Response.Headers.Append("Hx-Redirect", "/"); return Ok(); } }