From ea35a301981be88ddd5f953187378b4e94cf1bcc Mon Sep 17 00:00:00 2001 From: poyrazavsever Date: Mon, 31 Aug 2026 09:28:01 +0300 Subject: [PATCH] refactor(content): separate blog and agenda feeds --- data/blog.ts | 69 +++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 65 insertions(+), 4 deletions(-) diff --git a/data/blog.ts b/data/blog.ts index 5e8dd16..2294d37 100644 --- a/data/blog.ts +++ b/data/blog.ts @@ -26,7 +26,15 @@ export type BlogPageData = { const DEFAULT_IMAGE = "/news/design.svg"; const DEFAULT_READ_TIME = "5 min"; -const BLOG_CATEGORIES = ["All", "Newsletter", "Frontend", "UX", "Software", "TypeScript", "Testing", "General"]; +const NEWSLETTER_CATEGORY = "Newsletter"; +const BLOG_CATEGORY_ORDER = [ + "Frontend", + "UX", + "Software", + "TypeScript", + "Testing", + "General", +]; function toTimestamp(value: string) { const timestamp = Date.parse(value); @@ -54,7 +62,11 @@ function normalizeCategory(value: string) { return value.trim().toLocaleLowerCase(); } -export async function getAllBlogArticles(locale?: string): Promise { +export function isNewsletterCategory(category: string) { + return normalizeCategory(category) === normalizeCategory(NEWSLETTER_CATEGORY); +} + +async function getAllArticles(locale?: string): Promise { const posts = await listBlogDetails(locale); const articles = posts.map((post) => ({ @@ -66,13 +78,25 @@ export async function getAllBlogArticles(locale?: string): Promise { + const articles = await getAllArticles(locale); + return articles.filter((article) => !isNewsletterCategory(article.category)); +} + +export async function getAllAgendaArticles(locale?: string): Promise { + const articles = await getAllArticles(locale); + return articles.filter((article) => isNewsletterCategory(article.category)); +} + export async function getHomeBlogNews(locale?: string, limit = 3) { const articles = await getAllBlogArticles(locale); @@ -94,7 +118,14 @@ export async function getBlogPageData( searchQueryParam?: string, ): Promise { const articles = await getAllBlogArticles(locale); - const categories = BLOG_CATEGORIES; + const availableCategories = new Set(articles.map((article) => article.category)); + const categories = [ + "All", + ...BLOG_CATEGORY_ORDER.filter((category) => availableCategories.has(category)), + ...[...availableCategories] + .filter((category) => !BLOG_CATEGORY_ORDER.includes(category)) + .sort((a, b) => a.localeCompare(b)), + ]; const categoryByNormalized = new Map( categories.map((category) => [normalizeCategory(category), category]), ); @@ -131,3 +162,33 @@ export async function getBlogPageData( currentPage, }; } + +export async function getAgendaPageData( + locale?: string, + page = 1, + pageSize = 12, + searchQueryParam?: string, +): Promise { + const articles = await getAllAgendaArticles(locale); + const searchQuery = (searchQueryParam ?? "").trim(); + const searchLower = searchQuery.toLocaleLowerCase(); + const filtered = searchLower + ? articles.filter( + (item) => + item.title.toLocaleLowerCase().includes(searchLower) || + item.excerpt.toLocaleLowerCase().includes(searchLower), + ) + : articles; + const totalPages = Math.max(1, Math.ceil(Math.max(filtered.length, 1) / pageSize)); + const currentPage = Math.min(Math.max(1, page), totalPages); + const start = (currentPage - 1) * pageSize; + + return { + articles: filtered.slice(start, start + pageSize), + categories: ["All"], + selectedCategory: "All", + searchQuery, + totalPages, + currentPage, + }; +}