add EmailSubscribe component

main
Mike Fix 5 years ago
parent 03bf53a8c2
commit e432dadd8b
No known key found for this signature in database
GPG Key ID: 1D85E862314CA79F

@ -0,0 +1,173 @@
import React from 'react'
import MailchimpSubscribe from 'react-mailchimp-subscribe'
import { validate } from 'email-validator'
import { useKeyboardListener } from 'actionsack'
import Input from './Input'
import Button from './Button'
import { COLORS } from '../lib/constants'
const Error = ({ message = 'something went wrong' }) => {
if (
message.indexOf &&
message.indexOf('The domain portion of the email address is invalid') > -1
) {
message = `Oh no, that's not a valid email!`
}
if (message.indexOf && message.indexOf('is already subscribed')) {
message = message.split('<a')[0] // cut off 'Click to subscribe link'
}
return (
<span>
{message}
<style jsx>{`
span {
position: absolute;
bottom: 2.75rem;
font-size: 12px;
color: ${COLORS.RED};
text-align: left;
}
`}</style>
</span>
)
}
const Form = ({ message, subscribe, error }) => {
const [email, setEmail] = React.useState('')
const [showError, setShowError] = React.useState(true)
const disabled = !validate(email)
return (
<form
className="subscribe-form"
onSubmit={e => {
e.preventDefault()
subscribe({ EMAIL: email })
}}
>
<Input
type="email"
name="email"
placeholder="Email address"
onChange={e => {
setEmail(e.target.value)
setShowError(false)
}}
/>
<Button hoverBackground={COLORS.BLACK} disabled={disabled}>
<span>subscribe</span>
</Button>
{error && showError && <Error message={message} />}
<style jsx>
{`
span {
font-size: 14px;
}
form {
display: flex;
}
:global(button) > span {
color: ${disabled ? 'rgba(255, 255, 255, 0.5)' : '#fff'};
}
form > :global(input) {
text-align: left;
margin-right: 1rem;
font-size: 14px;
}
form > :global(input:-webkit-autofill) {
background-clip: content-box;
-webkit-text-fill-color: #fff;
-webkit-box-shadow: 0 0 0px 1000px ${COLORS.BLACK} inset;
}
form > :global(input:-webkit-autofill::selection) {
-webkit-text-fill-color: #000;
-webkit-box-shadow: 0 0 0px 1000px #fff inset;
}
`}
</style>
</form>
)
}
const EmailSubscribe = () => {
const [open, setOpen] = React.useState(false)
useKeyboardListener('Escape', () => setOpen(false))
if (!process.env.NEXT_PUBLIC_MAILCHIMP_URL) {
return null
}
return (
<div className="container link">
<button
onClick={e => {
e.preventDefault()
setOpen(true)
}}
>
mailing list
</button>
{open && (
<MailchimpSubscribe
url={process.env.NEXT_PUBLIC_MAILCHIMP_URL}
render={({ status, ...props }) => {
const success = status === 'success'
const loading = status === 'sending'
const error = status === 'error'
return (
<div className="subscribe-container">
{loading || success ? (
<span>{loading ? 'loading...' : 'subscribed!'}</span>
) : (
<Form {...props} error={error} />
)}
</div>
)
}}
/>
)}
<style jsx>
{`
button {
padding: 0;
border: none;
color: white;
background: none;
font-size: 100%;
cursor: pointer;
visibility: ${open ? 'hidden' : 'visible'};
}
button:hover {
color: ${COLORS.PRIMARY};
}
span {
font-size: 14px;
}
.container {
display: inline-block;
position: relative;
${open ? 'background: none; margin-top: -2px;' : ''};
margin-right: 1rem;
padding-bottom: 2px;
}
.subscribe-container {
position: absolute;
top: -0.5rem;
justify-content: space-between;
border: 1px solid #fff;
border-radius: 3px;
padding: 0.5rem 1rem;
width: 15rem;
text-align: center;
/* TODO remove these styles after fixing footer */
background: ${COLORS.BLACK};
z-index: 3;
}
`}
</style>
</div>
)
}
export default EmailSubscribe

@ -1,7 +1,13 @@
import React from 'react'
import Link from 'next/link'
import dynamic from 'next/dynamic'
import { COLORS } from '../lib/constants'
const EmailSubscribe = dynamic(() => import('./EmailSubscribe'), {
loading: () => null,
})
const Footer = () => (
<footer role="contentinfo" className="mt3">
<nav className="mt3">
@ -22,6 +28,7 @@ const Footer = () => (
<a className="link" href="/privacy">
privacy
</a>
<EmailSubscribe />
<a className="link" href="/offsets">
offsets
</a>

@ -32,6 +32,7 @@
"downshift": "^5.4.5",
"dropperx": "^1.0.1",
"eitherx": "^1.0.2",
"email-validator": "^2.0.4",
"escape-goat": "^3.0.0",
"firebase": "^7.15.5",
"graphql": "^15.2.0",
@ -54,6 +55,7 @@
"react-dom": "^16.13.1",
"react-image-crop": "^6.0.16",
"react-is": "^16.13.1",
"react-mailchimp-subscribe": "^2.1.0",
"react-stripe-elements": "^6.1.2",
"react-syntax-highlight": "^15.3.1",
"serialize-javascript": "^3.0.0",

@ -4264,7 +4264,7 @@ dateformat@^3.0.3:
resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-3.0.3.tgz#a6e37499a4d9a9cf85ef5872044d62901c9889ae"
integrity sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==
debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.9:
debug@2.6.9, debug@^2.1.3, debug@^2.2.0, debug@^2.3.3, debug@^2.6.9:
version "2.6.9"
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==
@ -4595,6 +4595,11 @@ elliptic@^6.0.0:
minimalistic-assert "^1.0.0"
minimalistic-crypto-utils "^1.0.0"
email-validator@^2.0.4:
version "2.0.4"
resolved "https://registry.yarnpkg.com/email-validator/-/email-validator-2.0.4.tgz#b8dfaa5d0dae28f1b03c95881d904d4e40bfe7ed"
integrity sha512-gYCwo7kh5S3IDyZPLZf6hSS0MnZT8QmJFqYvbqlDZSbwdZlY6QZWxJ4i/6UhITOJ4XzyI647Bm2MXKCLqnJ4nQ==
emoji-regex@^7.0.1:
version "7.0.3"
resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156"
@ -6617,6 +6622,13 @@ jsonfile@^4.0.0:
optionalDependencies:
graceful-fs "^4.1.6"
jsonp@^0.2.1:
version "0.2.1"
resolved "https://registry.yarnpkg.com/jsonp/-/jsonp-0.2.1.tgz#a65b4fa0f10bda719a05441ea7b94c55f3e15bae"
integrity sha1-pltPoPEL2nGaBUQep7lMVfPhW64=
dependencies:
debug "^2.1.3"
jsprim@^1.2.2:
version "1.4.1"
resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2"
@ -8876,6 +8888,15 @@ react-is@^16.3.2, react-is@^16.8.1:
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.0.tgz#0f37c3613c34fe6b37cd7f763a0d6293ab15c527"
integrity sha512-GFMtL0vHkiBv9HluwNZTggSn/sCyEt9n02aM0dSAjGGyqyNlAyftYm4phPxdvCigG15JreC5biwxCgTAJZ7yAA==
react-mailchimp-subscribe@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/react-mailchimp-subscribe/-/react-mailchimp-subscribe-2.1.0.tgz#a2bb7064af4bad310ef5d308322de95491d401c3"
integrity sha512-sBB2XW0DPlysv+aVGRHbGQqDi8WITxXFjMzWiN07/t7U3FH2Io68EMBEU7atOUk5Y/WtsVnSytcs06aoEaf5ow==
dependencies:
jsonp "^0.2.1"
prop-types "^15.5.10"
to-querystring "^1.0.4"
react-refresh@0.8.3:
version "0.8.3"
resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.8.3.tgz#721d4657672d400c5e3c75d063c4a85fb2d5d68f"
@ -10344,6 +10365,11 @@ to-object-path@^0.3.0:
dependencies:
kind-of "^3.0.2"
to-querystring@^1.0.4:
version "1.1.0"
resolved "https://registry.yarnpkg.com/to-querystring/-/to-querystring-1.1.0.tgz#31efbcebb332bcb2522de36129b4234179399fbd"
integrity sha512-nlYTDlLrE9+JJlEcoqEvOytgReSG4z8+hdHeSO8+WF4VLzF7sY5KFyIGvCEWJc0bROdMJsyhOnbPEb5R2LOI8A==
to-regex-range@^2.1.0:
version "2.1.1"
resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38"

Loading…
Cancel
Save