From 253e3be3093d18f93611a027499cbbcc2bcfe8cf Mon Sep 17 00:00:00 2001
From: benjamin hoffman <6520022+benjaminhoffman@users.noreply.github.com>
Date: Sun, 24 Dec 2017 15:18:47 -0800
Subject: [PATCH 1/6] Adds email capture to bottom of blog
---
www/src/components/email-capture-form.js | 77 ++++++++++++++++++++++++
www/src/templates/template-blog-post.js | 2 +
2 files changed, 79 insertions(+)
create mode 100644 www/src/components/email-capture-form.js
diff --git a/www/src/components/email-capture-form.js b/www/src/components/email-capture-form.js
new file mode 100644
index 0000000000000..25e8b0a5b280a
--- /dev/null
+++ b/www/src/components/email-capture-form.js
@@ -0,0 +1,77 @@
+import React from "react"
+import { rhythm } from "../utils/typography"
+import presets from "../utils/presets"
+
+class EmailCaptureForm extends React.Component {
+ constructor() {
+ super()
+ this.state = {
+ email: ``,
+ }
+ }
+
+ render() {
+ return (
+
Date: Sun, 24 Dec 2017 15:18:47 -0800
Subject: [PATCH 2/6] Adds email capture to bottom of blog
---
www/src/components/email-capture-form.js | 77 ++++++++++++++++++++++++
www/src/templates/template-blog-post.js | 2 +
2 files changed, 79 insertions(+)
create mode 100644 www/src/components/email-capture-form.js
diff --git a/www/src/components/email-capture-form.js b/www/src/components/email-capture-form.js
new file mode 100644
index 0000000000000..25e8b0a5b280a
--- /dev/null
+++ b/www/src/components/email-capture-form.js
@@ -0,0 +1,77 @@
+import React from "react"
+import { rhythm } from "../utils/typography"
+import presets from "../utils/presets"
+
+class EmailCaptureForm extends React.Component {
+ constructor() {
+ super()
+ this.state = {
+ email: ``,
+ }
+ }
+
+ render() {
+ return (
+
+ Enjoyed this post? Receive the next in your inbox!
+
+
+
+ )
+ }
+}
+
+export default EmailCaptureForm
diff --git a/www/src/templates/template-blog-post.js b/www/src/templates/template-blog-post.js
index ffebb0cbae324..1579432fe96f4 100644
--- a/www/src/templates/template-blog-post.js
+++ b/www/src/templates/template-blog-post.js
@@ -8,6 +8,7 @@ import Img from "gatsby-image"
import presets from "../utils/presets"
import typography, { rhythm, scale, options } from "../utils/typography"
import Container from "../components/container"
+import EmailCaptureForm from '../components/email-capture-form'
class BlogPostTemplate extends React.Component {
render() {
@@ -200,6 +201,7 @@ class BlogPostTemplate extends React.Component {
__html: this.props.data.markdownRemark.html,
}}
/>
+
Date: Thu, 28 Dec 2017 11:52:59 -0800
Subject: [PATCH 3/6] Adds Mailchimp functionality
---
www/package.json | 1 +
www/src/components/email-capture-form.js | 176 ++++++++++++++++-------
2 files changed, 123 insertions(+), 54 deletions(-)
diff --git a/www/package.json b/www/package.json
index 106f4eee86da8..dbe46803004e3 100644
--- a/www/package.json
+++ b/www/package.json
@@ -38,6 +38,7 @@
"gatsby-transformer-yaml": "^1.5.7",
"graphql-request": "^1.4.0",
"gray-percentage": "^2.0.0",
+ "jsonp": "^0.2.1",
"limax": "^1.5.0",
"lodash": "^4.16.6",
"mitt": "^1.1.2",
diff --git a/www/src/components/email-capture-form.js b/www/src/components/email-capture-form.js
index 25e8b0a5b280a..f54c33bc352c6 100644
--- a/www/src/components/email-capture-form.js
+++ b/www/src/components/email-capture-form.js
@@ -1,13 +1,84 @@
import React from "react"
import { rhythm } from "../utils/typography"
import presets from "../utils/presets"
+import jsonp from "jsonp"
+
+// Mailchimp endpoint
+// From: https://us17.admin.mailchimp.com/lists/integration/embeddedcode?id=XXXXXX
+// Where `XXXXXX` is the MC list ID
+// Note: we change `/post` to `/post-json`
+const MAILCHIMP_URL = `https://gatsbyjs.us17.list-manage.com/subscribe/post-json?u=1dc33f19eb115f7ebe4afe5ee&id=f366064ba7`
class EmailCaptureForm extends React.Component {
- constructor() {
- super()
- this.state = {
- email: ``,
+ state = {
+ email: ``,
+ }
+
+ // Update state each time user edits their email address
+ _handleEmailChange = e => {
+ this.setState({ email: e.target.value })
+ }
+
+ // Check whether the email address is valid
+ // 1) not an empty string
+ // 2) greater than 5 characters
+ // 3) includes both a `@` and `.`
+ _isValidEmailAddress = email =>
+ !!email && email.length > 5 && (email.includes(`@`) && email.includes(`.`))
+
+ _handleFormSubmit = e => {
+ e.preventDefault()
+ e.stopPropagation()
+
+ // If email is not valid, break early
+ if (!this._isValidEmailAddress(this.state.email)) {
+ this.setState({
+ status: `error`,
+ msg: `${this.state.email} is not a valid email address`,
+ })
+ return
}
+
+ // Construct the url for our jsonp request
+ // Query params must be in CAPS
+ const url = `${MAILCHIMP_URL}
+ &EMAIL=${encodeURIComponent(this.state.email)}
+ &PATHNAME=${window.location.pathname}
+ `
+
+ this.setState(
+ {
+ msg: null,
+ status: `sending`,
+ },
+ // setState callback (jsonp)
+ () =>
+ jsonp(
+ url,
+ {
+ param: `c`,
+ },
+ // jsonp callback
+ (err, data) => {
+ if (err) {
+ this.setState({
+ status: `error`,
+ msg: err,
+ })
+ } else if (data.result !== `success`) {
+ this.setState({
+ status: `error`,
+ msg: data.msg,
+ })
+ } else {
+ this.setState({
+ status: `success`,
+ msg: data.msg,
+ })
+ }
+ }
+ )
+ )
}
render() {
@@ -17,58 +88,55 @@ class EmailCaptureForm extends React.Component {
border: `2px solid ${presets.brand}`,
backgroundColor: presets.veryLightPurple,
borderRadius: `4px`,
- padding: `${rhythm(0.75)} 0 0 ${rhythm(0.75)}`,
+ padding: `${rhythm(0.75)}`,
}}
- >
- Enjoyed this post? Receive the next in your inbox!
-
-
+ {this.state.status === `success` ? (
+
Thank you! Youʼll receive your first email shortly.
+ ) : (
+
+ Enjoyed this post? Receive the next one in your inbox!
+
+
+
+ )}
)
}
From 3066ff513a7039005e220aca4f2e14af27a56430 Mon Sep 17 00:00:00 2001
From: benjamin hoffman <6520022+benjaminhoffman@users.noreply.github.com>
Date: Sat, 30 Dec 2017 17:00:13 -0800
Subject: [PATCH 4/6] Refactors postEmailToMailchimp method, updates cc
---
www/src/components/email-capture-form.js | 155 +++++++++++++----------
1 file changed, 85 insertions(+), 70 deletions(-)
diff --git a/www/src/components/email-capture-form.js b/www/src/components/email-capture-form.js
index 842a533888605..085afa6a49eb0 100644
--- a/www/src/components/email-capture-form.js
+++ b/www/src/components/email-capture-form.js
@@ -10,8 +10,11 @@ import jsonp from "jsonp"
const MAILCHIMP_URL = `https://gatsbyjs.us17.list-manage.com/subscribe/post-json?u=1dc33f19eb115f7ebe4afe5ee&id=f366064ba7`
class EmailCaptureForm extends React.Component {
- state = {
- email: ``,
+ constructor() {
+ super()
+ this.state = {
+ email: ``,
+ }
}
// Update state each time user edits their email address
@@ -20,12 +23,42 @@ class EmailCaptureForm extends React.Component {
}
// Check whether the email address is valid:
- // not an empty string,
- // greater than 5 characters,
- // includes both `@` and `.`
+ // - not an empty string,
+ // - greater than 5 characters,
+ // - includes both `@` and `.`
_isValidEmailAddress = email =>
!!email && email.length > 5 && (email.includes(`@`) && email.includes(`.`))
+ // Using jsonp, post to MC server & handle its response
+ _postEmailToMailchimp = url => {
+ // jsonp lib takes an `endpoint`, {options}, & callback
+ jsonp(url, { param: `c` }, (err, data) => {
+ // network failures, timeouts, etc
+ if (err) {
+ this.setState({
+ status: `error`,
+ msg: err,
+ })
+
+ // Mailchimp errors & failures
+ } else if (data.result !== `success`) {
+ this.setState({
+ status: `error`,
+ msg: data.msg,
+ })
+
+ // Posted email successfully to Mailchimp
+ } else {
+ this.setState({
+ status: `success`,
+ msg: data.msg,
+ })
+ }
+ })
+ }
+
+ // On form submit, validate email
+ // then jsonp to Mailchimp, and update state
_handleFormSubmit = e => {
e.preventDefault()
e.stopPropagation()
@@ -34,13 +67,14 @@ class EmailCaptureForm extends React.Component {
if (!this._isValidEmailAddress(this.state.email)) {
this.setState({
status: `error`,
- msg: `${this.state.email} is not a valid email address`,
+ msg: `"${this.state.email}" is not a valid email address`,
})
return
}
// Construct the url for our jsonp request
// Query params must be in CAPS
+ // Capture pathname for better email targeting
const url = `${MAILCHIMP_URL}
&EMAIL=${encodeURIComponent(this.state.email)}
&PATHNAME=${window.location.pathname}
@@ -51,33 +85,8 @@ class EmailCaptureForm extends React.Component {
msg: null,
status: `sending`,
},
- // setState callback (jsonp)
- () =>
- jsonp(
- url,
- {
- param: `c`,
- },
- // jsonp callback
- (err, data) => {
- if (err) {
- this.setState({
- status: `error`,
- msg: err,
- })
- } else if (data.result !== `success`) {
- this.setState({
- status: `error`,
- msg: data.msg,
- })
- } else {
- this.setState({
- status: `success`,
- msg: data.msg,
- })
- }
- }
- )
+ // jsonp request as setState callback
+ this._postEmailToMailchimp(url)
)
}
@@ -90,50 +99,56 @@ class EmailCaptureForm extends React.Component {
borderRadius: `4px`,
padding: `${rhythm(0.75)}`,
}}
- >
+ >
{this.state.status === `success` ? (
Thank you! Youʼll receive your first email shortly.
) : (
Enjoyed this post? Receive the next one in your inbox!
-
)}
From 0d6f9f91d6e0946790fdb9a0b67b334353b90b9e Mon Sep 17 00:00:00 2001
From: benjamin hoffman <6520022+benjaminhoffman@users.noreply.github.com>
Date: Wed, 3 Jan 2018 20:36:56 -0800
Subject: [PATCH 5/6] updates rhythm css, installs & uses validator module
---
www/package.json | 3 ++-
www/src/components/email-capture-form.js | 32 ++++++++++--------------
2 files changed, 15 insertions(+), 20 deletions(-)
diff --git a/www/package.json b/www/package.json
index dbe46803004e3..4b3cee1d28ad6 100644
--- a/www/package.json
+++ b/www/package.json
@@ -48,7 +48,8 @@
"typeface-space-mono": "^0.0.40",
"typeface-spectral": "^0.0.40",
"typography-breakpoint-constants": "^0.15.10",
- "typography-plugin-code": "^0.16.11"
+ "typography-plugin-code": "^0.16.11",
+ "validator": "^9.2.0"
},
"keywords": [
"gatsby"
diff --git a/www/src/components/email-capture-form.js b/www/src/components/email-capture-form.js
index 085afa6a49eb0..89634ccaef5b6 100644
--- a/www/src/components/email-capture-form.js
+++ b/www/src/components/email-capture-form.js
@@ -2,6 +2,7 @@ import React from "react"
import { rhythm } from "../utils/typography"
import presets from "../utils/presets"
import jsonp from "jsonp"
+import { validate } from "email-validator"
// Mailchimp endpoint
// From: https://us17.admin.mailchimp.com/lists/integration/embeddedcode?id=XXXXXX
@@ -22,13 +23,6 @@ class EmailCaptureForm extends React.Component {
this.setState({ email: e.target.value })
}
- // Check whether the email address is valid:
- // - not an empty string,
- // - greater than 5 characters,
- // - includes both `@` and `.`
- _isValidEmailAddress = email =>
- !!email && email.length > 5 && (email.includes(`@`) && email.includes(`.`))
-
// Using jsonp, post to MC server & handle its response
_postEmailToMailchimp = url => {
// jsonp lib takes an `endpoint`, {options}, & callback
@@ -40,14 +34,14 @@ class EmailCaptureForm extends React.Component {
msg: err,
})
- // Mailchimp errors & failures
+ // Mailchimp errors & failures
} else if (data.result !== `success`) {
this.setState({
status: `error`,
msg: data.msg,
})
- // Posted email successfully to Mailchimp
+ // Posted email successfully to Mailchimp
} else {
this.setState({
status: `success`,
@@ -64,7 +58,7 @@ class EmailCaptureForm extends React.Component {
e.stopPropagation()
// If email is not valid, break early
- if (!this._isValidEmailAddress(this.state.email)) {
+ if (!validate(this.state.email)) {
this.setState({
status: `error`,
msg: `"${this.state.email}" is not a valid email address`,
@@ -97,7 +91,7 @@ class EmailCaptureForm extends React.Component {
border: `2px solid ${presets.brand}`,
backgroundColor: presets.veryLightPurple,
borderRadius: `4px`,
- padding: `${rhythm(0.75)}`,
+ padding: `${rhythm(1 / 2)}`,
}}
>
{this.state.status === `success` ? (
@@ -119,10 +113,10 @@ class EmailCaptureForm extends React.Component {
placeholder="you@email.com"
onChange={this._handleEmailChange}
css={{
- marginTop: rhythm(0.3),
- padding: `${rhythm(0.3)} ${rhythm(0.3)} ${rhythm(
- 0.3
- )} ${rhythm(0.7)}`,
+ marginTop: rhythm(1 / 4),
+ padding: `${rhythm(1 / 4)} ${rhythm(1 / 4)} ${rhythm(
+ 1 / 4
+ )} ${rhythm(1 / 2)}`,
width: `250px`,
color: presets.bodyColor,
}}
@@ -132,12 +126,12 @@ class EmailCaptureForm extends React.Component {
onClick={this._handleFormSubmit}
css={{
borderRadius: `2px`,
- border: `2px solid ${presets.brand}`,
+ border: `${rhythm(1 / 4)} solid ${presets.brand}`,
backgroundColor: presets.brand,
height: `43px`,
cursor: `pointer`,
- padding: `0 ${rhythm(0.75)} 0 ${rhythm(0.75)}`,
- margin: `${rhythm(0.75)} 0 0 ${rhythm(0.75)}`,
+ padding: `0 ${rhythm(1 / 2)} 0 ${rhythm(1 / 2)}`,
+ margin: `${rhythm(1 / 2)} 0 0 ${rhythm(1 / 2)}`,
}}
>
Subscribe
@@ -145,7 +139,7 @@ class EmailCaptureForm extends React.Component {
{this.state.status === `error` && (
)}
From 00b2fd8b9d7169c3c7728bea40e0e59be9aaaaf8 Mon Sep 17 00:00:00 2001
From: Kyle Mathews