1
1
import React , { useState } from "react" ;
2
+ import { useStaticQuery } from "gatsby" ;
2
3
import fetch from "unfetch" ;
3
4
import styled from "styled-components" ;
5
+ import toast from "react-hot-toast" ;
4
6
import analytics from "./../utils/analytics.js" ;
5
7
8
+ function sendBytesOptIn ( { email, source } ) {
9
+ return fetch ( `https://bytes.dev/api/bytes-optin-cors` , {
10
+ method : "POST" ,
11
+ body : JSON . stringify ( { email, source } ) ,
12
+ headers : {
13
+ Accept : "application/json" ,
14
+ "Content-Type" : "application/json" ,
15
+ } ,
16
+ } ) . then ( ( res ) => res . json ( ) ) ;
17
+ }
18
+
19
+ function useBytesCount ( ) {
20
+ const {
21
+ bytes : { subcount } ,
22
+ } = useStaticQuery ( graphql `
23
+ query subCountQuery {
24
+ bytes {
25
+ subcount
26
+ }
27
+ }
28
+ ` ) ;
29
+
30
+ return subcount ;
31
+ }
32
+
6
33
const EmailSignup = ( ) => {
34
+ const subcount = useBytesCount ( ) ;
35
+ const [ isLoading , setIsLoading ] = useState ( false ) ;
7
36
const [ subscribed , setSubscribed ] = useState ( false ) ;
8
37
const [ email , setEmail ] = useState ( "" ) ;
9
38
10
39
const subscribe = ( event ) => {
11
40
event . preventDefault ( ) ;
12
41
if ( ! email ) return ;
13
- analytics . track ( "subscribe" ) ;
14
- setSubscribed ( true ) ;
15
- return fetch ( "https://usehooks-next.vercel.app/api/subscribe" , {
16
- method : "POST" ,
17
- headers : {
18
- "Content-Type" : "application/json" ,
19
- } ,
20
- body : JSON . stringify ( { email } ) ,
21
- } ) . then ( ( r ) => r . json ( ) ) ;
42
+ setIsLoading ( true ) ;
43
+ return sendBytesOptIn ( { email, source : "useHooks" } ) . then ( ( res ) => {
44
+ if ( res . error ) {
45
+ setEmail ( "" ) ;
46
+ setIsLoading ( false ) ;
47
+ return toast . error (
48
+ "There was an error. Check to see if your email is correct."
49
+ ) ;
50
+ }
51
+ analytics . track ( "subscribe" ) ;
52
+ setSubscribed ( true ) ;
53
+ setIsLoading ( false ) ;
54
+ setEmail ( "" ) ;
55
+ return toast . success ( `Check your email to confirm your subscription.` ) ;
56
+ } ) ;
22
57
} ;
23
58
24
59
return (
@@ -33,12 +68,21 @@ const EmailSignup = () => {
33
68
</ div >
34
69
) : (
35
70
< >
36
- < Title >
71
+ < h4 className = "subtitle is-5" >
37
72
< span role = "img" aria-label = "letter" >
38
73
📩
39
74
</ span >
40
- Get new recipes in your inbox
41
- </ Title >
75
+ Subscribe to Bytes
76
+ </ h4 >
77
+ < p >
78
+ Most newsletters are terrible. Thats why we created Bytes. Our
79
+ goal was to create a JavaScript newsletter that was both
80
+ educational and entertaining. < b > { subcount . toLocaleString ( ) } </ b > { " " }
81
+ subscribers and an almost 50% weekly open rate later, it looks
82
+ like we did it...
83
+ </ p >
84
+ < br />
85
+
42
86
< form onSubmit = { subscribe } >
43
87
< div className = "field has-addons" >
44
88
< div className = "control is-expanded" >
@@ -53,26 +97,28 @@ const EmailSignup = () => {
53
97
</ div >
54
98
< div className = "control" >
55
99
< button
100
+ disabled = { isLoading }
56
101
className = "button is-primary has-text-weight-semibold"
57
102
type = "submit"
58
103
>
59
- Subscribe
104
+ { isLoading ? "Loading..." : " Subscribe" }
60
105
</ button >
61
106
</ div >
62
107
</ div >
63
108
</ form >
64
- < Extra > Join 7,031 subscribers. No spam ever.</ Extra >
109
+ < Extra >
110
+ Join { subcount . toLocaleString ( ) } subscribers. No spam ever. < br />
111
+ < a href = "https://bytes.dev/archives" target = "_blank" >
112
+ See the most recent issue.
113
+ </ a >
114
+ </ Extra >
65
115
</ >
66
116
) }
67
117
</ div >
68
118
</ div >
69
119
) ;
70
120
} ;
71
121
72
- const Title = styled ( "div" ) . attrs ( { className : "subtitle is-5" } ) `
73
- margin-bottom: 1.2rem;
74
- ` ;
75
-
76
122
const Extra = styled ( "div" ) `
77
123
margin-top: 1rem;
78
124
font-size: 0.8rem;
0 commit comments