From 613c1027ad26d90942c2b63eb3d0b03b1c36f826 Mon Sep 17 00:00:00 2001 From: Kamran Ahmed Date: Fri, 3 Dec 2021 19:58:25 +0100 Subject: [PATCH] Refactor roadmap page logic --- components/roadmap/new-alert-banner.tsx | 50 ++++ components/roadmap/roadmap-page-header.tsx | 48 ++++ .../roadmaps/100-frontend/content-paths.json | 260 +++++++++--------- lib/roadmap.ts | 1 + pages/[roadmap]/index.tsx | 107 +++---- pages/[roadmap]/interactive.tsx | 55 +--- pages/[roadmap]/resources.tsx | 38 +-- public/sitemap.xml | 2 +- scripts/content-skeleton.ts | 9 +- 9 files changed, 274 insertions(+), 296 deletions(-) create mode 100644 components/roadmap/new-alert-banner.tsx create mode 100644 components/roadmap/roadmap-page-header.tsx diff --git a/components/roadmap/new-alert-banner.tsx b/components/roadmap/new-alert-banner.tsx new file mode 100644 index 000000000..c390261f2 --- /dev/null +++ b/components/roadmap/new-alert-banner.tsx @@ -0,0 +1,50 @@ +import { Badge, Link, Text } from '@chakra-ui/react'; +import siteConfig from '../../content/site.json'; +import { event } from '../../lib/gtag'; +import React from 'react'; + +export function NewAlertBanner() { + return ( + + event({ + category: 'Subscription', + action: 'Clicked the YouTube banner', + label: 'YouTube Alert on Roadmap', + }) + } + > + + New + + + Roadmap topics to be covered on our YouTube Channel + + + Topic videos being made on YouTube + + + » + + + ); +} diff --git a/components/roadmap/roadmap-page-header.tsx b/components/roadmap/roadmap-page-header.tsx new file mode 100644 index 000000000..8b1ac8768 --- /dev/null +++ b/components/roadmap/roadmap-page-header.tsx @@ -0,0 +1,48 @@ +import { RoadmapType } from '../../lib/roadmap'; +import { NewAlertBanner } from './new-alert-banner'; +import { Button, Link, Stack, Text } from '@chakra-ui/react'; +import { AtSignIcon, DownloadIcon } from '@chakra-ui/icons'; +import { PageHeader } from '../page-header'; +import React from 'react'; + +type RoadmapPageHeaderType = { + roadmap: RoadmapType; +} + +export function RoadmapPageHeader(props: RoadmapPageHeaderType) { + const { roadmap } = props; + + return ( + } + title={roadmap.title} + subtitle={roadmap.description} + > + + + + {roadmap.pdfUrl && ( + + )} + + + + ); +} diff --git a/content/roadmaps/100-frontend/content-paths.json b/content/roadmaps/100-frontend/content-paths.json index fe789d40b..fa275af97 100644 --- a/content/roadmaps/100-frontend/content-paths.json +++ b/content/roadmaps/100-frontend/content-paths.json @@ -1,132 +1,132 @@ { - "home": "/100-frontend/content/readme.md", - "internet": "/100-frontend/content/100-internet/readme.md", - "internet:how-does-the-internet-work": "/100-frontend/content/100-internet/100-how-does-the-internet-work.md", - "internet:what-is-http": "/100-frontend/content/100-internet/101-what-is-http.md", - "internet:browsers-and-how-they-work": "/100-frontend/content/100-internet/102-browsers-and-how-they-work.md", - "internet:dns-and-how-it-works": "/100-frontend/content/100-internet/103-dns-and-how-it-works.md", - "internet:what-is-domain-name": "/100-frontend/content/100-internet/104-what-is-domain-name.md", - "internet:what-is-hosting": "/100-frontend/content/100-internet/105-what-is-hosting.md", - "html": "/100-frontend/content/101-html/readme.md", - "html:learn-the-basics": "/100-frontend/content/101-html/100-learn-the-basics.md", - "html:writing-semantic-html": "/100-frontend/content/101-html/101-writing-semantic-html.md", - "html:forms-and-validations": "/100-frontend/content/101-html/102-forms-and-validations.md", - "html:conventions-and-best-practices": "/100-frontend/content/101-html/103-conventions-and-best-practices.md", - "html:accessibility": "/100-frontend/content/101-html/104-accessibility.md", - "html:seo-basics": "/100-frontend/content/101-html/105-seo-basics.md", - "css": "/100-frontend/content/102-css/readme.md", - "css:learn-the-basics": "/100-frontend/content/102-css/100-learn-the-basics.md", - "css:making-layouts": "/100-frontend/content/102-css/101-making-layouts.md", - "css:responsive-design-and-media-queries": "/100-frontend/content/102-css/102-responsive-design-and-media-queries.md", - "javascript": "/100-frontend/content/103-javascript/readme.md", - "javascript:syntax-and-basic-constructs": "/100-frontend/content/103-javascript/100-syntax-and-basic-constructs.md", - "javascript:learn-dom-manipulation": "/100-frontend/content/103-javascript/101-learn-dom-manipulation.md", - "javascript:learn-fetch-api-ajax-xhr": "/100-frontend/content/103-javascript/102-learn-fetch-api-ajax-xhr.md", - "javascript:es6-and-modular-javascript": "/100-frontend/content/103-javascript/103-es6-and-modular-javascript.md", - "javascript:concepts": "/100-frontend/content/103-javascript/104-concepts.md", - "version-control-systems": "/100-frontend/content/104-version-control-systems/readme.md", - "version-control-systems:basic-usage-of-git": "/100-frontend/content/104-version-control-systems/100-basic-usage-of-git.md", - "repo-hosting-services": "/100-frontend/content/105-repo-hosting-services/readme.md", - "repo-hosting-services:github": "/100-frontend/content/105-repo-hosting-services/100-github.md", - "repo-hosting-services:gitlab": "/100-frontend/content/105-repo-hosting-services/101-gitlab.md", - "repo-hosting-services:bitbucket": "/100-frontend/content/105-repo-hosting-services/102-bitbucket.md", - "web-security-knowledge": "/100-frontend/content/106-web-security-knowledge/readme.md", - "web-security-knowledge:cors": "/100-frontend/content/106-web-security-knowledge/102-cors.md", - "web-security-knowledge:https": "/100-frontend/content/106-web-security-knowledge/100-https.md", - "web-security-knowledge:content-security-policy": "/100-frontend/content/106-web-security-knowledge/101-content-security-policy.md", - "web-security-knowledge:owasp-security-risks": "/100-frontend/content/106-web-security-knowledge/103-owasp-security-risks.md", - "package-managers": "/100-frontend/content/107-package-managers/readme.md", - "package-managers:npm": "/100-frontend/content/107-package-managers/100-npm.md", - "package-managers:yarn": "/100-frontend/content/107-package-managers/101-yarn.md", - "css-architecture": "/100-frontend/content/108-css-architecture/readme.md", - "css-architecture:bem": "/100-frontend/content/108-css-architecture/100-bem.md", - "css-architecture:oocss": "/100-frontend/content/108-css-architecture/101-oocss.md", - "css-architecture:smacss": "/100-frontend/content/108-css-architecture/102-smacss.md", - "css-preprocessors": "/100-frontend/content/109-css-preprocessors/readme.md", - "css-preprocessors:sass": "/100-frontend/content/109-css-preprocessors/100-sass.md", - "css-preprocessors:postcss": "/100-frontend/content/109-css-preprocessors/101-postcss.md", - "css-preprocessors:less": "/100-frontend/content/109-css-preprocessors/102-less.md", - "build-tools": "/100-frontend/content/110-build-tools/readme.md", - "build-tools:task-runners": "/100-frontend/content/110-build-tools/100-task-runners/readme.md", - "build-tools:100-task-runners/npm-scripts": "/100-frontend/content/110-build-tools/100-task-runners/npm-scripts.md", - "build-tools:linters-formatters": "/100-frontend/content/110-build-tools/102-linters-formatters/readme.md", - "build-tools:102-linters-formatters/prettier": "/100-frontend/content/110-build-tools/102-linters-formatters/prettier.md", - "build-tools:102-linters-formatters/eslint": "/100-frontend/content/110-build-tools/102-linters-formatters/eslint.md", - "build-tools:102-linters-formatters/standardjs": "/100-frontend/content/110-build-tools/102-linters-formatters/standardjs.md", - "build-tools:module-bundlers": "/100-frontend/content/110-build-tools/101-module-bundlers/readme.md", - "build-tools:101-module-bundlers/webpack": "/100-frontend/content/110-build-tools/101-module-bundlers/webpack.md", - "build-tools:101-module-bundlers/esbuild": "/100-frontend/content/110-build-tools/101-module-bundlers/esbuild.md", - "build-tools:101-module-bundlers/rollup": "/100-frontend/content/110-build-tools/101-module-bundlers/rollup.md", - "build-tools:101-module-bundlers/parcel": "/100-frontend/content/110-build-tools/101-module-bundlers/parcel.md", - "build-tools:101-module-bundlers/vite": "/100-frontend/content/110-build-tools/101-module-bundlers/vite.md", - "pick-a-framework": "/100-frontend/content/111-pick-a-framework/readme.md", - "pick-a-framework:react-js": "/100-frontend/content/111-pick-a-framework/100-react-js/readme.md", - "pick-a-framework:100-react-js/recoil": "/100-frontend/content/111-pick-a-framework/100-react-js/recoil.md", - "pick-a-framework:100-react-js/redux": "/100-frontend/content/111-pick-a-framework/100-react-js/redux.md", - "pick-a-framework:100-react-js/mobx": "/100-frontend/content/111-pick-a-framework/100-react-js/mobx.md", - "pick-a-framework:angular": "/100-frontend/content/111-pick-a-framework/101-angular/readme.md", - "pick-a-framework:101-angular/rxjs": "/100-frontend/content/111-pick-a-framework/101-angular/rxjs.md", - "pick-a-framework:101-angular/ngrx": "/100-frontend/content/111-pick-a-framework/101-angular/ngrx.md", - "pick-a-framework:vue-js": "/100-frontend/content/111-pick-a-framework/102-vue-js/readme.md", - "pick-a-framework:102-vue-js/vuex": "/100-frontend/content/111-pick-a-framework/102-vue-js/vuex.md", - "modern-css": "/100-frontend/content/112-modern-css/readme.md", - "modern-css:styled-components": "/100-frontend/content/112-modern-css/100-styled-components.md", - "modern-css:css-modules": "/100-frontend/content/112-modern-css/101-css-modules.md", - "modern-css:styled-jsx": "/100-frontend/content/112-modern-css/102-styled-jsx.md", - "modern-css:emotion": "/100-frontend/content/112-modern-css/103-emotion.md", - "web-components": "/100-frontend/content/113-web-components/readme.md", - "web-components:html-templates": "/100-frontend/content/113-web-components/100-html-templates.md", - "web-components:custom-elements": "/100-frontend/content/113-web-components/101-custom-elements.md", - "web-components:shadow-dom": "/100-frontend/content/113-web-components/102-shadow-dom.md", - "css-frameworks": "/100-frontend/content/114-css-frameworks/readme.md", - "css-frameworks:js-first": "/100-frontend/content/114-css-frameworks/114-js-first/readme.md", - "css-frameworks:114-js-first/chakra-ui": "/100-frontend/content/114-css-frameworks/114-js-first/chakra-ui.md", - "css-frameworks:114-js-first/material-ui": "/100-frontend/content/114-css-frameworks/114-js-first/material-ui.md", - "css-frameworks:114-js-first/radix-ui": "/100-frontend/content/114-css-frameworks/114-js-first/radix-ui.md", - "css-frameworks:114-js-first/tailwind-css": "/100-frontend/content/114-css-frameworks/114-js-first/tailwind-css.md", - "css-frameworks:css-first": "/100-frontend/content/114-css-frameworks/114-css-first/readme.md", - "css-frameworks:114-css-first/bootstrap": "/100-frontend/content/114-css-frameworks/114-css-first/bootstrap.md", - "css-frameworks:114-css-first/bulma": "/100-frontend/content/114-css-frameworks/114-css-first/bulma.md", - "testing-your-apps": "/100-frontend/content/115-testing-your-apps/readme.md", - "testing-your-apps:jest": "/100-frontend/content/115-testing-your-apps/100-jest.md", - "testing-your-apps:react-testing-library": "/100-frontend/content/115-testing-your-apps/101-react-testing-library.md", - "testing-your-apps:cypress": "/100-frontend/content/115-testing-your-apps/102-cypress.md", - "testing-your-apps:enzyme": "/100-frontend/content/115-testing-your-apps/103-enzyme.md", - "testing-your-apps:other-options": "/100-frontend/content/115-testing-your-apps/104-other-options.md", - "type-checkers": "/100-frontend/content/116-type-checkers/readme.md", - "type-checkers:typescript": "/100-frontend/content/116-type-checkers/100-typescript.md", - "type-checkers:flow": "/100-frontend/content/116-type-checkers/101-flow.md", - "progressive-web-apps": "/100-frontend/content/117-progressive-web-apps/readme.md", - "progressive-web-apps:performance": "/100-frontend/content/117-progressive-web-apps/101-performance.md", - "progressive-web-apps:apis": "/100-frontend/content/117-progressive-web-apps/100-apis.md", - "server-side-rendering": "/100-frontend/content/118-server-side-rendering/readme.md", - "server-side-rendering:react-js": "/100-frontend/content/118-server-side-rendering/100-react-js/readme.md", - "server-side-rendering:100-react-js/next-js": "/100-frontend/content/118-server-side-rendering/100-react-js/next-js.md", - "server-side-rendering:100-react-js/after-js": "/100-frontend/content/118-server-side-rendering/100-react-js/after-js.md", - "server-side-rendering:angular": "/100-frontend/content/118-server-side-rendering/101-angular/readme.md", - "server-side-rendering:101-angular/universal": "/100-frontend/content/118-server-side-rendering/101-angular/universal.md", - "server-side-rendering:vue-js": "/100-frontend/content/118-server-side-rendering/102-vue-js/readme.md", - "server-side-rendering:102-vue-js/nuxt-js": "/100-frontend/content/118-server-side-rendering/102-vue-js/nuxt-js.md", - "graphql": "/100-frontend/content/119-graphql/readme.md", - "graphql:apollo": "/100-frontend/content/119-graphql/100-apollo.md", - "graphql:relay-modern": "/100-frontend/content/119-graphql/101-relay-modern.md", - "static-site-generators": "/100-frontend/content/120-static-site-generators/readme.md", - "static-site-generators:next-js": "/100-frontend/content/120-static-site-generators/100-next-js.md", - "static-site-generators:gatsbyjs": "/100-frontend/content/120-static-site-generators/101-gatsbyjs.md", - "static-site-generators:nuxt-js": "/100-frontend/content/120-static-site-generators/102-nuxt-js.md", - "static-site-generators:vuepress": "/100-frontend/content/120-static-site-generators/103-vuepress.md", - "static-site-generators:jekyll": "/100-frontend/content/120-static-site-generators/104-jekyll.md", - "static-site-generators:hugo": "/100-frontend/content/120-static-site-generators/105-hugo.md", - "static-site-generators:gridsome": "/100-frontend/content/120-static-site-generators/106-gridsome.md", - "static-site-generators:eleventy": "/100-frontend/content/120-static-site-generators/107-eleventy.md", - "mobile-applications": "/100-frontend/content/121-mobile-applications/readme.md", - "mobile-applications:react-native": "/100-frontend/content/121-mobile-applications/100-react-native.md", - "mobile-applications:nativescript": "/100-frontend/content/121-mobile-applications/101-nativescript.md", - "mobile-applications:flutter": "/100-frontend/content/121-mobile-applications/102-flutter.md", - "mobile-applications:ionic": "/100-frontend/content/121-mobile-applications/103-ionic.md", - "desktop-applications": "/100-frontend/content/122-desktop-applications/readme.md", - "desktop-applications:electron": "/100-frontend/content/122-desktop-applications/100-electron.md", - "desktop-applications:carlo": "/100-frontend/content/122-desktop-applications/101-carlo.md", - "desktop-applications:proton-native": "/100-frontend/content/122-desktop-applications/102-proton-native.md", - "web-assembly": "/100-frontend/content/123-web-assembly.md" + "home": "/roadmaps/100-frontend/content/readme.md", + "internet": "/roadmaps/100-frontend/content/100-internet/readme.md", + "internet:how-does-the-internet-work": "/roadmaps/100-frontend/content/100-internet/100-how-does-the-internet-work.md", + "internet:what-is-http": "/roadmaps/100-frontend/content/100-internet/101-what-is-http.md", + "internet:browsers-and-how-they-work": "/roadmaps/100-frontend/content/100-internet/102-browsers-and-how-they-work.md", + "internet:dns-and-how-it-works": "/roadmaps/100-frontend/content/100-internet/103-dns-and-how-it-works.md", + "internet:what-is-domain-name": "/roadmaps/100-frontend/content/100-internet/104-what-is-domain-name.md", + "internet:what-is-hosting": "/roadmaps/100-frontend/content/100-internet/105-what-is-hosting.md", + "html": "/roadmaps/100-frontend/content/101-html/readme.md", + "html:learn-the-basics": "/roadmaps/100-frontend/content/101-html/100-learn-the-basics.md", + "html:writing-semantic-html": "/roadmaps/100-frontend/content/101-html/101-writing-semantic-html.md", + "html:forms-and-validations": "/roadmaps/100-frontend/content/101-html/102-forms-and-validations.md", + "html:conventions-and-best-practices": "/roadmaps/100-frontend/content/101-html/103-conventions-and-best-practices.md", + "html:accessibility": "/roadmaps/100-frontend/content/101-html/104-accessibility.md", + "html:seo-basics": "/roadmaps/100-frontend/content/101-html/105-seo-basics.md", + "css": "/roadmaps/100-frontend/content/102-css/readme.md", + "css:learn-the-basics": "/roadmaps/100-frontend/content/102-css/100-learn-the-basics.md", + "css:making-layouts": "/roadmaps/100-frontend/content/102-css/101-making-layouts.md", + "css:responsive-design-and-media-queries": "/roadmaps/100-frontend/content/102-css/102-responsive-design-and-media-queries.md", + "javascript": "/roadmaps/100-frontend/content/103-javascript/readme.md", + "javascript:syntax-and-basic-constructs": "/roadmaps/100-frontend/content/103-javascript/100-syntax-and-basic-constructs.md", + "javascript:learn-dom-manipulation": "/roadmaps/100-frontend/content/103-javascript/101-learn-dom-manipulation.md", + "javascript:learn-fetch-api-ajax-xhr": "/roadmaps/100-frontend/content/103-javascript/102-learn-fetch-api-ajax-xhr.md", + "javascript:es6-and-modular-javascript": "/roadmaps/100-frontend/content/103-javascript/103-es6-and-modular-javascript.md", + "javascript:concepts": "/roadmaps/100-frontend/content/103-javascript/104-concepts.md", + "version-control-systems": "/roadmaps/100-frontend/content/104-version-control-systems/readme.md", + "version-control-systems:basic-usage-of-git": "/roadmaps/100-frontend/content/104-version-control-systems/100-basic-usage-of-git.md", + "repo-hosting-services": "/roadmaps/100-frontend/content/105-repo-hosting-services/readme.md", + "repo-hosting-services:github": "/roadmaps/100-frontend/content/105-repo-hosting-services/100-github.md", + "repo-hosting-services:gitlab": "/roadmaps/100-frontend/content/105-repo-hosting-services/101-gitlab.md", + "repo-hosting-services:bitbucket": "/roadmaps/100-frontend/content/105-repo-hosting-services/102-bitbucket.md", + "web-security-knowledge": "/roadmaps/100-frontend/content/106-web-security-knowledge/readme.md", + "web-security-knowledge:cors": "/roadmaps/100-frontend/content/106-web-security-knowledge/102-cors.md", + "web-security-knowledge:https": "/roadmaps/100-frontend/content/106-web-security-knowledge/100-https.md", + "web-security-knowledge:content-security-policy": "/roadmaps/100-frontend/content/106-web-security-knowledge/101-content-security-policy.md", + "web-security-knowledge:owasp-security-risks": "/roadmaps/100-frontend/content/106-web-security-knowledge/103-owasp-security-risks.md", + "package-managers": "/roadmaps/100-frontend/content/107-package-managers/readme.md", + "package-managers:npm": "/roadmaps/100-frontend/content/107-package-managers/100-npm.md", + "package-managers:yarn": "/roadmaps/100-frontend/content/107-package-managers/101-yarn.md", + "css-architecture": "/roadmaps/100-frontend/content/108-css-architecture/readme.md", + "css-architecture:bem": "/roadmaps/100-frontend/content/108-css-architecture/100-bem.md", + "css-architecture:oocss": "/roadmaps/100-frontend/content/108-css-architecture/101-oocss.md", + "css-architecture:smacss": "/roadmaps/100-frontend/content/108-css-architecture/102-smacss.md", + "css-preprocessors": "/roadmaps/100-frontend/content/109-css-preprocessors/readme.md", + "css-preprocessors:sass": "/roadmaps/100-frontend/content/109-css-preprocessors/100-sass.md", + "css-preprocessors:postcss": "/roadmaps/100-frontend/content/109-css-preprocessors/101-postcss.md", + "css-preprocessors:less": "/roadmaps/100-frontend/content/109-css-preprocessors/102-less.md", + "build-tools": "/roadmaps/100-frontend/content/110-build-tools/readme.md", + "build-tools:task-runners": "/roadmaps/100-frontend/content/110-build-tools/100-task-runners/readme.md", + "build-tools:100-task-runners/npm-scripts": "/roadmaps/100-frontend/content/110-build-tools/100-task-runners/npm-scripts.md", + "build-tools:linters-formatters": "/roadmaps/100-frontend/content/110-build-tools/102-linters-formatters/readme.md", + "build-tools:102-linters-formatters/prettier": "/roadmaps/100-frontend/content/110-build-tools/102-linters-formatters/prettier.md", + "build-tools:102-linters-formatters/eslint": "/roadmaps/100-frontend/content/110-build-tools/102-linters-formatters/eslint.md", + "build-tools:102-linters-formatters/standardjs": "/roadmaps/100-frontend/content/110-build-tools/102-linters-formatters/standardjs.md", + "build-tools:module-bundlers": "/roadmaps/100-frontend/content/110-build-tools/101-module-bundlers/readme.md", + "build-tools:101-module-bundlers/webpack": "/roadmaps/100-frontend/content/110-build-tools/101-module-bundlers/webpack.md", + "build-tools:101-module-bundlers/esbuild": "/roadmaps/100-frontend/content/110-build-tools/101-module-bundlers/esbuild.md", + "build-tools:101-module-bundlers/rollup": "/roadmaps/100-frontend/content/110-build-tools/101-module-bundlers/rollup.md", + "build-tools:101-module-bundlers/parcel": "/roadmaps/100-frontend/content/110-build-tools/101-module-bundlers/parcel.md", + "build-tools:101-module-bundlers/vite": "/roadmaps/100-frontend/content/110-build-tools/101-module-bundlers/vite.md", + "pick-a-framework": "/roadmaps/100-frontend/content/111-pick-a-framework/readme.md", + "pick-a-framework:react-js": "/roadmaps/100-frontend/content/111-pick-a-framework/100-react-js/readme.md", + "pick-a-framework:100-react-js/recoil": "/roadmaps/100-frontend/content/111-pick-a-framework/100-react-js/recoil.md", + "pick-a-framework:100-react-js/redux": "/roadmaps/100-frontend/content/111-pick-a-framework/100-react-js/redux.md", + "pick-a-framework:100-react-js/mobx": "/roadmaps/100-frontend/content/111-pick-a-framework/100-react-js/mobx.md", + "pick-a-framework:angular": "/roadmaps/100-frontend/content/111-pick-a-framework/101-angular/readme.md", + "pick-a-framework:101-angular/rxjs": "/roadmaps/100-frontend/content/111-pick-a-framework/101-angular/rxjs.md", + "pick-a-framework:101-angular/ngrx": "/roadmaps/100-frontend/content/111-pick-a-framework/101-angular/ngrx.md", + "pick-a-framework:vue-js": "/roadmaps/100-frontend/content/111-pick-a-framework/102-vue-js/readme.md", + "pick-a-framework:102-vue-js/vuex": "/roadmaps/100-frontend/content/111-pick-a-framework/102-vue-js/vuex.md", + "modern-css": "/roadmaps/100-frontend/content/112-modern-css/readme.md", + "modern-css:styled-components": "/roadmaps/100-frontend/content/112-modern-css/100-styled-components.md", + "modern-css:css-modules": "/roadmaps/100-frontend/content/112-modern-css/101-css-modules.md", + "modern-css:styled-jsx": "/roadmaps/100-frontend/content/112-modern-css/102-styled-jsx.md", + "modern-css:emotion": "/roadmaps/100-frontend/content/112-modern-css/103-emotion.md", + "web-components": "/roadmaps/100-frontend/content/113-web-components/readme.md", + "web-components:html-templates": "/roadmaps/100-frontend/content/113-web-components/100-html-templates.md", + "web-components:custom-elements": "/roadmaps/100-frontend/content/113-web-components/101-custom-elements.md", + "web-components:shadow-dom": "/roadmaps/100-frontend/content/113-web-components/102-shadow-dom.md", + "css-frameworks": "/roadmaps/100-frontend/content/114-css-frameworks/readme.md", + "css-frameworks:js-first": "/roadmaps/100-frontend/content/114-css-frameworks/114-js-first/readme.md", + "css-frameworks:114-js-first/chakra-ui": "/roadmaps/100-frontend/content/114-css-frameworks/114-js-first/chakra-ui.md", + "css-frameworks:114-js-first/material-ui": "/roadmaps/100-frontend/content/114-css-frameworks/114-js-first/material-ui.md", + "css-frameworks:114-js-first/radix-ui": "/roadmaps/100-frontend/content/114-css-frameworks/114-js-first/radix-ui.md", + "css-frameworks:114-js-first/tailwind-css": "/roadmaps/100-frontend/content/114-css-frameworks/114-js-first/tailwind-css.md", + "css-frameworks:css-first": "/roadmaps/100-frontend/content/114-css-frameworks/114-css-first/readme.md", + "css-frameworks:114-css-first/bootstrap": "/roadmaps/100-frontend/content/114-css-frameworks/114-css-first/bootstrap.md", + "css-frameworks:114-css-first/bulma": "/roadmaps/100-frontend/content/114-css-frameworks/114-css-first/bulma.md", + "testing-your-apps": "/roadmaps/100-frontend/content/115-testing-your-apps/readme.md", + "testing-your-apps:jest": "/roadmaps/100-frontend/content/115-testing-your-apps/100-jest.md", + "testing-your-apps:react-testing-library": "/roadmaps/100-frontend/content/115-testing-your-apps/101-react-testing-library.md", + "testing-your-apps:cypress": "/roadmaps/100-frontend/content/115-testing-your-apps/102-cypress.md", + "testing-your-apps:enzyme": "/roadmaps/100-frontend/content/115-testing-your-apps/103-enzyme.md", + "testing-your-apps:other-options": "/roadmaps/100-frontend/content/115-testing-your-apps/104-other-options.md", + "type-checkers": "/roadmaps/100-frontend/content/116-type-checkers/readme.md", + "type-checkers:typescript": "/roadmaps/100-frontend/content/116-type-checkers/100-typescript.md", + "type-checkers:flow": "/roadmaps/100-frontend/content/116-type-checkers/101-flow.md", + "progressive-web-apps": "/roadmaps/100-frontend/content/117-progressive-web-apps/readme.md", + "progressive-web-apps:performance": "/roadmaps/100-frontend/content/117-progressive-web-apps/101-performance.md", + "progressive-web-apps:apis": "/roadmaps/100-frontend/content/117-progressive-web-apps/100-apis.md", + "server-side-rendering": "/roadmaps/100-frontend/content/118-server-side-rendering/readme.md", + "server-side-rendering:react-js": "/roadmaps/100-frontend/content/118-server-side-rendering/100-react-js/readme.md", + "server-side-rendering:100-react-js/next-js": "/roadmaps/100-frontend/content/118-server-side-rendering/100-react-js/next-js.md", + "server-side-rendering:100-react-js/after-js": "/roadmaps/100-frontend/content/118-server-side-rendering/100-react-js/after-js.md", + "server-side-rendering:angular": "/roadmaps/100-frontend/content/118-server-side-rendering/101-angular/readme.md", + "server-side-rendering:101-angular/universal": "/roadmaps/100-frontend/content/118-server-side-rendering/101-angular/universal.md", + "server-side-rendering:vue-js": "/roadmaps/100-frontend/content/118-server-side-rendering/102-vue-js/readme.md", + "server-side-rendering:102-vue-js/nuxt-js": "/roadmaps/100-frontend/content/118-server-side-rendering/102-vue-js/nuxt-js.md", + "graphql": "/roadmaps/100-frontend/content/119-graphql/readme.md", + "graphql:apollo": "/roadmaps/100-frontend/content/119-graphql/100-apollo.md", + "graphql:relay-modern": "/roadmaps/100-frontend/content/119-graphql/101-relay-modern.md", + "static-site-generators": "/roadmaps/100-frontend/content/120-static-site-generators/readme.md", + "static-site-generators:next-js": "/roadmaps/100-frontend/content/120-static-site-generators/100-next-js.md", + "static-site-generators:gatsbyjs": "/roadmaps/100-frontend/content/120-static-site-generators/101-gatsbyjs.md", + "static-site-generators:nuxt-js": "/roadmaps/100-frontend/content/120-static-site-generators/102-nuxt-js.md", + "static-site-generators:vuepress": "/roadmaps/100-frontend/content/120-static-site-generators/103-vuepress.md", + "static-site-generators:jekyll": "/roadmaps/100-frontend/content/120-static-site-generators/104-jekyll.md", + "static-site-generators:hugo": "/roadmaps/100-frontend/content/120-static-site-generators/105-hugo.md", + "static-site-generators:gridsome": "/roadmaps/100-frontend/content/120-static-site-generators/106-gridsome.md", + "static-site-generators:eleventy": "/roadmaps/100-frontend/content/120-static-site-generators/107-eleventy.md", + "mobile-applications": "/roadmaps/100-frontend/content/121-mobile-applications/readme.md", + "mobile-applications:react-native": "/roadmaps/100-frontend/content/121-mobile-applications/100-react-native.md", + "mobile-applications:nativescript": "/roadmaps/100-frontend/content/121-mobile-applications/101-nativescript.md", + "mobile-applications:flutter": "/roadmaps/100-frontend/content/121-mobile-applications/102-flutter.md", + "mobile-applications:ionic": "/roadmaps/100-frontend/content/121-mobile-applications/103-ionic.md", + "desktop-applications": "/roadmaps/100-frontend/content/122-desktop-applications/readme.md", + "desktop-applications:electron": "/roadmaps/100-frontend/content/122-desktop-applications/100-electron.md", + "desktop-applications:carlo": "/roadmaps/100-frontend/content/122-desktop-applications/101-carlo.md", + "desktop-applications:proton-native": "/roadmaps/100-frontend/content/122-desktop-applications/102-proton-native.md", + "web-assembly": "/roadmaps/100-frontend/content/123-web-assembly.md" } \ No newline at end of file diff --git a/lib/roadmap.ts b/lib/roadmap.ts index 97fe58017..cd698e68e 100644 --- a/lib/roadmap.ts +++ b/lib/roadmap.ts @@ -18,6 +18,7 @@ export type RoadmapType = { imagePath?: string, landingPath?: string; resourcesPath: string; + contentPathsFilePath?: string; metaPath: string; isCommunity: boolean; isUpcoming: boolean; diff --git a/pages/[roadmap]/index.tsx b/pages/[roadmap]/index.tsx index 7c12bef77..02d45c03f 100644 --- a/pages/[roadmap]/index.tsx +++ b/pages/[roadmap]/index.tsx @@ -1,5 +1,18 @@ -import { Box, Button, Text, Container, Link, Stack, Badge } from '@chakra-ui/react'; -import { ArrowBackIcon, AtSignIcon, DownloadIcon, ViewIcon } from '@chakra-ui/icons'; +import { + Box, + Button, + Text, + Container, + Link, + Stack, + Badge, +} from '@chakra-ui/react'; +import { + ArrowBackIcon, + AtSignIcon, + DownloadIcon, + ViewIcon, +} from '@chakra-ui/icons'; import { GlobalHeader } from '../../components/global-header'; import { OpensourceBanner } from '../../components/opensource-banner'; import { UpdatesBanner } from '../../components/updates-banner'; @@ -11,6 +24,8 @@ import Helmet from '../../components/helmet'; import siteConfig from '../../content/site.json'; import React from 'react'; import { event } from '../../lib/gtag'; +import { NewAlertBanner } from '../../components/roadmap/new-alert-banner'; +import { RoadmapPageHeader } from '../../components/roadmap/roadmap-page-header'; type RoadmapProps = { roadmap: RoadmapType; @@ -23,9 +38,9 @@ function ImageRoadmap(props: RoadmapProps) { } return ( - - - Frontend Roadmap + + + Frontend Roadmap ); @@ -42,7 +57,7 @@ function TextualRoadmap(props: RoadmapProps) { const LandingContent = require(`../../content/${normalizedPath}`).default; return ( - + @@ -50,75 +65,19 @@ function TextualRoadmap(props: RoadmapProps) { ); } -export function NewBanner() { - return ( - event({ - category: 'Subscription', - action: 'Clicked the YouTube banner', - label: 'YouTube Alert on Roadmap' - })}> - New - Roadmap topics to be covered on our YouTube - Channel - Topic videos being made on YouTube - » - - ); -} - export default function Roadmap(props: RoadmapProps) { const { roadmap } = props; return ( - + - - } - title={roadmap.title} - subtitle={roadmap.description} - > - - - - {roadmap.pdfUrl && ( - - )} - - - - + + @@ -132,26 +91,26 @@ export default function Roadmap(props: RoadmapProps) { type StaticPathItem = { params: { - roadmap: string - } + roadmap: string; + }; }; export async function getStaticPaths() { const roadmaps = getAllRoadmaps(); - const paramsList: StaticPathItem[] = roadmaps.map(roadmap => ({ - params: { 'roadmap': roadmap.id } + const paramsList: StaticPathItem[] = roadmaps.map((roadmap) => ({ + params: { roadmap: roadmap.id }, })); return { paths: paramsList, - fallback: false + fallback: false, }; } type ContextType = { params: { - roadmap: string - } + roadmap: string; + }; }; export async function getStaticProps(context: ContextType) { @@ -159,7 +118,7 @@ export async function getStaticProps(context: ContextType) { return { props: { - roadmap: getRoadmapById(roadmapId) - } + roadmap: getRoadmapById(roadmapId), + }, }; } diff --git a/pages/[roadmap]/interactive.tsx b/pages/[roadmap]/interactive.tsx index 666c7e5a6..2c7387a0e 100644 --- a/pages/[roadmap]/interactive.tsx +++ b/pages/[roadmap]/interactive.tsx @@ -1,14 +1,13 @@ -import { Box, Button, Container, Link, Stack } from '@chakra-ui/react'; -import { ArrowBackIcon, AtSignIcon, DownloadIcon } from '@chakra-ui/icons'; +import { Box, Container } from '@chakra-ui/react'; 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 Helmet from '../../components/helmet'; import { useEffect, useRef, useState } from 'react'; import { wireframeJSONToSVG } from '../../lib/renderer'; +import { RoadmapPageHeader } from '../../components/roadmap/roadmap-page-header'; type RoadmapProps = { roadmap: RoadmapType; @@ -71,55 +70,7 @@ export default function InteractiveRoadmap(props: RoadmapProps) { keywords={roadmap?.seo.keywords || []} /> - - - - - {roadmap.pdfUrl && ( - - )} - - - - + diff --git a/pages/[roadmap]/resources.tsx b/pages/[roadmap]/resources.tsx index dcd9ffaf8..a7fcb600a 100644 --- a/pages/[roadmap]/resources.tsx +++ b/pages/[roadmap]/resources.tsx @@ -1,13 +1,12 @@ -import { Box, Button, Container, Link, Stack } from '@chakra-ui/react'; -import { ArrowBackIcon, AtSignIcon, DownloadIcon } from '@chakra-ui/icons'; +import { Box, Container } from '@chakra-ui/react'; 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'; import Helmet from '../../components/helmet'; +import { RoadmapPageHeader } from '../../components/roadmap/roadmap-page-header'; type RoadmapProps = { roadmap: RoadmapType; @@ -44,38 +43,7 @@ export default function Roadmap(props: RoadmapProps) { keywords={roadmap?.seo.keywords || []} /> - - - - - {roadmap.pdfUrl && ( - - )} - - - - + diff --git a/public/sitemap.xml b/public/sitemap.xml index bb6e6a19c..be4e76246 100644 --- a/public/sitemap.xml +++ b/public/sitemap.xml @@ -3,7 +3,7 @@ https://roadmap.sh/frontend monthly - 2021-12-03T14:00:37.506Z + 2021-12-03T18:57:23.101Z 1.0 diff --git a/scripts/content-skeleton.ts b/scripts/content-skeleton.ts index d06f92b09..3d6f31d76 100644 --- a/scripts/content-skeleton.ts +++ b/scripts/content-skeleton.ts @@ -1,8 +1,9 @@ import fs from 'fs'; import path from 'path'; +const CONTENT_DIR = path.join(__dirname, '../content'); // Directory containing the roadmaps -const CONTENT_DIR = path.join(__dirname, '../content/roadmaps'); +const ROADMAP_CONTENT_DIR = path.join(__dirname, '../content/roadmaps'); const roadmapKey = process.argv[2]; type ControlType = { @@ -53,7 +54,7 @@ if (!roadmapKey || !roadmaps[roadmapKey]) { // Directory holding the roadmap content files const roadmapDirName = fs - .readdirSync(CONTENT_DIR) + .readdirSync(ROADMAP_CONTENT_DIR) .find((dirName: string) => dirName.replace(/\d+-/, '') === roadmapKey); if (!roadmapDirName) { @@ -61,8 +62,8 @@ if (!roadmapDirName) { process.exit(1); } -const roadmapDirPath = path.join(CONTENT_DIR, roadmapDirName); -const roadmapContentDirPath = path.join(CONTENT_DIR, roadmapDirName, 'content'); +const roadmapDirPath = path.join(ROADMAP_CONTENT_DIR, roadmapDirName); +const roadmapContentDirPath = path.join(ROADMAP_CONTENT_DIR, roadmapDirName, 'content'); // If roadmap content already exists do not proceed as it would override the files if (fs.existsSync(roadmapContentDirPath)) {