Make the guides page working

pull/1331/head
Kamran Ahmed 3 years ago
parent fc159ecb9b
commit 93797cc5ee
  1. 45
      components/content-page-header.tsx
  2. 3
      content/authors.json
  3. 75
      content/guides.json
  4. 34
      lib/guide.ts
  5. 1
      lib/roadmap.ts
  6. 59
      pages/guides/[guide].tsx
  7. BIN
      public/authors/dmytrobol.png
  8. BIN
      public/authors/ebrahimbharmal007.png
  9. BIN
      public/authors/jesse.png
  10. BIN
      public/authors/kamranahmedse.jpeg
  11. BIN
      public/authors/lesovsky.jpeg
  12. BIN
      public/authors/spekulatius.jpg

@ -1,28 +1,55 @@
import { Box, Container, Flex, Heading, Image, Link, Text } from '@chakra-ui/react';
import React from 'react';
type GuideHeaderProps = {
type ContentPageHeaderProps = {
formattedDate: string;
title: string;
subtitle: string;
author?: {
name: string;
twitter: string;
picture: string;
},
subLink?: {
text: string;
url: string;
}
};
export function ContentPageHeader(props: GuideHeaderProps) {
const { title, subtitle } = props;
export function ContentPageHeader(props: ContentPageHeaderProps) {
const { title, subtitle, author = null, formattedDate, subLink = null } = props;
return (
<Box pt={['35px', '35px', '70px']} pb={['35px', '35px', '55px']} borderBottomWidth={1} mb='30px'>
<Container maxW='container.md' position='relative' textAlign={['left', 'left', 'center']}>
<Flex alignItems='center' justifyContent={['flex-start', 'flex-start', 'center']} fontSize={['12px', '12px', '14px']}>
<Flex alignItems='center' justifyContent={['flex-start', 'flex-start', 'center']}
fontSize={['12px', '12px', '14px']}>
<Link d={['none', 'flex', 'flex']} href='#' alignItems='center' fontWeight={600} color='gray.500'>
<Image mr='7px' w='22px' src='https://github.com/kamranahmedse.png' />
Kamran Ahmed
{author?.name && (
<>
<Link
d={['none', 'flex', 'flex']}
target='_blank'
href={`https://twitter.com/${author.twitter}`}
alignItems='center'
fontWeight={600}
color='gray.500'
>
<Image rounded={'full'} mr='7px' w='22px' src={author.picture} />
{author.name}
</Link>
<Text d={['none', 'inline', 'inline']} mx='7px' color='gray.500' as='span'>&middot;</Text>
</>
)}
<Text color='gray.500' as='span'>Monday, May 4, 2021</Text>
<Text color='gray.500' as='span'>{formattedDate}</Text>
{subLink?.text && (
<>
<Text d={['none', 'none', 'inline']} mx='7px' color='gray.500' as='span'>&middot;</Text>
<Link d={['none', 'none', 'inline']} color='blue.500' fontWeight={500} href='#'>Improve this Guide</Link>
<Link d={['none', 'none', 'inline']} color='blue.500' fontWeight={500}
href={subLink.url} target={'_blank'}>{subLink.text}</Link>
</>
)}
</Flex>
<Heading as='h1' color='black' fontSize={['30px', '30px', '45px']} lineHeight={['40px', '40px', '53px']}
fontWeight={700} my={['5px', '5px', '10px']}>{title}</Heading>

@ -37,6 +37,7 @@
{
"username": "lesovsky",
"name": "Alexey Lesovsky",
"bio": "Linux system administrator and PostgreSQL DBA at DataEgret."
"bio": "Linux system administrator and PostgreSQL DBA at DataEgret.",
"picture": "/authors/lesovsky.jpeg"
}
]

@ -1,179 +1,197 @@
[
{
"id": "ci-cd",
"title": "What is CI and CD?",
"description": "Learn the basics of CI/CD and how to implement that with GitHub Actions.",
"url": "/guides/ci-cd",
"fileName": "ci-cd",
"fileName": "ci-cd.md",
"isPro": false,
"authorUsername": "kamranahmedse",
"updatedAt": "2020-07-09T19:59:14.191Z",
"createdAt": "2020-07-09T19:59:14.191Z"
},
{
"id": "sso",
"title": "SSO — Single Sign On",
"description": "Learn the basics of SAML and understand how does Single Sign On work.",
"url": "/guides/sso",
"fileName": "sso",
"fileName": "sso.md",
"isPro": false,
"authorUsername": "kamranahmedse",
"updatedAt": "2020-07-01T19:59:14.191Z",
"createdAt": "2020-07-01T19:59:14.191Z"
},
{
"id": "oauth",
"title": "OAuth — Open Authorization",
"description": "Learn and understand what is OAuth and how it works",
"url": "/guides/oauth",
"fileName": "oauth",
"fileName": "oauth.md",
"isPro": false,
"authorUsername": "kamranahmedse",
"updatedAt": "2020-06-28T19:59:14.191Z",
"createdAt": "2020-06-28T19:59:14.191Z"
},
{
"id": "jwt-authentication",
"title": "JWT Authentication",
"description": "Understand what is JWT authentication and how is it implemented",
"url": "/guides/jwt-authentication",
"fileName": "jwt-authentication",
"fileName": "jwt-authentication.md",
"isPro": false,
"authorUsername": "kamranahmedse",
"updatedAt": "2020-06-20T19:59:14.191Z",
"createdAt": "2020-06-20T19:59:14.191Z"
},
{
"id": "token-authentication",
"title": "Token Based Authentication",
"description": "Understand what is token based authentication and how it is implemented",
"url": "/guides/token-authentication",
"fileName": "token-authentication",
"fileName": "token-authentication.md",
"isPro": false,
"authorUsername": "kamranahmedse",
"updatedAt": "2020-06-02T20:59:14.191Z",
"createdAt": "2020-06-02T20:59:14.191Z"
},
{
"id": "session-authentication",
"title": "Session Based Authentication",
"description": "Understand what is session based authentication and how it is implemented",
"url": "/guides/session-authentication",
"fileName": "session-authentication",
"fileName": "session-authentication.md",
"isPro": false,
"authorUsername": "kamranahmedse",
"updatedAt": "2020-05-26T20:59:14.191Z",
"createdAt": "2020-05-26T20:59:14.191Z"
},
{
"id": "basic-authentication",
"title": "Basic Authentication",
"description": "Understand what is basic authentication and how it is implemented",
"url": "/guides/basic-authentication",
"fileName": "basic-authentication",
"fileName": "basic-authentication.md",
"isPro": false,
"authorUsername": "kamranahmedse",
"updatedAt": "2020-05-19T20:59:14.191Z",
"createdAt": "2020-05-19T20:59:14.191Z"
},
{
"id": "character-encodings",
"title": "Character Encodings",
"description": "Covers the basics of character encodings and explains ASCII vs Unicode",
"url": "/guides/character-encodings",
"fileName": "character-encodings",
"fileName": "character-encodings.md",
"isPro": false,
"authorUsername": "kamranahmedse",
"updatedAt": "2020-05-14T20:59:14.191Z",
"createdAt": "2020-05-14T20:59:14.191Z"
},
{
"id": "unfamiliar-codebase",
"title": "Unfamiliar Codebase",
"description": "Tips on getting getting familiar with an unfamiliar codebase",
"url": "/guides/unfamiliar-codebase",
"fileName": "unfamiliar-codebase",
"fileName": "unfamiliar-codebase.md",
"isPro": false,
"authorUsername": "kamranahmedse",
"updatedAt": "2020-05-04T20:59:14.191Z",
"createdAt": "2020-05-04T20:59:14.191Z"
},
{
"id": "why-build-it-and-they-will-come-wont-work-anymore",
"title": "Build it and they will come?",
"description": "Why “build it and they will come” alone won’t work anymore",
"url": "/guides/why-build-it-and-they-will-come-wont-work-anymore",
"fileName": "why-build-it-and-they-will-come-wont-work-anymore",
"fileName": "why-build-it-and-they-will-come-wont-work-anymore.md",
"isPro": false,
"authorUsername": "spekulatius",
"updatedAt": "2020-05-04T12:59:14.191Z",
"createdAt": "2020-05-04T12:59:14.191Z"
},
{
"id": "dhcp-in-one-picture",
"title": "DHCP in One Picture",
"description": "Here is what happens when a new device joins the network.",
"url": "/guides/dhcp-in-one-picture",
"fileName": "dhcp-in-one-picture",
"fileName": "dhcp-in-one-picture.md",
"isPro": false,
"authorUsername": "kamranahmedse",
"updatedAt": "2020-04-28T15:48:21.191Z",
"createdAt": "2020-04-28T15:48:21.191Z"
},
{
"id": "ssl-tls-https-ssh",
"title": "SSL vs TLS vs SSH",
"description": "Quick tidbit on the differences between SSL, TLS, HTTPS and SSH",
"url": "/guides/ssl-tls-https-ssh",
"fileName": "ssl-tls-https-ssh",
"fileName": "ssl-tls-https-ssh.md",
"isPro": false,
"authorUsername": "kamranahmedse",
"updatedAt": "2020-04-22T15:48:21.191Z",
"createdAt": "2020-04-22T15:48:21.191Z"
},
{
"id": "asymptotic-notation",
"title": "Asymptotic Notation",
"description": "Learn the basics of measuring the time and space complexity of algorithms",
"url": "/guides/asymptotic-notation",
"fileName": "asymptotic-notation",
"fileName": "asymptotic-notation.md",
"isPro": false,
"authorUsername": "kamranahmedse",
"updatedAt": "2020-04-03T15:48:21.191Z",
"createdAt": "2020-04-03T15:48:21.191Z"
},
{
"id": "big-o-notation",
"title": "Big-O Notation",
"description": "Easy to understand explanation of Big-O notation without any fancy terms",
"url": "/guides/big-o-notation",
"fileName": "big-o-notation",
"fileName": "big-o-notation.md",
"isPro": false,
"authorUsername": "kamranahmedse",
"updatedAt": "2020-03-15T15:48:21.191Z",
"createdAt": "2020-03-15T15:48:21.191Z"
},
{
"id": "random-numbers",
"title": "Random Numbers: Are they?",
"description": "Learn how they are generated and why they may not be truly random.",
"url": "/guides/random-numbers",
"fileName": "random-numbers",
"fileName": "random-numbers.md",
"isPro": false,
"authorUsername": "kamranahmedse",
"updatedAt": "2020-03-14T15:48:21.191Z",
"createdAt": "2020-03-14T15:48:21.191Z"
},
{
"id": "scaling-databases",
"title": "Scaling Databases",
"description": "Learn the ups and downs of different database scaling strategies",
"url": "/guides/scaling-databases",
"fileName": "scaling-databases",
"fileName": "scaling-databases.md",
"isPro": false,
"authorUsername": "kamranahmedse",
"updatedAt": "2020-02-18T15:48:21.191Z",
"createdAt": "2020-02-18T15:48:21.191Z"
},
{
"id": "what-is-internet",
"title": "How does the internet work?",
"description": "Learn the basics of internet and everything involved with this short video series",
"url": "/guides/what-is-internet",
"fileName": "what-is-internet",
"fileName": "what-is-internet.md",
"isPro": false,
"authorUsername": "dmytrobol",
"updatedAt": "2020-02-29T15:48:21.191Z",
"createdAt": "2020-02-29T15:48:21.191Z"
},
{
"id": "torrent-client",
"title": "Building a BitTorrent Client",
"description": "Learn everything you need to know about BitTorrent by writing a client in Go",
"url": "/guides/torrent-client",
"fileName": "torrent-client",
"fileName": "torrent-client.md",
"isPro": false,
"authorUsername": "jesse",
"updatedAt": "2020-01-17T15:48:21.191Z",
@ -181,30 +199,33 @@
"canonical": "https://blog.jse.li/posts/torrent/"
},
{
"id": "levels-of-seniority",
"title": "Levels of Seniority",
"description": "How to Step Up as a Junior, Mid Level or a Senior Developer?",
"url": "/guides/levels-of-seniority",
"fileName": "levels-of-seniority",
"fileName": "levels-of-seniority.md",
"isPro": false,
"authorUsername": "kamranahmedse",
"updatedAt": "2019-12-03T12:13:00.860Z",
"createdAt": "2019-12-03T12:13:00.860Z"
},
{
"id": "design-patterns-for-humans",
"title": "Design Patterns for Humans",
"description": "A language agnostic, ultra-simplified explanation to design patterns",
"url": "/guides/design-patterns-for-humans",
"fileName": "design-patterns-for-humans",
"fileName": "design-patterns-for-humans.md",
"isPro": false,
"authorUsername": "kamranahmedse",
"updatedAt": "2019-10-09T12:00:00.860Z",
"createdAt": "2019-01-23T17:00:00.860Z"
},
{
"id": "journey-to-http2",
"title": "Journey to HTTP/2",
"description": "The evolution of HTTP. How it all started and where we stand today",
"url": "/guides/journey-to-http2",
"fileName": "journey-to-http2",
"fileName": "journey-to-http2.md",
"isPro": false,
"authorUsername": "kamranahmedse",
"createdAt": "2018-12-04T12:00:00.860Z",
@ -212,40 +233,44 @@
"isDraft": true
},
{
"id": "dns-in-one-picture",
"title": "DNS in One Picture",
"description": "Quick illustrative guide on how a website is found on the internet.",
"url": "/guides/dns-in-one-picture",
"fileName": "dns-in-one-picture",
"fileName": "dns-in-one-picture.md",
"isPro": false,
"authorUsername": "kamranahmedse",
"updatedAt": "2018-12-04T12:00:00.860Z",
"createdAt": "2018-12-04T17:00:00.860Z"
},
{
"id": "http-caching",
"title": "HTTP Caching",
"description": "Everything you need to know about web caching",
"url": "/guides/http-caching",
"fileName": "http-caching",
"fileName": "http-caching.md",
"isPro": false,
"authorUsername": "kamranahmedse",
"createdAt": "2018-11-29T17:00:00.860Z",
"updatedAt": "2018-11-29T17:00:00.860Z"
},
{
"id": "history-of-javascript",
"title": "Brief History of JavaScript",
"description": "How JavaScript was introduced and evolved over the years",
"url": "/guides/history-of-javascript",
"fileName": "history-of-javascript",
"fileName": "history-of-javascript.md",
"isPro": false,
"authorUsername": "kamranahmedse",
"createdAt": "2017-10-28T17:00:00.860Z",
"updatedAt": "2017-10-28T17:00:00.860Z"
},
{
"id": "proxy-servers",
"title": "Proxy Servers",
"description": "How do proxy servers work and what are forward and reverse proxies?",
"url": "/guides/proxy-servers",
"fileName": "proxy-servers",
"fileName": "proxy-servers.md",
"isPro": false,
"authorUsername": "ebrahimbharmal007",
"createdAt": "2020-07-24T12:40:18",

@ -4,6 +4,7 @@ import { NextApiRequest } from 'next';
import { AuthorType, findAuthorByUsername } from './author';
export type GuideType = {
id: string;
title: string;
description: string;
url: string;
@ -18,6 +19,19 @@ export type GuideType = {
author?: AuthorType;
};
export function getGuideById(id: string): GuideType | undefined {
const allGuides = getAllGuides();
const foundGuide = allGuides.find(guide => guide.id === id);
if (!foundGuide) {
return undefined;
}
return {
...foundGuide,
author: findAuthorByUsername(foundGuide.authorUsername)
};
}
export function getAllGuides(limit: number = 0): GuideType[] {
return (guides as GuideType[])
.filter(guide => !guide.isDraft)
@ -29,23 +43,3 @@ export function getAllGuides(limit: number = 0): GuideType[] {
}))
.slice(0, limit ? limit : guides.length);
}
export function getRequestedGuide(req: NextApiRequest): GuideType | undefined {
const allGuides = getAllGuides();
const guide = allGuides.find(guide => guide.url === req.url);
if (!guide) {
return undefined;
}
try {
return {
...guide,
author: findAuthorByUsername(guide.authorUsername)
};
} catch (e) {
console.log(e);
}
return undefined;
}

@ -1,4 +1,3 @@
import { NextApiRequest } from 'next';
import roadmaps from '../content/roadmaps.json';
export type RoadmapType = {

@ -5,17 +5,34 @@ import { UpdatesBanner } from '../../components/updates-banner';
import { Footer } from '../../components/footer';
import { ContentPageHeader } from '../../components/content-page-header';
import MdRenderer from '../../components/md-renderer';
import { getAllGuides, getGuideById, GuideType } from '../../lib/guide';
import siteConfig from '../../content/site.json';
export default function Guide() {
const GuideContent = require(`../../content/guides/build-it.md`).default;
type GuideProps = {
guide: GuideType;
};
export default function Guide(props: GuideProps) {
const { guide } = props;
const GuideContent = require(`../../content/guides/${guide.fileName}`).default;
return (
<Box bg='white' minH='100vh'>
<GlobalHeader />
<Box mb='60px'>
<ContentPageHeader
title={'Build it and they will come?'}
subtitle={'Why “build it and they will come” alone won’t work anymore'}
title={guide.title}
subtitle={guide.description}
formattedDate={guide.formattedUpdatedAt}
author={{
twitter: guide?.author?.twitter!,
picture: guide?.author?.picture!,
name: guide?.author?.name!
}}
subLink={{
text: 'Improve this Guide',
url: `${siteConfig.url.repo}/tree/master/content/guides/${guide.fileName}`
}}
/>
<Container maxW={'container.md'} position='relative'>
<MdRenderer>
@ -30,3 +47,37 @@ export default function Guide() {
</Box>
);
}
type StaticPathItem = {
params: {
guide: string
}
};
export async function getStaticPaths() {
const guides = getAllGuides();
const paramsList: StaticPathItem[] = guides.map(guide => ({
params: { 'guide': guide.id }
}));
return {
paths: paramsList,
fallback: false
};
}
type ContextType = {
params: {
guide: string
}
};
export async function getStaticProps(context: ContextType) {
const guideId: string = context?.params?.guide;
return {
props: {
guide: getGuideById(guideId)
}
};
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 844 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

Loading…
Cancel
Save