Topics listing page

astro
Kamran Ahmed 2 years ago
parent 6f337f6b53
commit 32761b5587
  1. 2
      src/components/TopicOverlay.astro
  2. 67
      src/lib/topic.ts
  3. 2
      src/pages/[...topicId].astro
  4. 2
      src/pages/[roadmapId]/topics.astro

@ -24,7 +24,7 @@ import Loader from "./Loader.astro";
</button> </button>
</div> </div>
<div id='topic-content' class='prose prose-h1:mt-7 prose-h1:mb-2.5 prose-p:mt-0 prose-p:mb-2 prose-li:m-0 prose-li:mb-0.5'></div> <div id='topic-content' class='prose prose-h1:mt-7 prose-h1:mb-2.5 prose-p:mt-0 prose-p:mb-2 prose-li:m-0 prose-li:mb-0.5 prose-h2:mb-3 prose-h2:mt-0'></div>
</div> </div>
<div class="bg-gray-900 bg-opacity-50 dark:bg-opacity-80 fixed inset-0 z-30"></div> <div class="bg-gray-900 bg-opacity-50 dark:bg-opacity-80 fixed inset-0 z-30"></div>
</div> </div>

@ -87,6 +87,10 @@ export interface TopicFileType {
breadcrumbs: BreadcrumbItem[]; breadcrumbs: BreadcrumbItem[];
} }
/**
* Gets all the topic files available for all the roadmaps
* @returns Hashmap containing the topic slug and the topic file content
*/
export async function getTopicFiles(): Promise<Record<string, TopicFileType>> { export async function getTopicFiles(): Promise<Record<string, TopicFileType>> {
const contentFiles = await import.meta.glob<string>( const contentFiles = await import.meta.glob<string>(
'/src/roadmaps/*/content/**/*.md', '/src/roadmaps/*/content/**/*.md',
@ -152,6 +156,64 @@ export async function getTopicFiles(): Promise<Record<string, TopicFileType>> {
return mapping; return mapping;
} }
// [
// '/frontend/internet/how-does-the-internet-work',
// '/frontend/internet/what-is-http',
// '/frontend/internet/browsers-and-how-they-work',
// '/frontend/internet/dns-and-how-it-works',
// '/frontend/internet/what-is-domain-name',
// '/frontend/internet/what-is-hosting',
// '/frontend/internet',
// '/frontend/html/learn-the-basics',
// '/frontend/html/writing-semantic-html',
// '/frontend/html/forms-and-validations',
// '/frontend/html/conventions-and-best-practices',
// '/frontend/html/accessibility',
// '/frontend/html/seo-basics',
// '/frontend/html',
// '/frontend/css/learn-the-basics',
// '/frontend/css/making-layouts',
// '/frontend/css/responsive-design-and-media-queries',
// '/frontend/css',
// '/frontend/javascript/syntax-and-basic-constructs',
// '/frontend/javascript/learn-dom-manipulation',
// '/frontend/javascript/learn-fetch-api-ajax-xhr',
// '/frontend/javascript/es6-and-modular-javascript',
// '/frontend/javascript/concepts',
// '/frontend/javascript',
// '/frontend/version-control-systems/basic-usage-of-git',
// '/frontend/version-control-systems'
// ]
export async function sortTopics(topics: TopicFileType[]): Promise<TopicFileType[]> {
let sortedTopics: TopicFileType[] = [];
// For each of the topic, find its place in the sorted topics
for (let i = 0; i < topics.length; i++) {
const currTopic = topics[i];
const currUrl = currTopic.url;
let isPlaced = false;
// Find the first sorted topic which starts with the current topic
for (let j = 0; j < sortedTopics.length; j++) {
const sortedTopic = sortedTopics[j];
const sortedUrl = sortedTopic.url;
// Insert before the current URL and break
if (sortedUrl.startsWith(`${currUrl}/`)) {
sortedTopics.splice(j, 0, currTopic);
isPlaced = true;
break;
}
}
if (!isPlaced) {
sortedTopics.push(currTopic);
}
}
return sortedTopics;
}
/** /**
* Gets the the topics for a given roadmap * Gets the the topics for a given roadmap
* @param roadmapId Roadmap id for which you want the topics * @param roadmapId Roadmap id for which you want the topics
@ -160,8 +222,9 @@ export async function getTopicFiles(): Promise<Record<string, TopicFileType>> {
export async function getTopicsByRoadmapId(roadmapId: string): Promise<TopicFileType[]> { export async function getTopicsByRoadmapId(roadmapId: string): Promise<TopicFileType[]> {
const topicFileMapping = await getTopicFiles(); const topicFileMapping = await getTopicFiles();
const allTopics = Object.values(topicFileMapping); const allTopics = Object.values(topicFileMapping);
const roadmapTopics = allTopics.filter(
return Object.values(allTopics).filter(
(topic) => topic.roadmapId === roadmapId (topic) => topic.roadmapId === roadmapId
); );
return sortTopics(roadmapTopics);
} }

@ -23,7 +23,7 @@ const { file, breadcrumbs, roadmapId, roadmap } = Astro.props as TopicFileType;
<div class="bg-gray-50"> <div class="bg-gray-50">
<Breadcrumbs breadcrumbs={breadcrumbs} roadmapId={roadmapId} /> <Breadcrumbs breadcrumbs={breadcrumbs} roadmapId={roadmapId} />
<div class="container pb-16 prose prose-p:mt-0 prose-h1:mb-4"> <div class="container pb-16 prose prose-p:mt-0 prose-h1:mb-4 prose-h2:mb-3 prose-h2:mt-0">
<main id="main-content"> <main id="main-content">
<file.Content /> <file.Content />
</main> </main>

@ -51,7 +51,7 @@ const roadmapData = roadmapFile.frontmatter as RoadmapFrontmatter;
{ {
'bg-gray-400 hover:bg-gray-500': totalParentCount === 1, 'bg-gray-400 hover:bg-gray-500': totalParentCount === 1,
'bg-gray-300 hover:bg-gray-400': totalParentCount === 2, 'bg-gray-300 hover:bg-gray-400': totalParentCount === 2,
'bg-gray-200 hover:bg-gray-300': totalParentCount === 3, 'bg-gray-100 hover:bg-gray-300': totalParentCount === 3,
}, },
]} ]}
href={topic.url} href={topic.url}

Loading…
Cancel
Save