From 880ee2997bf1550a4a72b3c14504a67cde320e66 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt <sean@lbry.io> Date: Sat, 27 Mar 2021 19:33:47 -0400 Subject: [PATCH] email working --- pages/api/email.js | 53 ++++++++++++++++++++++++++++++ pages/index.js | 80 ++++++++++++++++++++++++++++++++++++++++----- styles/globals.scss | 23 +++++++++---- 3 files changed, 142 insertions(+), 14 deletions(-) create mode 100644 pages/api/email.js diff --git a/pages/api/email.js b/pages/api/email.js new file mode 100644 index 0000000..27ad563 --- /dev/null +++ b/pages/api/email.js @@ -0,0 +1,53 @@ +import { renderSync } from 'sass'; + +const AUTH_TOKEN = process.env.COMMANDER_AUTH_TOKEN; +const API = 'https://api.lbry.com/'; +const USER_TAG = 'lbry-sec'; + +const USER_DOES_NOT_EXIST = 'USER_DOES_NOT_EXIST'; + +function buildUrl(email, createUser) { + let url = `${API}/users/tag?auth_token=${AUTH_TOKEN}&emails=${encodeURIComponent( + email + )}&tag=${USER_TAG}`; + + if (createUser) { + url += `&create_user=true`; + } + + return url; +} + +export default (req, res) => { + const { email } = req.body; + + if (!email) { + res.statusCode = 400; + res.json({ error: true }); + return; + } + + return fetch(buildUrl(email)) + .then((res) => res.json()) + .then((res) => { + if (res.data && res.data.failed_emails.length > 0) { + throw Error(USER_DOES_NOT_EXIST); + } + + res.statusCode = 200; + res.json({ success: true }); + }) + .catch((error) => { + if (error.message === USER_DOES_NOT_EXIST) { + return fetch(buildUrl(email, true)) + .then((res) => res.json()) + .then((data) => { + res.statusCode = 200; + res.json({ success: true }); + }); + } + + res.statusCode = 400; + res.json({ error }); + }); +}; diff --git a/pages/index.js b/pages/index.js index 73b173b..da39a3b 100644 --- a/pages/index.js +++ b/pages/index.js @@ -1,6 +1,49 @@ +import React from 'react'; import Head from 'next/head'; export default function Home() { + const [email, setEmail] = React.useState(''); + const [emailLoading, setEmailLoading] = React.useState(false); + const [emailError, setEmailError] = React.useState(); + const [emailSuccess, setEmailSuccess] = React.useState(); + + function handleEmailSubmit(e) { + e.preventDefault(); + + if (!email) { + return; + } + + setEmailError(false); + setEmailSuccess(false); + setEmailLoading(true); + + fetch('/api/email', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + email, + }), + }) + .then((res) => { + if (res.status >= 200 && res.status < 300) { + return res.json(); + } else { + throw Error(res.error); + } + }) + .then((data) => { + setEmailLoading(false); + setEmailSuccess(true); + }) + .catch(() => { + setEmailLoading(false); + setEmailSuccess(false); + setEmailError(true); + }); + } return ( <div> <Head> @@ -27,15 +70,19 @@ export default function Home() { <div className="landing__text"> <h1 className="landing__title"> - Save LBRY + HELP LBRY <br /> - Save Crypto + SAVE CRYPTO </h1> <div className="landing__subtitle"> - <div>Some catchy subtitle that says some different things.</div> - <div className="landing__subtitle-catchy"> - <span>The SEC are dorks.</span> + <div> + The SEC don’t understand blockchain or crypto. + <br /> + They’re saying LBC is a security, it’s not! </div> + <button className="landing__action"> + <span>Educate the SEC</span> + </button> </div> </div> @@ -74,14 +121,29 @@ export default function Home() { </div> <label htmlFor="email">Email</label> - <div className="email__group"> + <form className="email__group" onSubmit={handleEmailSubmit}> <input type="email" name="email" placeholder="ihatecensorship@protonmail.com" + value={email} + onChange={(e) => setEmail(e.target.value)} /> - <button>Submit</button> - </div> + <button disabled={!email || emailLoading}> + {emailLoading ? 'Submitting' : 'Submit'} + </button> + </form> + + {emailSuccess && ( + <div className="email__success"> + Thank you! We will keep you in the loop. + </div> + )} + {emailError && ( + <div className="email__success"> + Sorry, there was an error. Please try again. + </div> + )} </div> <h2>Sign the petition</h2> @@ -90,6 +152,8 @@ export default function Home() { </div> <div className="petition">Petition iframe or link</div> + + <h2>See what people are saying</h2> </div> </main> </div> diff --git a/styles/globals.scss b/styles/globals.scss index cf3ec85..023548f 100644 --- a/styles/globals.scss +++ b/styles/globals.scss @@ -6,6 +6,7 @@ $border-radius: 10px; html, body { + font-size: 16px; padding: 0; margin: 0; font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, @@ -119,24 +120,26 @@ header { font-weight: 300; @media (min-width: $breakpoint-small) { - font-size: 2rem; + font-size: 1.8rem; } } -.landing__subtitle-catchy { +.landing__action { margin-top: 1.5rem; font-weight: bolder; - transform: skew(-10deg); display: inline-block; background-color: #5726ab; color: white; padding: 0.75rem; margin-top: 2rem; + font-weight: 700; + font-size: 1.5rem; + padding: 1.5rem; + border-radius: 10px; - span { - font-weight: 700; - transform: skew(10deg); + &:hover { + opacity: 0.9; } } @@ -203,6 +206,7 @@ header { label { font-size: 1rem; + font-weight: 700; } @media (min-width: $breakpoint-small) { @@ -263,6 +267,13 @@ header { } } +.email__success, +.email__error { + font-size: 1rem; + margin-top: 0.5rem; + margin-bottom: -0.5rem; +} + .petition { height: 30rem; padding: 5rem;