Skip to content

Commit 39313fb

Browse files
committed
Add newsletter form api
1 parent a3f2308 commit 39313fb

File tree

6 files changed

+328
-249
lines changed

6 files changed

+328
-249
lines changed

.env

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
REACT_APP_HUBSPOT_PORTAL_ID=25945010
2+
REACT_APP_HUBSPOT_FORM_GUID=991e2a09-77c2-4428-9242-ebf26bfc6c64

jsconfig.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
{
22
"compilerOptions": {
3-
"baseUrl": "src"
3+
"baseUrl": "src",
4+
"jsx": "react"
45
},
56
"include": ["src"]
67
}

src/components/NewsletterForm.jsx

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
import React from 'react'
2+
import styled from 'styled-components'
3+
4+
import useNewsletter from 'hooks/useNewsletter'
5+
6+
const Input = styled.input`
7+
width: 100%;
8+
padding: 0.75rem 1rem;
9+
border: 1px solid ${(p) => p.theme.colors.gray[8]};
10+
border-radius: 8px;
11+
font-size: 0.875rem;
12+
color: ${(p) => p.theme.colors.gray[0]};
13+
background: ${(p) => p.theme.colors.white};
14+
margin: 1rem 0;
15+
16+
&:focus {
17+
outline: none;
18+
border-color: ${(p) => p.theme.colors.main.default};
19+
}
20+
21+
&::placeholder {
22+
color: ${(p) => p.theme.colors.gray[6]};
23+
}
24+
`
25+
26+
const Button = styled.button`
27+
width: 100%;
28+
padding: 0.75rem 1rem;
29+
background: ${(p) => p.theme.colors.main.default};
30+
color: white;
31+
border: none;
32+
border-radius: 8px;
33+
font-size: 0.875rem;
34+
font-weight: 600;
35+
cursor: pointer;
36+
transition: background-color 0.2s;
37+
38+
&:hover {
39+
background: ${(p) => p.theme.colors.main.dark};
40+
}
41+
`
42+
43+
const NewsletterForm = () => {
44+
const [email, setEmail] = React.useState('')
45+
const { subscribe } = useNewsletter()
46+
const [status, setStatus] = React.useState('idle')
47+
48+
const handleSubmit = (e) => {
49+
e.preventDefault()
50+
setStatus('loading')
51+
subscribe(email)
52+
.then(() => setStatus('success'))
53+
.catch(() => setStatus('error'))
54+
}
55+
56+
return (
57+
<form onSubmit={handleSubmit}>
58+
<Input
59+
type="email"
60+
placeholder="Enter your email"
61+
value={email}
62+
onChange={(e) => setEmail(e.target.value)}
63+
disabled={status === 'loading'}
64+
required
65+
/>
66+
<Button type="submit">Subscribe</Button>
67+
{status === 'loading' && <p>Loading...</p>}
68+
{status === 'success' && <p>Success!</p>}
69+
{status === 'error' && <p>Error</p>}
70+
</form>
71+
)
72+
}
73+
74+
export default NewsletterForm

src/components/RightPanel.jsx

Lines changed: 193 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
1+
import React from 'react'
2+
import styled from 'styled-components'
3+
import Link from 'components/Link'
4+
import Typography from 'components/Typography'
5+
import AcademicHatIcon from 'components/icons/heroicons/AcademicHatIcon'
6+
import LifebuoyIcon from 'components/icons/heroicons/LifebuoyIcon'
7+
import ChatBubbleIcon from 'components/icons/heroicons/ChatBubbleIcon'
8+
import MenuBarsIcon from 'components/icons/heroicons/MenuBarsIcon'
9+
import NewsletterForm from 'components/NewsletterForm'
10+
11+
const PanelWrapper = styled.div`
12+
position: fixed;
13+
top: 0;
14+
right: 0;
15+
width: 430px;
16+
height: 100vh;
17+
background: ${(p) => p.theme.colors.white};
18+
box-shadow: -2px 0 5px rgba(0, 0, 0, 0.1);
19+
transform: translateX(${({ isOpen }) => (isOpen ? '0' : '100%')});
20+
transition: transform 0.3s ease-in-out;
21+
padding: 2rem 2.5rem;
22+
z-index: 10;
23+
`
24+
25+
const Title = styled.h2`
26+
color: ${(p) => p.theme.colors.main.default};
27+
font-size: 1.5rem;
28+
font-weight: 600;
29+
margin: 0;
30+
`
31+
32+
const SectionTitle = styled.h3`
33+
color: ${(p) => p.theme.colors.gray[0]};
34+
font-weight: 600;
35+
margin-bottom: 2rem;
36+
`
37+
38+
const Header = styled.div`
39+
display: flex;
40+
align-items: center;
41+
justify-content: space-between;
42+
height: 3rem;
43+
margin-bottom: 2rem;
44+
`
45+
46+
const CloseButton = styled.button`
47+
background: none;
48+
border: none;
49+
cursor: pointer;
50+
font-size: 2rem;
51+
color: ${(p) => p.theme.colors.gray[0]};
52+
padding: 0;
53+
display: flex;
54+
align-items: center;
55+
justify-content: center;
56+
57+
svg {
58+
width: 24px;
59+
height: 24px;
60+
color: ${(p) => p.theme.colors.gray[0]};
61+
}
62+
`
63+
64+
const HelpLink = styled(Link)`
65+
display: flex;
66+
align-items: center;
67+
gap: 0.75rem;
68+
padding: 0.75rem 1rem;
69+
margin-bottom: 0.75rem;
70+
background-color: transparent;
71+
border: 1px solid ${(p) => p.theme.colors.gray[10]};
72+
border-radius: 8px;
73+
box-shadow: 0px 4px 6px ${(p) => p.theme.colors.gray[10]}10;
74+
text-decoration: none;
75+
color: ${(p) => p.theme.colors.gray[0]};
76+
transition: all 0.2s;
77+
78+
svg {
79+
width: 20px;
80+
height: 20px;
81+
color: ${(p) => p.theme.colors.gray[0]};
82+
transition: color 0.1s;
83+
}
84+
85+
&:hover {
86+
box-shadow: none;
87+
border-color: ${(p) => p.theme.colors.main.default};
88+
text-decoration: none;
89+
color: ${(p) => p.theme.colors.gray[0]};
90+
91+
svg {
92+
// color: ${(p) => p.theme.colors.main.default};
93+
}
94+
}
95+
`
96+
97+
const Section = styled.div`
98+
margin-bottom: 2.5rem;
99+
`
100+
const CloudButton = styled.button`
101+
width: 100%;
102+
padding: 0.75rem 1rem;
103+
display: flex;
104+
flex-direction: row;
105+
align-items: center;
106+
justify-content: center;
107+
gap: 0.75rem;
108+
background: linear-gradient(269.85deg, #ff1786 0%, #8e33de 100%);
109+
color: white;
110+
border: none;
111+
border-radius: 8px;
112+
font-size: 0.875rem;
113+
font-weight: 600;
114+
cursor: pointer;
115+
transition: transform 0.2s;
116+
117+
&:hover {
118+
transform: translateY(-2px);
119+
}
120+
`
121+
122+
const CloudCardLink = styled(Link)`
123+
text-decoration: none;
124+
display: block;
125+
126+
&:hover {
127+
text-decoration: none;
128+
}
129+
`
130+
131+
const RightPanel = ({ isOpen, onClose }) => (
132+
<PanelWrapper isOpen={isOpen}>
133+
<Header>
134+
<Title>Getting started</Title>
135+
<CloseButton onClick={onClose}>
136+
<MenuBarsIcon />
137+
</CloseButton>
138+
</Header>
139+
140+
<Section>
141+
<SectionTitle>Try Meilisearch Cloud</SectionTitle>
142+
<Typography
143+
variant="typo11"
144+
color="gray.6"
145+
style={{ marginBottom: '1rem' }}
146+
>
147+
Streamline your experience with search analytics, monitoring, and more.
148+
</Typography>
149+
<CloudCardLink href="https://cloud.meilisearch.com?utm_campaign=oss&utm_source=integration&utm_medium=minidashboard">
150+
<CloudButton>Start free trial</CloudButton>
151+
</CloudCardLink>
152+
</Section>
153+
154+
<Section>
155+
<SectionTitle>Need help?</SectionTitle>
156+
<Typography
157+
variant="typo11"
158+
color="gray.6"
159+
style={{ marginBottom: '1.25rem' }}
160+
>
161+
Check out our resources to get started.
162+
</Typography>
163+
164+
<HelpLink href="https://docs.meilisearch.com/?utm_campaign=oss&utm_source=integration&utm_medium=minidashboard">
165+
<AcademicHatIcon />
166+
<span>Documentation</span>
167+
</HelpLink>
168+
<HelpLink href="https://help.meilisearch.com?utm_campaign=oss&utm_source=integration&utm_medium=minidashboard">
169+
<LifebuoyIcon />
170+
<span>Help center</span>
171+
</HelpLink>
172+
<HelpLink href="https://dub.sh/meili-discord?utm_campaign=oss&utm_source=integration&utm_medium=minidashboard">
173+
<ChatBubbleIcon />
174+
<span>Community</span>
175+
</HelpLink>
176+
</Section>
177+
178+
<Section>
179+
<SectionTitle>Stay up to date</SectionTitle>
180+
<Typography
181+
variant="typo11"
182+
color="gray.6"
183+
style={{ marginBottom: '0rem' }}
184+
>
185+
Get monthly updates about new features and tips to get the the most out
186+
of Meilisearch.
187+
</Typography>
188+
<NewsletterForm />
189+
</Section>
190+
</PanelWrapper>
191+
)
192+
193+
export default RightPanel

0 commit comments

Comments
 (0)