Add roadmap rendering
This commit is contained in:
@ -5,6 +5,7 @@ const BlockQuote = styled.blockquote`
|
||||
position: relative;
|
||||
background: #e8e8e8;
|
||||
border-radius: 5px;
|
||||
margin-bottom: 18px;
|
||||
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
margin-top: 0;
|
||||
|
10
components/md-renderer/mdx-components/code.tsx
Normal file
10
components/md-renderer/mdx-components/code.tsx
Normal file
@ -0,0 +1,10 @@
|
||||
import React from 'react';
|
||||
import { Code as ChakraCode } from '@chakra-ui/react';
|
||||
|
||||
type CodeType = {
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
export default function Code(props: CodeType) {
|
||||
return <ChakraCode bg='blue.500'>{props.children}</ChakraCode>;
|
||||
}
|
@ -10,6 +10,7 @@ import { BadgeLink } from './badge-link';
|
||||
import Ul from './ul';
|
||||
import Li from './li';
|
||||
import PremiumBlock from './premium-block';
|
||||
import { Code } from '@chakra-ui/react';
|
||||
|
||||
const MdxComponents = {
|
||||
p: P,
|
||||
@ -20,6 +21,7 @@ const MdxComponents = {
|
||||
table: Table,
|
||||
iframe: IFrame,
|
||||
img: Img,
|
||||
code: Code,
|
||||
BadgeLink: BadgeLink,
|
||||
PremiumBlock: PremiumBlock,
|
||||
ul: Ul,
|
||||
|
@ -16,7 +16,7 @@ export function PageHeader(props: PageHeaderProps) {
|
||||
<Heading
|
||||
as='h1'
|
||||
color='black'
|
||||
fontSize={['25px', '25px', '35px']}
|
||||
fontSize={['25px', '25px', '40px']}
|
||||
fontWeight={700}
|
||||
mb={['2px', '2px', '5px']}
|
||||
>
|
||||
|
@ -38,6 +38,7 @@
|
||||
"featured": true,
|
||||
"imagePath": "/roadmaps/frontend.png",
|
||||
"resourcesPath": "/roadmaps/1-frontend/resources.md",
|
||||
"id": "frontend",
|
||||
"url": "/frontend"
|
||||
},
|
||||
{
|
||||
@ -79,6 +80,7 @@
|
||||
"name": "Kamran Ahmed",
|
||||
"url": "https://twitter.com/kamranahmedse"
|
||||
},
|
||||
"id": "backend",
|
||||
"url": "/backend"
|
||||
},
|
||||
{
|
||||
@ -119,6 +121,7 @@
|
||||
"name": "Kamran Ahmed",
|
||||
"url": "https://twitter.com/kamranahmedse"
|
||||
},
|
||||
"id": "devops",
|
||||
"url": "/devops"
|
||||
},
|
||||
{
|
||||
@ -157,6 +160,7 @@
|
||||
"name": "Kamran Ahmed",
|
||||
"url": "https://twitter.com/kamranahmedse"
|
||||
},
|
||||
"id": "react",
|
||||
"url": "/react"
|
||||
},
|
||||
{
|
||||
@ -199,6 +203,7 @@
|
||||
"featured": true,
|
||||
"detailed": false,
|
||||
"versions": [],
|
||||
"id": "postgresql-dba",
|
||||
"url": "/postgresql-dba"
|
||||
},
|
||||
{
|
||||
@ -237,6 +242,7 @@
|
||||
"name": "Kamran Ahmed",
|
||||
"url": "https://twitter.com/kamranahmedse"
|
||||
},
|
||||
"id": "android",
|
||||
"url": "/android"
|
||||
},
|
||||
{
|
||||
@ -269,6 +275,7 @@
|
||||
"name": "Anas Fitiani",
|
||||
"url": "https://github.com/anas-qa"
|
||||
},
|
||||
"id": "qa",
|
||||
"url": "/qa"
|
||||
}
|
||||
]
|
@ -5,6 +5,3 @@ Also, please note that the list below is exhaustive, and the items are listed in
|
||||

|
||||
|
||||
Please note that the list is opinionated, and you might have different opinions than those of the author. Having said that, [we would love to hear your opinions](https://github.com/kamranahmedse/roadmap.sh/issues/new) and incorporate them in the picture if suitable.
|
||||
|
||||
<!-- @fixme add padding to the container -->
|
||||
<br /><br /><br />
|
||||
|
@ -1,2 +1,11 @@
|
||||
## QA Roadmap
|
||||
Roadmap to becoming a QA Engineer
|
||||
> **Roadmap is not ready yet**. Please check back later or [subscribe to get notified](/signup).
|
||||
|
||||
While we prepare the roadmap, follow this simple advice to learn anything
|
||||
|
||||
> Just **pick a project and start working on it**, you will learn all that you need along the way.
|
||||
|
||||
**→** [All Roadmaps](/roadmaps) • [Programming guides](/guides) • [Subscribe](/signup)
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -20,14 +20,12 @@ export type RoadmapType = {
|
||||
contentPath?: string;
|
||||
resourcesPath: string;
|
||||
isCommunity: boolean;
|
||||
id: string;
|
||||
url: string;
|
||||
};
|
||||
|
||||
export function getRequestedRoadmap(req: NextApiRequest): RoadmapType | undefined {
|
||||
// remove trailing slashes
|
||||
const normalizedUrl = req.url?.replace(/\/$/, '') || '';
|
||||
|
||||
return (roadmaps as RoadmapType[]).find(roadmap => normalizedUrl.startsWith(roadmap.url));
|
||||
export function getRoadmapById(id: string): RoadmapType | undefined {
|
||||
return (roadmaps as RoadmapType[]).find(roadmap => roadmap.id === id);
|
||||
}
|
||||
|
||||
export function getAllRoadmaps(): RoadmapType[] {
|
||||
|
5
package-lock.json
generated
5
package-lock.json
generated
@ -6100,6 +6100,11 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"prism-themes": {
|
||||
"version": "1.8.0",
|
||||
"resolved": "https://registry.npmjs.org/prism-themes/-/prism-themes-1.8.0.tgz",
|
||||
"integrity": "sha512-pj7A7C9C8juQRFkZHYeApQHdUiak5nkKYlHyWwh7n/b6WjI9KzGtqaGhxUZAIaV1PZ9Z1epJwe41Px3TUGsNJw=="
|
||||
},
|
||||
"prismjs": {
|
||||
"version": "1.24.1",
|
||||
"resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.24.1.tgz",
|
||||
|
@ -21,6 +21,7 @@
|
||||
"date-fns": "^2.23.0",
|
||||
"framer-motion": "^4.1.17",
|
||||
"next": "^11.1.0",
|
||||
"prism-themes": "^1.8.0",
|
||||
"react": "17.0.2",
|
||||
"react-dom": "17.0.2",
|
||||
"styled-components": "^5.3.0"
|
||||
|
@ -1,50 +1,61 @@
|
||||
import { Box, Button, Container, SimpleGrid, Stack } from '@chakra-ui/react';
|
||||
import { Box, Button, Container, Stack } from '@chakra-ui/react';
|
||||
import { DownloadIcon, EmailIcon } from '@chakra-ui/icons';
|
||||
import styled from 'styled-components';
|
||||
import Image from 'next/image';
|
||||
import { GlobalHeader } from '../../components/global-header';
|
||||
import { OpensourceBanner } from '../../components/opensource-banner';
|
||||
import { UpdatesBanner } from '../../components/updates-banner';
|
||||
import { Footer } from '../../components/footer';
|
||||
import { PageHeader } from '../../components/page-header';
|
||||
import { getAllRoadmaps, getRoadmapById, RoadmapType } from '../../lib/roadmap';
|
||||
import MdRenderer from '../../components/md-renderer';
|
||||
|
||||
const RoadmapBody = styled.div`
|
||||
margin-bottom: 30px;
|
||||
font-size: 15px;
|
||||
type RoadmapProps = {
|
||||
roadmap: RoadmapType;
|
||||
};
|
||||
|
||||
h1 {
|
||||
font-size: 32px;
|
||||
font-weight: 700;
|
||||
function ImageRoadmap(props: RoadmapProps) {
|
||||
const { roadmap } = props;
|
||||
if (!roadmap.imagePath) {
|
||||
return null;
|
||||
}
|
||||
|
||||
p {
|
||||
line-height: 25px;
|
||||
margin-bottom: 20px
|
||||
return (
|
||||
<Container maxW={'900px'} position='relative'>
|
||||
<Box mb='30px'>
|
||||
<img alt='Frontend Roadmap' src={roadmap.imagePath} />
|
||||
</Box>
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
|
||||
function TextualRoadmap(props: RoadmapProps) {
|
||||
const { roadmap } = props;
|
||||
if (!roadmap.contentPath) {
|
||||
return null;
|
||||
}
|
||||
|
||||
ul, ol {
|
||||
margin: 0 0 20px 40px;
|
||||
// Remove trailing slashes
|
||||
const normalizedPath = roadmap.contentPath.replace(/^\//, '');
|
||||
const RoadmapContent = require(`../../content/${normalizedPath}`).default;
|
||||
|
||||
li + li {
|
||||
margin-top: 7px;
|
||||
}
|
||||
}
|
||||
return (
|
||||
<Container maxW={'container.md'} position='relative'>
|
||||
<MdRenderer>
|
||||
<RoadmapContent />
|
||||
</MdRenderer>
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
|
||||
img {
|
||||
max-width: 100%;
|
||||
}
|
||||
`;
|
||||
|
||||
export default function Roadmap() {
|
||||
const isImageOnly = true;
|
||||
export default function Roadmap(props: RoadmapProps) {
|
||||
const { roadmap } = props;
|
||||
|
||||
return (
|
||||
<Box bg='white' minH='100vh'>
|
||||
<GlobalHeader />
|
||||
<Box mb='60px'>
|
||||
<PageHeader
|
||||
title={'Frontend Developer'}
|
||||
subtitle={'Step by step guide to becoming a modern frontend developer'}
|
||||
title={ roadmap.title }
|
||||
subtitle={ roadmap.description }
|
||||
>
|
||||
<Stack mt='20px' isInline>
|
||||
<Button size='xs' py='14px' px='10px' leftIcon={<DownloadIcon />} colorScheme='yellow' variant='solid'>
|
||||
@ -55,11 +66,9 @@ export default function Roadmap() {
|
||||
</Button>
|
||||
</Stack>
|
||||
</PageHeader>
|
||||
<Container maxW={ isImageOnly ? '900px': 'container.md'} position='relative'>
|
||||
<RoadmapBody>
|
||||
<img alt='Frontend Roadmap' src='/roadmaps/frontend.png' />
|
||||
</RoadmapBody>
|
||||
</Container>
|
||||
|
||||
<ImageRoadmap roadmap={roadmap} />
|
||||
<TextualRoadmap roadmap={roadmap} />
|
||||
</Box>
|
||||
|
||||
<OpensourceBanner />
|
||||
@ -68,3 +77,37 @@ export default function Roadmap() {
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
type StaticPathItem = {
|
||||
params: {
|
||||
roadmap: string
|
||||
}
|
||||
};
|
||||
|
||||
export async function getStaticPaths() {
|
||||
const roadmaps = getAllRoadmaps();
|
||||
const paramsList: StaticPathItem[] = roadmaps.map(roadmap => ({
|
||||
params: { 'roadmap': roadmap.id }
|
||||
}));
|
||||
|
||||
return {
|
||||
paths: paramsList,
|
||||
fallback: false
|
||||
};
|
||||
}
|
||||
|
||||
type ContextType = {
|
||||
params: {
|
||||
roadmap: string
|
||||
}
|
||||
};
|
||||
|
||||
export async function getStaticProps(context: ContextType) {
|
||||
const roadmapId: string = context?.params?.roadmap;
|
||||
|
||||
return {
|
||||
props: {
|
||||
roadmap: getRoadmapById(roadmapId)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
import type { AppProps } from 'next/app';
|
||||
import { ChakraProvider } from '@chakra-ui/react';
|
||||
import { roadmapTheme } from './theme';
|
||||
import 'prism-themes/themes/prism-shades-of-purple.css';
|
||||
|
||||
function MyApp({ Component, pageProps }: AppProps) {
|
||||
return (
|
||||
|
@ -82,6 +82,7 @@ export default function Home(props: HomeProps) {
|
||||
{videos.map(video => (
|
||||
<LinksListItem
|
||||
key={video.url}
|
||||
badgeText={video.isPro ? 'PRO' : ''}
|
||||
hideSubtitleOnMobile
|
||||
title={video.title}
|
||||
subtitle={video.duration}
|
||||
|
@ -33,6 +33,7 @@ const roadmapsMeta = roadmapDirs.reduce((metaAcc, roadmapDirName) => {
|
||||
...metaAcc,
|
||||
{
|
||||
...roadmapMeta,
|
||||
id: roadmapSlug,
|
||||
url: `/${roadmapSlug}`,
|
||||
contentPath: contentPath,
|
||||
resourcesPath: resourcesPath
|
||||
|
Reference in New Issue
Block a user