├── .prettierignore ├── src ├── images │ ├── bg-masthead.jpg │ ├── gatsby-icon.png │ ├── gatsby-astronaut.png │ └── portfolio │ │ ├── fullsize │ │ ├── 1.jpg │ │ ├── 2.jpg │ │ ├── 3.jpg │ │ ├── 4.jpg │ │ ├── 5.jpg │ │ └── 6.jpg │ │ └── thumbnails │ │ ├── 1.jpg │ │ ├── 2.jpg │ │ ├── 3.jpg │ │ ├── 4.jpg │ │ ├── 5.jpg │ │ └── 6.jpg ├── pages │ ├── 404.js │ └── index.js ├── components │ ├── portfolio │ │ ├── modal.scss │ │ ├── carousel.scss │ │ ├── modal.js │ │ └── carousel.js │ ├── layout.scss │ ├── scroller.js │ ├── image.js │ ├── seo.js │ ├── layout.js │ └── header.js └── sass │ ├── _global.scss │ ├── _variables.scss │ ├── _masthead.scss │ ├── _portfolio.scss │ └── _navbar.scss ├── .prettierrc ├── gatsby-node.js ├── gatsby-browser.js ├── gatsby-ssr.js ├── .github └── workflows │ ├── deploy.yml │ └── stale.yml ├── LICENSE ├── .gitignore ├── gatsby-config.js ├── package.json └── README.md /.prettierignore: -------------------------------------------------------------------------------- 1 | .cache 2 | package.json 3 | package-lock.json 4 | public 5 | -------------------------------------------------------------------------------- /src/images/bg-masthead.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnJKerr/gatsby-creative/HEAD/src/images/bg-masthead.jpg -------------------------------------------------------------------------------- /src/images/gatsby-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnJKerr/gatsby-creative/HEAD/src/images/gatsby-icon.png -------------------------------------------------------------------------------- /src/images/gatsby-astronaut.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnJKerr/gatsby-creative/HEAD/src/images/gatsby-astronaut.png -------------------------------------------------------------------------------- /src/images/portfolio/fullsize/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnJKerr/gatsby-creative/HEAD/src/images/portfolio/fullsize/1.jpg -------------------------------------------------------------------------------- /src/images/portfolio/fullsize/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnJKerr/gatsby-creative/HEAD/src/images/portfolio/fullsize/2.jpg -------------------------------------------------------------------------------- /src/images/portfolio/fullsize/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnJKerr/gatsby-creative/HEAD/src/images/portfolio/fullsize/3.jpg -------------------------------------------------------------------------------- /src/images/portfolio/fullsize/4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnJKerr/gatsby-creative/HEAD/src/images/portfolio/fullsize/4.jpg -------------------------------------------------------------------------------- /src/images/portfolio/fullsize/5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnJKerr/gatsby-creative/HEAD/src/images/portfolio/fullsize/5.jpg -------------------------------------------------------------------------------- /src/images/portfolio/fullsize/6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnJKerr/gatsby-creative/HEAD/src/images/portfolio/fullsize/6.jpg -------------------------------------------------------------------------------- /src/images/portfolio/thumbnails/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnJKerr/gatsby-creative/HEAD/src/images/portfolio/thumbnails/1.jpg -------------------------------------------------------------------------------- /src/images/portfolio/thumbnails/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnJKerr/gatsby-creative/HEAD/src/images/portfolio/thumbnails/2.jpg -------------------------------------------------------------------------------- /src/images/portfolio/thumbnails/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnJKerr/gatsby-creative/HEAD/src/images/portfolio/thumbnails/3.jpg -------------------------------------------------------------------------------- /src/images/portfolio/thumbnails/4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnJKerr/gatsby-creative/HEAD/src/images/portfolio/thumbnails/4.jpg -------------------------------------------------------------------------------- /src/images/portfolio/thumbnails/5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnJKerr/gatsby-creative/HEAD/src/images/portfolio/thumbnails/5.jpg -------------------------------------------------------------------------------- /src/images/portfolio/thumbnails/6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnJKerr/gatsby-creative/HEAD/src/images/portfolio/thumbnails/6.jpg -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "endOfLine": "lf", 3 | "semi": false, 4 | "singleQuote": false, 5 | "tabWidth": 2, 6 | "trailingComma": "es5" 7 | } 8 | -------------------------------------------------------------------------------- /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-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-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 | -------------------------------------------------------------------------------- /src/pages/404.js: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | 3 | import Layout from "../components/layout" 4 | import SEO from "../components/seo" 5 | 6 | const NotFoundPage = () => ( 7 | 8 | 9 |

NOT FOUND

10 |

You just hit a route that doesn't exist... the sadness.

11 |
12 | ) 13 | 14 | export default NotFoundPage 15 | -------------------------------------------------------------------------------- /.github/workflows/deploy.yml: -------------------------------------------------------------------------------- 1 | name: Build and Deploy 2 | on: 3 | push: 4 | branches: 5 | - master 6 | jobs: 7 | build-and-deploy: 8 | runs-on: ubuntu-latest 9 | steps: 10 | - uses: actions/checkout@master 11 | - name: build 12 | run: npm install && npx gatsby build --prefix-paths 13 | - name: deploy 14 | uses: JamesIves/github-pages-deploy-action@v4 15 | with: 16 | folder: public 17 | -------------------------------------------------------------------------------- /src/components/portfolio/modal.scss: -------------------------------------------------------------------------------- 1 | .modal-dialog { 2 | position: static; 3 | transition: none !important; 4 | } 5 | 6 | .modal-content { 7 | background: transparent; 8 | border: none; 9 | position: static; 10 | 11 | .modal-header { 12 | border: none; 13 | 14 | button { 15 | color: #fff; 16 | opacity: 0.65; 17 | 18 | &:hover { 19 | opacity: 1; 20 | } 21 | } 22 | } 23 | 24 | .modal-body { 25 | padding-top: 0; 26 | position: static; 27 | } 28 | } -------------------------------------------------------------------------------- /.github/workflows/stale.yml: -------------------------------------------------------------------------------- 1 | name: Mark stale issues and pull requests 2 | 3 | on: 4 | schedule: 5 | - cron: "0 * * * *" 6 | 7 | jobs: 8 | stale: 9 | 10 | runs-on: ubuntu-latest 11 | 12 | steps: 13 | - uses: actions/stale@v1 14 | with: 15 | repo-token: ${{ secrets.GITHUB_TOKEN }} 16 | stale-issue-message: 'Stale issue message' 17 | stale-pr-message: 'Stale pull request message' 18 | stale-issue-label: 'no-issue-activity' 19 | stale-pr-label: 'no-pr-activity' 20 | -------------------------------------------------------------------------------- /src/components/layout.scss: -------------------------------------------------------------------------------- 1 | // Import custom variables (overrides Bootstrap default variables) 2 | @import "../sass/variables.scss"; 3 | 4 | // Import font awesome 5 | @import "~@fortawesome/fontawesome-free/css/all.css"; 6 | @import "~@fortawesome/fontawesome-free/scss/fontawesome"; 7 | 8 | // Import Bootstrap 9 | @import "~bootstrap/scss/bootstrap"; 10 | 11 | // Import custom styles 12 | @import "../sass/global.scss"; 13 | @import "../sass/navbar.scss"; 14 | @import "../sass/masthead.scss"; 15 | @import "../sass/portfolio.scss"; -------------------------------------------------------------------------------- /src/components/portfolio/carousel.scss: -------------------------------------------------------------------------------- 1 | .carousel { 2 | position: static; 3 | 4 | .carousel-control-prev, .carousel-control-next { 5 | width: 5%; 6 | padding-top: 56px; 7 | } 8 | 9 | figure { 10 | margin: 0; 11 | 12 | figcaption { 13 | height: 24px; 14 | position: relative; 15 | } 16 | 17 | .bottom-bar { 18 | position: absolute; 19 | top: 0; 20 | left: 0; 21 | width: 100%; 22 | cursor: auto; 23 | 24 | .counter { 25 | position: absolute; 26 | top: 4px; 27 | right: 0; 28 | color: #CCC; 29 | font-size: 12px; 30 | line-height: 18px; 31 | white-space: nowrap; 32 | } 33 | } 34 | } 35 | } 36 | 37 | -------------------------------------------------------------------------------- /src/components/portfolio/modal.js: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | import PropTypes from "prop-types" 3 | import { Modal } from "react-bootstrap" 4 | 5 | import "./modal.scss" 6 | 7 | const PortfolioModal = ({ show, onHide, children }) => { 8 | 9 | return ( 10 | 16 | 17 | 18 | 19 | {children} 20 | 21 | 22 | ); 23 | } 24 | 25 | PortfolioModal.propTypes = { 26 | show: PropTypes.bool.isRequired, 27 | onHide: PropTypes.func.isRequired, 28 | children: PropTypes.node.isRequired 29 | } 30 | 31 | export default PortfolioModal -------------------------------------------------------------------------------- /src/components/scroller.js: -------------------------------------------------------------------------------- 1 | export default class Scroller { 2 | static handleAnchorScroll(e) { 3 | e.preventDefault(); 4 | const element = e.target; 5 | const id = element.getAttribute('href'); 6 | const document = element.ownerDocument.scrollingElement || element.ownerDocument.documentElement; 7 | const scrollNode = document.querySelector(id); 8 | const top = scrollNode.getBoundingClientRect().top; 9 | const scrollTop = window.pageYOffset || document.scrollTop; 10 | const fixedHeight = 72; 11 | const scrollTo = top + scrollTop - fixedHeight; 12 | if(document.scrollTo) { 13 | document.scrollTo({ 14 | top: scrollTo, 15 | left: 0, 16 | behavior: 'smooth' 17 | }); 18 | } else { 19 | document.scrollTop = scrollTo; 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /src/sass/_global.scss: -------------------------------------------------------------------------------- 1 | // Global styling for this template 2 | body, 3 | html { 4 | width: 100%; 5 | height: 100%; 6 | } 7 | 8 | // Typography 9 | .text-white-75 { 10 | color: fade-out($white, .25); 11 | } 12 | 13 | // Custom horizontal rules 14 | hr.divider { 15 | max-width: 3.25rem; 16 | border-width: 0.2rem; 17 | border-color: $primary; 18 | } 19 | 20 | hr.light { 21 | border-color: $white; 22 | } 23 | 24 | // Button restyling 25 | .btn { 26 | font-family: $font-family-sans-serif; 27 | } 28 | 29 | .btn-xl { 30 | padding: 1.25rem 2.25rem; 31 | font-size: 0.85rem; 32 | font-weight: 700; 33 | text-transform: uppercase; 34 | border: none; 35 | border-radius: 10rem; 36 | } 37 | 38 | // Page section padding 39 | .page-section { 40 | padding: 8rem 0; 41 | } 42 | 43 | // Modal 44 | .modal-backdrop { 45 | background-color: #0b0b0b; 46 | } 47 | 48 | .modal-backdrop.show { 49 | opacity: 0.8; 50 | } -------------------------------------------------------------------------------- /src/sass/_variables.scss: -------------------------------------------------------------------------------- 1 | // Variables 2 | 3 | // Color overrides 4 | 5 | // Set a custom color 6 | $orange: #f4623a !default; 7 | $brown: #5c4d42 !default; 8 | 9 | // Set primary color to orange 10 | $primary: $orange !default; 11 | 12 | // Font overrides 13 | $font-family-sans-serif: "Merriweather Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", 'Noto Color Emoji' !default; 14 | 15 | $font-family-serif: "Merriweather", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", 'Noto Color Emoji' !default; 16 | 17 | $font-family-base: $font-family-serif !default; 18 | 19 | $headings-font-family: $font-family-sans-serif !default; 20 | 21 | // Custom variables 22 | $navbar-height: 72px; -------------------------------------------------------------------------------- /src/sass/_masthead.scss: -------------------------------------------------------------------------------- 1 | // Styling for the masthead 2 | header.masthead { 3 | padding-top: 10rem; 4 | padding-bottom: calc(10rem - #{$navbar-height}); 5 | // replace the masthead.jpg image in the /img directory to change the image 6 | // if the image name change, make sure to update the url path below! 7 | background: linear-gradient(to bottom, #{fade-out($brown, .2)} 0%,#{fade-out($brown, .2)} 100%), url('../images/bg-masthead.jpg'); 8 | background-position: center; 9 | background-repeat: no-repeat; 10 | background-attachment: scroll; 11 | background-size: cover; 12 | h1 { 13 | font-size: 2.25rem; 14 | } 15 | @include media-breakpoint-up(lg) { 16 | height: 100vh; 17 | min-height: 40rem; 18 | padding-top: $navbar-height; 19 | padding-bottom: 0; 20 | p { 21 | font-size: 1.15rem; 22 | } 23 | h1 { 24 | font-size: 3rem; 25 | } 26 | } 27 | @include media-breakpoint-up(xl) { 28 | h1 { 29 | font-size: 3.5rem; 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/sass/_portfolio.scss: -------------------------------------------------------------------------------- 1 | // Styling for the portfolio section 2 | #portfolio { 3 | .container-fluid { 4 | max-width: 1920px; 5 | .portfolio-box { 6 | position: relative; 7 | display: block; 8 | .portfolio-box-caption { 9 | display: flex; 10 | align-items: center; 11 | justify-content: center; 12 | flex-direction: column; 13 | 14 | width: 100%; 15 | height: 100%; 16 | 17 | position: absolute; 18 | bottom: 0; 19 | 20 | text-align: center; 21 | opacity: 0; 22 | 23 | color: $white; 24 | background: fade-out($primary, .1); 25 | transition: opacity 0.25s ease; 26 | text-align: center; 27 | .project-category { 28 | font-family: $font-family-sans-serif; 29 | font-size: 0.85rem; 30 | font-weight: 600; 31 | text-transform: uppercase; 32 | } 33 | .project-name { 34 | font-size: 1.2rem; 35 | } 36 | } 37 | &:hover { 38 | .portfolio-box-caption { 39 | opacity: 1; 40 | } 41 | } 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/components/portfolio/carousel.js: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | import PropTypes from "prop-types" 3 | import { Carousel } from "react-bootstrap" 4 | import Img from "gatsby-image" 5 | 6 | import "./carousel.scss" 7 | 8 | const PortfolioCarousel = ({ images, current }) => { 9 | const carouselItems = images.map((image, index) => 10 | 11 |
12 | 13 |
14 |
15 |
{index + 1} of {images.length}
16 |
17 |
18 |
19 |
20 | ); 21 | 22 | return ( 23 | 24 | {carouselItems} 25 | 26 | ); 27 | } 28 | 29 | PortfolioCarousel.propTypes = { 30 | images: PropTypes.array.isRequired, 31 | current: PropTypes.number.isRequired, 32 | } 33 | 34 | export default PortfolioCarousel -------------------------------------------------------------------------------- /src/components/image.js: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | import { useStaticQuery, graphql } from "gatsby" 3 | import Img from "gatsby-image" 4 | 5 | /* 6 | * This component is built using `gatsby-image` to automatically serve optimized 7 | * images with lazy loading and reduced file sizes. The image is loaded using a 8 | * `useStaticQuery`, which allows us to load the image from directly within this 9 | * component, rather than having to pass the image data down from pages. 10 | * 11 | * For more information, see the docs: 12 | * - `gatsby-image`: https://gatsby.dev/gatsby-image 13 | * - `useStaticQuery`: https://www.gatsbyjs.org/docs/use-static-query/ 14 | */ 15 | 16 | const Image = () => { 17 | const data = useStaticQuery(graphql` 18 | query { 19 | placeholderImage: file(relativePath: { eq: "gatsby-astronaut.png" }) { 20 | childImageSharp { 21 | fluid(maxWidth: 300) { 22 | ...GatsbyImageSharpFluid 23 | } 24 | } 25 | } 26 | } 27 | `) 28 | 29 | return 30 | } 31 | 32 | export default Image 33 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /.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 | # JetBrains 72 | .idea/ 73 | -------------------------------------------------------------------------------- /gatsby-config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | pathPrefix: `/gatsby-creative`, 3 | siteMetadata: { 4 | title: `Gatsby Default Starter`, 5 | description: `Kick off your next, great Gatsby project with this default starter. This barebones starter ships with the main Gatsby configuration files you might need.`, 6 | author: `@gatsbyjs`, 7 | }, 8 | plugins: [ 9 | `gatsby-plugin-react-helmet`, 10 | { 11 | resolve: `gatsby-source-filesystem`, 12 | options: { 13 | name: `images`, 14 | path: `${__dirname}/src/images`, 15 | }, 16 | }, 17 | `gatsby-transformer-sharp`, 18 | `gatsby-plugin-sharp`, 19 | { 20 | resolve: `gatsby-plugin-manifest`, 21 | options: { 22 | name: `gatsby-starter-default`, 23 | short_name: `starter`, 24 | start_url: `/`, 25 | background_color: `#663399`, 26 | theme_color: `#663399`, 27 | display: `minimal-ui`, 28 | icon: `src/images/gatsby-icon.png`, // This path is relative to the root of the site. 29 | }, 30 | }, 31 | `gatsby-plugin-sass`, 32 | { 33 | resolve: 'gatsby-plugin-web-font-loader', 34 | options: { 35 | google: { 36 | families: ['Merriweather:400,300,300italic,400italic,700,700italic', 'Merriweather+Sans:400,700'] 37 | } 38 | } 39 | }, 40 | // this (optional) plugin enables Progressive Web App + Offline functionality 41 | // To learn more, visit: https://gatsby.dev/offline 42 | // `gatsby-plugin-offline`, 43 | ], 44 | } 45 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "gatsby-starter-default", 3 | "private": true, 4 | "description": "A simple starter to get up and developing quickly with Gatsby", 5 | "version": "0.1.0", 6 | "author": "Kyle Mathews ", 7 | "dependencies": { 8 | "@fortawesome/fontawesome-free": "^6.4.0", 9 | "bootstrap": "^5.3.0", 10 | "gatsby": "^5.11.0", 11 | "gatsby-image": "^3.11.0", 12 | "gatsby-plugin-manifest": "^5.11.0", 13 | "gatsby-plugin-offline": "^6.11.0", 14 | "gatsby-plugin-react-helmet": "^6.11.0", 15 | "gatsby-plugin-sass": "^6.11.0", 16 | "gatsby-plugin-sharp": "^5.11.0", 17 | "gatsby-plugin-web-font-loader": "^1.0.4", 18 | "gatsby-source-filesystem": "^5.11.0", 19 | "gatsby-transformer-sharp": "^5.11.0", 20 | "prop-types": "^15.7.2", 21 | "react": "^18.2.0", 22 | "react-bootstrap": "^2.8.0", 23 | "react-dom": "^18.2.0", 24 | "react-helmet": "^6.1.0", 25 | "react-scrollspy": "^3.4.0", 26 | "sass": "^1.64.1" 27 | }, 28 | "devDependencies": { 29 | "prettier": "^3.0.0" 30 | }, 31 | "keywords": [ 32 | "gatsby" 33 | ], 34 | "license": "MIT", 35 | "scripts": { 36 | "build": "gatsby build", 37 | "develop": "gatsby develop", 38 | "format": "prettier --write \"**/*.{js,jsx,json,md}\"", 39 | "start": "npm run develop", 40 | "serve": "gatsby serve", 41 | "test": "echo \"Write tests! -> https://gatsby.dev/unit-testing\"" 42 | }, 43 | "repository": { 44 | "type": "git", 45 | "url": "https://github.com/gatsbyjs/gatsby-starter-default" 46 | }, 47 | "bugs": { 48 | "url": "https://github.com/gatsbyjs/gatsby/issues" 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/sass/_navbar.scss: -------------------------------------------------------------------------------- 1 | // Base styling for the navbar 2 | #mainNav { 3 | box-shadow: $box-shadow; 4 | background-color: $white; 5 | transition: background-color 0.2s ease; 6 | .navbar-brand { 7 | font-family: $font-family-sans-serif; 8 | font-weight: $font-weight-bold; 9 | color: $gray-900; 10 | } 11 | .navbar-nav { 12 | .nav-item { 13 | &.active { 14 | .nav-link { 15 | color: $primary !important; 16 | } 17 | } 18 | 19 | .nav-link { 20 | color: $gray-600; 21 | font-family: $font-family-sans-serif; 22 | font-weight: $font-weight-bold; 23 | font-size: 0.9rem; 24 | padding: 0.75rem 0; 25 | &:hover, 26 | &:active { 27 | color: $primary; 28 | } 29 | } 30 | } 31 | } 32 | @include media-breakpoint-up(lg) { 33 | // Base styling for the navbar - screen sizes greater than the large breakpoint 34 | box-shadow: none; 35 | background-color: transparent; 36 | .navbar-brand { 37 | color: fade-out($white, .3); 38 | &:hover { 39 | color: $white; 40 | } 41 | } 42 | .navbar-nav { 43 | .nav-item { 44 | .nav-link { 45 | color: fade-out($white, .3); 46 | padding: 0 1rem; 47 | &:hover { 48 | color: $white; 49 | } 50 | } 51 | &:last-child { 52 | .nav-link { 53 | padding-right: 0; 54 | } 55 | } 56 | } 57 | } 58 | } 59 | } 60 | 61 | @include media-breakpoint-up(lg) { 62 | // Navbar styling applied when the page is scrolled 63 | .site-container.navbar-scrolled #mainNav { 64 | box-shadow: $box-shadow; 65 | background-color: $white; 66 | .navbar-brand { 67 | color: $gray-900; 68 | &:hover { 69 | color: $primary; 70 | } 71 | } 72 | .navbar-nav { 73 | .nav-item { 74 | .nav-link { 75 | color: $gray-900; 76 | &:hover { 77 | color: $primary; 78 | } 79 | } 80 | } 81 | } 82 | } 83 | } -------------------------------------------------------------------------------- /src/components/seo.js: -------------------------------------------------------------------------------- 1 | /** 2 | * SEO component that queries for data with 3 | * Gatsby's useStaticQuery React hook 4 | * 5 | * See: https://www.gatsbyjs.org/docs/use-static-query/ 6 | */ 7 | 8 | import React from "react" 9 | import PropTypes from "prop-types" 10 | import Helmet from "react-helmet" 11 | import { useStaticQuery, graphql } from "gatsby" 12 | 13 | function SEO({ description, lang, meta, title }) { 14 | const { site } = useStaticQuery( 15 | graphql` 16 | query { 17 | site { 18 | siteMetadata { 19 | title 20 | description 21 | author 22 | } 23 | } 24 | } 25 | ` 26 | ) 27 | 28 | const metaDescription = description || site.siteMetadata.description 29 | 30 | return ( 31 | 72 | ) 73 | } 74 | 75 | SEO.defaultProps = { 76 | lang: `en`, 77 | meta: [], 78 | description: ``, 79 | } 80 | 81 | SEO.propTypes = { 82 | description: PropTypes.string, 83 | lang: PropTypes.string, 84 | meta: PropTypes.arrayOf(PropTypes.object), 85 | title: PropTypes.string.isRequired, 86 | } 87 | 88 | export default SEO 89 | -------------------------------------------------------------------------------- /src/components/layout.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Layout component that queries for data 3 | * with Gatsby's useStaticQuery component 4 | * 5 | * See: https://www.gatsbyjs.org/docs/use-static-query/ 6 | */ 7 | 8 | import React from "react" 9 | import PropTypes from "prop-types" 10 | import Header from "./header" 11 | import "./layout.scss" 12 | 13 | const getScrollNode = (element) => { 14 | return element.ownerDocument.scrollingElement || element.ownerDocument.documentElement 15 | } 16 | 17 | const isScrolled = (element) => { 18 | const scrollNode = getScrollNode(element) 19 | return scrollNode.scrollTop > 0 20 | } 21 | 22 | export default class Layout extends React.Component { 23 | constructor(props) { 24 | super(props) 25 | this.siteContainer = React.createRef() 26 | this.state = { 27 | scrolled: false, 28 | } 29 | this.handleScroll = this.handleScroll.bind(this) 30 | } 31 | 32 | componentDidMount() { 33 | window.addEventListener("scroll", this.handleScroll) 34 | const element = this.siteContainer.current 35 | this.setState({ 36 | scrolled: isScrolled(element), 37 | }) 38 | } 39 | 40 | componentWillUnmount() { 41 | window.removeEventListener("scroll", this.handleScroll) 42 | } 43 | 44 | handleScroll() { 45 | const element = this.siteContainer.current 46 | this.setState({ 47 | scrolled: isScrolled(element), 48 | }) 49 | } 50 | 51 | render() { 52 | let className = "site-container" 53 | if (this.props.className) className += ` ${this.props.className}` 54 | if (this.state.scrolled) className += " navbar-scrolled" 55 | 56 | return ( 57 |
61 |
62 |
{this.props.children}
63 |
64 |
65 |
Copyright © 2019 - Start Bootstrap
66 |
67 |
68 |
69 | ) 70 | } 71 | } 72 | 73 | Layout.propTypes = { 74 | children: PropTypes.node.isRequired, 75 | className: PropTypes.string, 76 | } -------------------------------------------------------------------------------- /src/components/header.js: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | import Scrollspy from "react-scrollspy" 3 | import { Navbar, Nav } from "react-bootstrap" 4 | import Scroller from './scroller' 5 | 6 | export default class Header extends React.Component { 7 | constructor(props) { 8 | super(props); 9 | Scroller.handleAnchorScroll = Scroller.handleAnchorScroll.bind(this); 10 | } 11 | 12 | render() { 13 | return ( 14 | <> 15 | 17 |
18 | Start Bootstrap 19 | 20 | 21 | 39 | 40 |
41 |
42 |
43 |
44 |
45 |
46 |

Your Favorite Source of Free Bootstrap 47 | Themes

48 |
49 |
50 |
51 |

Start Bootstrap can help you build better websites 52 | using the Bootstrap framework! Just download a theme and start customizing, no strings attached!

53 | Find Out More 54 |
55 |
56 |
57 |
58 | 59 | ); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 |

3 | 4 | Gatsby 5 | 6 |

7 |

8 | Gatsby x Start Bootstrap Creative 9 |

10 | 11 | Gatsby implementation of [Start Bootstrap's Creative](https://startbootstrap.com/previews/creative/) template. 12 | 13 | [**Demo Website**](https://johnjkerr.github.io/gatsby-creative) 14 | 15 | ## ✨ Features 16 | 17 | - [React Bootstrap](https://react-bootstrap.github.io) 18 | - [Start Bootstrap Creative](https://startbootstrap.com/previews/creative) 19 | - [GitHub Actions](https://github.com/features/actions) 20 | - [React Scrollspy](https://github.com/makotot/react-scrollspy) 21 | 22 | ## 👀 Template Differences 23 | 24 | Efforts have been made to keep the implementation as close to the source template as possible, however in adapting from jQuery to React there have been some changes. 25 | 26 | - Scrolling to page sections uses the browser [`scrollTo`](https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollTo) function rather than a jQuery animation. This means that [browsers which do not support `scrollTo`](https://caniuse.com/#search=scrollTo) are not animated. 27 | - The portfolio carousel uses React Bootstrap functionality for modal and carousel rather than Magnific Popup. 28 | 29 | ## 🚀 Getting Started 30 | 31 | 1. **Create a Gatsby site.** 32 | 33 | Use the Gatsby CLI to create a new site, specifying the starter project. 34 | 35 | ```sh 36 | gatsby new project-name https://github.com/JohnJKerr/gatsby-creative 37 | ``` 38 | 39 | 2. **Start developing.** 40 | 41 | Navigate into your new site’s directory and start it up. 42 | 43 | ```sh 44 | cd project-name 45 | gatsby develop 46 | ``` 47 | 48 | 3. **Open the source code and start editing!** 49 | 50 | Your site is now running at `http://localhost:8000`! 51 | 52 | _Note: You'll also see a second link: _`http://localhost:8000/___graphql`_. This is a tool you can use to experiment with querying your data. Learn more about using this tool in the [Gatsby tutorial](https://www.gatsbyjs.org/tutorial/part-five/#introducing-graphiql)._ 53 | 54 | Open the `project-name` directory in your code editor of choice and edit `src/pages/index.js`. Save your changes and the browser will update in real time! 55 | 56 | ## 🎓 Learning Gatsby 57 | 58 | Looking for more guidance? Full documentation for Gatsby lives [on the website](https://www.gatsbyjs.org/). Here are some places to start: 59 | 60 | - **For most developers, we recommend starting with our [in-depth tutorial for creating a site with Gatsby](https://www.gatsbyjs.org/tutorial/).** It starts with zero assumptions about your level of ability and walks through every step of the process. 61 | 62 | - **To dive straight into code samples, head [to our documentation](https://www.gatsbyjs.org/docs/).** In particular, check out the _Guides_, _API Reference_, and _Advanced Tutorials_ sections in the sidebar. 63 | 64 | ## 💫 Deploy 65 | 66 | [![Deploy to Netlify](https://www.netlify.com/img/deploy/button.svg)](https://app.netlify.com/start/deploy?repository=https://github.com/JohnJKerr/gatsby-creative) 67 | 68 | ### GitHub Actions x GitHub Pages 69 | 70 | This project also contains an example of [GitHub Actions](https://github.com/features/actions) deployment to [GitHub Pages](https://pages.github.com). View the [`deploy.yml`](https://github.com/JohnJKerr/gatsby-creative/blob/master/.github/workflows/deploy.yml) for the build definition. 71 | 72 | The build process deploys to a folder rather than the root, and therefore uses the `--pages-prefix` flag in the build step and `pathPrefix: '/gatsby-creative'` in [`gatsby-config.js`](https://github.com/JohnJKerr/gatsby-creative/blob/master/gatsby-config.js). 73 | 74 | #### Access Token 75 | 76 | If you wish to use the GitHub Actions workflow to deploy to GitHub Pages you will need to add an `ACCESS_TOKEN` secret to your repository 77 | 78 | Go to https://github.com/settings/tokens to generate a Personal Access Token and add it to your account. The token will need the following permissions: 79 | 80 | - repo 81 | - read:packages 82 | - write:packages 83 | 84 | Make a copy of your token as you will not be able to access it again. 85 | 86 | Return to your repository, go to settings and add a secret with the name `ACCESS_TOKEN`. 87 | 88 | The Action will then deploy your site to `{your-github-pages-url}/{your-repository}`. 89 | 90 | #### Not Using GitHub Pages? 91 | 92 | If you do not wish to use GitHub Pages, simply remove the `/.github/workflows/deploy.yml` file. 93 | 94 | 95 | -------------------------------------------------------------------------------- /src/pages/index.js: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | import { graphql } from "gatsby" 3 | import Img from "gatsby-image" 4 | 5 | import Layout from "../components/layout" 6 | import SEO from "../components/seo" 7 | import Scroller from "../components/scroller" 8 | import PortfolioModal from "../components/portfolio/modal" 9 | import PortfolioCarousel from "../components/portfolio/carousel" 10 | 11 | export default class IndexPage extends React.Component { 12 | constructor(props) { 13 | super(props) 14 | Scroller.handleAnchorScroll = Scroller.handleAnchorScroll.bind(this) 15 | this.state = { 16 | modalShow: false, 17 | modalCurrent: 0 18 | } 19 | this.handlePortfolioClick = this.handlePortfolioClick.bind(this); 20 | this.setModal = this.setModal.bind(this); 21 | } 22 | 23 | handlePortfolioClick(index, e) { 24 | e.preventDefault(); 25 | this.setModal(true, index); 26 | } 27 | 28 | setModal(isShown, current) { 29 | this.setState({ 30 | modalShow: isShown, 31 | modalCurrent: current 32 | }); 33 | } 34 | 35 | render() { 36 | return ( 37 | 38 | 39 |
40 |
41 |
42 |
43 |

We've got what you need!

44 |
45 |

Start Bootstrap has everything you need to get your new website up 46 | and 47 | running in no time! Choose one of our open source, free to download, and easy to use themes! No 48 | strings 49 | attached!

50 | Get Started! 52 |
53 |
54 |
55 |
56 | 57 |
58 |
59 |

At Your Service

60 |
61 |
62 |
63 |
64 | 65 |

Sturdy Themes

66 |

Our themes are updated regularly to keep them bug free!

67 |
68 |
69 |
70 |
71 | 72 |

Up to Date

73 |

All dependencies are kept current to keep things fresh.

74 |
75 |
76 |
77 |
78 | 79 |

Ready to Publish

80 |

You can use this design as is, or you can make changes!

81 |
82 |
83 |
84 |
85 | 86 |

Made with Love

87 |

Is it really open source if it's not made with love?

88 |
89 |
90 |
91 |
92 |
93 | 94 |
95 | 177 |
178 | 179 |
180 |
181 |

Free Download at Start Bootstrap!

182 | Download Now! 183 |
184 |
185 | 186 |
187 |
188 |
189 |
190 |

Let's Get In Touch!

191 |
192 |

Ready to start your next project with us? Give us a call or send us an 193 | email 194 | and we will get back to you as soon as possible!

195 |
196 |
197 |
198 |
199 | 200 |
+1 (202) 555-0149
201 |
202 |
203 | 204 | contact@yourwebsite.com 205 |
206 |
207 |
208 |
209 | this.setModal(false, 0)}> 210 | 211 | 212 |
213 | ) 214 | } 215 | } 216 | 217 | 218 | export const imageData = graphql` 219 | query { 220 | images: allFile(filter: {relativePath: {glob: "portfolio/fullsize/*.jpg"}}, sort: {fields: name}) { 221 | edges { 222 | node { 223 | childImageSharp { 224 | fluid { 225 | ...GatsbyImageSharpFluid 226 | } 227 | } 228 | } 229 | } 230 | } 231 | } 232 | ` 233 | --------------------------------------------------------------------------------