diff --git a/gatsby-config.js b/gatsby-config.js
index b61de85..6bedde0 100644
--- a/gatsby-config.js
+++ b/gatsby-config.js
@@ -19,6 +19,13 @@ module.exports = {
path: `${__dirname}/src/images`,
},
},
+ {
+ resolve: `gatsby-source-filesystem`,
+ options: {
+ name: `site`,
+ path: `${__dirname}/src/content/site`,
+ },
+ },
{
resolve: `gatsby-source-filesystem`,
options: {
@@ -34,7 +41,7 @@ module.exports = {
resolve: `gatsby-plugin-manifest`,
options: {
name: `The Programmers Hangout`,
- short_name: `starter`,
+ short_name: `TPH`,
start_url: `/`,
background_color: `#663399`,
theme_color: `#ba1a2e`,
diff --git a/package-lock.json b/package-lock.json
index 02d364c..01d19f1 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1745,6 +1745,11 @@
"resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.2.tgz",
"integrity": "sha512-ce5d3q03Ex0sy4R14722Rmt6MT07Ua+k4FwDfdcToYJcMKNtRVQvJ6JCAPdAmAnbRb6CsX6aYb9m96NGod9uTw=="
},
+ "@types/ramda": {
+ "version": "0.26.18",
+ "resolved": "https://registry.npmjs.org/@types/ramda/-/ramda-0.26.18.tgz",
+ "integrity": "sha512-wK3NLaAkL/ht7Nw4IZsOagJuYqzZgoboFvILolOPtmoKyy25gTdz/uvB/bXsv6vdWENYv+ml5ph873P2d/+9HA=="
+ },
"@types/reach__router": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/@types/reach__router/-/reach__router-1.2.4.tgz",
@@ -1785,15 +1790,26 @@
"version": "0.60.2",
"resolved": "https://registry.npmjs.org/@types/react-native/-/react-native-0.60.2.tgz",
"integrity": "sha512-K4+/etirpv52xu24xAc++OdhbD0VQEt0Kq0h6dZrLU82OlA+I7BhpKF3JBvx9tbmrFaZDxhHp8N4TEvRYS4fdQ==",
+ "dev": true,
"requires": {
"@types/prop-types": "*",
"@types/react": "*"
}
},
+ "@types/react-treeview": {
+ "version": "0.4.2",
+ "resolved": "https://registry.npmjs.org/@types/react-treeview/-/react-treeview-0.4.2.tgz",
+ "integrity": "sha512-pL2IuQrSPbOgn4wQ4B24bekCjyoa6KpereAtYroMwt3dAeFivchksF00oWkNjEoX3NBQ0gZGuu6fa1AzL5Whgw==",
+ "dev": true,
+ "requires": {
+ "@types/react": "*"
+ }
+ },
"@types/styled-components": {
"version": "4.1.18",
"resolved": "https://registry.npmjs.org/@types/styled-components/-/styled-components-4.1.18.tgz",
"integrity": "sha512-VrHkgvjbxQXOw0xWSUckusUUZ4y/jqN1u7kF29ngh0oE6uOrlZHleTgqeUqylQqHQIeQ8MxFb50BRHy8ju5DHg==",
+ "dev": true,
"requires": {
"@types/react": "*",
"@types/react-native": "*",
@@ -13765,9 +13781,9 @@
"integrity": "sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA=="
},
"ramda": {
- "version": "0.21.0",
- "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.21.0.tgz",
- "integrity": "sha1-oAGr7bP/YQd9T/HVd9RN536NCjU="
+ "version": "0.26.1",
+ "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.26.1.tgz",
+ "integrity": "sha512-hLWjpy7EnsDBb0p+Z3B7rPi3GDeRG5ZtiI33kJhTt+ORCd38AbAIjB/9zRIUoeTbE/AVX5ZkU7m6bznsvrf8eQ=="
},
"randombytes": {
"version": "2.1.0",
@@ -14094,6 +14110,14 @@
"shallowequal": "^1.0.1"
}
},
+ "react-treeview": {
+ "version": "0.4.7",
+ "resolved": "https://registry.npmjs.org/react-treeview/-/react-treeview-0.4.7.tgz",
+ "integrity": "sha1-9kfgT3BJbrEfsJEsNRh+gOtg1Fg=",
+ "requires": {
+ "prop-types": "^15.5.8"
+ }
+ },
"read": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/read/-/read-1.0.7.tgz",
@@ -16253,6 +16277,11 @@
"json5": "^0.5.0"
}
},
+ "ramda": {
+ "version": "0.21.0",
+ "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.21.0.tgz",
+ "integrity": "sha1-oAGr7bP/YQd9T/HVd9RN536NCjU="
+ },
"xml2js": {
"version": "0.4.17",
"resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.17.tgz",
diff --git a/package.json b/package.json
index 9da9037..26ddca5 100644
--- a/package.json
+++ b/package.json
@@ -5,7 +5,7 @@
"version": "0.1.0",
"author": "TPH",
"dependencies": {
- "@types/styled-components": "^4.1.18",
+ "@types/ramda": "^0.26.18",
"axios": "^0.19.0",
"babel-plugin-styled-components": "^1.10.6",
"gatsby": "^2.13.39",
@@ -27,10 +27,12 @@
"highlight.js": "^9.15.8",
"node-sass": "^4.12.0",
"prismjs": "^1.17.1",
+ "ramda": "^0.26.1",
"react": "^16.8.6",
"react-dom": "^16.8.6",
"react-helmet": "^5.2.1",
"react-perfect-scrollbar": "^1.5.3",
+ "react-treeview": "^0.4.7",
"styled-components": "^4.3.2"
},
"devDependencies": {
@@ -38,6 +40,8 @@
"@types/react": "^16.8.23",
"@types/react-dom": "^16.8.5",
"@types/react-helmet": "^5.0.8",
+ "@types/react-treeview": "^0.4.2",
+ "@types/styled-components": "^4.1.18",
"prettier": "^1.18.2",
"@graphql-codegen/typescript": "1.4.0",
"@graphql-codegen/typescript-operations": "1.4.0",
diff --git a/src/components/Docs/Sidebar/index.tsx b/src/components/Docs/Sidebar/index.tsx
deleted file mode 100644
index 2ec7ed8..0000000
--- a/src/components/Docs/Sidebar/index.tsx
+++ /dev/null
@@ -1,5 +0,0 @@
-import React from "react";
-
-const Sidebar = () => { }
-
-export default Sidebar;
\ No newline at end of file
diff --git a/src/components/Docs/index.ts b/src/components/Docs/index.ts
deleted file mode 100644
index 3564e0a..0000000
--- a/src/components/Docs/index.ts
+++ /dev/null
@@ -1 +0,0 @@
-export { default as Sidebar } from "./Sidebar";
\ No newline at end of file
diff --git a/src/components/DocsLayout/index.tsx b/src/components/DocsLayout/index.tsx
new file mode 100644
index 0000000..6d09c2f
--- /dev/null
+++ b/src/components/DocsLayout/index.tsx
@@ -0,0 +1,46 @@
+/**
+ * Layout component that queries for data
+ * with Gatsby's useStaticQuery component
+ *
+ * See: https://www.gatsbyjs.org/docs/use-static-query/
+ */
+
+import React, { PropsWithChildren } from "react"
+import { useStaticQuery, graphql } from "gatsby"
+
+import Container from "../Container"
+import DocsSidebar from "../DocsSidebar"
+import { Main, MainContent } from "./styles"
+import Scrollbar from "react-perfect-scrollbar"
+import "react-perfect-scrollbar/dist/css/styles.css"
+
+const DocsLayout = ({ children }: PropsWithChildren<{}>) => {
+ const data = useStaticQuery(graphql`
+ query {
+ site {
+ siteMetadata {
+ title
+ }
+ }
+ }
+ `)
+
+ return (
+
+
+
+
+ {data.site.siteMetadata.title}
+ {children}
+
+
+
+
+ )
+}
+
+export default DocsLayout
diff --git a/src/components/DocsLayout/layout.scss b/src/components/DocsLayout/layout.scss
new file mode 100644
index 0000000..e033dcd
--- /dev/null
+++ b/src/components/DocsLayout/layout.scss
@@ -0,0 +1,41 @@
+// TODO: refactor this into styled components
+
+html {
+ font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Helvetica, Arial,
+ sans-serif, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol;
+ -ms-text-size-adjust: 100%;
+ -webkit-text-size-adjust: 100%;
+}
+
+body {
+ margin: 0;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+/**
+ * If you already use line highlighting
+ */
+
+/* Adjust the position of the line numbers */
+.gatsby-highlight pre[class*="language-"].line-numbers {
+ padding-left: 2.8em;
+}
+
+/**
+ * If you only want to use line numbering
+ */
+
+.gatsby-highlight {
+ background-color: #fdf6e3;
+ border-radius: 0.3em;
+ margin: 0.5em 0;
+ padding: 1em;
+ overflow: auto;
+}
+
+.gatsby-highlight pre[class*="language-"].line-numbers {
+ padding: 0;
+ padding-left: 2.8em;
+ overflow: initial;
+}
diff --git a/src/components/DocsLayout/styles.tsx b/src/components/DocsLayout/styles.tsx
new file mode 100644
index 0000000..5bc63b3
--- /dev/null
+++ b/src/components/DocsLayout/styles.tsx
@@ -0,0 +1,19 @@
+import styled from "styled-components"
+
+export const Main = styled.div`
+ display: flex;
+ margin: 128px auto 64px !important;
+ width: 100%;
+`
+
+export const MainContent = styled.main`
+ flex: 1 0 auto;
+
+ & > :first-child {
+ margin-top: 0;
+ }
+
+ & > :last-child {
+ margin-bottom: 0;
+ }
+`
diff --git a/src/components/DocsSidebar/index.tsx b/src/components/DocsSidebar/index.tsx
new file mode 100644
index 0000000..caabcbf
--- /dev/null
+++ b/src/components/DocsSidebar/index.tsx
@@ -0,0 +1,142 @@
+import * as R from "ramda"
+import React from "react"
+import Tree from "react-treeview"
+import { useStaticQuery, graphql } from "gatsby"
+
+export interface DocsSidebarProps {
+ readonly width: string | number
+}
+
+interface IFile {
+ title: string
+ type: "file"
+}
+
+interface IFolder {
+ title: string
+ type: "folder"
+ children: IFileOrFolder[]
+}
+
+type IFileOrFolder = IFile | IFolder
+
+const traverse = ([head, ...tail]: string[]): IFileOrFolder => {
+ const isFile = !tail.length
+ if (isFile) {
+ // probably not more than one dot
+ const [name] = head.split(".")
+ return {
+ title: name,
+ type: "file",
+ }
+ }
+ return {
+ title: head,
+ type: "folder",
+ children: [traverse(tail)],
+ }
+}
+
+const generateFolder = ({
+ title,
+ targets,
+}: {
+ title: IFolder["title"]
+ targets: IFolder[]
+}): IFolder => {
+ const children = join(R.chain(target => target.children, targets))
+
+ return {
+ title,
+ type: "folder",
+ children,
+ }
+}
+
+const generateFile = ({ title }: { title: IFile["title"] }): IFile => {
+ return {
+ title,
+ type: "file",
+ }
+}
+
+const join = ([head, ...tail]: IFileOrFolder[]): IFileOrFolder[] => {
+ if (!head) return []
+
+ const [similarFs, remaining] = R.partition(
+ obj => obj.title === head.title && obj.type === head.type,
+ tail
+ )
+ const targets = [head, ...similarFs]
+ const { title } = head
+
+ const current =
+ head.type === "folder"
+ ? generateFolder({ title, targets: targets as IFolder[] })
+ : generateFile({ title })
+
+ return [current, ...join(remaining)]
+}
+
+interface IFileQuery {
+ node: {
+ relativePath: string
+ childMarkdownRemark: {
+ frontmatter: {
+ author: string
+ date: string
+ }
+ }
+ }
+}
+
+interface IAllDocsQuery {
+ allFile: {
+ edges: IFileQuery[]
+ }
+}
+
+const ALL_DOCS = graphql`
+ query {
+ allFile(filter: { sourceInstanceName: { eq: "docs" } }) {
+ edges {
+ node {
+ relativePath
+ childMarkdownRemark {
+ frontmatter {
+ author
+ date
+ }
+ }
+ }
+ }
+ }
+ }
+`
+
+const plantTree = (item: IFileOrFolder) => {
+ if (item.type === "file") {
+ return
{item.title}
+ }
+
+ return (
+ {item.title}}>
+ {item.children.map(plantTree)}
+
+ )
+}
+
+const DocsSidebar = ({ width }: DocsSidebarProps) => {
+ const docs = useStaticQuery(ALL_DOCS)
+
+ const objects = docs.allFile.edges.map(({ node: file }: IFileQuery) =>
+ traverse(file.relativePath.split("/"))
+ )
+ const results = join(objects)
+
+ console.log(results)
+
+ return {results.map(node => plantTree(node))}
+}
+
+export default DocsSidebar
diff --git a/src/components/DocsSidebar/style.tsx b/src/components/DocsSidebar/style.tsx
new file mode 100644
index 0000000..8b67f01
--- /dev/null
+++ b/src/components/DocsSidebar/style.tsx
@@ -0,0 +1,6 @@
+import styled from "styled-components"
+
+export const DocsSidebarScroller = styled.div`
+ display: flex;
+ flex-direction: column;
+`
diff --git a/src/components/DocsSidebarSection/index.tsx b/src/components/DocsSidebarSection/index.tsx
new file mode 100644
index 0000000..e04e899
--- /dev/null
+++ b/src/components/DocsSidebarSection/index.tsx
@@ -0,0 +1,20 @@
+import React from "react"
+import { SidebarTitle } from "./style"
+
+export interface DocsSidebarSectionProps {
+ readonly title: string
+}
+
+const DocsSidebarSection = ({
+ title,
+ children,
+}: React.PropsWithChildren) => {
+ return (
+
+ {title}
+ {children}
+
+ )
+}
+
+export default DocsSidebarSection
diff --git a/src/components/DocsSidebarSection/style.tsx b/src/components/DocsSidebarSection/style.tsx
new file mode 100644
index 0000000..41ebe9d
--- /dev/null
+++ b/src/components/DocsSidebarSection/style.tsx
@@ -0,0 +1,5 @@
+import styled from "styled-components";
+
+export const SidebarTitle = styled.h3`
+ text-transform: uppercase;
+`;
\ No newline at end of file
diff --git a/src/components/Layout/index.tsx b/src/components/Layout/index.tsx
index bfe4f70..68d9645 100644
--- a/src/components/Layout/index.tsx
+++ b/src/components/Layout/index.tsx
@@ -18,7 +18,7 @@ import "react-perfect-scrollbar/dist/css/styles.css"
const Layout = ({ children }: PropsWithChildren<{}>) => {
const data = useStaticQuery(graphql`
- query SiteTitleQuery {
+ query {
site {
siteMetadata {
title
diff --git a/src/components/Layout/layout.scss b/src/components/Layout/layout.scss
index e033dcd..f12a80c 100644
--- a/src/components/Layout/layout.scss
+++ b/src/components/Layout/layout.scss
@@ -39,3 +39,44 @@ body {
padding-left: 2.8em;
overflow: initial;
}
+
+/* temp */
+/* the tree node's style */
+.tree-view {
+ overflow-y: hidden;
+}
+
+.tree-view_item {
+ display: flex;
+}
+
+/* style for the children nodes container */
+.tree-view_children {
+ margin-left: 16px;
+}
+
+.tree-view_children-collapsed {
+ height: 0px;
+}
+
+.tree-view_arrow {
+ cursor: pointer;
+ margin-right: 6px;
+ display: inline-block;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+}
+
+.tree-view_arrow:after {
+ content: "▾";
+}
+
+/* rotate the triangle to close it */
+.tree-view_arrow-collapsed {
+ -webkit-transform: rotate(-90deg);
+ -moz-transform: rotate(-90deg);
+ -ms-transform: rotate(-90deg);
+ transform: rotate(-90deg);
+}
diff --git a/src/content/docs/javascript/promises/intro.md b/src/content/docs/javascript/promises/intro.md
index fd35f46..636d98d 100644
--- a/src/content/docs/javascript/promises/intro.md
+++ b/src/content/docs/javascript/promises/intro.md
@@ -8,6 +8,7 @@ recommended_reading:
- javascript/callbacks
- javascript/es6/arrow-functions
---
+
# A Promise to Keep
A `Promise` in Javascript represents an action that has already started, but one that will be
diff --git a/src/content/docs/javascript/simplifying-promises.md b/src/content/docs/javascript/promises/simplifying-promises.md
similarity index 100%
rename from src/content/docs/javascript/simplifying-promises.md
rename to src/content/docs/javascript/promises/simplifying-promises.md
diff --git a/src/content/site/index.md b/src/content/site/index.md
new file mode 100644
index 0000000..0ea1733
--- /dev/null
+++ b/src/content/site/index.md
@@ -0,0 +1,15 @@
+---
+path: /
+---
+# The Programmers Hangout
+
+The Programmer's Hangout (TPH) is a Discord community of programmers with members of
+all skill levels. If you're interested in programming, you're welcome here regardless
+of how much experience you have. You'll find that we're always learning here regardless
+of expertise.
+
+## How do I join?
+
+All you need to do is click!
+
+
diff --git a/src/templates/languagePost.tsx b/src/templates/languagePost.tsx
index 8483fc7..a0c94b8 100644
--- a/src/templates/languagePost.tsx
+++ b/src/templates/languagePost.tsx
@@ -1,25 +1,25 @@
-import React from "react";
-import { graphql } from "gatsby";
-import SEO from "../components/SEO";
-import Layout from "../components/Layout";
+import React from "react"
+import { graphql } from "gatsby"
+import SEO from "../components/SEO"
+import DocsLayout from "../components/DocsLayout"
// @todo maybe find alternative type for data
const LanguagePost = ({ data }: any) => {
- const { html, frontmatter } = data.file.post;
+ const { html, frontmatter } = data.file.post
console.log(data)
return (
-
+
-
+
)
}
-export default LanguagePost;
+export default LanguagePost
export const query = graphql`
query LanguagePost($file: String!) {
- file(relativePath: {eq: $file }) {
+ file(relativePath: { eq: $file }) {
post: childMarkdownRemark {
html
frontmatter {