Skip to content

Commit

Permalink
feat: filter by category
Browse files Browse the repository at this point in the history
  • Loading branch information
GioPan04 committed Mar 21, 2024
1 parent dd2f0c9 commit c440bff
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 15 deletions.
2 changes: 1 addition & 1 deletion src/components/CategoryChip.astro
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
<span class="mx-1 my-2 bg-accent/70 rounded-xl px-2 w-fit">
<span class="mx-1 my-2 bg-accent/70 rounded-xl py-1 px-2">
<slot />
</span>
33 changes: 19 additions & 14 deletions src/pages/blog/index.astro
Original file line number Diff line number Diff line change
@@ -1,21 +1,12 @@
---
import { format } from 'date-fns';
import { format, isAfter } from 'date-fns';
import Layout from '../../layouts/Layout.astro';
import type IPost from '../../types/post.ts';
import CategoryChip from '../../components/CategoryChip.astro';
import { getPostsCategories } from '../../repositories/blog';
const posts = (await Astro.glob<IPost>('./posts/[!_]*.md')).reverse();
const tags: {[name: string]: number} = {};
posts.forEach((p) => {
p.frontmatter.tags.forEach((t) => {
if (tags[t] === undefined) {
tags[t] = 1;
} else {
tags[t]++;
}
});
});
const tags = getPostsCategories(posts);
---

<Layout title="Blog">
Expand All @@ -26,7 +17,13 @@ posts.forEach((p) => {
<div class="lg:hidden">
<h3 class="font-pixel text-xl mb-3">Categories</h3>
<div class="flex -ml-1 overflow-x-auto">
{ Object.entries(tags).map((t, _) => <CategoryChip>{t[0]}</CategoryChip>) }
{ Object.entries(tags).map(([t, n], _) => (
<a href={`/blog/tag/${t}`}>
<CategoryChip>
{t}<span class="ml-1 text-xs inline-block"> - {n}</span>
</CategoryChip>
</a>
)) }
</div>
</div>
<div class="mt-10 lg:grid grid-cols-3">
Expand All @@ -39,14 +36,22 @@ posts.forEach((p) => {
<h3 class="text-2xl mb-2">{ p.frontmatter.title } <span class="text-xs text-white/60"> - { format(p.frontmatter.pubDate, 'dd/MM/yyyy') }</span></h3>
<p class="text-white/80 text-sm">{ p.frontmatter.description }</p>
</a>

{ JSON.stringify(isAfter(p.frontmatter.pubDate, new Date(2023, 0, 1))) }
</article>
)) }
</div>
</div>
<div class="ml-16 hidden lg:block">
<h3 class="font-pixel text-xl text-right mb-3">Categories</h3>
<div class="flex flex-wrap justify-end -mr-1 -mt-2">
{ Object.entries(tags).map((t, _) => <CategoryChip>{t[0]}<span class="ml-1 text-xs -translate-y-0.5 inline-block"> ({t[1]})</span></CategoryChip>) }
{ Object.entries(tags).map(([t, n], _) => (
<a href={`/blog/tag/${t}`}>
<CategoryChip>
{t}<span class="ml-1 text-xs inline-block"> - {n}</span>
</CategoryChip>
</a>
)) }
</div>
</div>
</div>
Expand Down
42 changes: 42 additions & 0 deletions src/pages/blog/tag/[tag].astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
---
import IPost from '../../../types/post';
import { getPostsCategories, filterPosts } from '../../../repositories/blog';
import Layout from '../../../layouts/Layout.astro';
import { format } from 'date-fns';
export const getStaticPaths = async () => {
const posts = await Astro.glob<IPost>('../posts/[!_]*.md');
const tags = getPostsCategories(posts);
return Object.entries(tags).map(([tag, n]) => {
return {
params: { tag }
}
});
};
const { tag } = Astro.params;
const posts = filterPosts(await Astro.glob<IPost>('../posts/[!_]*.md'), { tag }).reverse();
---

<Layout title="Blog">
<div class="mt-10 mb-16">
<h1 class="font-pixel text-3xl text-center mb-2">Gioele's blog</h1>
<span class="text-sm text-white/60 text-center block">aka: a nerd's blog</span>
</div>
<div class="mt-10">
<div>
<h3 class="font-pixel text-xl mb-3 leading-loose sm:leading-normal">Latest posts tagged <span class="bg-white/5 -ml-2 pl-3 p-2 rounded">{tag}</span></h3>
<div class="space-y-5 divide-y divide-white/10">
{ posts.map((p) => (
<article class="pt-5 first:pt-0">
<a href={p.url}>
<h3 class="text-2xl mb-2">{ p.frontmatter.title } <span class="text-xs text-white/60"> - { format(p.frontmatter.pubDate, 'dd/MM/yyyy') }</span></h3>
<p class="text-white/80 text-sm">{ p.frontmatter.description }</p>
</a>
</article>
)) }
</div>
</div>
</div>
</Layout>
41 changes: 41 additions & 0 deletions src/repositories/blog.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import type { MarkdownInstance } from 'astro';
import type IPost from '../types/post';
import { isAfter, isBefore } from 'date-fns';

interface ITags {
[name: string]: number
}

type Posts = MarkdownInstance<IPost>[];

export const getPostsCategories = (posts: Posts) : ITags => {
const tags: ITags = {};

posts.forEach((p) => {
p.frontmatter.tags.forEach((t) => {
if (tags[t] === undefined) {
tags[t] = 1;
} else {
tags[t]++;
}
});
});

return tags;
}

interface PostFilter {
tag?: string;
date?: {
after?: string | number | Date;
before?: string | number | Date
}
}

export const filterPosts = (posts: Posts, filter?: PostFilter): Posts => {
return posts.filter((p) =>
(filter?.tag === undefined ? true : p.frontmatter.tags.includes(filter.tag)) &&
(filter?.date?.after === undefined ? true : isAfter(p.frontmatter.pubDate, filter.date.after)) &&
(filter?.date?.before === undefined ? true : isBefore(p.frontmatter.pubDate, filter.date.before))
);
}

0 comments on commit c440bff

Please sign in to comment.