parent
274060a08f
commit
9b74a5fa62
5 changed files with 129 additions and 6 deletions
@ -0,0 +1,40 @@ |
|||||||
|
--- |
||||||
|
import type { GuideFileType } from "../lib/guide"; |
||||||
|
|
||||||
|
export interface Props { |
||||||
|
guide: GuideFileType; |
||||||
|
} |
||||||
|
|
||||||
|
const { guide } = Astro.props; |
||||||
|
const { frontmatter, id } = guide; |
||||||
|
--- |
||||||
|
|
||||||
|
<a |
||||||
|
class:list={[ |
||||||
|
"block no-underline py-2 group text-md items-center text-gray-600 hover:text-blue-600 flex justify-between border-b", |
||||||
|
]} |
||||||
|
href={`/guides/${id}`} |
||||||
|
> |
||||||
|
<span class="group-hover:translate-x-2 transition-transform"> |
||||||
|
{frontmatter.title} |
||||||
|
|
||||||
|
{ |
||||||
|
frontmatter.isNew && ( |
||||||
|
<span class="bg-green-300 text-green-900 text-xs font-medium px-1.5 py-0.5 rounded-sm uppercase ml-1.5"> |
||||||
|
New |
||||||
|
<span class="hidden sm:inline"> |
||||||
|
· |
||||||
|
{new Date(frontmatter.date).toLocaleString("default", { |
||||||
|
month: "long", |
||||||
|
})} |
||||||
|
</span> |
||||||
|
</span> |
||||||
|
) |
||||||
|
} |
||||||
|
</span> |
||||||
|
<span class="capitalize text-gray-500 text-xs hidden sm:block"> |
||||||
|
{frontmatter.type} |
||||||
|
</span> |
||||||
|
|
||||||
|
<span class="text-gray-400 text-xs block sm:hidden"> »</span> |
||||||
|
</a> |
@ -0,0 +1,59 @@ |
|||||||
|
import type { MarkdownFileType } from "./file"; |
||||||
|
|
||||||
|
export interface GuideFrontmatter { |
||||||
|
title: string; |
||||||
|
description: string; |
||||||
|
author: { |
||||||
|
name: string; |
||||||
|
url: string; |
||||||
|
imageUrl: string; |
||||||
|
}; |
||||||
|
seo: { |
||||||
|
title: string; |
||||||
|
description: string; |
||||||
|
}; |
||||||
|
isNew: boolean; |
||||||
|
type: "visual" | "textual"; |
||||||
|
date: string; |
||||||
|
sitemap: { |
||||||
|
priority: number; |
||||||
|
changefreq: "daily" | "weekly" | "monthly" | "yealry"; |
||||||
|
}; |
||||||
|
tags: string[]; |
||||||
|
} |
||||||
|
|
||||||
|
export type GuideFileType = MarkdownFileType<GuideFrontmatter> & { |
||||||
|
id: string; |
||||||
|
}; |
||||||
|
|
||||||
|
/** |
||||||
|
* Generates id from the given guide file |
||||||
|
* @param filePath Markdown file path |
||||||
|
* |
||||||
|
* @returns unique guide identifier |
||||||
|
*/ |
||||||
|
function guidePathToId(filePath: string): string { |
||||||
|
return filePath.replace("/src/guides/", "").replace(".md", ""); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Gets all the guides sorted by the publishing date |
||||||
|
* @returns Promisifed guide files |
||||||
|
*/ |
||||||
|
export async function getAllGuides(): Promise<GuideFileType[]> { |
||||||
|
const guides = await import.meta.glob<GuideFileType>("/src/guides/*.md", { |
||||||
|
eager: true, |
||||||
|
}); |
||||||
|
|
||||||
|
const guideFiles = Object.values(guides); |
||||||
|
const enrichedGuides = guideFiles.map((guideFile) => ({ |
||||||
|
...guideFile, |
||||||
|
id: guidePathToId(guideFile.file), |
||||||
|
})); |
||||||
|
|
||||||
|
return enrichedGuides.sort( |
||||||
|
(a, b) => |
||||||
|
new Date(b.frontmatter.date).valueOf() - |
||||||
|
new Date(a.frontmatter.date).valueOf() |
||||||
|
); |
||||||
|
} |
@ -0,0 +1,23 @@ |
|||||||
|
--- |
||||||
|
import GuideListItem from "../components/GuideListItem.astro"; |
||||||
|
import SimplePageHeader from "../components/SimplePageHeader.astro"; |
||||||
|
import BaseLayout from "../layouts/BaseLayout.astro"; |
||||||
|
import { getAllGuides } from "../lib/guide"; |
||||||
|
|
||||||
|
const guides = await getAllGuides(); |
||||||
|
--- |
||||||
|
|
||||||
|
<BaseLayout title="Guides"> |
||||||
|
<SimplePageHeader |
||||||
|
title="Guides" |
||||||
|
description="Succinct graphical explanations to engineering topics." |
||||||
|
/> |
||||||
|
|
||||||
|
<div class="pb-20 pt-2 bg-gray-50"> |
||||||
|
<div class="container"> |
||||||
|
<div class="mt-3 sm:my-5"> |
||||||
|
{guides.map((guide) => <GuideListItem guide={guide} />)} |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</BaseLayout> |
Loading…
Reference in new issue