├── .gitignore
├── .prettierignore
├── .prettierrc
├── LICENSE
├── README.md
├── gatsby-browser.js
├── gatsby-config.js
├── gatsby-node.js
├── gatsby-ssr.js
├── package-lock.json
├── package.json
├── src
├── assets
│ ├── hero-1.svg
│ └── main.css
├── components
│ ├── Hero.js
│ ├── Project.js
│ ├── Projects.js
│ └── seo.js
└── pages
│ ├── 404.js
│ └── index.js
└── static
├── favicon.ico
└── mainBcg.jpeg
/.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.development
56 | .env.*
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 |
--------------------------------------------------------------------------------
/.prettierignore:
--------------------------------------------------------------------------------
1 | .cache
2 | package.json
3 | package-lock.json
4 | public
5 |
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "endOfLine": "lf",
3 | "semi": false,
4 | "singleQuote": false,
5 | "tabWidth": 2,
6 | "trailingComma": "es5"
7 | }
8 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The BSD Zero Clause License (0BSD)
2 |
3 | Copyright (c) 2020 Gatsby Inc.
4 |
5 | Permission to use, copy, modify, and/or distribute this software for any
6 | purpose with or without fee is hereby granted.
7 |
8 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
9 | REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
10 | AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
11 | INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
12 | LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
13 | OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
14 | PERFORMANCE OF THIS SOFTWARE.
15 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## Setup
2 |
3 | ## Styled Components
4 |
5 | VS-Extension
6 |
7 | vscode-styled-components
8 |
9 | Regural Setup
10 |
11 | ```jsx
12 | import styled from 'styled-components'
13 | const NameOfElement = styled.htmlElement`
14 | your
15 | styles
16 | go
17 | here
18 | `
19 | ```
20 |
21 | Global Styles
22 |
23 | ```jsx
24 | import { createGlobalStyle } from "styled-components"
25 |
26 | const GlobalStyle = createGlobalStyle`
27 | your
28 | global
29 | styles
30 | go here
31 | `
32 | // wrap root element
33 | export const wrapRootElement = ({ element }) => {
34 | return (
35 | <>
36 |
37 | {element}
38 | >
39 | )
40 | }
41 |
42 | Both files
43 | - gatsby-browser.js
44 | - gatsby-ssr.js
45 |
46 | ```
47 |
48 | ## Airtable
49 |
50 | [airtable](https://airtable.com/invite/r/h4p0v9Vg)
51 |
52 | ## env variables
53 |
54 | gatsby-config
55 |
56 | ```js
57 | require('dotenv').config({
58 | path: `.env.${process.env.NODE_ENV}`,
59 | })
60 | ```
61 |
62 | #### ROOT!!!!!!!!!!!!!!!
63 |
64 | .env.development
65 |
66 | ## Algolia
67 |
68 | [algolia](https://www.algolia.com/);
69 |
70 | ## Project Steps
71 |
72 | - cover setup
73 | - styled components global css
74 | - basic gatsby background image
75 | - basic navbar
76 | - about
77 | - airtable
78 | - connect to airtable
79 | - env vars
80 |
--------------------------------------------------------------------------------
/gatsby-browser.js:
--------------------------------------------------------------------------------
1 | import 'normalize.css'
2 | import './src/assets/main.css'
3 |
--------------------------------------------------------------------------------
/gatsby-config.js:
--------------------------------------------------------------------------------
1 | require("dotenv").config({
2 | path: `.env.${process.env.NODE_ENV}`,
3 | })
4 |
5 | module.exports = {
6 | siteMetadata: {
7 | title: `John Smilga`,
8 | description: `Vanilla Javascript Projects`,
9 | author: `@johnsmilga`,
10 | twitterUsername: "@john_smilga",
11 | image: "/mainBcg.jpeg",
12 | siteUrl: "https://www.johnsmilga.com",
13 | },
14 | plugins: [
15 | {
16 | resolve: `gatsby-source-airtable`,
17 | options: {
18 | apiKey: process.env.GATSBY_AIRTABLE_API,
19 | concurrency: 5,
20 | tables: [
21 | {
22 | baseId: process.env.GATSBY_AIRTABLE_BASE_ID,
23 | tableName: `Projects`,
24 | mapping: { image: `fileNode` },
25 | },
26 | ],
27 | },
28 | },
29 | {
30 | resolve: "gatsby-plugin-robots-txt",
31 | options: {
32 | host: "https://www.johnsmilga.com",
33 | sitemap: "https://www.johnsmilga.com/sitemap.xml",
34 | policy: [{ userAgent: "*", allow: "/" }],
35 | },
36 | },
37 | {
38 | resolve: `gatsby-plugin-webfonts`,
39 | options: {
40 | fonts: {
41 | google: [
42 | {
43 | family: "Montserrat",
44 | variants: ["400", "500", "600", "700"],
45 | },
46 | {
47 | family: "Inconsolata",
48 | variants: ["400", "500", "600", "700"],
49 | },
50 | ],
51 | },
52 | },
53 | },
54 | `gatsby-plugin-sitemap`,
55 | `gatsby-plugin-image`,
56 | `gatsby-plugin-sharp`,
57 | `gatsby-transformer-sharp`,
58 | `gatsby-plugin-react-helmet`,
59 | `gatsby-plugin-styled-components`,
60 | ],
61 | }
62 |
--------------------------------------------------------------------------------
/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 | import 'normalize.css'
2 | import './src/assets/main.css'
3 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "gatsby-starter-hello-world",
3 | "private": true,
4 | "description": "A simplified bare-bones starter for Gatsby",
5 | "version": "0.1.0",
6 | "license": "0BSD",
7 | "scripts": {
8 | "build": "gatsby build",
9 | "develop": "gatsby develop",
10 | "format": "prettier --write \"**/*.{js,jsx,ts,tsx,json,md}\"",
11 | "start": "npm run develop",
12 | "serve": "gatsby serve",
13 | "clean": "gatsby clean",
14 | "test": "echo \"Write tests! -> https://gatsby.dev/unit-testing\" && exit 1"
15 | },
16 | "dependencies": {
17 | "babel-plugin-styled-components": "^1.12.0",
18 | "gatsby": "^3.3.1",
19 | "gatsby-plugin-image": "^1.3.1",
20 | "gatsby-plugin-react-helmet": "^4.3.0",
21 | "gatsby-plugin-robots-txt": "^1.5.6",
22 | "gatsby-plugin-sharp": "^3.3.1",
23 | "gatsby-plugin-sitemap": "^3.3.0",
24 | "gatsby-plugin-styled-components": "^4.3.0",
25 | "gatsby-plugin-webfonts": "^2.1.0",
26 | "gatsby-source-airtable": "^2.1.1",
27 | "gatsby-source-filesystem": "^3.3.0",
28 | "gatsby-transformer-sharp": "^3.3.0",
29 | "install": "^0.13.0",
30 | "normalize.css": "^8.0.1",
31 | "npm": "^7.11.1",
32 | "react": "^17.0.1",
33 | "react-dom": "^17.0.1",
34 | "react-helmet": "^6.1.0",
35 | "react-icons": "^4.2.0",
36 | "react-is": "^17.0.2",
37 | "styled-components": "^5.2.3"
38 | },
39 | "devDependencies": {
40 | "prettier": "2.2.1"
41 | },
42 | "repository": {
43 | "type": "git",
44 | "url": "https://github.com/gatsbyjs/gatsby-starter-hello-world"
45 | },
46 | "bugs": {
47 | "url": "https://github.com/gatsbyjs/gatsby/issues"
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/src/assets/hero-1.svg:
--------------------------------------------------------------------------------
1 | Load_more
--------------------------------------------------------------------------------
/src/assets/main.css:
--------------------------------------------------------------------------------
1 | *,
2 | ::after,
3 | ::before {
4 | box-sizing: border-box;
5 | }
6 | :root {
7 | /* COLORS */
8 | /* primary */
9 |
10 | --primary-100: #e0deff;
11 | --primary-200: #c1beff;
12 | --primary-300: #a29dff;
13 | --primary-400: #837dff;
14 | /* main */
15 | --primary-500: #645cff;
16 | --primary-600: #504acc;
17 | --primary-700: #3c3799;
18 | --primary-800: #282566;
19 | --primary-900: #141233;
20 |
21 | /* grey */
22 | --grey-50: #f8fafc;
23 | --grey-100: #f1f5f9;
24 | --grey-200: #e2e8f0;
25 | --grey-300: #cbd5e1;
26 | --grey-400: #94a3b8;
27 | --grey-500: #64748b;
28 | --grey-600: #475569;
29 | --grey-700: #334155;
30 | --grey-800: #1e293b;
31 | --grey-900: #0f172a;
32 |
33 | /* rest */
34 | --primary-design: #60dbfb;
35 | --black-design: #0d0d0d;
36 | --grey-design: #eff0f3;
37 | --black: #222;
38 | --white: #fff;
39 | --red-light: #f8d7da;
40 | --red-dark: #842029;
41 | --green-light: #d1e7dd;
42 | --green-dark: #0f5132;
43 | --yellow: #f0db51;
44 | --yellow-light: #f8e881;
45 | --yellow-dark: #6b5d00;
46 |
47 | /* typography */
48 | --defaultFontSize: 112.5%;
49 | --headingFont: "Inconsolata", monospace;
50 | --bodyFont: "Montserrat", sans-serif;
51 | --smallText: 0.7em;
52 | /* rest */
53 | --backgroundColor: var(--white);
54 | --textColor: var(--grey-900);
55 | --borderRadius: 0.25rem;
56 | --letterSpacing: 1px;
57 | --transition: 0.3s ease-in-out all;
58 | --max-width: 1120px;
59 | --fixed-width: 600px;
60 |
61 | /* box shadows */
62 | --shadow-1: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06);
63 | --shadow-2: 0 4px 6px -1px rgba(0, 0, 0, 0.1),
64 | 0 2px 4px -1px rgba(0, 0, 0, 0.06);
65 | --shadow-3: 0 10px 15px -3px rgba(0, 0, 0, 0.1),
66 | 0 4px 6px -2px rgba(0, 0, 0, 0.05);
67 | --shadow-4: 0 20px 25px -5px rgba(0, 0, 0, 0.1),
68 | 0 10px 10px -5px rgba(0, 0, 0, 0.04);
69 | }
70 |
71 | /* @media only screen and (min-width: 576px) {
72 | :root {
73 | --defaultFontSize: 100%;
74 | }
75 | }
76 | @media only screen and (min-width: 768px) {
77 | :root {
78 | --defaultFontSize: 112.5%;
79 | }
80 | } */
81 |
82 | body {
83 | background: var(--backgroundColor);
84 | color: var(--textColor);
85 | font-family: var(--bodyFont);
86 | font-weight: 400;
87 | line-height: 1.75;
88 | }
89 |
90 | p {
91 | margin-bottom: 1.5rem;
92 | max-width: 40em;
93 | }
94 |
95 | h1,
96 | h2,
97 | h3,
98 | h4,
99 | h5 {
100 | margin: 0;
101 | margin-bottom: 1.38rem;
102 | font-family: var(--headingFont);
103 | font-weight: 400;
104 | line-height: 1.3;
105 | text-transform: capitalize;
106 | letter-spacing: var(--letterSpacing);
107 | }
108 | .img {
109 | width: 100%;
110 | display: block;
111 | }
112 | h1 {
113 | font-size: 3.052rem;
114 | }
115 |
116 | h2 {
117 | font-size: 2.441rem;
118 | }
119 |
120 | h3 {
121 | font-size: 1.953rem;
122 | }
123 |
124 | h4 {
125 | font-size: 1.563rem;
126 | }
127 |
128 | h5 {
129 | font-size: 1.25rem;
130 | }
131 |
132 | small,
133 | .text_small {
134 | font-size: var(--smallText);
135 | }
136 |
137 | ul {
138 | padding: 0;
139 | list-style-type: none;
140 | }
141 | a {
142 | text-decoration: none;
143 | }
144 | /*************
145 | Buttons
146 | *************/
147 | button,
148 | .btn {
149 | cursor: pointer;
150 | appearance: none;
151 | color: var(--white);
152 | background: var(--primary-500);
153 | border: none;
154 | border-radius: var(--borderRadius);
155 | letter-spacing: var(--letterSpacing);
156 | padding: 0.375rem 0.75rem;
157 | box-shadow: var(--shadow-1);
158 | transition: var(--transition);
159 | text-transform: capitalize;
160 | }
161 | button:hover,
162 | .btn:hover {
163 | color: var(--white);
164 | background: var(--primary-700);
165 | box-shadow: var(--shadow-2);
166 | }
167 | button.small {
168 | padding: 0.25rem 0.5rem;
169 | font-size: var(--smallText);
170 | }
171 | button.hipster {
172 | color: var(--primary-500);
173 | background: var(--primary-50);
174 | box-shadow: var(--shadow-1);
175 | }
176 | button.hipster:hover {
177 | background: var(--primary-100);
178 | box-shadow: var(--shadow-2);
179 | }
180 | button.block {
181 | width: 100%;
182 | }
183 |
184 | /*
185 | ===============
186 | Animation
187 | ===============
188 | */
189 | @keyframes bounce {
190 | 0% {
191 | transform: scale(1);
192 | }
193 | 50% {
194 | transform: scale(1.1);
195 | }
196 | 100% {
197 | transform: scale(1);
198 | }
199 | }
200 |
--------------------------------------------------------------------------------
/src/components/Hero.js:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import styled from "styled-components"
3 | import heroImg1 from "../assets/hero-1.svg"
4 |
5 | const Hero = () => {
6 | return (
7 |
8 |
9 |
10 |
React Projects
11 |
12 | Projects are the most practical way to learn any language, and
13 | React is no exception. Solidify your knowledge of
14 | React by creating these cool projects.
15 |
16 |
22 | join the course
23 |
24 |
25 |
26 |
27 |
28 | )
29 | }
30 |
31 | const Wrapper = styled.div`
32 | min-height: 40vh;
33 | background: var(--white);
34 | display: flex;
35 | align-items: center;
36 | justify-content: center;
37 | padding: 5rem 0;
38 | img {
39 | display: none;
40 | }
41 | .hero-center {
42 | width: 90vw;
43 | max-width: var(--max-width);
44 | }
45 | @media (min-width: 992px) {
46 | min-height: 60vh;
47 |
48 | .hero-center {
49 | display: grid;
50 | grid-template-columns: 1fr 1fr;
51 | place-items: center;
52 | gap: 2rem;
53 | }
54 | img {
55 | display: block;
56 | }
57 | }
58 | .hero-title h1 {
59 | color: var(--black-design);
60 | margin: 0;
61 | }
62 | .hero-title p {
63 | margin: 2rem 0;
64 | color: var(--grey-900);
65 | font-size: 1.25rem;
66 | }
67 | .hero-title span {
68 | letter-spacing: 5px;
69 | border-bottom: 2px solid var(--primary-design);
70 | margin: 0 0.5rem;
71 | text-align: center;
72 | display: inline-block;
73 | text-align: center;
74 | line-height: 1.25;
75 | font-style: italic;
76 | font-weight: 900;
77 | }
78 | .hero-btn {
79 | display: inline-block;
80 | background: var(--primary-design);
81 | border: 2px solid var(--primary-design);
82 | color: var(--black-design);
83 | font-weight: 500;
84 | text-transform: uppercase;
85 | padding: 0.75rem 1.25rem;
86 | box-shadow: var(--shadow-1);
87 | animation: bounce 2s infinite;
88 | }
89 | .hero-btn:hover {
90 | background: transparent;
91 |
92 | box-shadow: var(--shadow-2);
93 | color: var(--primary-design);
94 | }
95 | `
96 |
97 | export default Hero
98 |
--------------------------------------------------------------------------------
/src/components/Project.js:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import { GatsbyImage } from "gatsby-plugin-image"
3 | import styled from "styled-components"
4 | const Project = ({ name, image, url }) => {
5 | return (
6 |
12 |
13 |
16 |
17 | )
18 | }
19 |
20 | const Wrapper = styled.a`
21 | border-radius: var(--borderRadius);
22 | background: var(--white);
23 | box-shadow: var(--shadow-1);
24 | transition: var(--transition);
25 |
26 | &:hover {
27 | transform: scale(1.05);
28 | box-shadow: var(--shadow-2);
29 | }
30 | .img {
31 | width: 100%;
32 | display: block;
33 | border-top-left-radius: var(--borderRadius);
34 | border-top-right-radius: var(--borderRadius);
35 | height: 15rem;
36 | object-fit: cover;
37 | }
38 |
39 | footer {
40 | text-align: center;
41 | padding: 1rem 1.25rem;
42 | background: var(--white);
43 | border-bottom-left-radius: var(--borderRadius);
44 | border-bottom-right-radius: var(--borderRadius);
45 | }
46 | footer h5 {
47 | margin-bottom: 0;
48 | color: var(--grey-900);
49 | font-weight: 500;
50 | }
51 | `
52 |
53 | export default Project
54 |
--------------------------------------------------------------------------------
/src/components/Projects.js:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import styled from "styled-components"
3 | import Project from "./Project"
4 | const Projects = ({ title, projects }) => {
5 | return (
6 |
7 |
11 |
12 | {projects.map((project) => {
13 | return
14 | })}
15 |
16 |
17 | )
18 | }
19 |
20 | const Wrapper = styled.section`
21 | padding: 5rem 0;
22 | background: var(--grey-200);
23 | .title {
24 | text-align: center;
25 | margin-bottom: 3rem;
26 | }
27 |
28 | .title-underline {
29 | height: 0.2rem;
30 | width: 7rem;
31 | background: var(--primary-design);
32 | margin: 0 auto;
33 | margin-top: -1rem;
34 | }
35 | .section-center {
36 | width: 90vw;
37 | max-width: var(--max-width);
38 | margin: 0 auto 2rem auto;
39 | display: grid;
40 | gap: 3rem 2rem;
41 | grid-template-columns: repeat(auto-fill, minmax(330px, 1fr));
42 | }
43 | @media (min-width: 992px) {
44 | .center {
45 | width: 95vw;
46 | }
47 | }
48 | `
49 | export default Projects
50 |
--------------------------------------------------------------------------------
/src/components/seo.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import { Helmet } from 'react-helmet'
3 | import { graphql, useStaticQuery } from 'gatsby'
4 |
5 | const query = graphql`
6 | query {
7 | site {
8 | siteMetadata {
9 | siteTitle: title
10 | siteDesc: description
11 | author
12 | siteUrl
13 | image
14 | twitterUsername
15 | }
16 | }
17 | }
18 | `
19 |
20 | const SEO = ({ title }) => {
21 | const { site } = useStaticQuery(query)
22 | const {
23 | siteDesc,
24 | siteTitle,
25 | siteUrl,
26 | image,
27 | twitterUsername,
28 | } = site.siteMetadata
29 | return (
30 |
31 |
32 |
33 | {/* twitter card */}
34 |
35 |
36 |
37 |
38 |
39 |
40 | )
41 | }
42 |
43 | export default SEO
44 |
--------------------------------------------------------------------------------
/src/pages/404.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 |
3 | const NotFound = () => {
4 | return
404
5 | }
6 |
7 | export default NotFound
8 |
--------------------------------------------------------------------------------
/src/pages/index.js:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import { graphql } from "gatsby"
3 | import Hero from "../components/Hero"
4 | import Projects from "../components/Projects"
5 | import Seo from "../components/seo"
6 | const HomePage = ({ data }) => {
7 | const {
8 | allAirtable: { nodes: projects },
9 | } = data
10 | const formattedProjects = projects.map((project) => {
11 | return {
12 | id: project.id,
13 | ...project.data,
14 | image: project.data.image.localFiles[0].childImageSharp.gatsbyImageData,
15 | }
16 | })
17 | const basicProjects = formattedProjects
18 | .filter((project) => project.type === "basic")
19 | .sort((a, b) => a.order - b.order)
20 | const advancedProjects = formattedProjects
21 | .filter((project) => project.type === "advanced")
22 | .sort((a, b) => a.order - b.order)
23 | const finalProjects = formattedProjects
24 | .filter((p) => p.type === "final")
25 | .sort((a, b) => a.order - b.order)
26 | return (
27 | <>
28 |
29 |
30 |
31 |
32 |
33 | >
34 | )
35 | }
36 |
37 | export const query = graphql`
38 | {
39 | allAirtable(sort: { fields: data___order, order: ASC }) {
40 | nodes {
41 | id
42 | data {
43 | name
44 | order
45 | type
46 | url
47 | image {
48 | localFiles {
49 | childImageSharp {
50 | gatsbyImageData(layout: CONSTRAINED, placeholder: TRACED_SVG)
51 | }
52 | }
53 | }
54 | }
55 | }
56 | }
57 | }
58 | `
59 |
60 | export default HomePage
61 |
--------------------------------------------------------------------------------
/static/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/john-smilga/react-projects-site/5802a8d03294d553432a9eacb987d14a9a286e6c/static/favicon.ico
--------------------------------------------------------------------------------
/static/mainBcg.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/john-smilga/react-projects-site/5802a8d03294d553432a9eacb987d14a9a286e6c/static/mainBcg.jpeg
--------------------------------------------------------------------------------