From 9f98b305688aa20f130c644dbd60de71c2293a34 Mon Sep 17 00:00:00 2001 From: Kamran Ahmed Date: Thu, 31 Oct 2019 23:45:09 +0400 Subject: [PATCH] Refactor and roadmap summary pages --- components/featured-content/roadmaps.js | 2 +- components/roadmap-summary/index.js | 16 +++++++++- components/roadmap-summary/style.js | 40 +++++++++++++++++++++++-- data/roadmaps.json | 31 ++++++++++++++----- layouts/default/global.scss | 4 +++ lib/roadmap.js | 26 ++++++++++++++++ package.json | 1 + pages/[fallback].js | 21 ------------- pages/[fallback]/[version].js | 3 ++ pages/[fallback]/index.js | 22 ++++++++++++++ pages/roadmaps/[roadmap].js | 25 ---------------- pages/roadmaps/[roadmap]/[version].js | 3 ++ pages/roadmaps/[roadmap]/index.js | 24 +++++++++++++++ yarn.lock | 5 ++++ 14 files changed, 165 insertions(+), 58 deletions(-) create mode 100644 lib/roadmap.js delete mode 100644 pages/[fallback].js create mode 100644 pages/[fallback]/[version].js create mode 100644 pages/[fallback]/index.js delete mode 100644 pages/roadmaps/[roadmap].js create mode 100644 pages/roadmaps/[roadmap]/[version].js create mode 100644 pages/roadmaps/[roadmap]/index.js diff --git a/components/featured-content/roadmaps.js b/components/featured-content/roadmaps.js index aa0230c5f..a47991fc8 100644 --- a/components/featured-content/roadmaps.js +++ b/components/featured-content/roadmaps.js @@ -20,7 +20,7 @@ const FeaturedRoadmaps = () => ( { roadmaps .filter(({ featured }) => featured) .map(roadmap => ( -
+

{ roadmap.title }

diff --git a/components/roadmap-summary/index.js b/components/roadmap-summary/index.js index ffca086f8..775281c7c 100644 --- a/components/roadmap-summary/index.js +++ b/components/roadmap-summary/index.js @@ -1,3 +1,6 @@ +import Link from 'next/link'; +import classNames from 'classnames'; + import { SummaryContainer, Title, @@ -5,6 +8,8 @@ import { Image, Header, Summary, + VersionLink, + VersionList, } from './style'; const RoadmapSummary = ({ roadmap }) => ( @@ -12,8 +17,17 @@ const RoadmapSummary = ({ roadmap }) => (
{ roadmap.title } { roadmap.description } + + { (roadmap.versions || []).map(versionItem => ( + + { versionItem } Version + + )) } +
- +
diff --git a/components/roadmap-summary/style.js b/components/roadmap-summary/style.js index e7e73d2a2..94ece8d5d 100644 --- a/components/roadmap-summary/style.js +++ b/components/roadmap-summary/style.js @@ -9,7 +9,7 @@ export const Header = styled.div` export const Summary = styled.div` text-align: center; - padding: 50px 0; + padding: 0 0 50px; `; export const Title = styled.h1` @@ -17,10 +17,46 @@ export const Title = styled.h1` margin-bottom: 12px; font-size: 42px; `; + export const Description = styled.p` font-size: 19px; - margin-bottom: 0; `; + export const Image = styled.img` width: 100%; `; + +export const VersionList = styled.div` + margin: 35px 0 15px; +`; + +export const VersionLink = styled.a` + display: inline-block; + position: relative; + padding: 5px 10px 8px; + text-decoration: none; + color: rgb(102, 102, 102); + font-size: 14px; + font-weight: 400; + text-transform: capitalize; + + &.active, &.active:hover { + color: #2d2d2d; + + &:after { + position: absolute; + content: ""; + display: block; + height: 0; + left: 9px; + right: 9px; + bottom: -1px; + border-bottom: 2px solid currentColor; + } + } + + &:hover { + text-decoration: none; + color: #111111; + } +`; \ No newline at end of file diff --git a/data/roadmaps.json b/data/roadmaps.json index 05b85464a..763c130bf 100644 --- a/data/roadmaps.json +++ b/data/roadmaps.json @@ -3,24 +3,39 @@ "title": "Frontend Developer", "description": "Step by step guide to becoming a modern frontend developer", "featuredDescription": "Step by step guide to becoming a modern frontend developer in 2019", - "slug": "/frontend", + "slug": "/roadmaps/frontend", "picture": "/static/roadmaps/frontend.png", - "featured": true + "featured": true, + "versions": [ + "latest", + "2018", + "2017" + ] }, { "title": "Backend Developer", - "description": "Roadmap to becoming a backend developer", + "description": "Step by step guide to becoming a modern backend developer", "featuredDescription": "Step by step guide to becoming a modern backend developer in 2019", - "slug": "/backend", + "slug": "/roadmaps/backend", "picture": "/static/roadmaps/backend.png", - "featured": true + "featured": true, + "versions": [ + "latest", + "2018", + "2017" + ] }, { "title": "DevOps Roadmap", - "description": "Roadmap for DevOps or any other Operations Role", + "description": "Step by step guide for DevOps or any other Operations Role", "featuredDescription": "Step by step guide to become an SRE or for any operations role in 2019", - "slug": "/devops", + "slug": "/roadmaps/devops", "picture": "/static/roadmaps/devops.png", - "featured": true + "featured": true, + "versions": [ + "latest", + "2018", + "2017" + ] } ] \ No newline at end of file diff --git a/layouts/default/global.scss b/layouts/default/global.scss index 86c68b481..a1e978fc6 100644 --- a/layouts/default/global.scss +++ b/layouts/default/global.scss @@ -16,6 +16,10 @@ background-color: #fafafa !important; } +.muted { + color: #757575; +} + .dark-link { font-weight: 500; color: #000000; diff --git a/lib/roadmap.js b/lib/roadmap.js new file mode 100644 index 000000000..c9798295e --- /dev/null +++ b/lib/roadmap.js @@ -0,0 +1,26 @@ +import roadmaps from "../data/roadmaps"; + +export const getRequestedRoadmap = req => { + // Considering it a new roadmap URL e.g. `/roadmaps/frontend` + const currentUrl = req.url.replace(/\/$/, ''); + // Considering it a legacy URL e.g. converting `/frontend` to `roadmap.sh/roadmaps/frontend` + const legacyUrl = `/roadmaps${currentUrl}`; + // Get the roadmap version out of the URL e.g. `/roadmaps/frontend/2019` + const [foundVersion = ''] = currentUrl.match(/(\d+|latest)$/) || ['latest']; + const foundVersionRegex = new RegExp(`\/?${foundVersion}$`); + // Remove version from the URL because slugs in roadmaps list don't have versions + const newUrlWithoutVersion = currentUrl.replace(foundVersionRegex, ''); + const legacyUrlWithoutVersion = legacyUrl.replace(foundVersionRegex, ''); + + const urlToSlugList = [ + currentUrl, + legacyUrl, + newUrlWithoutVersion, + legacyUrlWithoutVersion, + ]; + + return { + ...roadmaps.find(roadmap => urlToSlugList.includes(roadmap.slug)), + version: foundVersion, + }; +}; \ No newline at end of file diff --git a/package.json b/package.json index 0dee1a905..8731f777c 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,7 @@ "@zeit/next-sass": "^1.0.1", "autoprefixer": "^9.6.1", "bootstrap": "^4.3.1", + "classnames": "^2.2.6", "font-awesome": "^4.7.0", "next": "^9.0.4", "node-sass": "^4.12.0", diff --git a/pages/[fallback].js b/pages/[fallback].js deleted file mode 100644 index 204b54e88..000000000 --- a/pages/[fallback].js +++ /dev/null @@ -1,21 +0,0 @@ -import Roadmap from './roadmaps/[roadmap]'; -import roadmapsList from "../data/roadmaps.json"; -import { serverOnlyProps } from '../lib/server'; - -// Fallback page to handle the old roadmap pages implementation -const OldRoadmap = ({ roadmap }) => { - if (roadmap) { - return - } - - return

404

-}; - -OldRoadmap.getInitialProps = serverOnlyProps(({ req }) => { - return { - roadmap: roadmapsList.find(roadmap => roadmap.slug === req.url), - }; -}); - - -export default OldRoadmap; \ No newline at end of file diff --git a/pages/[fallback]/[version].js b/pages/[fallback]/[version].js new file mode 100644 index 000000000..9d2cd34f1 --- /dev/null +++ b/pages/[fallback]/[version].js @@ -0,0 +1,3 @@ +import OldRoadmap from './index'; + +export default OldRoadmap; \ No newline at end of file diff --git a/pages/[fallback]/index.js b/pages/[fallback]/index.js new file mode 100644 index 000000000..3dc355bed --- /dev/null +++ b/pages/[fallback]/index.js @@ -0,0 +1,22 @@ +import Error from 'next/error'; +import Roadmap from '../roadmaps/[roadmap]/index'; +import { serverOnlyProps } from '../../lib/server'; +import { getRequestedRoadmap } from '../../lib/roadmap'; + +// Fallback page to handle the old roadmap pages implementation +const OldRoadmap = ({ roadmap }) => { + if (roadmap) { + return + } + + return ; +}; + +OldRoadmap.getInitialProps = serverOnlyProps(({ req }) => { + return { + roadmap: getRequestedRoadmap(req), + }; +}); + + +export default OldRoadmap; \ No newline at end of file diff --git a/pages/roadmaps/[roadmap].js b/pages/roadmaps/[roadmap].js deleted file mode 100644 index 31a75e18c..000000000 --- a/pages/roadmaps/[roadmap].js +++ /dev/null @@ -1,25 +0,0 @@ -import roadmaps from "../../data/roadmaps"; -import DefaultLayout from '../../layouts/default/index'; -import PageHeader from '../../components/page-header/index'; -import { serverOnlyProps } from '../../lib/server'; -import RoadmapSummary from '../../components/roadmap-summary'; -import PageFooter from '../../components/page-footer'; - -const Roadmap = ({ roadmap }) => { - return ( - - - - - - ); -}; - -Roadmap.getInitialProps = serverOnlyProps(({ req }) => { - const normalizedUrl = req.url.replace('roadmaps/', ''); - return { - roadmap: roadmaps.find(roadmap => roadmap.slug === normalizedUrl), - }; -}); - -export default Roadmap; \ No newline at end of file diff --git a/pages/roadmaps/[roadmap]/[version].js b/pages/roadmaps/[roadmap]/[version].js new file mode 100644 index 000000000..8ab4b316d --- /dev/null +++ b/pages/roadmaps/[roadmap]/[version].js @@ -0,0 +1,3 @@ +import Roadmap from './index'; + +export default Roadmap; \ No newline at end of file diff --git a/pages/roadmaps/[roadmap]/index.js b/pages/roadmaps/[roadmap]/index.js new file mode 100644 index 000000000..d020a9e3f --- /dev/null +++ b/pages/roadmaps/[roadmap]/index.js @@ -0,0 +1,24 @@ +import DefaultLayout from '../../../layouts/default'; +import { serverOnlyProps } from '../../../lib/server'; +import PageHeader from '../../../components/page-header'; +import PageFooter from '../../../components/page-footer'; +import { getRequestedRoadmap } from '../../../lib/roadmap'; +import RoadmapSummary from '../../../components/roadmap-summary'; + +const Roadmap = ({ roadmap }) => { + return ( + + + + + + ); +}; + +Roadmap.getInitialProps = serverOnlyProps(({ req }) => { + return { + roadmap: getRequestedRoadmap(req), + }; +}); + +export default Roadmap; \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index a5f5761a1..688a1fc88 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1754,6 +1754,11 @@ class-utils@^0.3.5: isobject "^3.0.0" static-extend "^0.1.1" +classnames@^2.2.6: + version "2.2.6" + resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.2.6.tgz#43935bffdd291f326dad0a205309b38d00f650ce" + integrity sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q== + cliui@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/cliui/-/cliui-3.2.0.tgz#120601537a916d29940f934da3b48d585a39213d"