├── .gitignore ├── .netlify └── state.json ├── .prettierrc ├── LICENSE ├── README.md ├── functions └── subscribe.js ├── gatsby-browser.js ├── gatsby-config.js ├── gatsby-node.js ├── gatsby-ssr.js ├── netlify.toml ├── package-lock.json ├── package.json └── src ├── components ├── Button.js ├── Card.js ├── CourseCard.js ├── CourseList.js ├── Featured.js ├── Footer.js ├── FullscreenVideo.js ├── Hero.js ├── Layout.js ├── Navbar.js ├── Newsletter.js ├── Philosophy.js ├── Section.js ├── SocialFollow.js ├── SplitView.js ├── YouTubeGallery.js ├── YouTubeThumbnail.js └── seo.js ├── elements ├── Animations.js ├── Button.js ├── Card.js ├── CourseList.js ├── Featured.js ├── Flexbox.js ├── Footer.js ├── Forms.js ├── FullScreenVideo.js ├── Gallery.js ├── Global.js ├── Hero.js ├── Navbar.js ├── Newsletter.js ├── Philosophy.js ├── Section.js ├── SocialFollow.js └── SplitView.js ├── images ├── courses │ ├── html-css-js.png │ ├── node.png │ └── vscode.png ├── hamburger.svg ├── lbt-icon.png ├── lbt-icon.svg ├── lbt-logo.svg ├── learn-vs-code-cover.svg ├── logo360-white.svg └── me-circle.png ├── md └── courses │ ├── ChatApp.md │ ├── CoreFundamentals.md │ ├── LearnVSCode.md │ └── QuizApp.md ├── netlify.toml ├── pages ├── 404.js └── index.js └── utilities ├── Colors.js └── Mixins.js /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Runtime data 9 | pids 10 | *.pid 11 | *.seed 12 | *.pid.lock 13 | 14 | # Directory for instrumented libs generated by jscoverage/JSCover 15 | lib-cov 16 | 17 | # Coverage directory used by tools like istanbul 18 | coverage 19 | 20 | # nyc test coverage 21 | .nyc_output 22 | 23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 24 | .grunt 25 | 26 | # Bower dependency directory (https://bower.io/) 27 | bower_components 28 | 29 | # node-waf configuration 30 | .lock-wscript 31 | 32 | # Compiled binary addons (http://nodejs.org/api/addons.html) 33 | build/Release 34 | 35 | # Dependency directories 36 | node_modules/ 37 | jspm_packages/ 38 | 39 | # Typescript v1 declaration files 40 | typings/ 41 | 42 | # Optional npm cache directory 43 | .npm 44 | 45 | # Optional eslint cache 46 | .eslintcache 47 | 48 | # Optional REPL history 49 | .node_repl_history 50 | 51 | # Output of 'npm pack' 52 | *.tgz 53 | 54 | # dotenv environment variables file 55 | .env 56 | 57 | # gatsby files 58 | .cache/ 59 | public 60 | 61 | # Mac files 62 | .DS_Store 63 | 64 | # Yarn 65 | yarn-error.log 66 | .pnp/ 67 | .pnp.js 68 | # Yarn Integrity file 69 | .yarn-integrity 70 | 71 | #netlify stuff 72 | /lambda -------------------------------------------------------------------------------- /.netlify/state.json: -------------------------------------------------------------------------------- 1 | { 2 | "siteId": "b37b31fd-23fd-4c5f-90d4-11e7a347ab25" 3 | } -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "endOfLine": "lf", 3 | "semi": false, 4 | "singleQuote": false, 5 | "tabWidth": 2, 6 | "trailingComma": "es5" 7 | } 8 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 gatsbyjs 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Learn Build Teach 2 | 3 | [![Netlify Status](https://api.netlify.com/api/v1/badges/b9a205dd-5ae4-45e5-ae7e-b13aa830b669/deploy-status)](https://app.netlify.com/sites/hardcore-liskov-ec6efe/deploys) 4 | 5 | Want to learn more about Web Development, Design, and Tools? Then, you're in the right place! I LEARN the newest techniques in Web Development, Design, and Tools. I BUILD projects for myself and others. I TEACH others through online content. 6 | -------------------------------------------------------------------------------- /functions/subscribe.js: -------------------------------------------------------------------------------- 1 | const axios = require("axios"); 2 | require("dotenv").config(); 3 | 4 | exports.handler = function(event, context, callback) { 5 | const password = process.env.MAILCHIMP_API_KEY; 6 | console.log(password); 7 | if (!password) { 8 | console.error("No MailChimp API Key include in environment variables"); 9 | process.exit(1); 10 | } 11 | 12 | const parsedBody = JSON.parse(event.body); 13 | const email = parsedBody.email; 14 | 15 | var re = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; 16 | 17 | if (!re.test(email)) { 18 | return callback(null, { 19 | statusCode: 400, 20 | body: JSON.stringify({ msg: "Invalid Email" }) 21 | }); 22 | } 23 | 24 | const body = { 25 | email_address: email, 26 | status: "subscribed" 27 | }; 28 | 29 | const username = "james"; 30 | 31 | axios({ 32 | method: "post", 33 | url: "https://us15.api.mailchimp.com/3.0/lists/f236f68fc1/members/", 34 | data: body, 35 | auth: { 36 | username, 37 | password 38 | } 39 | }) 40 | .then(response => { 41 | return callback(null, { 42 | statusCode: 200, 43 | body: JSON.stringify({ msg: "Thanks for subscribing!" }) 44 | }); 45 | }) 46 | .catch(({ response }) => { 47 | let title = ""; 48 | if (response && response.data && response.data.title) { 49 | title = response.data.title; 50 | } 51 | callback(null, { 52 | statusCode: 500, 53 | body: JSON.stringify({ 54 | msg: `Failed to subscribe. ${title}` 55 | }) 56 | }); 57 | }); 58 | }; 59 | -------------------------------------------------------------------------------- /gatsby-browser.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Implement Gatsby's Browser APIs in this file. 3 | * 4 | * See: https://www.gatsbyjs.org/docs/browser-apis/ 5 | */ 6 | 7 | // You can delete this file if you're not using it 8 | -------------------------------------------------------------------------------- /gatsby-config.js: -------------------------------------------------------------------------------- 1 | const path = require("path") 2 | 3 | module.exports = { 4 | siteMetadata: { 5 | title: `Learn Build Teach.`, 6 | description: `Learn Web Development, Design, and Developer Tools.`, 7 | author: `@jamesqquick`, 8 | }, 9 | proxy: { 10 | prefix: "/.netlify/functions", 11 | url: "http://localhost:9000", 12 | }, 13 | plugins: [ 14 | `gatsby-plugin-react-helmet`, 15 | { 16 | resolve: `gatsby-source-filesystem`, 17 | options: { 18 | name: `images`, 19 | path: path.join(__dirname, `src`, `images`), 20 | }, 21 | }, 22 | { 23 | resolve: `gatsby-source-filesystem`, 24 | options: { 25 | path: `${__dirname}/src/md`, 26 | name: "markdown-pages", 27 | }, 28 | }, 29 | `gatsby-transformer-sharp`, 30 | `gatsby-plugin-sharp`, 31 | { 32 | resolve: `gatsby-plugin-manifest`, 33 | options: { 34 | name: `gatsby-starter-default`, 35 | short_name: `Learn Build Teach`, 36 | start_url: `/`, 37 | icon: "src/images/lbt-icon.png", // This path is relative to the root of the site. 38 | }, 39 | }, 40 | { 41 | resolve: `gatsby-plugin-google-analytics`, 42 | options: { 43 | trackingId: "UA-130194764-1", 44 | // Puts tracking script in the head instead of the body 45 | head: false, 46 | // Setting this parameter is optional 47 | anonymize: true, 48 | // Setting this parameter is also optional 49 | respectDNT: true, 50 | }, 51 | }, 52 | { 53 | resolve: `gatsby-plugin-google-fonts`, 54 | options: { 55 | fonts: [`oswald\:300,500,700`, `roboto\:300,500,700`], 56 | display: "swap", 57 | }, 58 | }, 59 | `gatsby-transformer-remark`, 60 | { 61 | resolve: `gatsby-plugin-styled-components`, 62 | }, 63 | { 64 | resolve: `gatsby-source-youtube-v2`, 65 | options: { 66 | channelId: ["UC-T8W79DN6PBnzomelvqJYw"], 67 | apiKey: "AIzaSyDKVI3I7T1exxi6mIL-UkNmWYE1f7E40TI", 68 | maxVideos: 8, 69 | }, 70 | }, 71 | // this (optional) plugin enables Progressive Web App + Offline functionality 72 | // To learn more, visit: https://gatsby.dev/offline 73 | // `gatsby-plugin-offline`, 74 | ], 75 | } 76 | -------------------------------------------------------------------------------- /gatsby-node.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Implement Gatsby's Node APIs in this file. 3 | * 4 | * See: https://www.gatsbyjs.org/docs/node-apis/ 5 | */ 6 | 7 | // You can delete this file if you're not using it 8 | -------------------------------------------------------------------------------- /gatsby-ssr.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Implement Gatsby's SSR (Server Side Rendering) APIs in this file. 3 | * 4 | * See: https://www.gatsbyjs.org/docs/ssr-apis/ 5 | */ 6 | 7 | // You can delete this file if you're not using it 8 | -------------------------------------------------------------------------------- /netlify.toml: -------------------------------------------------------------------------------- 1 | [build] 2 | functions = "lambda" 3 | Command = "npm run prod" 4 | 5 | [[redirects]] 6 | from = "/*" 7 | to = "https://discord.gg/vM2bagU" 8 | status = 200 9 | force = true 10 | headers = {X-From = "Netlify"} 11 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "learn-build-teach", 3 | "private": true, 4 | "description": "Web Develop, Design, and Developer Tools. Learn Build Teach.", 5 | "version": "2.1.0", 6 | "author": "James Q Quick ", 7 | "dependencies": { 8 | "@fortawesome/fontawesome-svg-core": "^1.2.19", 9 | "@fortawesome/free-brands-svg-icons": "^5.9.0", 10 | "@fortawesome/free-solid-svg-icons": "^5.9.0", 11 | "@fortawesome/react-fontawesome": "^0.1.4", 12 | "axios": "^0.19.0", 13 | "base-64": "^0.1.0", 14 | "dotenv": "^8.0.0", 15 | "email-validator": "^2.0.4", 16 | "gatsby": "^2.13.31", 17 | "gatsby-image": "^2.2.6", 18 | "gatsby-plugin-google-analytics": "^2.1.4", 19 | "gatsby-plugin-google-fonts": "^1.0.1", 20 | "gatsby-plugin-manifest": "^2.2.3", 21 | "gatsby-plugin-offline": "^2.2.4", 22 | "gatsby-plugin-react-helmet": "^3.1.2", 23 | "gatsby-plugin-sharp": "^2.2.8", 24 | "gatsby-plugin-styled-components": "^3.1.2", 25 | "gatsby-source-filesystem": "^2.1.5", 26 | "gatsby-source-youtube-v2": "^1.0.1", 27 | "gatsby-transformer-remark": "^2.6.8", 28 | "gatsby-transformer-sharp": "^2.2.4", 29 | "netlify-lambda": "^1.5.0", 30 | "polished": "^3.4.1", 31 | "prop-types": "^15.7.2", 32 | "react": "^16.8.6", 33 | "react-dom": "^16.8.6", 34 | "react-helmet": "^5.2.1", 35 | "react-scroll": "^1.7.12", 36 | "styled-components": "^4.3.2" 37 | }, 38 | "devDependencies": { 39 | "prettier": "^1.18.2" 40 | }, 41 | "keywords": [ 42 | "gatsby" 43 | ], 44 | "license": "MIT", 45 | "scripts": { 46 | "build": "gatsby build", 47 | "prod": "npm run build; npm run build:lambda", 48 | "develop": "gatsby develop", 49 | "format": "prettier --write '**/*.js'", 50 | "test": "echo \"Error: no test specified\" && exit 1", 51 | "start:lambda": "netlify-lambda serve functions", 52 | "build:lambda": "netlify-lambda build functions" 53 | }, 54 | "repository": { 55 | "type": "git", 56 | "url": "https://github.com/gatsbyjs/gatsby-starter-default" 57 | }, 58 | "bugs": { 59 | "url": "https://github.com/gatsbyjs/gatsby/issues" 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/components/Button.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Button } from "../elements/Button"; 3 | 4 | export default props => { 5 | return ( 6 | 11 | ); 12 | }; 13 | -------------------------------------------------------------------------------- /src/components/Card.js: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | import { StyledCard, CardImage, CardContent } from "../elements/Card" 3 | import Img from "gatsby-image" 4 | 5 | export default function card(props) { 6 | const { overlayUrl, image, imageAlt } = props 7 | return ( 8 | 9 | {/* {tag && {tag}} */} 10 | {overlayUrl && } 11 | 12 | {imageAlt} 13 | 14 | {props.children[0] || props.children} 15 | 16 | ) 17 | } 18 | -------------------------------------------------------------------------------- /src/components/CourseCard.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from "react" 2 | import Card from "./Card" 3 | 4 | export const CARD_TYPES = { 5 | horizontal: "horizontal", 6 | } 7 | 8 | export default class CourseCard extends Component { 9 | render() { 10 | const { 11 | title, 12 | description, 13 | image, 14 | imageAlt, 15 | url, 16 | hours, 17 | videos, 18 | tag, 19 | id, 20 | } = this.props.course 21 | return ( 22 | 30 |
31 |

{title}

32 |

{description}

33 |

34 | {videos} videos {hours} hours 35 |

36 |
37 |
38 | ) 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/components/CourseList.js: -------------------------------------------------------------------------------- 1 | import React, { Fragment } from "react" 2 | import { StaticQuery, graphql } from "gatsby" 3 | import CourseCard, { CARD_TYPES } from "./CourseCard" 4 | import { CardList } from "../elements/Card" 5 | import { StyledCourseList } from "../elements/CourseList" 6 | import { FontAwesomeIcon } from "@fortawesome/react-fontawesome" 7 | import { faYoutube } from "@fortawesome/free-brands-svg-icons" 8 | import { SocialFollowIcon } from "../elements/SocialFollow" 9 | const CourseList = props => { 10 | return ( 11 | { 46 | const courses = data.allMarkdownRemark.edges.map( 47 | course => course.node.frontmatter 48 | ) 49 | const featuredCourses = courses.filter( 50 | course => course.featured === "true" 51 | ) 52 | const notFeaturedCourses = courses.filter( 53 | course => course.featured !== "true" 54 | ) 55 | const featuredCourse = featuredCourses[0] 56 | return ( 57 | 58 | {featuredCourse && ( 59 | 60 | 64 | 65 | )} 66 | 67 | {notFeaturedCourses.map(course => ( 68 | 73 | ))} 74 | 75 |

76 | More FREE content? Subscribe to the YouTube 77 | channel! 78 | 83 | 84 | 85 |

86 |
87 | ) 88 | }} 89 | /> 90 | ) 91 | } 92 | 93 | export default CourseList 94 | -------------------------------------------------------------------------------- /src/components/Featured.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { StyledFeatureTitle, StyledFeatureDetails } from "../elements/Featured"; 3 | import {LinkButton} from "../elements/Button"; 4 | export const FeaturedLeft = props => { 5 | return ( 6 | 7 |

{props.title}

8 |
9 | ); 10 | }; 11 | 12 | export const FeaturedRight = props => { 13 | return ( 14 | 15 |

{props.title}

16 |

{props.description}

17 | Check it Out! 18 |
19 | ); 20 | }; 21 | -------------------------------------------------------------------------------- /src/components/Footer.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import SocialFollow from "./SocialFollow"; 3 | import { Footer } from "../elements/Footer"; 4 | import logo from "../images/logo360-white.svg"; 5 | 6 | export default function footer() { 7 | return
8 | Learn Build Teach Logo. 9 | 10 |
; 11 | } 12 | -------------------------------------------------------------------------------- /src/components/FullscreenVideo.js: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | import { FontAwesomeIcon } from "@fortawesome/react-fontawesome" 3 | import { StyledFullScreenVideo } from "../elements/FullScreenVideo" 4 | import { faTimes } from "@fortawesome/free-solid-svg-icons" 5 | export default function FullscreenVideo({ video, onClose }) { 6 | return ( 7 | 8 | 14 |
15 |