computer-scienceangular-roadmapbackend-roadmapblockchain-roadmapdba-roadmapdeveloper-roadmapdevops-roadmapfrontend-roadmapgo-roadmaphactoberfestjava-roadmapjavascript-roadmapnodejs-roadmappython-roadmapqa-roadmapreact-roadmaproadmapstudy-planvue-roadmapweb3-roadmap
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
130 lines
3.8 KiB
130 lines
3.8 KiB
--- |
|
import BestPracticeHeader from '../../../components/BestPracticeHeader.astro'; |
|
import FrameRenderer from '../../../components/FrameRenderer/FrameRenderer.astro'; |
|
import MarkdownFile from '../../../components/MarkdownFile.astro'; |
|
import ShareIcons from '../../../components/ShareIcons/ShareIcons.astro'; |
|
import { TopicDetail } from '../../../components/TopicDetail/TopicDetail'; |
|
import UpcomingForm from '../../../components/UpcomingForm.astro'; |
|
import BaseLayout from '../../../layouts/BaseLayout.astro'; |
|
import { UserProgressModal } from '../../../components/UserProgress/UserProgressModal'; |
|
import { |
|
type BestPracticeFileType, |
|
type BestPracticeFrontmatter, |
|
getAllBestPractices, |
|
} from '../../../lib/best-pratice'; |
|
import { generateArticleSchema } from '../../../lib/jsonld-schema'; |
|
|
|
export async function getStaticPaths() { |
|
const bestPractices = await getAllBestPractices(); |
|
|
|
return bestPractices.map((bestPractice: BestPracticeFileType) => ({ |
|
params: { bestPracticeId: bestPractice.id }, |
|
props: { |
|
bestPractice: bestPractice, |
|
}, |
|
})); |
|
} |
|
|
|
interface Params extends Record<string, string | undefined> { |
|
bestPracticeId: string; |
|
} |
|
|
|
interface Props { |
|
bestPractice: BestPracticeFileType; |
|
} |
|
|
|
const { bestPracticeId } = Astro.params as Params; |
|
const { bestPractice } = Astro.props as Props; |
|
const bestPracticeData = bestPractice.frontmatter as BestPracticeFrontmatter; |
|
|
|
let jsonLdSchema = []; |
|
|
|
if (bestPracticeData.schema) { |
|
const bestPracticeSchema = bestPracticeData.schema; |
|
jsonLdSchema.push( |
|
generateArticleSchema({ |
|
url: `https://roadmap.sh/best-practices/${bestPracticeId}`, |
|
headline: bestPracticeSchema.headline, |
|
description: bestPracticeSchema.description, |
|
datePublished: bestPracticeSchema.datePublished, |
|
dateModified: bestPracticeSchema.dateModified, |
|
imageUrl: bestPracticeSchema.imageUrl, |
|
}), |
|
); |
|
} |
|
|
|
const ogImageUrl = `${import.meta.env.PUBLIC_API_URL}/v1-open-graph?${new URLSearchParams( |
|
{ |
|
type: 'roadmap', |
|
title: bestPracticeData.title, |
|
description: bestPracticeData.description, |
|
}, |
|
)}`; |
|
--- |
|
|
|
<BaseLayout |
|
permalink={`/best-practices/${bestPracticeId}`} |
|
title={bestPracticeData?.seo?.title} |
|
briefTitle={bestPracticeData?.briefTitle} |
|
ogImageUrl={ogImageUrl} |
|
description={bestPracticeData.seo.description} |
|
keywords={bestPracticeData.seo.keywords} |
|
noIndex={bestPracticeData.isUpcoming} |
|
jsonLd={jsonLdSchema} |
|
resourceId={bestPracticeId} |
|
resourceType='best-practice' |
|
> |
|
<!-- Preload the font being used in the renderer --> |
|
<link |
|
rel='preload' |
|
href='/fonts/balsamiq.woff2' |
|
as='font' |
|
type='font/woff2' |
|
crossorigin |
|
slot='after-header' |
|
/> |
|
|
|
<BestPracticeHeader |
|
title={bestPracticeData.title} |
|
description={bestPracticeData.description} |
|
bestPracticeId={bestPracticeId} |
|
isUpcoming={bestPracticeData.isUpcoming} |
|
/> |
|
|
|
<div class='bg-gray-50 py-4 sm:py-12'> |
|
{ |
|
!bestPracticeData.isUpcoming && bestPracticeData.jsonUrl && ( |
|
<div class='container relative !max-w-[1000px]'> |
|
<ShareIcons |
|
description={bestPracticeData.briefDescription} |
|
pageUrl={`https://roadmap.sh/best-practices/${bestPracticeId}`} |
|
/> |
|
|
|
<TopicDetail client:idle canSubmitContribution={true} /> |
|
|
|
<FrameRenderer |
|
resourceType={'best-practice'} |
|
resourceId={bestPracticeId} |
|
dimensions={bestPracticeData.dimensions} |
|
/> |
|
</div> |
|
) |
|
} |
|
|
|
{ |
|
!bestPracticeData.isUpcoming && !bestPracticeData.jsonUrl && ( |
|
<MarkdownFile> |
|
<bestPractice.Content /> |
|
</MarkdownFile> |
|
) |
|
} |
|
</div> |
|
|
|
<UserProgressModal |
|
resourceId={bestPracticeId} |
|
resourceType='best-practice' |
|
client:only='react' |
|
/> |
|
|
|
{bestPracticeData.isUpcoming && <UpcomingForm />} |
|
</BaseLayout>
|
|
|