Files
site-profile/src/components/sections/CategorySection.astro

94 lines
2.5 KiB
Plaintext

---
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>