mirror of
https://github.com/kamranahmedse/developer-roadmap.git
synced 2025-08-29 20:21:50 +02:00
Add guide detail page
This commit is contained in:
42
src/components/GuideHeader.astro
Normal file
42
src/components/GuideHeader.astro
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
---
|
||||||
|
import type { GuideFileType } from '../lib/guide';
|
||||||
|
|
||||||
|
export interface Props {
|
||||||
|
guide: GuideFileType;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { guide } = Astro.props;
|
||||||
|
const { frontmatter } = guide;
|
||||||
|
const { author } = frontmatter;
|
||||||
|
---
|
||||||
|
|
||||||
|
<div class='bg-white border-b py-5 sm:py-12'>
|
||||||
|
<div class='container text-left sm:text-center'>
|
||||||
|
<p
|
||||||
|
class='text-gray-400 hidden sm:flex items-center justify-start sm:justify-center'
|
||||||
|
>
|
||||||
|
<a
|
||||||
|
href={author.url}
|
||||||
|
target='_blank'
|
||||||
|
class='font-medium hover:text-gray-600 inline-flex items-center hover:underline'
|
||||||
|
>
|
||||||
|
<img src={author.imageUrl} class='w-5 h-5 inline mr-2 rounded-full' />
|
||||||
|
{author.name}
|
||||||
|
</a>
|
||||||
|
<span class='mx-1.5'>·</span>
|
||||||
|
<span class='capitalize'>{frontmatter.type} Guide</span>
|
||||||
|
<span class='mx-1.5'>·</span>
|
||||||
|
<a
|
||||||
|
class='text-blue-400 hover:text-blue-500 hover:underline'
|
||||||
|
href={`https://github.com/kamranahmedse/roadmap.sh/tree/master/src/guides/${guide.id}.md`}
|
||||||
|
target='_blank'>Improve this Guide</a
|
||||||
|
>
|
||||||
|
</p>
|
||||||
|
<h1 class='text-2xl sm:text-5xl my-0 sm:my-3.5 font-bold'>
|
||||||
|
{frontmatter.title}
|
||||||
|
</h1>
|
||||||
|
<p class='hidden sm:block text-gray-400 text-md'>
|
||||||
|
{frontmatter.description}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
@@ -1,4 +1,4 @@
|
|||||||
import type { MarkdownFileType } from "./file";
|
import type { MarkdownFileType } from './file';
|
||||||
|
|
||||||
export interface GuideFrontmatter {
|
export interface GuideFrontmatter {
|
||||||
title: string;
|
title: string;
|
||||||
@@ -13,11 +13,11 @@ export interface GuideFrontmatter {
|
|||||||
description: string;
|
description: string;
|
||||||
};
|
};
|
||||||
isNew: boolean;
|
isNew: boolean;
|
||||||
type: "visual" | "textual";
|
type: 'visual' | 'textual';
|
||||||
date: string;
|
date: string;
|
||||||
sitemap: {
|
sitemap: {
|
||||||
priority: number;
|
priority: number;
|
||||||
changefreq: "daily" | "weekly" | "monthly" | "yealry";
|
changefreq: 'daily' | 'weekly' | 'monthly' | 'yealry';
|
||||||
};
|
};
|
||||||
tags: string[];
|
tags: string[];
|
||||||
}
|
}
|
||||||
@@ -33,7 +33,9 @@ export type GuideFileType = MarkdownFileType<GuideFrontmatter> & {
|
|||||||
* @returns unique guide identifier
|
* @returns unique guide identifier
|
||||||
*/
|
*/
|
||||||
function guidePathToId(filePath: string): string {
|
function guidePathToId(filePath: string): string {
|
||||||
return filePath.replace("/src/guides/", "").replace(".md", "");
|
const fileName = filePath.split('/').pop() || '';
|
||||||
|
|
||||||
|
return fileName.replace('.md', '');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -41,7 +43,7 @@ function guidePathToId(filePath: string): string {
|
|||||||
* @returns Promisifed guide files
|
* @returns Promisifed guide files
|
||||||
*/
|
*/
|
||||||
export async function getAllGuides(): Promise<GuideFileType[]> {
|
export async function getAllGuides(): Promise<GuideFileType[]> {
|
||||||
const guides = await import.meta.glob<GuideFileType>("/src/guides/*.md", {
|
const guides = await import.meta.glob<GuideFileType>('/src/guides/*.md', {
|
||||||
eager: true,
|
eager: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@@ -1,23 +0,0 @@
|
|||||||
---
|
|
||||||
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>
|
|
32
src/pages/guides/[guideId].astro
Normal file
32
src/pages/guides/[guideId].astro
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
---
|
||||||
|
import GuideHeader from '../../components/GuideHeader.astro';
|
||||||
|
import BaseLayout from '../../layouts/BaseLayout.astro';
|
||||||
|
import { getAllGuides, GuideFileType } from '../../lib/guide';
|
||||||
|
import '../../styles/prism.css';
|
||||||
|
|
||||||
|
export interface Props {
|
||||||
|
guide: GuideFileType;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function getStaticPaths() {
|
||||||
|
const guides = await getAllGuides();
|
||||||
|
|
||||||
|
return guides.map((guide) => ({
|
||||||
|
params: { guideId: guide.id },
|
||||||
|
props: { guide },
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
const { guideId } = Astro.params;
|
||||||
|
const { guide } = Astro.props;
|
||||||
|
---
|
||||||
|
|
||||||
|
<BaseLayout title='Simple Guide'>
|
||||||
|
<GuideHeader guide={guide} />
|
||||||
|
|
||||||
|
<div class='bg-gray-50 py-5 sm:py-10'>
|
||||||
|
<div class='container prose prose-code:bg-transparent prose-h2:text-3xl prose-h2:mt-4 prose-h2:mb-2 prose-h3:mt-2 prose-img:mt-1'>
|
||||||
|
<guide.Content />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</BaseLayout>
|
23
src/pages/guides/index.astro
Normal file
23
src/pages/guides/index.astro
Normal file
@@ -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>
|
@@ -44,8 +44,8 @@ code:not([class]) {
|
|||||||
padding: 2px 4px;
|
padding: 2px 4px;
|
||||||
font-family: 'Operator Mono', 'Fira Code', Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
|
font-family: 'Operator Mono', 'Fira Code', Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
|
||||||
font-size: .875rem;
|
font-size: .875rem;
|
||||||
background-color: #FAFAFA;
|
/* background-color: #FAFAFA;
|
||||||
border: 1px solid #EAEAEA;
|
border: 1px solid #EAEAEA; */
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user