feat: refactor blog components
This commit is contained in:
93
src/components/sections/CategorySection.astro
Normal file
93
src/components/sections/CategorySection.astro
Normal file
@@ -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<string, Post[]> = 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<string, Post[]>());
|
||||
|
||||
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,
|
||||
},
|
||||
};
|
||||
});
|
||||
---
|
||||
|
||||
<section class="mx-auto px-4 py-10 sm:px-6 lg:px-8 lg:py-14 lg:pt-10 2xl:max-w-full">
|
||||
<div class="grid grid-flow-row-dense grid-cols-2 md:grid-cols-4 gap-4">
|
||||
{categories.map((category) => {
|
||||
return (
|
||||
<div
|
||||
class={category.gridItemClass}
|
||||
style={category.layoutPattern.row > 1 ? 'grid-row: span 2 / span 2;' : ''}
|
||||
>
|
||||
<CategoryCard
|
||||
slug={category.slug}
|
||||
title={category.data.title}
|
||||
description={category.data.description}
|
||||
count={postMap.get(category.slug)?.length ?? 0}
|
||||
publishDate={timeago(postMap.get(category.slug)?.[0]?.published_date)}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</section>
|
||||
@@ -78,7 +78,7 @@ const experiences = ((await directus.request(
|
||||
</div>
|
||||
)}
|
||||
{(experience.responsibilities || experience.achievements) && (
|
||||
<div class="relative flex flex-col gap-4 max-sm:h-auto! md:after:absolute md:after:bottom-0 md:after:h-12 md:after:w-full md:after:bg-gradient-to-t md:after:from-neutral-200 dark:md:after:from-stone-700 md:after:content-[''] " :class="expanded ? 'after:hidden' : ''" x-show="expanded" x-collapse.min.50px>
|
||||
<div class="relative flex flex-col gap-4 max-sm:h-auto! md:after:absolute md:after:bottom-0 md:after:h-12 md:after:w-full md:after:bg-linear-to-t md:after:from-neutral-200 dark:md:after:from-stone-700 md:after:content-[''] " :class="expanded ? 'after:hidden' : ''" x-show="expanded" x-collapse.min.50px>
|
||||
{experience.responsibilities && (
|
||||
<div class="flex flex-col gap-1">
|
||||
<h4 class="text-header font-semibold">
|
||||
|
||||
@@ -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);
|
||||
---
|
||||
|
||||
<section class="mx-auto mb-20 max-w-340 px-4 py-10 sm:px-6 lg:px-8 lg:py-14 2xl:max-w-full">
|
||||
<div class="mx-auto mb-10 max-w-2xl text-center lg:mb-14">
|
||||
<h1 class="smooth-reveal card-text-header block">
|
||||
Latest Posts
|
||||
</h1>
|
||||
<div class="smooth-reveal mx-auto mt-5 max-w-3xl text-center">
|
||||
<span class="card-text-header-description">
|
||||
Checkout my most recent thoughts here
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="grid gap-6 sm:grid-cols-2 lg:grid-cols-3">
|
||||
{recentPosts.map((b) => <BlogCard post={b} />)}
|
||||
</div>
|
||||
</section>
|
||||
29
src/components/sections/RecentPostsSection.astro
Normal file
29
src/components/sections/RecentPostsSection.astro
Normal file
@@ -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;
|
||||
---
|
||||
|
||||
<section class="mx-auto mb-20 max-w-340 px-4 py-10 sm:px-6 lg:px-8 lg:py-14 2xl:max-w-full">
|
||||
<div class="mx-auto mb-10 max-w-2xl text-center lg:mb-14">
|
||||
<h1 class="smooth-reveal card-text-header block">
|
||||
{title}
|
||||
</h1>
|
||||
<div class="smooth-reveal mx-auto mt-5 max-w-3xl text-center">
|
||||
<span class="card-text-header-description">
|
||||
{subTitle}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="grid gap-6 sm:grid-cols-2 lg:grid-cols-3">
|
||||
{posts.map((b) => <BlogCard post={b} />)}
|
||||
</div>
|
||||
</section>
|
||||
36
src/components/sections/SelectedPostsSection.astro
Normal file
36
src/components/sections/SelectedPostsSection.astro
Normal file
@@ -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;
|
||||
---
|
||||
|
||||
<section class="smooth-reveal">
|
||||
{posts.map((b, index) => index % 2 === 0 ? (
|
||||
<LargeBlogLeftCard
|
||||
title={b.title}
|
||||
subTitle={b.description}
|
||||
url={`/blog/${b.slug}`}
|
||||
img={getDirectusImageURL(b.image)}
|
||||
imgAlt={b.image_alt}
|
||||
/>
|
||||
) : (
|
||||
<LargeBlogRightCard
|
||||
title={b.title}
|
||||
subTitle={b.description}
|
||||
url={`/blog/${b.slug}`}
|
||||
single={!b.image_second}
|
||||
imgOne={getDirectusImageURL(b.image)}
|
||||
imgOneAlt={b.image_alt}
|
||||
imgTwo={getDirectusImageURL(b?.image_second)}
|
||||
imgTwoAlt={b?.image_second_alt}
|
||||
/>
|
||||
))};
|
||||
</section>
|
||||
Reference in New Issue
Block a user