Skip to content

Commit e9e101c

Browse files
authored
feat(www): add unbird feedback component to starter lib (#10450)
add unbird feedback form component
1 parent 2eb2a17 commit e9e101c

File tree

4 files changed

+231
-1
lines changed

4 files changed

+231
-1
lines changed

www/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
"author": "Kyle Mathews <[email protected]>",
66
"dependencies": {
77
"@reach/skip-nav": "^0.1.1",
8+
"axios": "^0.18.0",
89
"bluebird": "^3.5.1",
910
"dotenv": "^6.0.0",
1011
"email-validator": "^1.1.1",

www/src/components/unbird.js

Lines changed: 223 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,223 @@
1+
import React from "react"
2+
import PropTypes from "prop-types"
3+
import axios from "axios"
4+
import styled from "react-emotion"
5+
import { rhythm, options } from "../utils/typography"
6+
import presets, { colors } from "../utils/presets"
7+
import EnvelopeFaIcon from "react-icons/lib/fa/envelope-o"
8+
import CancelMdIcon from "react-icons/lib/md/close"
9+
import SendIcon from "react-icons/lib/io/paper-airplane"
10+
11+
const FeedbackComponent = styled(`section`)`
12+
box-sizing: border-box;
13+
position: relative;
14+
`
15+
16+
const FeedbackToggle = styled(`div`)`
17+
width: 60px;
18+
height: 60px;
19+
bottom: 64px;
20+
background-color: ${colors.gatsby};
21+
color: #fff;
22+
border-radius: 100%;
23+
box-shadow: 0 1px 6px rgba(0, 0, 0, 0.06), 0 2px 32px rgba(0, 0, 0, 0.16);
24+
position: fixed;
25+
right: 20px;
26+
z-index: 99999;
27+
cursor: pointer;
28+
29+
:hover {
30+
background-color: ${colors.gatsbyDark};
31+
}
32+
33+
${presets.Tablet} {
34+
bottom: 30px;
35+
right: 30px;
36+
}
37+
`
38+
39+
const IconWrapper = styled(`div`)`
40+
align-items: center;
41+
display: flex;
42+
height: 100%;
43+
justify-content: center;
44+
width: 100%;
45+
46+
svg {
47+
height: auto;
48+
}
49+
`
50+
51+
const EnvelopeIcon = styled(EnvelopeFaIcon)`
52+
font-size: ${rhythm(1)};
53+
`
54+
const CancelIcon = styled(CancelMdIcon)`
55+
font-size: ${rhythm(1.2)};
56+
`
57+
58+
const StatusMessage = styled(`span`)`
59+
position: absolute;
60+
width: 100%;
61+
background: ${colors.gray.dark};
62+
bottom: 60px;
63+
color: #fff;
64+
font-size: 16px;
65+
padding: 0.4rem 0.8rem;
66+
text-align: left;
67+
left: 0;
68+
`
69+
70+
const FeedbackForm = styled(`div`)`
71+
position: fixed;
72+
right: 5%;
73+
bottom: 134px;
74+
width: 90%;
75+
background-color: ${colors.gatsby};
76+
box-shadow: 0 0 40px 5px rgba(0, 0, 0, 0.2);
77+
border-radius: ${presets.radiusLg}px;
78+
font-family: ${options.systemFontFamily.join(`,`)};
79+
80+
${presets.Tablet} {
81+
width: 350px;
82+
right: 30px;
83+
bottom: 100px;
84+
}
85+
`
86+
87+
const Label = styled(`label`)`
88+
font-family: ${options.headerFontFamily.join(`,`)};
89+
font-weight: 600;
90+
height: 240px;
91+
color: #fff;
92+
display: flex;
93+
justify-content: center;
94+
align-items: center;
95+
padding: 40px;
96+
font-size: 22px;
97+
float: left;
98+
`
99+
100+
const Form = styled(`form`)`
101+
margin: 0;
102+
`
103+
104+
const Input = styled(`input`)`
105+
float: left;
106+
height: 60px;
107+
width: calc(100% - 60px);
108+
font-size: 14px;
109+
padding: 20px;
110+
border: none;
111+
resize: none;
112+
border-right: 1px solid #ddd;
113+
border-radius: 0;
114+
`
115+
116+
const Send = styled(`button`)`
117+
float: left;
118+
width: 60px;
119+
height: 60px;
120+
cursor: pointer;
121+
border: none;
122+
background: #fff;
123+
padding: 0;
124+
125+
svg {
126+
width: 50%;
127+
height: auto;
128+
fill: ${colors.gatsby};
129+
}
130+
`
131+
132+
class Unbird extends React.Component {
133+
state = {
134+
visible: false,
135+
feedbackInput: ``,
136+
statusMessage: ``,
137+
}
138+
139+
static defaultProps = {
140+
feedbackPrompt: `How can we improve your experience?`,
141+
feedbackPlaceholder: `Send feedback...`,
142+
}
143+
144+
render() {
145+
return (
146+
<FeedbackComponent>
147+
<FeedbackToggle onClick={this.toggleFeedbackForm}>
148+
<IconWrapper>
149+
{this.state.visible ? <CancelIcon /> : <EnvelopeIcon />}
150+
</IconWrapper>
151+
</FeedbackToggle>
152+
153+
{this.state.visible && (
154+
<FeedbackForm>
155+
<Form autoComplete="off" onSubmit={this.submitFeedback}>
156+
<Label htmlFor="unbird-feedback">
157+
{this.props.feedbackPrompt}
158+
</Label>
159+
{this.state.statusMessage && (
160+
<StatusMessage>{this.state.statusMessage}</StatusMessage>
161+
)}
162+
<Input
163+
id="unbird-feedback"
164+
type="text"
165+
value={this.state.feedbackInput}
166+
onChange={this.handleFeedbackInput}
167+
placeholder={this.props.feedbackPlaceholder}
168+
required
169+
/>
170+
<Send>
171+
<SendIcon />
172+
</Send>
173+
</Form>
174+
</FeedbackForm>
175+
)}
176+
</FeedbackComponent>
177+
)
178+
}
179+
180+
toggleFeedbackForm = () => {
181+
this.setState({
182+
visible: !this.state.visible,
183+
statusMessage: ``,
184+
feedbackInput: ``,
185+
})
186+
}
187+
188+
handleFeedbackInput = e => {
189+
this.setState({ feedbackInput: e.target.value })
190+
}
191+
192+
setStatusMessage = msg => {
193+
this.setState({ statusMessage: msg })
194+
}
195+
196+
submitFeedback = async e => {
197+
e.preventDefault()
198+
199+
const { dataSetId, publicKey } = this.props
200+
const Unbird = `https://app.unbird.com/widget/entry/${dataSetId}/${publicKey}`
201+
202+
return axios
203+
.post(Unbird, {
204+
entry: this.state.feedbackInput,
205+
})
206+
.then(_ => {
207+
this.setStatusMessage(`Sent! Thanks :)`)
208+
this.setState({ feedbackInput: `` })
209+
})
210+
.catch(_ => {
211+
this.setStatusMessage(`Oops. Something went wrong...`)
212+
})
213+
}
214+
}
215+
216+
Unbird.propTypes = {
217+
dataSetId: PropTypes.string.isRequired,
218+
publicKey: PropTypes.string.isRequired,
219+
feedbackPrompt: PropTypes.string,
220+
feedbackPlaceholder: PropTypes.string,
221+
}
222+
223+
export default Unbird

www/src/utils/typography.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ const _options = {
9797
paddingTop: `0.2em`,
9898
paddingBottom: `0.2em`,
9999
},
100-
"tt, code, kbd, .gatsby-code-title": {
100+
"tt, code, kbd, label, .gatsby-code-title": {
101101
fontFamily: options.monospaceFontFamily.join(`,`),
102102
fontSize: `80%`,
103103
},

www/src/views/starter-library/index.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import React, { Component } from "react"
22
import Helmet from "react-helmet"
33
import Layout from "../../components/layout"
4+
import Unbird from "../../components/unbird"
45
import RRSM from "../../utils/reach-router-state-manager"
56
import queryString from "query-string"
67

@@ -55,6 +56,11 @@ class StarterLibraryPage extends Component {
5556
)}
5657
defaultSearchState={{ v: [`2`] }}
5758
/>
59+
<Unbird
60+
dataSetId="5c113a828240aa564734d954"
61+
publicKey="LCrEeIhIqPlNchPYkyXGww2azg5aCtC1"
62+
feedbackPrompt="Have feedback on the Starter Library?"
63+
/>
5864
</Layout>
5965
)
6066
}

0 commit comments

Comments
 (0)