mirror of
https://github.com/kamranahmedse/developer-roadmap.git
synced 2025-08-30 20:49:49 +02:00
Roadmap filtering by tags
This commit is contained in:
26
src/components/SimplePageHeader.astro
Normal file
26
src/components/SimplePageHeader.astro
Normal file
@@ -0,0 +1,26 @@
|
||||
---
|
||||
import YouTubeAlert from './YouTubeAlert.astro';
|
||||
|
||||
export interface Props {
|
||||
title: string;
|
||||
description: string;
|
||||
showYouTubeAlert?: boolean;
|
||||
}
|
||||
|
||||
const { title, description, showYouTubeAlert = false } = Astro.props;
|
||||
---
|
||||
|
||||
<div class="bg-white border-b pt-6 pb-5 sm:pt-12 sm:pb-10">
|
||||
<div class="container">
|
||||
{
|
||||
showYouTubeAlert && (
|
||||
<div class="mb-4 hidden sm:block">
|
||||
<YouTubeAlert />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
<h1 class="text-3xl sm:text-5xl mb-1 sm:mb-2 font-bold">{title}</h1>
|
||||
<p class="text-gray-500 text-sm sm:text-lg">{description}</p>
|
||||
</div>
|
||||
</div>
|
11
src/lib/File.ts
Normal file
11
src/lib/File.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
export interface MarkdownFileType<T = Record<string, string>> {
|
||||
frontmatter: T;
|
||||
file: string;
|
||||
url: string;
|
||||
Content: any;
|
||||
getHeadings: () => {
|
||||
depth: number;
|
||||
slug: string;
|
||||
text: string;
|
||||
}[];
|
||||
}
|
@@ -1,3 +1,7 @@
|
||||
import type { MarkdownFileType } from "./File";
|
||||
|
||||
type RoadmapFileType = MarkdownFileType<RoadmapFrontmatter>;
|
||||
|
||||
export interface RoadmapFrontmatter {
|
||||
id: string;
|
||||
jsonUrl: string;
|
||||
@@ -25,6 +29,11 @@ export interface RoadmapFrontmatter {
|
||||
tags: string[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the IDs of all the roadmaps available on the website
|
||||
*
|
||||
* @returns string[] Array of roadmap IDs
|
||||
*/
|
||||
export async function getRoadmapIds() {
|
||||
const roadmapFiles = await import.meta.glob<string>("/src/roadmaps/*/*.md", {
|
||||
eager: true,
|
||||
@@ -35,4 +44,24 @@ export async function getRoadmapIds() {
|
||||
|
||||
return fileName.replace(".md", "");
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the roadmap files which have the given tag assigned
|
||||
*
|
||||
* @param tag Tag assigned to roadmap
|
||||
* @returns Promisified RoadmapFileType[]
|
||||
*/
|
||||
export async function getRoadmapsByTag(tag: string): Promise<RoadmapFileType[]> {
|
||||
const roadmapFilesMap = await import.meta.glob<RoadmapFileType>(
|
||||
'/src/roadmaps/*/*.md',
|
||||
{
|
||||
eager: true,
|
||||
}
|
||||
);
|
||||
|
||||
const roadmapFiles: MarkdownFileType<RoadmapFrontmatter>[] = Object.values(roadmapFilesMap);
|
||||
const filteredRoadmaps = roadmapFiles.filter(roadmapFile => roadmapFile.frontmatter.tags.includes(tag));
|
||||
|
||||
return filteredRoadmaps;
|
||||
}
|
@@ -1,4 +1,4 @@
|
||||
import { joinPath } from './path';
|
||||
import type { MarkdownFileType } from './File';
|
||||
import type { RoadmapFrontmatter } from './roadmap';
|
||||
|
||||
// Generates URL from the topic file path e.g.
|
||||
@@ -64,24 +64,10 @@ export type BreadcrumbItem = {
|
||||
url: string;
|
||||
};
|
||||
|
||||
type FileHeadingType = {
|
||||
depth: number;
|
||||
slug: string;
|
||||
text: string;
|
||||
};
|
||||
|
||||
export interface TopicFileContentType {
|
||||
frontMatter: Record<string, string>;
|
||||
file: string;
|
||||
url: string;
|
||||
Content: any;
|
||||
getHeadings: () => FileHeadingType[];
|
||||
}
|
||||
|
||||
export interface TopicFileType {
|
||||
url: string;
|
||||
text: string;
|
||||
file: TopicFileContentType;
|
||||
file: MarkdownFileType;
|
||||
roadmap: RoadmapFrontmatter;
|
||||
roadmapId: string;
|
||||
breadcrumbs: BreadcrumbItem[];
|
||||
@@ -102,7 +88,7 @@ export async function getTopicFiles(): Promise<Record<string, TopicFileType>> {
|
||||
const mapping: Record<string, TopicFileType> = {};
|
||||
|
||||
for (let filePath of Object.keys(contentFiles)) {
|
||||
const fileContent: TopicFileContentType = contentFiles[filePath] as any;
|
||||
const fileContent: MarkdownFileType = contentFiles[filePath] as any;
|
||||
const fileHeadings = fileContent.getHeadings();
|
||||
const firstHeading = fileHeadings[0];
|
||||
|
||||
|
25
src/pages/roadmaps.astro
Normal file
25
src/pages/roadmaps.astro
Normal file
@@ -0,0 +1,25 @@
|
||||
---
|
||||
import SimplePageHeader from '../components/SimplePageHeader.astro';
|
||||
import BaseLayout from '../layouts/BaseLayout.astro';
|
||||
import { getRoadmapsByTag } from '../lib/roadmap';
|
||||
|
||||
const roleRoadmaps = await getRoadmapsByTag('role-roadmap');
|
||||
const skillRoadmaps = await getRoadmapsByTag('skill-roadmap');
|
||||
---
|
||||
|
||||
<BaseLayout title="Roadmap">
|
||||
<SimplePageHeader
|
||||
title="Developer Roadmaps"
|
||||
description="Step by step guides and paths to learn different tools or technologies"
|
||||
showYouTubeAlert={true}
|
||||
/>
|
||||
|
||||
<div class="bg-gray-100 pt-4 pb-14 sm:pt-8 sm:pb-16">
|
||||
<div class="container">
|
||||
<div class="grid grid-cols-1 sm:grid-cols-2 gap-0.5 sm:gap-3">
|
||||
<h1>{ roleRoadmaps.length }</h1>
|
||||
<h1>{ skillRoadmaps.length }</h1>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</BaseLayout>
|
Reference in New Issue
Block a user