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); +--- + +
+ + {text} +
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 && ( 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; +};