From f48713c4703fc6a1f13479225da1af8244cdab2e Mon Sep 17 00:00:00 2001 From: Oliver Booth Date: Sun, 24 Sep 2023 17:03:06 +0100 Subject: [PATCH] feat: add tag filtering (resolves WEB-1) --- .../Controllers/Blog/BlogApiController.cs | 11 +++++++++ src/ts/API.ts | 5 ++++ src/ts/app.ts | 24 ++++++++++++++++++- 3 files changed, 39 insertions(+), 1 deletion(-) diff --git a/OliverBooth/Controllers/Blog/BlogApiController.cs b/OliverBooth/Controllers/Blog/BlogApiController.cs index 792186f..c0f8704 100644 --- a/OliverBooth/Controllers/Blog/BlogApiController.cs +++ b/OliverBooth/Controllers/Blog/BlogApiController.cs @@ -41,6 +41,17 @@ public sealed class BlogApiController : ControllerBase return Ok(allPosts.Select(post => CreatePostObject(post))); } + [HttpGet("posts/tagged/{tag}/{page:int?}")] + public IActionResult GetTaggedBlogPosts(string tag, int page = 0) + { + const int itemsPerPage = 10; + tag = tag.Replace('-', ' ').ToLowerInvariant(); + + IReadOnlyList allPosts = _blogPostService.GetBlogPosts(page, itemsPerPage); + allPosts = allPosts.Where(post => post.Tags.Contains(tag)).ToList(); + return Ok(allPosts.Select(post => CreatePostObject(post))); + } + [HttpGet("author/{id:guid}")] public IActionResult GetAuthor(Guid id) { diff --git a/src/ts/API.ts b/src/ts/API.ts index f8b1aeb..a1e070d 100644 --- a/src/ts/API.ts +++ b/src/ts/API.ts @@ -20,6 +20,11 @@ class API { return response.map(obj => new BlogPost(obj)); } + static async getBlogPostsByTag(tag: string, page: number): Promise { + const response = await API.getResponse(`posts/tagged/${tag}/${page}`); + return response.map(obj => new BlogPost(obj)); + } + static async getAuthor(id: string): Promise { const response = await API.getResponse(`author/${id}`); return new Author(response); diff --git a/src/ts/app.ts b/src/ts/app.ts index d69f389..39ee1f5 100644 --- a/src/ts/app.ts +++ b/src/ts/app.ts @@ -2,6 +2,7 @@ import API from "./API"; import UI from "./UI"; import Input from "./Input"; import Author from "./Author"; +import BlogPost from "./BlogPost"; declare const Handlebars: any; declare const Prism: any; @@ -27,6 +28,19 @@ declare const Prism: any; } }); + function getQueryVariable(variable: string): string { + const query = window.location.search.substring(1); + const vars = query.split("&"); + for (const element of vars) { + const pair = element.split("="); + if (pair[0] == variable) { + return pair[1]; + } + } + + return null; + } + Input.registerShortcut(Input.KONAMI_CODE, () => { window.open("https://www.youtube.com/watch?v=dQw4w9WgXcQ", "_blank"); }); @@ -46,7 +60,15 @@ declare const Prism: any; const template = Handlebars.compile(UI.blogPostTemplate.innerHTML); API.getBlogPostCount().then(async (count) => { for (let i = 0; i <= count / 10; i++) { - const posts = await API.getBlogPosts(i); + let posts: BlogPost[]; + + const tag = getQueryVariable("tag"); + if (tag !== null) { + posts = await API.getBlogPostsByTag(tag, i); + } else { + posts = await API.getBlogPosts(i); + } + for (const post of posts) { let author: Author; if (authors[post.authorId]) {