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 {