From 6423ffba639130cafd9d7d526588a6b707f81687 Mon Sep 17 00:00:00 2001 From: Alex Lebens Date: Mon, 16 Feb 2026 22:26:53 -0600 Subject: [PATCH] feat: refactor blog components --- src/components/blog/BlogCard.astro | 61 ------------ src/components/blog/BlogLeftSection.astro | 44 --------- src/components/blog/BlogRecentArticles.astro | 29 ------ src/components/blog/BlogRightSection.astro | 87 ----------------- .../blog/BlogSelectedArticles.astro | 44 --------- src/components/cards/BlogCard.astro | 58 +++++++++++ .../CategoryCard.astro} | 41 ++++---- src/components/cards/FeaturesCard.astro | 8 +- src/components/cards/HighlightsCard.astro | 6 +- src/components/cards/LargeBlogLeftCard.astro | 54 +++++++++++ src/components/cards/LargeBlogRightCard.astro | 82 ++++++++++++++++ src/components/cards/WeatherCard.astro | 4 +- src/components/sections/CategorySection.astro | 93 ++++++++++++++++++ .../sections/ExperienceSection.astro | 2 +- ...uresSection.astro => FeatureSection.astro} | 0 .../sections/LatestPostsSection.astro | 36 ------- .../sections/RecentPostsSection.astro | 29 ++++++ .../sections/SelectedPostsSection.astro | 36 +++++++ src/pages/404.astro | 2 + src/pages/blog/[...slug].astro | 19 ++-- src/pages/blog/index.astro | 31 ++++-- src/pages/categories/[...slug].astro | 16 +++- src/pages/categories/index.astro | 95 ++----------------- src/pages/index.astro | 36 +++++-- src/styles/utilities.css | 23 ++++- 25 files changed, 476 insertions(+), 460 deletions(-) delete mode 100644 src/components/blog/BlogCard.astro delete mode 100644 src/components/blog/BlogLeftSection.astro delete mode 100644 src/components/blog/BlogRecentArticles.astro delete mode 100644 src/components/blog/BlogRightSection.astro delete mode 100644 src/components/blog/BlogSelectedArticles.astro create mode 100644 src/components/cards/BlogCard.astro rename src/components/{blog/BlogCategoryCard.astro => cards/CategoryCard.astro} (53%) create mode 100644 src/components/cards/LargeBlogLeftCard.astro create mode 100644 src/components/cards/LargeBlogRightCard.astro create mode 100644 src/components/sections/CategorySection.astro rename src/components/sections/{FeaturesSection.astro => FeatureSection.astro} (100%) delete mode 100644 src/components/sections/LatestPostsSection.astro create mode 100644 src/components/sections/RecentPostsSection.astro create mode 100644 src/components/sections/SelectedPostsSection.astro diff --git a/src/components/blog/BlogCard.astro b/src/components/blog/BlogCard.astro deleted file mode 100644 index 2a38fee..0000000 --- a/src/components/blog/BlogCard.astro +++ /dev/null @@ -1,61 +0,0 @@ ---- -import { Icon } from 'astro-icon/components'; - -import type { Post } from '@lib/directusTypes'; - -import { getDirectusImageURL } from '@lib/directusFunctions'; -import Image from '@components/ui/images/Image.astro'; -import { formatDate } from '@support/time'; - -interface Props { - post: Post; -} - -const { post } = Astro.props; - -const baseClasses = 'group group-hover smooth-reveal-cards rounded-xl flex flex-col'; -const borderClasses = 'border border-stone-200/50 dark:border-stone-700/50'; -const bgColorClasses = - 'bg-neutral-100/80 hover:bg-neutral-100 dark:bg-neutral-800/60 dark:hover:bg-neutral-800/90'; -const shadowClasses = 'shadow-xs hover:shadow-md dark:shadow-md dark:hover:shadow-lg'; ---- - -
- -
- {post.image_alt} -
-
-

- {post.title} -

-
- Read more - -

- {formatDate(post.published_date)} -

-
-
-
-
diff --git a/src/components/blog/BlogLeftSection.astro b/src/components/blog/BlogLeftSection.astro deleted file mode 100644 index 61710f6..0000000 --- a/src/components/blog/BlogLeftSection.astro +++ /dev/null @@ -1,44 +0,0 @@ ---- -import GoLinkPrimaryButton from '@components/buttons/GoLinkPrimaryButton.astro'; -import Image from '@components/ui/images/Image.astro'; - -interface Props { - title: string; - subTitle: string; - btnExists?: boolean; - btnTitle?: string; - btnURL?: string; - img: any; - imgAlt: any; -} - -const { title, subTitle, btnExists, btnTitle, btnURL, img, imgAlt } = Astro.props; ---- - -
- {imgAlt} - -
-

- {title} -

-

- {subTitle} -

- {btnExists ? : null} -
-
diff --git a/src/components/blog/BlogRecentArticles.astro b/src/components/blog/BlogRecentArticles.astro deleted file mode 100644 index e3695ca..0000000 --- a/src/components/blog/BlogRecentArticles.astro +++ /dev/null @@ -1,29 +0,0 @@ ---- -import type { Post } from '@lib/directusTypes'; -import BlogCard from '@components/blog/BlogCard.astro'; - -interface Props { - posts: Post[]; -} - -const { posts } = Astro.props; ---- - -
-
-

- Recent Posts -

-
- -
-
-
- {posts.map((b) => )} -
-
-
-
diff --git a/src/components/blog/BlogRightSection.astro b/src/components/blog/BlogRightSection.astro deleted file mode 100644 index 2e2accc..0000000 --- a/src/components/blog/BlogRightSection.astro +++ /dev/null @@ -1,87 +0,0 @@ ---- -import GoLinkPrimaryButton from '@components/buttons/GoLinkPrimaryButton.astro'; -import Image from '@components/ui/images/Image.astro'; - -interface Props { - title: string; - subTitle: string; - btnExists?: boolean; - btnTitle?: string; - btnURL?: string; - single?: boolean; - imgOne?: any; - imgOneAlt?: any; - imgTwo?: any; - imgTwoAlt?: any; -} - -const { - title, - subTitle, - btnExists, - btnTitle, - btnURL, - single, - imgOne, - imgOneAlt, - imgTwo, - imgTwoAlt, -} = Astro.props; ---- - -
-
-

- {title} -

-

- {subTitle} -

- {btnExists ? : null} -
- - { - single ? ( -
- {imgOneAlt} -
- ) : ( -
- {imgOneAlt} - {imgTwoAlt} -
- ) - } -
diff --git a/src/components/blog/BlogSelectedArticles.astro b/src/components/blog/BlogSelectedArticles.astro deleted file mode 100644 index f99bb67..0000000 --- a/src/components/blog/BlogSelectedArticles.astro +++ /dev/null @@ -1,44 +0,0 @@ ---- -import type { Post } from '@lib/directusTypes'; - -import { getDirectusImageURL } from '@lib/directusFunctions'; -import BlogLeftSection from '@components/blog/BlogLeftSection.astro'; -import BlogRightSection from '@components/blog/BlogRightSection.astro'; - -interface Props { - posts: Post[]; -} - -const { posts } = Astro.props; ---- - -
- { - posts.map((b, index) => - index % 2 === 0 ? ( - - ) : ( - - ) - ) - } -
diff --git a/src/components/cards/BlogCard.astro b/src/components/cards/BlogCard.astro new file mode 100644 index 0000000..dce7950 --- /dev/null +++ b/src/components/cards/BlogCard.astro @@ -0,0 +1,58 @@ +--- +import { Icon } from 'astro-icon/components'; + +import type { Post } from '@lib/directusTypes'; + +import Image from '@components/ui/images/Image.astro'; +import { getDirectusImageURL } from '@lib/directusFunctions'; + +interface Props { + post: Post; +} + +const { post } = Astro.props; +--- + +
+ +
+ {post.image_alt} +
+
+

+ {post.title} +

+
+
+
+ + Read more + + +

+ {new Date(post.published_date).toLocaleDateString('en-US', { + year: 'numeric', + month: 'short', + day: 'numeric', + })} +

+
+
+
+
+
+
diff --git a/src/components/blog/BlogCategoryCard.astro b/src/components/cards/CategoryCard.astro similarity index 53% rename from src/components/blog/BlogCategoryCard.astro rename to src/components/cards/CategoryCard.astro index a824319..65da302 100644 --- a/src/components/blog/BlogCategoryCard.astro +++ b/src/components/cards/CategoryCard.astro @@ -8,37 +8,30 @@ interface Props { } const { slug, title, description, count, publishDate } = Astro.props; - -const baseClasses = - 'group group-hover rounded-xl flex h-full min-h-[220px] cursor-pointer flex-col overflow-hidden'; -const bgColorClasses = - 'bg-neutral-100/60 dark:bg-neutral-800/60 hover:bg-neutral-100 dark:hover:bg-neutral-800/90 '; --- - -
-
+
+ + diff --git a/src/components/cards/FeaturesCard.astro b/src/components/cards/FeaturesCard.astro index 794c50b..e4d5f69 100644 --- a/src/components/cards/FeaturesCard.astro +++ b/src/components/cards/FeaturesCard.astro @@ -9,13 +9,11 @@ interface Props { } const { title, description, url, icon } = Astro.props; - -const sizeClasses = 'h-30 w-100 md:w-[300px]'; ---
diff --git a/src/components/cards/HighlightsCard.astro b/src/components/cards/HighlightsCard.astro index bb07db3..f9cbb40 100644 --- a/src/components/cards/HighlightsCard.astro +++ b/src/components/cards/HighlightsCard.astro @@ -39,9 +39,9 @@ const visitClass = visitSource ? 'card-hover-text-gitea' : 'card-hover-text-titl {title} - +

{description} - +

{highlights && ( @@ -55,7 +55,7 @@ const visitClass = visitSource ? 'card-hover-text-gitea' : 'card-hover-text-titl )}
-
+
{visitSource && } {visitText} diff --git a/src/components/cards/LargeBlogLeftCard.astro b/src/components/cards/LargeBlogLeftCard.astro new file mode 100644 index 0000000..1f8f57d --- /dev/null +++ b/src/components/cards/LargeBlogLeftCard.astro @@ -0,0 +1,54 @@ +--- +import { Icon } from 'astro-icon/components'; + +import Image from '@components/ui/images/Image.astro'; + +interface Props { + title: string; + subTitle: string; + url?: string; + img: any; + imgAlt: any; +} + +const { title, subTitle, url, img, imgAlt } = Astro.props; +--- + + diff --git a/src/components/cards/LargeBlogRightCard.astro b/src/components/cards/LargeBlogRightCard.astro new file mode 100644 index 0000000..78d2c1b --- /dev/null +++ b/src/components/cards/LargeBlogRightCard.astro @@ -0,0 +1,82 @@ +--- +import { Icon } from 'astro-icon/components'; + +import Image from '@components/ui/images/Image.astro'; + +interface Props { + title: string; + subTitle: string; + url?: string; + single?: boolean; + imgOne?: any; + imgOneAlt?: any; + imgTwo?: any; + imgTwoAlt?: any; +} + +const { title, subTitle, url, single, imgOne, imgOneAlt, imgTwo, imgTwoAlt } = Astro.props; +--- + + diff --git a/src/components/cards/WeatherCard.astro b/src/components/cards/WeatherCard.astro index 87a29f1..c48d61e 100644 --- a/src/components/cards/WeatherCard.astro +++ b/src/components/cards/WeatherCard.astro @@ -7,12 +7,10 @@ interface Props { } const { dayName, label, icon, temp } = Astro.props; - -const sizeClasses = 'w-32 md:w-40'; ---
-
+
{dayName} diff --git a/src/components/sections/CategorySection.astro b/src/components/sections/CategorySection.astro new file mode 100644 index 0000000..5554779 --- /dev/null +++ b/src/components/sections/CategorySection.astro @@ -0,0 +1,93 @@ +--- +import { getCollection } from 'astro:content'; +import { readItems } from '@directus/sdk'; + +import type { Post } from '@lib/directusTypes'; + +import CategoryCard from '@components/cards/CategoryCard.astro'; +import directus from '@lib/directus'; +import { timeago } from '@support/time'; + +const posts = await directus.request( + readItems('posts', { + filter: { published: { _eq: true } }, + fields: ['*'], + sort: ['-published_date'], + }) +); + +const layoutPattern = [ + { col: 2, row: 2 }, + { col: 2, row: 1 }, + { col: 1, row: 1 }, + { col: 1, row: 1 }, + { col: 1, row: 2 }, + { col: 2, row: 1 }, + { col: 1, row: 1 }, + { col: 1, row: 1 }, + { col: 1, row: 1 }, + { col: 1, row: 1 }, +]; + +const postMap: Map = posts + .sort((a: Post, b: Post) => b.published_date.valueOf() - a.published_date.valueOf()) + .reduce((acc, obj) => { + let posts = acc.get(obj.category); + if (!posts) { + posts = []; + } + posts.push(obj); + + acc.set(obj.category, posts); + + return acc; + }, new Map()); + +const categories = (await getCollection('categories')) + .sort((a, b) => { + const aCount = postMap.get(a.slug)?.length ?? 0; + const bCount = postMap.get(b.slug)?.length ?? 0; + return bCount - aCount; + }) + .map((c, index) => { + const posts = postMap.get(c.slug); + const pattern = layoutPattern[index % layoutPattern.length]; + const smColSpan = Math.min(pattern.col, 2); + const mdColSpan = Math.min(pattern.col, 4); + const rowSpan = pattern.row; + const rowSpanClass = rowSpan > 1 ? `row-span-${rowSpan}` : 'row-span-1'; + const gridItemClass = `col-span-${smColSpan} md:col-span-${mdColSpan} ${rowSpanClass}`; + return { + ...c, + posts, + gridItemClass, + layoutPattern: { + smCol: smColSpan, + mdCol: mdColSpan, + row: rowSpan, + index, + }, + }; + }); +--- + +
+
+ {categories.map((category) => { + return ( +
1 ? 'grid-row: span 2 / span 2;' : ''} + > + +
+ ); + })} +
+
diff --git a/src/components/sections/ExperienceSection.astro b/src/components/sections/ExperienceSection.astro index 7b2c388..2e209fa 100644 --- a/src/components/sections/ExperienceSection.astro +++ b/src/components/sections/ExperienceSection.astro @@ -78,7 +78,7 @@ const experiences = ((await directus.request(
)} {(experience.responsibilities || experience.achievements) && ( -
+
{experience.responsibilities && (

diff --git a/src/components/sections/FeaturesSection.astro b/src/components/sections/FeatureSection.astro similarity index 100% rename from src/components/sections/FeaturesSection.astro rename to src/components/sections/FeatureSection.astro diff --git a/src/components/sections/LatestPostsSection.astro b/src/components/sections/LatestPostsSection.astro deleted file mode 100644 index d0c32e9..0000000 --- a/src/components/sections/LatestPostsSection.astro +++ /dev/null @@ -1,36 +0,0 @@ ---- -import { readItems } from '@directus/sdk'; - -import type { Post } from '@lib/directusTypes'; - -import directus from '@lib/directus'; -import BlogCard from '@components/blog/BlogCard.astro'; - -const posts = await directus.request( - readItems('posts', { - filter: { published: { _eq: true } }, - fields: ['*'], - sort: ['-published_date'], - }) -); - -const recentPosts = posts - .sort((a: Post, b: Post) => (new Date(b.published_date).getTime()) - (new Date(a.published_date).getTime())) - .slice(0, 3); ---- - -
-
-

- Latest Posts -

-
- - Checkout my most recent thoughts here - -
-
-
- {recentPosts.map((b) => )} -
-
diff --git a/src/components/sections/RecentPostsSection.astro b/src/components/sections/RecentPostsSection.astro new file mode 100644 index 0000000..ec221e0 --- /dev/null +++ b/src/components/sections/RecentPostsSection.astro @@ -0,0 +1,29 @@ +--- +import type { Post } from '@lib/directusTypes'; + +import BlogCard from '@components/cards/BlogCard.astro'; + +interface Props { + posts: Post[]; + title: string; + subTitle?: string; +} + +const { posts, title, subTitle } = Astro.props; +--- + +
+
+

+ {title} +

+
+ + {subTitle} + +
+
+
+ {posts.map((b) => )} +
+
diff --git a/src/components/sections/SelectedPostsSection.astro b/src/components/sections/SelectedPostsSection.astro new file mode 100644 index 0000000..9243ce8 --- /dev/null +++ b/src/components/sections/SelectedPostsSection.astro @@ -0,0 +1,36 @@ +--- +import type { Post } from '@lib/directusTypes'; + +import LargeBlogLeftCard from '@components/cards/LargeBlogLeftCard.astro'; +import LargeBlogRightCard from '@components/cards/LargeBlogRightCard.astro'; +import { getDirectusImageURL } from '@lib/directusFunctions'; + +interface Props { + posts: Post[]; +} + +const { posts } = Astro.props; +--- + +
+ {posts.map((b, index) => index % 2 === 0 ? ( + + ) : ( + + ))}; +
diff --git a/src/pages/404.astro b/src/pages/404.astro index 71ee475..5fe8822 100644 --- a/src/pages/404.astro +++ b/src/pages/404.astro @@ -28,6 +28,7 @@ const global = await directus.request(readSingleton('site_global')); }, }} > +
@@ -67,6 +68,7 @@ const global = await directus.request(readSingleton('site_global'));
+