diff --git a/docs/todo3.md b/docs/todo3.md
index 258945c..613f9c0 100644
--- a/docs/todo3.md
+++ b/docs/todo3.md
@@ -269,4 +269,6 @@ codesandbox embed
cva default styles vs default variant, primer
design transparent logo for default ogImage
astro 4.10 types and zod for env vars
+CategoryListCard
+small PostItem
```
diff --git a/src/components/CategoryCard.astro b/src/components/CategoryCard.astro
new file mode 100644
index 0000000..bbf075a
--- /dev/null
+++ b/src/components/CategoryCard.astro
@@ -0,0 +1,22 @@
+---
+import { Icon } from 'astro-icon/components';
+
+import { getCategoryIcon } from '@/modules/post';
+import { CATEGORIES } from '@/constants/collections';
+import { ROUTES } from '@/constants/routes';
+import { cn } from '@/utils/styles';
+
+export interface Props extends astroHTML.JSX.AnchorHTMLAttributes {
+ category: string;
+ text: string;
+}
+
+const { category, text, class: className, ...props } = Astro.props;
+
+const categoryIcon = getCategoryIcon(category);
+---
+
+
diff --git a/src/components/FilterList.astro b/src/components/FilterList.astro
index e0356d1..c163c86 100644
--- a/src/components/FilterList.astro
+++ b/src/components/FilterList.astro
@@ -1,5 +1,6 @@
---
import { getFilterLinks } from '@/modules/post';
+import CategoryCard from '@/components/CategoryCard.astro';
import Tag from '@/components/Tag.astro';
import { cn } from '@/utils/styles';
@@ -20,11 +21,14 @@ const itemLinks = getFilterLinks(items, pathname);
{
itemLinks.length > 0 && (
- {itemLinks.map(({ href, text, isActive, type }) => (
+ {itemLinks.map(({ href, text, textWithCount, isActive, type }) => (
-
-
- {text}
-
+ {type === 'tag' && (
+
+ {textWithCount}
+
+ )}
+ {type === 'category' && }
))}
diff --git a/src/components/PostMeta.astro b/src/components/PostMeta.astro
index 42545ed..a3e9307 100644
--- a/src/components/PostMeta.astro
+++ b/src/components/PostMeta.astro
@@ -6,6 +6,7 @@ import { CATEGORIES } from '@/constants/collections';
import { ROUTES } from '@/constants/routes';
import { formatDate, formatDateIso } from '@/utils/datetime';
import { cn } from '@/utils/styles';
+import { getCategoryIcon } from '@/modules/post';
interface Props {
publishDate: Date;
@@ -17,9 +18,6 @@ interface Props {
const { category, publishDate, updatedDate, readingTime, class: className } = Astro.props;
-const categoryIcon = CATEGORIES.find((item) => item.name === category)?.icon;
-
-
const shouldDisplay = Object.values(Astro.props).some(Boolean);
// add variance authority
// fix this html
@@ -36,7 +34,7 @@ const shouldDisplay = Object.values(Astro.props).some(Boolean);
)}
{category && (
ยท
-
+
{category}
)}
{readingTime && (
diff --git a/src/constants/collections.ts b/src/constants/collections.ts
index 2909456..02a95c5 100644
--- a/src/constants/collections.ts
+++ b/src/constants/collections.ts
@@ -20,6 +20,8 @@ export const TAGS = [
/** adjust this later */
export const CATEGORIES = [
+ // add color here
+ // extract find function
{
name: 'tutorials',
icon: 'mdi:teach',
@@ -50,6 +52,8 @@ export const CATEGORIES = [
},
] as const;
+export type CategoryIconType = (typeof CATEGORIES)[number]['icon'];
+
// todo: use imported images here
export const DEFAULTS_POST = {
NO_HERO: false,
diff --git a/src/modules/post.ts b/src/modules/post.ts
index 6122738..ed9e3a6 100644
--- a/src/modules/post.ts
+++ b/src/modules/post.ts
@@ -1,9 +1,10 @@
import { getAllEntries } from '@/modules/common';
-import { COLLECTIONS } from '@/constants/collections';
+import { CATEGORIES, COLLECTIONS } from '@/constants/collections';
import { ROUTES } from '@/constants/routes';
import { CONFIG } from '@/config';
import { renderMarkdown } from '@/utils/markdown';
+import type { CategoryIconType } from '@/constants/collections';
import type { Post, PostCollection } from '@/types/post';
import type { MarkdownProcessorRenderResult } from '@astrojs/markdown-remark';
import type { MarkdownHeading } from 'astro';
@@ -144,6 +145,8 @@ export interface Filter {
export interface FilterLink {
href: string;
text: string;
+ count: number;
+ textWithCount: string;
isActive: boolean;
type: FilterType;
}
@@ -156,12 +159,12 @@ export const getFilterLinks = (filterItems: Filter[], pathname?: string): Filter
const itemText = type === 'tag' ? `#${text}` : text;
const href = `${pathSegment}${text}`;
- const textWithCount = `${itemText}(${count})`;
+ const textWithCount = `${itemText} ${count}`;
// unused, wont display in category and tag list
const isActive = href === pathname;
- const link = { href, text: textWithCount, isActive, type };
+ const link = { href, text, count, textWithCount, isActive, type };
return link;
});
@@ -218,3 +221,13 @@ export const getSortedUniqueCategoriesWithCount = (posts: PostCollection[]): Fil
const sortedCategoriesWithCount = categoriesWithCount.slice().sort((a, b) => b.count - a.count);
return sortedCategoriesWithCount;
};
+
+export const getCategoryIcon = (category: string): CategoryIconType => {
+ // set default to prevent breaking build
+ const defaultIcon = CATEGORIES[0].icon;
+ const foundIcon = CATEGORIES.find((item) => item.name === category)?.icon;
+
+ const categoryIcon = foundIcon ?? defaultIcon;
+
+ return categoryIcon;
+};