Add best practices page

pull/3356/head
Kamran Ahmed 2 years ago
parent c7302d7484
commit 359f5d6a4d
  1. 0
      public/pdfs/best-practices/frontend-performance.pdf
  2. 2
      src/best-practices/frontend-performance/frontend-performance.md
  3. 6
      src/components/FeaturedItems/FeaturedItems.astro
  4. 32
      src/components/GridItem.astro
  5. 31
      src/components/GridRoadmapItem.astro
  6. 6
      src/components/Navigation.astro
  7. 74
      src/lib/best-pratice.ts
  8. 37
      src/pages/best-practices/index.astro
  9. 14
      src/pages/index.astro
  10. 16
      src/pages/roadmaps.astro

@ -4,6 +4,8 @@ pdfUrl: "/pdfs/best-practices/frontend-performance.pdf"
order: 1
featuredTitle: "Frontend Performance"
featuredDescription: "Detailed list of best practices to improve your frontend performance"
isNew: true
isUpcoming: false
title: "Frontend Performance"
description: "Detailed list of best practices to improve your frontend performance"
dimensions:

@ -9,11 +9,9 @@ export interface Props {
const { featuredItems, heading } = Astro.props;
---
<div class='py-4 sm:py-14 border-b border-b-slate-900 relative'>
<div class='py-4 sm:py-14 border-b border-b-[#1e293c] relative'>
<div class='container'>
<h2
class='hidden sm:flex absolute rounded-lg -top-[17px] left-1/2 -translate-x-1/2 bg-slate-900 py-1 px-3 border border-slate-900 text-md text-slate-400 font-regular'
>
<h2 class='hidden sm:flex absolute rounded-lg -top-[17px] left-1/2 -translate-x-1/2 bg-slate-900 py-1 px-3 border border-[#1e293c] text-md text-slate-400 font-regular'>
{heading}
</h2>

@ -0,0 +1,32 @@
---
import type { RoadmapFileType } from '../lib/roadmap';
export interface Props {
url: string;
title: string;
description: string;
isNew: boolean;
}
const { url, title, description, isNew } = Astro.props;
---
<a
href={url}
class='bg-gradient-to-r from-slate-900 to-amber-900 hover:from-stone-900 hover:to-stone-900 hover:bg-gray-100 flex flex-col p-2.5 sm:p-5 rounded-md sm:rounded-lg border border-gray-200 relative h-full'
>
<span
class='font-regular sm:font-medium text-md sm:text-xl hover:text-gray-50 text-gray-200 sm:text-gray-100 mb-0 sm:mb-1.5'
>
{title}
</span>
<span class='text-sm leading-normal text-gray-400 hidden sm:block'>{description}</span>
{
isNew && (
<span class='absolute bottom-1 right-1 bg-yellow-300 text-yellow-900 text-xs font-medium px-1 sm:px-1.5 py-0.5 rounded-sm uppercase'>
New
</span>
)
}
</a>

@ -1,31 +0,0 @@
---
import type { RoadmapFileType } from '../lib/roadmap';
export interface Props {
roadmap: RoadmapFileType;
}
const { roadmap } = Astro.props;
const frontmatter = roadmap.frontmatter;
---
<a
href={`/${roadmap.id}`}
class="bg-gradient-to-r from-slate-900 to-amber-900 hover:from-stone-900 hover:to-stone-900 hover:bg-gray-100 flex flex-col p-2.5 sm:p-5 rounded-md sm:rounded-lg border border-gray-200 relative h-full"
>
<span
class="font-regular sm:font-medium text-md sm:text-xl hover:text-gray-50 text-gray-200 sm:text-gray-100 mb-0 sm:mb-1.5"
>{frontmatter.title}</span
>
<span class="text-sm leading-normal text-gray-400 hidden sm:block"
>{frontmatter.description}</span
>
{
frontmatter.isNew && (
<span class="absolute bottom-1 right-1 bg-yellow-300 text-yellow-900 text-xs font-medium px-1 sm:px-1.5 py-0.5 rounded-sm uppercase">
New
</span>
)
}
</a>

@ -14,6 +14,9 @@ import Icon from './Icon.astro';
<li>
<a href='/roadmaps' class='text-gray-400 hover:text-white'>Roadmaps</a>
</li>
<li>
<a href='/best-practices' class='text-gray-400 hover:text-white'>Best Practices</a>
</li>
<li>
<a href='/guides' class='text-gray-400 hover:text-white'>Guides</a>
</li>
@ -48,6 +51,9 @@ import Icon from './Icon.astro';
<li>
<a href='/roadmaps' class='text-xl md:text-lg hover:text-blue-300'>Roadmaps</a>
</li>
<li>
<a href='/best-practices' class='text-xl md:text-lg hover:text-blue-300'>Best Practices</a>
</li>
<li>
<a href='/guides' class='text-xl md:text-lg hover:text-blue-300'>Guides</a>
</li>

@ -0,0 +1,74 @@
import type { MarkdownFileType } from './file';
import type { SponsorType } from '../components/Sponsor/Sponsor.astro';
export interface BestPracticeFrontmatter {
jsonUrl: string;
pdfUrl: string;
order: number;
featuredTitle: string;
featuredDescription: string;
title: string;
description: string;
isNew: boolean;
isUpcoming: boolean;
dimensions?: {
width: number;
height: number;
};
sponsor?: SponsorType;
seo: {
title: string;
description: string;
keywords: string[];
};
schema?: {
headline: string;
description: string;
datePublished: string;
dateModified: string;
imageUrl: string;
};
}
export type BestPracticeFileType = MarkdownFileType<BestPracticeFrontmatter> & {
id: string;
};
function bestPracticePathToId(filePath: string): string {
const fileName = filePath.split('/').pop() || '';
return fileName.replace('.md', '');
}
/**
* Gets the IDs of all the best practices available on the website
*
* @returns string[] Array of best practices file IDs
*/
export async function getBestPracticeIds() {
const bestPracticeFiles = await import.meta.glob<BestPracticeFileType>('/src/best-practices/*/*.md', {
eager: true,
});
return Object.keys(bestPracticeFiles).map(bestPracticePathToId);
}
/**
* Gets all the best practice files
*
* @param tag Tag assigned to best practice
* @returns Promisified BestPracticeFileType[]
*/
export async function getAllBestPractices(): Promise<BestPracticeFileType[]> {
const bestPracticeFilesMap = await import.meta.glob<BestPracticeFileType>('/src/best-practices/*/*.md', {
eager: true,
});
const bestPracticeFiles = Object.values(bestPracticeFilesMap);
const bestPracticeItems = bestPracticeFiles.map((bestPracticeFile) => ({
...bestPracticeFile,
id: bestPracticePathToId(bestPracticeFile.file),
}));
return bestPracticeItems.sort((a, b) => a.frontmatter.order - b.frontmatter.order);
}

@ -0,0 +1,37 @@
---
import GridItem from '../../components/GridItem.astro';
import SimplePageHeader from '../../components/SimplePageHeader.astro';
import BaseLayout from '../../layouts/BaseLayout.astro';
import { getAllBestPractices } from '../../lib/best-pratice';
const bestPractices = await getAllBestPractices();
---
<BaseLayout
title='Best Practices'
description={'Step by step guides and paths to learn different tools or technologies'}
permalink={'/best-practices'}
>
<SimplePageHeader
title='Best Practices'
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'>
{
bestPractices.map((bestPractice) => (
<GridItem
url={`/best-practices/${bestPractice.id}`}
isNew={bestPractice.frontmatter.isNew}
title={bestPractice.frontmatter.title}
description={bestPractice.frontmatter.description}
/>
))
}
</div>
</div>
</div>
</BaseLayout>

@ -3,12 +3,14 @@ import FeaturedGuides from '../components/FeaturedGuides.astro';
import FeaturedItems from '../components/FeaturedItems/FeaturedItems.astro';
import FeaturedVideos from '../components/FeaturedVideos.astro';
import BaseLayout from '../layouts/BaseLayout.astro';
import { getAllBestPractices } from '../lib/best-pratice';
import { getAllGuides } from '../lib/guide';
import { getRoadmapsByTag } from '../lib/roadmap';
import { getAllVideos } from '../lib/video';
const roleRoadmaps = await getRoadmapsByTag('role-roadmap');
const skillRoadmaps = await getRoadmapsByTag('skill-roadmap');
const bestPractices = await getAllBestPractices();
const guides = await getAllGuides();
const videos = await getAllVideos();
@ -20,7 +22,7 @@ const videos = await getAllVideos();
permalink={'/'}
>
<div class='bg-gradient-to-b from-slate-900 to-black'>
<div class='border-b border-b-slate-900'>
<div class='border-b border-b-[#1e293c]'>
<div class='container text-left sm:text-center py-6 sm:py-20 px-6 sm:px-0'>
<h1
class='text-2xl sm:text-5xl mb-2 sm:mb-4 font-bold bg-gradient-to-b from-amber-50 to-purple-500 text-transparent bg-clip-text'
@ -59,6 +61,16 @@ const videos = await getAllVideos();
}))}
/>
<FeaturedItems
heading='Best Practices'
featuredItems={bestPractices.map((bestPractice) => ({
text: bestPractice.frontmatter.featuredTitle,
url: `/best-practices/${bestPractice.id}`,
isNew: bestPractice.frontmatter.isNew,
isUpcoming: bestPractice.frontmatter.isUpcoming,
}))}
/>
<div class='grid grid-cols-1 gap-7 sm:gap-16 bg-gray-50 py-7 sm:py-16'>
<FeaturedGuides heading='Guides' guides={guides.slice(0, 7)} />
<FeaturedVideos heading='Videos' videos={videos.slice(0, 7)} />

@ -1,5 +1,5 @@
---
import GridRoadmapItem from '../components/GridRoadmapItem.astro';
import GridItem from '../components/GridItem.astro';
import SimplePageHeader from '../components/SimplePageHeader.astro';
import BaseLayout from '../layouts/BaseLayout.astro';
import { getRoadmapsByTag } from '../lib/roadmap';
@ -24,13 +24,23 @@ const skillRoadmaps = await getRoadmapsByTag('skill-roadmap');
<div class='grid grid-cols-1 sm:grid-cols-2 gap-0.5 sm:gap-3'>
{
roleRoadmaps.map((roleRoadmap) => (
<GridRoadmapItem roadmap={roleRoadmap} />
<GridItem
url={`/${roleRoadmap.id}`}
isNew={roleRoadmap.frontmatter.isNew}
title={roleRoadmap.frontmatter.title}
description={roleRoadmap.frontmatter.description}
/>
))
}
{
skillRoadmaps.map((skillRoadmap) => (
<GridRoadmapItem roadmap={skillRoadmap} />
<GridItem
url={`/${skillRoadmap.id}`}
isNew={skillRoadmap.frontmatter.isNew}
title={skillRoadmap.frontmatter.title}
description={skillRoadmap.frontmatter.description}
/>
))
}
</div>

Loading…
Cancel
Save