From 1fd51a6a3f2bbfc78544d785418fd1036872dbb7 Mon Sep 17 00:00:00 2001 From: itsfinniii <102350242+itsfinniii@users.noreply.github.com> Date: Thu, 26 Mar 2026 22:03:03 +0100 Subject: [PATCH] Create Last Blogs component with responsive design --- astro/src/components/web/LastBlogs.astro | 60 +++++++++++++++ astro/src/components/webpage/Webpage.astro | 2 + astro/src/content/blogs/blogs.ts | 74 ++++++++++++++++++- .../graphql/blogs/getLastBlogPosts.graphql | 39 ++++++++++ 4 files changed, 174 insertions(+), 1 deletion(-) create mode 100644 astro/src/components/web/LastBlogs.astro create mode 100644 astro/src/graphql/blogs/getLastBlogPosts.graphql diff --git a/astro/src/components/web/LastBlogs.astro b/astro/src/components/web/LastBlogs.astro new file mode 100644 index 0000000..2d40dba --- /dev/null +++ b/astro/src/components/web/LastBlogs.astro @@ -0,0 +1,60 @@ +--- +import { getLastBlogs } from '@/content/blogs/blogs'; +import { getSettings } from '@/content/settings/settings'; +import CalendarIcon from '@/icons/CalendarIcon.astro'; +import { getImageUrl } from '@/lib/images'; +import { getBlogRoute } from '@/lib/routing'; +import type { ACTION_ERROR_CODES } from 'astro:actions'; +import { Image } from 'astro:assets'; + +interface Props { + blogs: LastBlogsComponent; +} + +function calculateSizeClasses(amount: number, length: number) { + if (amount === 2 || length <= 2) { + return "lg:w-[45%] w-full"; + } + else { + return "lg:w-[31%] w-full"; + } +} + +const blogs = Astro.props.blogs; +const settings = await getSettings(); +const lastBlogs = await getLastBlogs(blogs.amount); +const size = calculateSizeClasses(blogs.amount, lastBlogs.length); +--- + +
+
+

{blogs.title}

+
+ + {blogs.readMoreButtonText} + +
+
+ +
+ { lastBlogs.map((blog) => ( + + {blog.title} +

{blog.title}

+
+ +
{blog.date}
+
+
+ )) } +
+
diff --git a/astro/src/components/webpage/Webpage.astro b/astro/src/components/webpage/Webpage.astro index 195b134..4900ee9 100644 --- a/astro/src/components/webpage/Webpage.astro +++ b/astro/src/components/webpage/Webpage.astro @@ -6,6 +6,7 @@ import UpcomingEvents from '../web/UpcomingEvents.astro'; import WallOfText from '../web/WallOfText.astro'; import EquipmentTable from '../web/EquipmentTable.astro'; import Reviews from '../web/Reviews.astro'; +import LastBlogs from '../web/LastBlogs.astro'; interface Props { webpage: WebpageComponent[]; @@ -26,6 +27,7 @@ console.log(Astro.props.webpage); { component.component === "FrequentlyAskedQuestions" && } { component.component === "EquipmentTable" && } { component.component === "Reviews" && } + { component.component === "LastBlogs" && } )) } diff --git a/astro/src/content/blogs/blogs.ts b/astro/src/content/blogs/blogs.ts index 69db695..6f83001 100644 --- a/astro/src/content/blogs/blogs.ts +++ b/astro/src/content/blogs/blogs.ts @@ -2,6 +2,7 @@ import { createDirectusConnection } from "@/lib/directus"; import { print } from 'graphql'; import getBlogs from '@/graphql/blogs/getBlogs.graphql'; import getBlogPost from '@/graphql/blogs/getBlog.graphql'; +import getLastBlogPosts from '@/graphql/blogs/getLastBlogPosts.graphql'; import { formatDate } from "@/lib/dates"; export async function getAllBlogs(settings: GlobalSettings): Promise { @@ -24,6 +25,7 @@ export async function getAllBlogs(settings: GlobalSettings): Promise ]; const blog: BlogPost = { + exists: true, type: "BlogPost", id: blogRecord["id"], lastModified: new Date(), @@ -93,8 +95,8 @@ export async function getBlog(settings: GlobalSettings, route: string): Promise< ]; const blog: BlogPost = { - type: "BlogPost", exists: true, + type: "BlogPost", id: blogRecord["id"], lastModified: new Date(), title: blogRecord["title"], @@ -140,3 +142,73 @@ export async function getBlog(settings: GlobalSettings, route: string): Promise< return blog; } + +export async function getLastBlogs(amount: number): Promise { + const client = await createDirectusConnection(); + const result = await client.query(print(getLastBlogPosts), { + date: formatDate(new Date(), "%Y-%M-%D"), + amount: amount + }); + + let blogs: BlogPost[] = []; + + result["Blogs"].forEach((blogRecord: any) => { + let dates: string[] = [ + blogRecord["date_created"], + blogRecord["date_updated"], + blogRecord["search_engine"][0]["date_created"], + blogRecord["search_engine"][0]["date_updated"], + blogRecord["search_engine"][0]["thumbnail"]["created_on"] + ]; + + const blog: BlogPost = { + exists: true, + type: "BlogPost", + id: blogRecord["id"], + lastModified: new Date(), + title: blogRecord["title"], + content: blogRecord["content"], + date: blogRecord["date"], + url: blogRecord["url"], + searchEngine: { + title: blogRecord["search_engine"][0]["title"], + description: blogRecord["search_engine"][0]["description"], + allowCrawlers: blogRecord["search_engine"][0]["allow_crawler"], + canonical: blogRecord["search_engine"][0]["canonical"], + priority: blogRecord["search_engine"][0]["priority"], + thumbnail: { + url: blogRecord["search_engine"][0]["thumbnail"]["filename_disk"], + height: blogRecord["search_engine"][0]["thumbnail"]["height"], + width: blogRecord["search_engine"][0]["thumbnail"]["width"] + } + }, + tags: [] + }; + + blogRecord["tags"].forEach((tagRecord: any) => { + blog["tags"].push({ + text: tagRecord["Tags_id"]["text"], + code: tagRecord["Tags_id"]["code"], + color: tagRecord["Tags_id"]["color"] + }); + + dates.push(tagRecord["Tags_id"]["date_created"]); + dates.push(tagRecord["Tags_id"]["date_updated"]); + }); + + if (dates.filter(e => e !== null).length === 0) { + blog.lastModified = new Date(); + } + else { + const sortedDates: string[] = dates.sort((a: string, b: string) => { + return new Date(b).getTime() - new Date(a).getTime(); + }); + + blog.lastModified = new Date(sortedDates[0]); + } + + blogs.push(blog); + }); + + return blogs; +} diff --git a/astro/src/graphql/blogs/getLastBlogPosts.graphql b/astro/src/graphql/blogs/getLastBlogPosts.graphql new file mode 100644 index 0000000..ee3f90e --- /dev/null +++ b/astro/src/graphql/blogs/getLastBlogPosts.graphql @@ -0,0 +1,39 @@ +query getLastBlogPosts($date: String!, $amount: Int!) { + Blogs(sort: ["-date", "-date_created"], filter: { status: { _eq: "published" }, date: { _lte: $date } }, limit: $amount) { + id, + date_created, + date_updated, + status, + title, + url, + date, + content, + tags { + Tags_id { + id, + date_created, + date_updated, + text, + code, + color + } + }, + search_engine { + id, + date_created, + date_updated, + title, + description, + thumbnail { + id, + created_on, + filename_disk, + width, + height + }, + canonical, + allow_crawler, + priority + } + } +}