fixing git

This commit is contained in:
YOUR NAME 2018-07-22 21:19:09 +10:00
parent 504fdd7fd4
commit 51faec6a16
45 changed files with 29533 additions and 0 deletions

22
LICENSE Executable file
View file

@ -0,0 +1,22 @@
The MIT License (MIT)
Copyright (c) 2015 gatsbyjs
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

52
README.md Executable file
View file

@ -0,0 +1,52 @@
# Gatsby + Netlify CMS Starter
This repo contains an example business website that is built with [Gatsby](https://www.gatsbyjs.org/), and [Netlify CMS](https://www.netlifycms.org): **[Demo Link](https://gatsby-netlify-cms.netlify.com/)**.
It follows the [JAMstack architecture](https://jamstack.org) by using Git as a single source of truth, and [Netlify](https://www.netlify.com) for continuous deployment, and CDN distribution.
## Prerequisites
- Node (I recommend using v8.2.0 or higher)
- [Gatsby CLI](https://www.gatsbyjs.org/docs/)
## Getting Started (Recommended)
Netlify CMS can run in any frontend web environment, but the quickest way to try it out is by running it on a pre-configured starter site with Netlify. The example here is the Kaldi coffee company template (adapted from [One Click Hugo CMS](https://github.com/netlify-templates/one-click-hugo-cms)). Use the button below to build and deploy your own copy of the repository:
<a href="https://app.netlify.com/start/deploy?repository=https://github.com/AustinGreen/gatsby-starter-netlify-cms&amp;stack=cms"><img src="https://www.netlify.com/img/deploy/button.svg" alt="Deploy to Netlify"></a>
After clicking that button, youll authenticate with GitHub and choose a repository name. Netlify will then automatically create a repository in your GitHub account with a copy of the files from the template. Next, it will build and deploy the new site on Netlify, bringing you to the site dashboard when the build is complete. Next, youll need to set up Netlifys Identity service to authorize users to log in to the CMS.
### Access Locally
```
$ git clone https://github.com/[GITHUB_USERNAME]/[REPO_NAME].git
$ cd [REPO_NAME]
$ yarn
$ npm run develop
```
To test the CMS locally, you'll need run a production build of the site:
```
$ npm run build
$ npm run serve
```
## Getting Started (Without Netlify)
```
$ gatsby new [SITE_DIRECTORY_NAME] https://github.com/AustinGreen/gatsby-starter-netlify-cms/
$ cd [SITE_DIRECTORY_NAME]
$ npm run build
$ npm run serve
```
### Setting up the CMS
Follow the [Netlify CMS Quick Start Guide](https://www.netlifycms.org/docs/quick-start/#authentication) to set up authentication, and hosting.
## Debugging
Windows users might encounter ```node-gyp``` errors when trying to npm install.
To resolve, make sure that you have both Python 2.7 and the Visual C++ build environment installed.
```
npm config set python python2.7
npm install --global --production windows-build-tools
```
[Full details here](https://www.npmjs.com/package/node-gyp 'NPM node-gyp page')

38
gatsby-config.js Executable file
View file

@ -0,0 +1,38 @@
module.exports = {
siteMetadata: {
title: 'Gatsby + Netlify CMS Starter',
},
plugins: [
'gatsby-plugin-react-helmet',
'gatsby-plugin-sass',
{
resolve: 'gatsby-source-filesystem',
options: {
path: `${__dirname}/src/pages`,
name: 'pages',
},
},
{
resolve: 'gatsby-source-filesystem',
options: {
path: `${__dirname}/src/img`,
name: 'images',
},
},
'gatsby-plugin-sharp',
'gatsby-transformer-sharp',
{
resolve: 'gatsby-transformer-remark',
options: {
plugins: [],
},
},
{
resolve: 'gatsby-plugin-netlify-cms',
options: {
modulePath: `${__dirname}/src/cms/cms.js`,
},
},
'gatsby-plugin-netlify', // make sure to keep it last in the array
],
}

85
gatsby-node.js Executable file
View file

@ -0,0 +1,85 @@
const _ = require('lodash')
const path = require('path')
const { createFilePath } = require('gatsby-source-filesystem')
exports.createPages = ({ boundActionCreators, graphql }) => {
const { createPage } = boundActionCreators
return graphql(`
{
allMarkdownRemark(limit: 1000) {
edges {
node {
id
fields {
slug
}
frontmatter {
tags
templateKey
}
}
}
}
}
`).then(result => {
if (result.errors) {
result.errors.forEach(e => console.error(e.toString()))
return Promise.reject(result.errors)
}
const posts = result.data.allMarkdownRemark.edges
posts.forEach(edge => {
const id = edge.node.id
createPage({
path: edge.node.fields.slug,
tags: edge.node.frontmatter.tags,
component: path.resolve(
`src/templates/${String(edge.node.frontmatter.templateKey)}.js`
),
// additional data can be passed via context
context: {
id,
},
})
})
// Tag pages:
let tags = []
// Iterate through each post, putting all found tags into `tags`
posts.forEach(edge => {
if (_.get(edge, `node.frontmatter.tags`)) {
tags = tags.concat(edge.node.frontmatter.tags)
}
})
// Eliminate duplicate tags
tags = _.uniq(tags)
// Make tag pages
tags.forEach(tag => {
const tagPath = `/tags/${_.kebabCase(tag)}/`
createPage({
path: tagPath,
component: path.resolve(`src/templates/tags.js`),
context: {
tag,
},
})
})
})
}
exports.onCreateNode = ({ node, boundActionCreators, getNode }) => {
const { createNodeField } = boundActionCreators
if (node.internal.type === `MarkdownRemark`) {
const value = createFilePath({ node, getNode })
createNodeField({
name: `slug`,
node,
value,
})
}
}

6
netlify.toml Executable file
View file

@ -0,0 +1,6 @@
[build]
publish = "public"
command = "npm run build"
[build.environment]
YARN_VERSION = "1.3.2"
YARN_FLAGS = "--no-ignore-optional"

16743
package-lock.json generated Executable file

File diff suppressed because it is too large Load diff

43
package.json Executable file
View file

@ -0,0 +1,43 @@
{
"name": "gatsby-starter-netlify-cms",
"description": "Example Gatsby, and Netlify CMS project",
"version": "1.1.3",
"author": "Austin Green",
"dependencies": {
"bulma": "^0.7.1",
"gatsby": "^1.9.277",
"gatsby-link": "^1.6.46",
"gatsby-plugin-netlify": "^1.0.19",
"gatsby-plugin-netlify-cms": "^2.0.1",
"gatsby-plugin-react-helmet": "^2.0.5",
"gatsby-plugin-sass": "^1.0.17",
"gatsby-plugin-sharp": "^1.6.48",
"gatsby-remark-images": "^1.5.67",
"gatsby-source-filesystem": "^1.5.39",
"gatsby-transformer-remark": "^1.7.44",
"gatsby-transformer-sharp": "^1.6.27",
"lodash": "^4.17.5",
"lodash-webpack-plugin": "^0.11.4",
"netlify-cms": "^1.9.3",
"prop-types": "^15.6.2",
"react": "^16.2.0",
"react-helmet": "^5.2.0",
"uuid": "^3.3.2"
},
"keywords": [
"gatsby"
],
"license": "MIT",
"main": "n/a",
"scripts": {
"start": "npm run develop",
"build": "gatsby build",
"develop": "gatsby develop",
"serve": "gatsby serve",
"format": "prettier --trailing-comma es5 --no-semi --single-quote --write \"{gatsby-*.js,src/**/*.js}\"",
"test": "echo \"Error: no test specified\" && exit 1"
},
"devDependencies": {
"prettier": "^1.13.7"
}
}

19
src/blogComponents/Content.js Executable file
View file

@ -0,0 +1,19 @@
import React from 'react'
import PropTypes from 'prop-types'
export const HTMLContent = ({ content, className }) => (
<div className={className} dangerouslySetInnerHTML={{ __html: content }} />
)
const Content = ({ content, className }) => (
<div className={className}>{content}</div>
)
Content.propTypes = {
content: PropTypes.string,
className: PropTypes.string,
}
HTMLContent.propTypes = Content.propTypes
export default Content

28
src/blogComponents/Features.js Executable file
View file

@ -0,0 +1,28 @@
import React from 'react'
import PropTypes from 'prop-types'
const FeatureGrid = ({ gridItems }) => (
<div className="columns is-multiline">
{gridItems.map(item => (
<div key={item.image} className="column is-6">
<section className="section">
<p className="has-text-centered">
<img alt="" src={item.image} />
</p>
<p>{item.text}</p>
</section>
</div>
))}
</div>
)
FeatureGrid.propTypes = {
gridItems: PropTypes.arrayOf(
PropTypes.shape({
image: PropTypes.string,
text: PropTypes.string,
})
),
}
export default FeatureGrid

41
src/blogComponents/Navbar.js Executable file
View file

@ -0,0 +1,41 @@
import React from 'react'
import Link from 'gatsby-link'
import github from '../img/github-icon.svg'
import logo from '../img/logo.svg'
const Navbar = () => (
<nav className="navbar is-transparent">
<div className="container">
<div className="navbar-brand">
<Link to="/" className="navbar-item">
<figure className="image">
<img src={logo} alt="Kaldi" style={{ width: '88px' }} />
</figure>
</Link>
</div>
<div className="navbar-start">
<Link className="navbar-item" to="/about">
About
</Link>
<Link className="navbar-item" to="/products">
Products
</Link>
</div>
<div className="navbar-end">
<a
className="navbar-item"
href="https://github.com/AustinGreen/gatsby-netlify-cms-boilerplate"
target="_blank"
rel="noopener noreferrer"
>
<span className="icon">
<img src={github} alt="Github" />
</span>
</a>
</div>
</div>
</nav>
)
export default Navbar

40
src/blogComponents/Pricing.js Executable file
View file

@ -0,0 +1,40 @@
import React from 'react'
import PropTypes from 'prop-types'
const Pricing = ({ data }) => (
<div className="columns">
{data.map(price => (
<div key={price.plan} className="column">
<section className="section">
<h4 className="has-text-centered has-text-weight-semibold">
{price.plan}
</h4>
<h2 className="is-size-1 has-text-weight-bold has-text-primary has-text-centered">
${price.price}
</h2>
<p className="has-text-weight-semibold">{price.description}</p>
<ul>
{price.items.map(item => (
<li key={item} className="is-size-5">
{item}
</li>
))}
</ul>
</section>
</div>
))}
</div>
)
Pricing.propTypes = {
data: PropTypes.arrayOf(
PropTypes.shape({
plan: PropTypes.string,
price: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
description: PropTypes.string,
items: PropTypes.array,
})
),
}
export default Pricing

View file

@ -0,0 +1,28 @@
import React from 'react'
import PropTypes from 'prop-types'
import { v4 } from 'uuid'
const Testimonials = ({ testimonials }) => (
<div>
{testimonials.map(testimonial => (
<article key={v4()} className="message">
<div className="message-body">
{testimonial.quote}
<br />
<cite> {testimonial.author}</cite>
</div>
</article>
))}
</div>
)
Testimonials.propTypes = {
testimonials: PropTypes.arrayOf(
PropTypes.shape({
quote: PropTypes.string,
author: PropTypes.string,
})
),
}
export default Testimonials

10
src/cms/cms.js Executable file
View file

@ -0,0 +1,10 @@
import CMS from 'netlify-cms'
import AboutPagePreview from './preview-templates/AboutPagePreview'
import BlogPostPreview from './preview-templates/BlogPostPreview'
import ProductPagePreview from './preview-templates/ProductPagePreview'
CMS.registerPreviewStyle('/styles.css')
CMS.registerPreviewTemplate('about', AboutPagePreview)
CMS.registerPreviewTemplate('products', ProductPagePreview)
CMS.registerPreviewTemplate('blog', BlogPostPreview)

View file

@ -0,0 +1,19 @@
import React from 'react'
import PropTypes from 'prop-types'
import { AboutPageTemplate } from '../../templates/about-page'
const AboutPagePreview = ({ entry, widgetFor }) => (
<AboutPageTemplate
title={entry.getIn(['data', 'title'])}
content={widgetFor('body')}
/>
)
AboutPagePreview.propTypes = {
entry: PropTypes.shape({
getIn: PropTypes.func,
}),
widgetFor: PropTypes.func,
}
export default AboutPagePreview

View file

@ -0,0 +1,21 @@
import React from 'react'
import PropTypes from 'prop-types'
import { BlogPostTemplate } from '../../templates/blog-post'
const BlogPostPreview = ({ entry, widgetFor }) => (
<BlogPostTemplate
content={widgetFor('body')}
description={entry.getIn(['data', 'description'])}
tags={entry.getIn(['data', 'tags'])}
title={entry.getIn(['data', 'title'])}
/>
)
BlogPostPreview.propTypes = {
entry: PropTypes.shape({
getIn: PropTypes.func,
}),
widgetFor: PropTypes.func,
}
export default BlogPostPreview

View file

@ -0,0 +1,56 @@
import React from 'react'
import PropTypes from 'prop-types'
import { ProductPageTemplate } from '../../templates/product-page'
const ProductPagePreview = ({ entry, getAsset }) => {
const entryBlurbs = entry.getIn(['data', 'intro', 'blurbs'])
const blurbs = entryBlurbs ? entryBlurbs.toJS() : []
const entryTestimonials = entry.getIn(['data', 'testimonials'])
const testimonials = entryTestimonials ? entryTestimonials.toJS() : []
const entryPricingPlans = entry.getIn(['data', 'pricing', 'plans'])
const pricingPlans = entryPricingPlans ? entryPricingPlans.toJS() : []
return (
<ProductPageTemplate
image={entry.getIn(['data', 'image'])}
title={entry.getIn(['data', 'title'])}
heading={entry.getIn(['data', 'heading'])}
description={entry.getIn(['data', 'description'])}
intro={{ blurbs }}
main={{
heading: entry.getIn(['data', 'main', 'heading']),
description: entry.getIn(['data', 'main', 'description']),
image1: {
image: getAsset(entry.getIn(['data', 'main', 'image1', 'image'])),
alt: entry.getIn(['data', 'main', 'image1', 'alt']),
},
image2: {
image: getAsset(entry.getIn(['data', 'main', 'image2', 'image'])),
alt: entry.getIn(['data', 'main', 'image2', 'alt']),
},
image3: {
image: getAsset(entry.getIn(['data', 'main', 'image3', 'image'])),
alt: entry.getIn(['data', 'main', 'image3', 'alt']),
},
}}
fullImage={entry.getIn(['data', 'full_image'])}
testimonials={testimonials}
pricing={{
heading: entry.getIn(['data', 'pricing', 'heading']),
description: entry.getIn(['data', 'pricing', 'description']),
plans: pricingPlans,
}}
/>
)
}
ProductPagePreview.propTypes = {
entry: PropTypes.shape({
getIn: PropTypes.func,
}),
getAsset: PropTypes.func,
}
export default ProductPagePreview

5
src/img/github-icon.svg Executable file
View file

@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="Capa_1" x="0px" y="0px" width="438.549px" height="438.549px" viewBox="0 0 438.549 438.549" style="enable-background:new 0 0 438.549 438.549;" xml:space="preserve">
<g>
<path d="M409.132,114.573c-19.608-33.596-46.205-60.194-79.798-79.8C295.736,15.166,259.057,5.365,219.271,5.365 c-39.781,0-76.472,9.804-110.063,29.408c-33.596,19.605-60.192,46.204-79.8,79.8C9.803,148.168,0,184.854,0,224.63 c0,47.78,13.94,90.745,41.827,128.906c27.884,38.164,63.906,64.572,108.063,79.227c5.14,0.954,8.945,0.283,11.419-1.996 c2.475-2.282,3.711-5.14,3.711-8.562c0-0.571-0.049-5.708-0.144-15.417c-0.098-9.709-0.144-18.179-0.144-25.406l-6.567,1.136 c-4.187,0.767-9.469,1.092-15.846,1c-6.374-0.089-12.991-0.757-19.842-1.999c-6.854-1.231-13.229-4.086-19.13-8.559 c-5.898-4.473-10.085-10.328-12.56-17.556l-2.855-6.57c-1.903-4.374-4.899-9.233-8.992-14.559 c-4.093-5.331-8.232-8.945-12.419-10.848l-1.999-1.431c-1.332-0.951-2.568-2.098-3.711-3.429c-1.142-1.331-1.997-2.663-2.568-3.997 c-0.572-1.335-0.098-2.43,1.427-3.289c1.525-0.859,4.281-1.276,8.28-1.276l5.708,0.853c3.807,0.763,8.516,3.042,14.133,6.851 c5.614,3.806,10.229,8.754,13.846,14.842c4.38,7.806,9.657,13.754,15.846,17.847c6.184,4.093,12.419,6.136,18.699,6.136 c6.28,0,11.704-0.476,16.274-1.423c4.565-0.952,8.848-2.383,12.847-4.285c1.713-12.758,6.377-22.559,13.988-29.41 c-10.848-1.14-20.601-2.857-29.264-5.14c-8.658-2.286-17.605-5.996-26.835-11.14c-9.235-5.137-16.896-11.516-22.985-19.126 c-6.09-7.614-11.088-17.61-14.987-29.979c-3.901-12.374-5.852-26.648-5.852-42.826c0-23.035,7.52-42.637,22.557-58.817 c-7.044-17.318-6.379-36.732,1.997-58.24c5.52-1.715,13.706-0.428,24.554,3.853c10.85,4.283,18.794,7.952,23.84,10.994 c5.046,3.041,9.089,5.618,12.135,7.708c17.705-4.947,35.976-7.421,54.818-7.421s37.117,2.474,54.823,7.421l10.849-6.849 c7.419-4.57,16.18-8.758,26.262-12.565c10.088-3.805,17.802-4.853,23.134-3.138c8.562,21.509,9.325,40.922,2.279,58.24 c15.036,16.18,22.559,35.787,22.559,58.817c0,16.178-1.958,30.497-5.853,42.966c-3.9,12.471-8.941,22.457-15.125,29.979 c-6.191,7.521-13.901,13.85-23.131,18.986c-9.232,5.14-18.182,8.85-26.84,11.136c-8.662,2.286-18.415,4.004-29.263,5.146 c9.894,8.562,14.842,22.077,14.842,40.539v60.237c0,3.422,1.19,6.279,3.572,8.562c2.379,2.279,6.136,2.95,11.276,1.995 c44.163-14.653,80.185-41.062,108.068-79.226c27.88-38.161,41.825-81.126,41.825-128.906 C438.536,184.851,428.728,148.168,409.132,114.573z"/>
</g>
<div xmlns="" id="divScriptsUsed" style="display: none"/><script xmlns="" id="globalVarsDetection" src="chrome-extension://cmkdbmfndkfgebldhnkbfhlneefdaaip/js/wrs_env.js"/></svg>

After

Width:  |  Height:  |  Size: 2.6 KiB

1
src/img/logo.svg Executable file
View file

@ -0,0 +1 @@
<svg viewBox="0 0 109 24" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:figma="http://www.figma.com/figma/ns"><title>Logo</title><g transform="translate(-1470)" figma:type="canvas"><g style="mix-blend-mode:normal" figma:type="vector" transform="translate(1470)" fill="#f40"><use xlink:href="#b" style="mix-blend-mode:normal"/><use xlink:href="#c" style="mix-blend-mode:normal"/><use xlink:href="#d" style="mix-blend-mode:normal"/><use xlink:href="#e" style="mix-blend-mode:normal"/><use xlink:href="#f" style="mix-blend-mode:normal"/></g></g><defs><path id="b" d="M22.735 23.171c.283.323.053.829-.376.829h-5.907c-.285 0-.556-.121-.745-.333l-9.414-10.526v10.36c0 .276-.224.5-.5.5h-5.293c-.276 0-.5-.224-.5-.5v-23c0-.276.224-.5.5-.5h5.293c.276 0 .5.224.5.5v9.815l9.141-9.99c.19-.207.457-.325.738-.325h5.762c.437 0 .664.521.366.841l-9.851 10.563 10.287 11.767z"/><path id="c" d="M45.991 24c-.199 0-.38-.118-.459-.301l-2.024-4.669h-10.67l-2.024 4.669c-.079.183-.259.301-.459.301h-5.212c-.366 0-.608-.381-.453-.712l10.782-23c.082-.176.259-.288.453-.288h4.358c.194 0 .37.112.453.287l10.815 23c.156.332-.086.713-.452.713h-5.108zm-11.135-9.668h6.635l-3.317-7.694-3.317 7.694z"/><path id="d" d="M55.525 24c-.276 0-.5-.224-.5-.5v-23c0-.276.224-.5.5-.5h5.293c.276 0 .5.224.5.5v18.428h9.759c.276 0 .5.224.5.5v4.072c0 .276-.224.5-.5.5h-15.552z"/><path id="e" d="M75.279.5c0-.276.224-.5.5-.5h9.315c2.667 0 4.959.477 6.874 1.43 1.938.953 3.42 2.338 4.446 4.153 1.026 1.793 1.539 3.926 1.539 6.4 0 2.496-.513 4.652-1.539 6.468-1.003 1.793-2.474 3.166-4.412 4.119-1.915.953-4.218 1.43-6.908 1.43h-9.315c-.276 0-.5-.224-.5-.5v-23zm9.37 18.462c2.371 0 4.138-.579 5.301-1.736 1.163-1.157 1.744-2.905 1.744-5.242 0-2.338-.581-4.074-1.744-5.209-1.163-1.157-2.93-1.736-5.301-1.736h-3.078v13.923h3.078z"/><path id="f" d="M102.913 24c-.276 0-.5-.224-.5-.5v-23c0-.276.224-.5.5-.5h5.293c.276 0 .5.224.5.5v23c0 .276-.224.5-.5.5h-5.293z"/></defs></svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

42
src/layouts/all.sass Executable file
View file

@ -0,0 +1,42 @@
@import "~bulma/sass/utilities/initial-variables"
// Config vars
$kaldi-red: #FD461E
$kaldi-red-invert: #fff
$primary: $kaldi-red
$primary-invert: $kaldi-red-invert
.content .taglist
list-style: none
margin-bottom: 0
margin-left: 0
margin-right: 1.5rem
margin-top: 1.5rem
display: flex
flex-wrap: wrap
justify-content: left
align-items: center
li
padding: 0 2rem 1rem 0
margin-bottom: 1.5rem
margin-top: 0
// Helper Classes
.full-width-image-container
width: 100vw
height: 400px
position: relative
left: 50%
right: 50%
margin: 5em -50vw
background-size: cover
background-position: bottom
display: flex
justify-content: center
align-items: center
.margin-top-0
margin-top: 0 !important
@import "~bulma"

20
src/layouts/index.js Executable file
View file

@ -0,0 +1,20 @@
import React from 'react'
import PropTypes from 'prop-types'
import Helmet from 'react-helmet'
import Navbar from '../components/Navbar'
import './all.sass'
const TemplateWrapper = ({ children }) => (
<div>
<Helmet title="Home | Gatsby + Netlify CMS" />
<Navbar />
<div>{children()}</div>
</div>
)
TemplateWrapper.propTypes = {
children: PropTypes.func,
}
export default TemplateWrapper

10
src/pages/404.js Executable file
View file

@ -0,0 +1,10 @@
import React from 'react'
const NotFoundPage = () => (
<div>
<h1>NOT FOUND</h1>
<p>You just hit a route that doesn&#39;t exist... the sadness.</p>
</div>
)
export default NotFoundPage

19
src/pages/about/index.md Executable file
View file

@ -0,0 +1,19 @@
---
templateKey: 'about-page'
path: /about
title: About our values
---
### Shade-grown coffee
Coffee is a small tree or shrub that grows in the forest understory in its wild form, and traditionally was grown commercially under other trees that provided shade. The forest-like structure of shade coffee farms provides habitat for a great number of migratory and resident species.
### Single origin
Single-origin coffee is coffee grown within a single known geographic origin. Sometimes, this is a single farm or a specific collection of beans from a single country. The name of the coffee is then usually the place it was grown to whatever degree available.
### Sustainable farming
Sustainable agriculture is farming in sustainable ways based on an understanding of ecosystem services, the study of relationships between organisms and their environment. What grows where and how it is grown are a matter of choice and careful consideration for nature and communities.
### Direct sourcing
Direct trade is a form of sourcing practiced by some coffee roasters. Advocates of direct trade practices promote direct communication and price negotiation between buyer and farmer, along with systems that encourage and incentivize quality.
### Reinvest profits
We want to truly empower the communities that bring amazing coffee to you. Thats why we reinvest 20% of our profits into farms, local businesses and schools everywhere our coffee is grown. You can see the communities grow and learn more about coffee farming on our blog.

View file

@ -0,0 +1,32 @@
---
templateKey: blog-post
title: BOOBS BOOBS
date: 2016-12-17T15:04:10.000Z
description: I LOVW BOOBS
tags:
- flavor
- tasting
---
![flavor wheel](/img/flavor_wheel.jpg)
The SCAA updated the wheel to reflect the finer nuances needed to describe flavors more precisely. The new descriptions are more detailed and hence allow cuppers to distinguish between more flavors.
While this is going to be a big change for professional coffee tasters, it means a lot to you as a consumer as well. Well explain how the wheel came to be, how pros use it and what the flavors actually mean.
## What the updates mean to you
The Specialty Coffee Association of America (SCAA), founded in 1982, is a non-profit trade organization for the specialty coffee industry. With members located in more than 40 countries, SCAA represents every segment of the specialty coffee industry, including:
* producers
* roasters
* importers/exporters
* retailers
* manufacturers
* baristas
For over 30 years, SCAA has been dedicated to creating a vibrant specialty coffee community by recognizing, developing and promoting specialty coffee. SCAA sets and maintains quality standards for the industry, conducts market research, and provides education, training, resources, and business services for its members.
Coffee cupping, or coffee tasting, is the practice of observing the tastes and aromas of brewed coffee. It is a professional practice but can be done informally by anyone or by professionals known as "Q Graders". A standard coffee cupping procedure involves deeply sniffing the coffee, then loudly slurping the coffee so it spreads to the back of the tongue.
The coffee taster attempts to measure aspects of the coffee's taste, specifically the body (the texture or mouthfeel, such as oiliness), sweetness, acidity (a sharp and tangy feeling, like when biting into an orange), flavour (the characters in the cup), and aftertaste. Since coffee beans embody telltale flavours from the region where they were grown, cuppers may attempt to identify the coffee's origin.

View file

@ -0,0 +1,27 @@
---
templateKey: blog-post
title: A beginners guide to brewing with Chemex
date: 2017-01-04T15:04:10.000Z
description: Brewing with a Chemex probably seems like a complicated, time-consuming ordeal, but once you get used to the process, it becomes a soothing ritual that's worth the effort every time.
tags:
- brewing
- chemex
---
![chemex](/img/chemex.jpg)
This week well **take** a look at all the steps required to make astonishing coffee with a Chemex at home. The Chemex Coffeemaker is a manual, pour-over style glass-container coffeemaker that Peter Schlumbohm invented in 1941, and which continues to be manufactured by the Chemex Corporation in Chicopee, Massachusetts.
In 1958, designers at the [Illinois Institute of Technology](https://www.spacefarm.digital) said that the Chemex Coffeemaker is _"one of the best-designed products of modern times"_, and so is included in the collection of the Museum of Modern Art in New York City.
## The little secrets of Chemex brewing
The Chemex Coffeemaker consists of an hourglass-shaped glass flask with a conical funnel-like neck (rather than the cylindrical neck of an Erlenmeyer flask) and uses proprietary filters, made of bonded paper (thicker-gauge paper than the standard paper filters for a drip-method coffeemaker) that removes most of the coffee oils, brewing coffee with a taste that is different than coffee brewed in other coffee-making systems; also, the thicker paper of the Chemex coffee filters may assist in removing cafestol, a cholesterol-containing compound found in coffee oils. Heres three important tips newbies forget about:
1. Always buy dedicated Chemex filters.
2. Use a scale, dont try to eyeball it.
3. Never skip preheating the glass.
4. Timing is key, dont forget the clock.
The most visually distinctive feature of the Chemex is the heatproof wooden collar around the neck, allowing it to be handled and poured when full of hot water. This is turned, then split in two to allow it to fit around the glass neck. The two pieces are held loosely in place by a tied leather thong. The pieces are not tied tightly and can still move slightly, retained by the shape of the conical glass.
For a design piece that became popular post-war at a time of Modernism and precision manufacture, this juxtaposition of natural wood and the organic nature of a hand-tied knot with the laboratory nature of glassware was a distinctive feature of its appearance.

View file

@ -0,0 +1,33 @@
---
templateKey: 'blog-post'
title: 'Just in: small batch of Jamaican Blue Mountain in store next week'
date: 2017-01-04T15:04:10.000Z
description: >-
Were proud to announce that well be offering a small batch of Jamaica Blue
Mountain coffee beans in our store next week.
tags:
- jamaica
- green beans
- flavor
- tasting
---
We expect the shipment of a limited quantity of green beans next Monday. Well be offering the roasted beans from Tuesday, but quantities are limited, so be quick.
Blue Mountain Peak is the highest mountain in Jamaica and one of the highest peaks in the Caribbean at 7,402 ft. It is the home of Blue Mountain coffee and their famous tours. It is located on the border of the Portland and Saint Thomas parishes of Jamaica.
## A little history
The Blue Mountains are considered by many to be a hiker's and camper's paradise. The traditional Blue Mountain trek is a 7-mile hike to the peak and consists of a 3,000-foot increase in elevation. Jamaicans prefer to reach the peak at sunrise, thus the 34 hour hike is usually undertaken in darkness. Since the sky is usually very clear in the mornings, Cuba can be seen in the distance.
>Some of the plants found on the Blue Mountain cannot be found anywhere else in the world and they are often of a dwarfed sort.
This is mainly due to the cold climate which inhibits growth. The small coffee farming communities of Claverty Cottage and Hagley Gap are located near the peak.
## What you need to know before trying
Jamaican Blue Mountain Coffee or Jamaica Blue Mountain Coffee is a classification of coffee grown in the Blue Mountains of Jamaica. The best lots of Blue Mountain coffee are noted for their mild flavor and lack of bitterness. Over the past few decades, this coffee has developed a reputation that has made it one of the most expensive and sought-after coffees in the world. Over 80% of all Jamaican Blue Mountain Coffee is exported to Japan. In addition to its use for brewed coffee, the beans are the flavor base of Tia Maria coffee liqueur.
Jamaican Blue Mountain Coffee is a globally protected certification mark, meaning only coffee certified by the Coffee Industry Board of Jamaica can be labeled as such. It comes from a recognized growing region in the Blue Mountain region of Jamaica, and its cultivation is monitored by the Coffee Industry Board of Jamaica.
The Blue Mountains are generally located between Kingston to the south and Port Antonio to the north. Rising 7,402 ft, they are some of the highest mountains in the Caribbean. The climate of the region is cool and misty with high rainfall. The soil is rich, with excellent drainage. This combination of climate and soil is considered ideal for coffee.

76
src/pages/index.js Executable file
View file

@ -0,0 +1,76 @@
import React from 'react'
import PropTypes from 'prop-types'
import Link from 'gatsby-link'
export default class IndexPage extends React.Component {
render() {
const { data } = this.props
const { edges: posts } = data.allMarkdownRemark
return (
<section className="section">
<div className="container">
<div className="content">
<h1 className="has-text-weight-bold is-size-2">Latest Stories</h1>
</div>
{posts
.map(({ node: post }) => (
<div
className="content"
style={{ border: '1px solid #eaecee', padding: '2em 4em' }}
key={post.id}
>
<p>
<Link className="has-text-primary" to={post.fields.slug}>
{post.frontmatter.title}
</Link>
<span> &bull; </span>
<small>{post.frontmatter.date}</small>
</p>
<p>
{post.excerpt}
<br />
<br />
<Link className="button is-small" to={post.fields.slug}>
Keep Reading
</Link>
</p>
</div>
))}
</div>
</section>
)
}
}
IndexPage.propTypes = {
data: PropTypes.shape({
allMarkdownRemark: PropTypes.shape({
edges: PropTypes.array,
}),
}),
}
export const pageQuery = graphql`
query IndexQuery {
allMarkdownRemark(
sort: { order: DESC, fields: [frontmatter___date] },
filter: { frontmatter: { templateKey: { eq: "blog-post" } }}
) {
edges {
node {
excerpt(pruneLength: 400)
id
fields {
slug
}
frontmatter {
title
templateKey
date(formatString: "MMMM DD, YYYY")
}
}
}
}
}
`

101
src/pages/products/index.md Executable file
View file

@ -0,0 +1,101 @@
---
templateKey: 'product-page'
path: /products
title: Our Coffee
image: /img/jumbotron.jpg
heading: What we offer
description: >-
Kaldi is the ultimate spot for coffee lovers who want to learn about their
javas origin and support the farmers that grew it. We take coffee production,
roasting and brewing seriously and were glad to pass that knowledge to
anyone.
intro:
blurbs:
- image: /img/coffee.png
text: >
We sell green and roasted coffee beans that are sourced directly from
independent farmers and farm cooperatives. Were proud to offer a
variety of coffee beans grown with great care for the environment and
local communities. Check our post or contact us directly for current
availability.
- image: /img/coffee-gear.png
text: >
We offer a small, but carefully curated selection of brewing gear and
tools for every taste and experience level. No matter if you roast your
own beans or just bought your first french press, youll find a gadget
to fall in love with in our shop.
- image: /img/tutorials.png
text: >
Love a great cup of coffee, but never knew how to make one? Bought a
fancy new Chemex but have no clue how to use it? Don't worry, were here
to help. You can schedule a custom 1-on-1 consultation with our baristas
to learn anything you want to know about coffee roasting and brewing.
Email us or call the store for details.
- image: /img/meeting-space.png
text: >
We believe that good coffee has the power to bring people together.
Thats why we decided to turn a corner of our shop into a cozy meeting
space where you can hang out with fellow coffee lovers and learn about
coffee making techniques. All of the artwork on display there is for
sale. The full price you pay goes to the artist.
heading: What we offer
description: >
Kaldi is the ultimate spot for coffee lovers who want to learn about their
javas origin and support the farmers that grew it. We take coffee
production, roasting and brewing seriously and were glad to pass that
knowledge to anyone. This is an edit via identity...
main:
heading: Great coffee with no compromises
description: >
We hold our coffee to the highest standards from the shrub to the cup.
Thats why were meticulous and transparent about each step of the coffees
journey. We personally visit each farm to make sure the conditions are
optimal for the plants, farmers and the local environment.
image1:
alt: A close-up of a paper filter filled with ground coffee
image: /img/products-grid3.jpg
image2:
alt: A green cup of a coffee on a wooden table
image: /img/products-grid2.jpg
image3:
alt: Coffee beans
image: /img/products-grid1.jpg
testimonials:
- author: Elisabeth Kaurismäki
quote: >-
The first time I tried Kaldis coffee, I couldnt even believe that was
the same thing Ive been drinking every morning.
- author: Philipp Trommler
quote: >-
Kaldi is the place to go if you want the best quality coffee. I love their
stance on empowering farmers and transparency.
full_image: /img/products-full-width.jpg
pricing:
heading: Monthly subscriptions
description: >-
We make it easy to make great coffee a part of your life. Choose one of our
monthly subscription plans to receive great coffee at your doorstep each
month. Contact us about more details and payment info.
plans:
- description: Perfect for the drinker who likes to enjoy 1-2 cups per day.
items:
- 3 lbs of coffee per month
- Green or roasted beans"
- One or two varieties of beans"
plan: Small
price: '50'
- description: 'Great for avid drinkers, java-loving couples and bigger crowds'
items:
- 6 lbs of coffee per month
- Green or roasted beans
- Up to 4 different varieties of beans
plan: Big
price: '80'
- description: Want a few tiny batches from different varieties? Try our custom plan
items:
- Whatever you need
- Green or roasted beans
- Unlimited varieties
plan: Custom
price: '??'
---

49
src/pages/tags/index.js Executable file
View file

@ -0,0 +1,49 @@
import React from 'react'
import { kebabCase } from 'lodash'
import Helmet from 'react-helmet'
import Link from 'gatsby-link'
const TagsPage = ({
data: { allMarkdownRemark: { group }, site: { siteMetadata: { title } } },
}) => (
<section className="section">
<Helmet title={`Tags | ${title}`} />
<div className="container content">
<div className="columns">
<div
className="column is-10 is-offset-1"
style={{ marginBottom: '6rem' }}
>
<h1 className="title is-size-2 is-bold-light">Tags</h1>
<ul className="taglist">
{group.map(tag => (
<li key={tag.fieldValue}>
<Link to={`/tags/${kebabCase(tag.fieldValue)}/`}>
{tag.fieldValue} ({tag.totalCount})
</Link>
</li>
))}
</ul>
</div>
</div>
</div>
</section>
)
export default TagsPage
export const tagPageQuery = graphql`
query TagsQuery {
site {
siteMetadata {
title
}
}
allMarkdownRemark(limit: 1000) {
group(field: frontmatter___tags) {
fieldValue
totalCount
}
}
}
`

59
src/templates/about-page.js Executable file
View file

@ -0,0 +1,59 @@
import React from 'react'
import PropTypes from 'prop-types'
import Content, { HTMLContent } from '../components/Content'
export const AboutPageTemplate = ({ title, content, contentComponent }) => {
const PageContent = contentComponent || Content
return (
<section className="section section--gradient">
<div className="container">
<div className="columns">
<div className="column is-10 is-offset-1">
<div className="section">
<h2 className="title is-size-3 has-text-weight-bold is-bold-light">
{title}
</h2>
<PageContent className="content" content={content} />
</div>
</div>
</div>
</div>
</section>
)
}
AboutPageTemplate.propTypes = {
title: PropTypes.string.isRequired,
content: PropTypes.string,
contentComponent: PropTypes.func,
}
const AboutPage = ({ data }) => {
const { markdownRemark: post } = data
return (
<AboutPageTemplate
contentComponent={HTMLContent}
title={post.frontmatter.title}
content={post.html}
/>
)
}
AboutPage.propTypes = {
data: PropTypes.object.isRequired,
}
export default AboutPage
export const aboutPageQuery = graphql`
query AboutPage($id: String!) {
markdownRemark(id: { eq: $id }) {
html
frontmatter {
title
}
}
}
`

92
src/templates/blog-post.js Executable file
View file

@ -0,0 +1,92 @@
import React from 'react'
import PropTypes from 'prop-types'
import { kebabCase } from 'lodash'
import Helmet from 'react-helmet'
import Link from 'gatsby-link'
import Content, { HTMLContent } from '../components/Content'
export const BlogPostTemplate = ({
content,
contentComponent,
description,
tags,
title,
helmet,
}) => {
const PostContent = contentComponent || Content
return (
<section className="section">
{helmet || ''}
<div className="container content">
<div className="columns">
<div className="column is-10 is-offset-1">
<h1 className="title is-size-2 has-text-weight-bold is-bold-light">
{title}
</h1>
<p>{description}</p>
<PostContent content={content} />
{tags && tags.length ? (
<div style={{ marginTop: `4rem` }}>
<h4>Tags</h4>
<ul className="taglist">
{tags.map(tag => (
<li key={tag + `tag`}>
<Link to={`/tags/${kebabCase(tag)}/`}>{tag}</Link>
</li>
))}
</ul>
</div>
) : null}
</div>
</div>
</div>
</section>
)
}
BlogPostTemplate.propTypes = {
content: PropTypes.string.isRequired,
contentComponent: PropTypes.func,
description: PropTypes.string,
title: PropTypes.string,
helmet: PropTypes.instanceOf(Helmet),
}
const BlogPost = ({ data }) => {
const { markdownRemark: post } = data
return (
<BlogPostTemplate
content={post.html}
contentComponent={HTMLContent}
description={post.frontmatter.description}
helmet={<Helmet title={`${post.frontmatter.title} | Blog`} />}
tags={post.frontmatter.tags}
title={post.frontmatter.title}
/>
)
}
BlogPost.propTypes = {
data: PropTypes.shape({
markdownRemark: PropTypes.object,
}),
}
export default BlogPost
export const pageQuery = graphql`
query BlogPostByID($id: String!) {
markdownRemark(id: { eq: $id }) {
id
html
frontmatter {
date(formatString: "MMMM DD, YYYY")
title
description
tags
}
}
}
`

210
src/templates/product-page.js Executable file
View file

@ -0,0 +1,210 @@
import React from 'react'
import PropTypes from 'prop-types'
import Features from '../components/Features'
import Testimonials from '../components/Testimonials'
import Pricing from '../components/Pricing'
export const ProductPageTemplate = ({
image,
title,
heading,
description,
intro,
main,
testimonials,
fullImage,
pricing,
}) => (
<section className="section section--gradient">
<div className="container">
<div className="section">
<div className="columns">
<div className="column is-10 is-offset-1">
<div className="content">
<div
className="full-width-image-container margin-top-0"
style={{ backgroundImage: `url(${image})` }}
>
<h2
className="has-text-weight-bold is-size-1"
style={{
boxShadow: '0.5rem 0 0 #f40, -0.5rem 0 0 #f40',
backgroundColor: '#f40',
color: 'white',
padding: '1rem',
}}
>
{title}
</h2>
</div>
<div className="columns">
<div className="column is-7">
<h3 className="has-text-weight-semibold is-size-2">
{heading}
</h3>
<p>{description}</p>
</div>
</div>
<Features gridItems={intro.blurbs} />
<div className="columns">
<div className="column is-7">
<h3 className="has-text-weight-semibold is-size-3">
{main.heading}
</h3>
<p>{main.description}</p>
</div>
</div>
<div className="tile is-ancestor">
<div className="tile is-vertical">
<div className="tile">
<div className="tile is-parent is-vertical">
<article className="tile is-child">
<img
style={{ borderRadius: '5px' }}
src={main.image1.image}
alt={main.image1.alt}
/>
</article>
</div>
<div className="tile is-parent">
<article className="tile is-child">
<img
style={{ borderRadius: '5px' }}
src={main.image2.image}
alt={main.image2.alt}
/>
</article>
</div>
</div>
<div className="tile is-parent">
<article className="tile is-child">
<img
style={{ borderRadius: '5px' }}
src={main.image3.image}
alt={main.image3.alt}
/>
</article>
</div>
</div>
</div>
<Testimonials testimonials={testimonials} />
<div
className="full-width-image-container"
style={{ backgroundImage: `url(${fullImage})` }}
/>
<h2 className="has-text-weight-semibold is-size-2">
{pricing.heading}
</h2>
<p className="is-size-5">{pricing.description}</p>
<Pricing data={pricing.plans} />
</div>
</div>
</div>
</div>
</div>
</section>
)
ProductPageTemplate.propTypes = {
image: PropTypes.string,
title: PropTypes.string,
heading: PropTypes.string,
description: PropTypes.string,
intro: PropTypes.shape({
blurbs: PropTypes.array,
}),
main: PropTypes.shape({
heading: PropTypes.string,
description: PropTypes.string,
image1: PropTypes.object,
image2: PropTypes.object,
image3: PropTypes.object,
}),
testimonials: PropTypes.array,
fullImage: PropTypes.string,
pricing: PropTypes.shape({
heading: PropTypes.string,
description: PropTypes.string,
plans: PropTypes.array,
}),
}
const ProductPage = ({ data }) => {
const { frontmatter } = data.markdownRemark
return (
<ProductPageTemplate
image={frontmatter.image}
title={frontmatter.title}
heading={frontmatter.heading}
description={frontmatter.description}
intro={frontmatter.intro}
main={frontmatter.main}
testimonials={frontmatter.testimonials}
fullImage={frontmatter.full_image}
pricing={frontmatter.pricing}
/>
)
}
ProductPage.propTypes = {
data: PropTypes.shape({
markdownRemark: PropTypes.shape({
frontmatter: PropTypes.object,
}),
}),
}
export default ProductPage
export const productPageQuery = graphql`
query ProductPage($id: String!) {
markdownRemark(id: { eq: $id }) {
frontmatter {
title
image
heading
description
intro {
blurbs {
image
text
}
heading
description
}
main {
heading
description
image1 {
alt
image
}
image2 {
alt
image
}
image3 {
alt
image
}
}
testimonials {
author
quote
}
full_image
pricing {
heading
description
plans {
description
items
plan
price
}
}
}
}
}
`

71
src/templates/tags.js Executable file
View file

@ -0,0 +1,71 @@
import React from 'react'
import Helmet from 'react-helmet'
import Link from 'gatsby-link'
class TagRoute extends React.Component {
render() {
const posts = this.props.data.allMarkdownRemark.edges
const postLinks = posts.map(post => (
<li key={post.node.fields.slug}>
<Link to={post.node.fields.slug}>
<h2 className="is-size-2">{post.node.frontmatter.title}</h2>
</Link>
</li>
))
const tag = this.props.pathContext.tag
const title = this.props.data.site.siteMetadata.title
const totalCount = this.props.data.allMarkdownRemark.totalCount
const tagHeader = `${totalCount} post${
totalCount === 1 ? '' : 's'
} tagged with ${tag}`
return (
<section className="section">
<Helmet title={`${tag} | ${title}`} />
<div className="container content">
<div className="columns">
<div
className="column is-10 is-offset-1"
style={{ marginBottom: '6rem' }}
>
<h3 className="title is-size-4 is-bold-light">{tagHeader}</h3>
<ul className="taglist">{postLinks}</ul>
<p>
<Link to="/tags/">Browse all tags</Link>
</p>
</div>
</div>
</div>
</section>
)
}
}
export default TagRoute
export const tagPageQuery = graphql`
query TagPage($tag: String) {
site {
siteMetadata {
title
}
}
allMarkdownRemark(
limit: 1000
sort: { fields: [frontmatter___date], order: DESC }
filter: { frontmatter: { tags: { in: [$tag] } } }
) {
totalCount
edges {
node {
fields {
slug
}
frontmatter {
title
}
}
}
}
}
`

45
static/admin/config.yml Executable file
View file

@ -0,0 +1,45 @@
backend:
name: git-gateway
branch: master
media_folder: static/img
public_folder: /img
collections:
- name: "blog"
label: "Blog"
folder: "src/pages/blog"
create: true
slug: "{{year}}-{{month}}-{{day}}-{{slug}}"
fields:
- {label: "Template Key", name: "templateKey", widget: "hidden", default: "blog-post"}
- {label: "Title", name: "title", widget: "string"}
- {label: "Publish Date", name: "date", widget: "datetime"}
- {label: "Description", name: "description", widget: "text"}
- {label: "Body", name: "body", widget: "markdown"}
- {label: "Tags", name: "tags", widget: "list"}
- name: "pages"
label: "Pages"
files:
- file: "src/pages/about/index.md"
label: "About"
name: "about"
fields:
- {label: "Template Key", name: "templateKey", widget: "hidden", default: "about-page"}
- {label: "Title", name: "title", widget: "string"}
- {label: "Body", name: "body", widget: "markdown"}
- file: "src/pages/products/index.md"
label: "Products Page"
name: "products"
fields:
- {label: "Template Key", name: "templateKey", widget: "hidden", default: "product-page"}
- {label: Title, name: title, widget: string}
- {label: Image, name: image, widget: image}
- {label: Heading, name: heading, widget: string}
- {label: Description, name: description, widget: string}
- {label: Intro, name: intro, widget: object, fields: [{label: Heading, name: heading, widget: string}, {label: Description, name: description, widget: text}, {label: Blurbs, name: blurbs, widget: list, fields: [{label: Image, name: image, widget: image}, {label: Text, name: text, widget: text}]}]}
- {label: Main, name: main, widget: object, fields: [{label: Heading, name: heading, widget: string}, {label: Description, name: description, widget: text}, {label: Image1, name: image1, widget: object, fields: [{label: Image, name: image, widget: image}, {label: Alt, name: alt, widget: string}]}, {label: Image2, name: image2, widget: object, fields: [{label: Image, name: image, widget: image}, {label: Alt, name: alt, widget: string}]}, {label: Image3, name: image3, widget: object, fields: [{label: Image, name: image, widget: image}, {label: Alt, name: alt, widget: string}]}]}
- {label: Testimonials, name: testimonials, widget: list, fields: [{label: Quote, name: quote, widget: string}, {label: Author, name: author, widget: string}]}
- {label: Full_image, name: full_image, widget: image}
- {label: Pricing, name: pricing, widget: object, fields: [{label: Heading, name: heading, widget: string}, {label: Description, name: description, widget: string}, {label: Plans, name: plans, widget: list, fields: [{label: Plan, name: plan, widget: string}, {label: Price, name: price, widget: string}, {label: Description, name: description, widget: string}, {label: Items, name: items, widget: list}]}]}

BIN
static/img/chemex.jpg Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 143 KiB

BIN
static/img/coffee-gear.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

BIN
static/img/coffee.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

BIN
static/img/flavor_wheel.jpg Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

BIN
static/img/jumbotron.jpg Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 133 KiB

BIN
static/img/meeting-space.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 212 KiB

BIN
static/img/products-grid1.jpg Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 322 KiB

BIN
static/img/products-grid2.jpg Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 162 KiB

BIN
static/img/products-grid3.jpg Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 146 KiB

BIN
static/img/tutorials.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

11390
yarn.lock Executable file

File diff suppressed because it is too large Load diff