Skip to content

Commit 1717d2d

Browse files
committed
feat: add newsletter & amicaux signup forms
1 parent 9497c2d commit 1717d2d

File tree

5 files changed

+226
-8
lines changed

5 files changed

+226
-8
lines changed
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
import { FormEventHandler, useState } from "react"
2+
3+
interface Props {
4+
id: string
5+
title: string
6+
description: string
7+
submit: string
8+
statusSubmitting: string
9+
statusSuccess: string
10+
statusError: string
11+
includeName?: boolean
12+
}
13+
interface Values {
14+
email: string
15+
name?: string
16+
}
17+
enum Status {
18+
Initial,
19+
Submitting,
20+
Success,
21+
Error,
22+
}
23+
24+
export const NewsletterSignupForm = ({
25+
id,
26+
title,
27+
description,
28+
submit,
29+
statusSubmitting,
30+
statusSuccess,
31+
statusError,
32+
includeName,
33+
}: Props) => {
34+
const [values, setValues] = useState<Values>({ email: "" })
35+
const setValue = (key: keyof Values, value: string) => {
36+
setValues((values) => ({ ...values, [key]: value }))
37+
}
38+
39+
const [status, setStatus] = useState<Status>(Status.Initial)
40+
41+
const handleSubmit: FormEventHandler<HTMLFormElement> = (event) => {
42+
event.preventDefault()
43+
setStatus(Status.Submitting)
44+
45+
let url = `https://assets.mailerlite.com/jsonp/622467/forms/${id}/subscribe`
46+
url = `${url}?fields[email]=${encodeURIComponent(values.email)}`
47+
if (includeName && values.name) {
48+
url = `${url}&fields[name]=${encodeURIComponent(values.name)}`
49+
}
50+
url = `${url}&ml-submit=1&anticsrf=true`
51+
52+
fetch(url)
53+
.then((result) => result?.json())
54+
.then((body) => {
55+
if (body.success === true) {
56+
setStatus(Status.Success)
57+
} else {
58+
throw new Error()
59+
}
60+
})
61+
.catch(() => {
62+
setStatus(Status.Error)
63+
})
64+
}
65+
66+
const describeStatus = () => {
67+
switch (status) {
68+
case Status.Submitting:
69+
return <p className="loading">{statusSubmitting}</p>
70+
case Status.Success:
71+
return <p className="success">{statusSuccess}</p>
72+
case Status.Error:
73+
return <p className="error">{statusError}</p>
74+
default:
75+
return null
76+
}
77+
}
78+
79+
return (
80+
<div className="newsletter-signup-form">
81+
<div className="main-col text-styles">
82+
<h4>{title}</h4>
83+
</div>
84+
<div className="inner text-styles inverted">
85+
<div className="main-col">
86+
<p>{description}</p>
87+
{status !== Status.Success && (
88+
<form onSubmit={handleSubmit}>
89+
{includeName && (
90+
<input
91+
aria-label="Name"
92+
aria-required="true"
93+
type="text"
94+
data-inputmask=""
95+
name="name"
96+
placeholder="Name"
97+
autoComplete="name"
98+
onChange={(event) => setValue("name", event.target.value)}
99+
disabled={status === Status.Submitting}
100+
/>
101+
)}
102+
<input
103+
aria-label="E-Mail"
104+
aria-required="true"
105+
type="email"
106+
data-inputmask=""
107+
name="email"
108+
placeholder="E-Mail"
109+
autoComplete="email"
110+
onChange={(event) => setValue("email", event.target.value)}
111+
disabled={status === Status.Submitting}
112+
/>
113+
<button type="submit" disabled={status === Status.Submitting}>
114+
{submit}
115+
</button>
116+
</form>
117+
)}
118+
{describeStatus()}
119+
</div>
120+
</div>
121+
</div>
122+
)
123+
}

src/components/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
export * from "./EventContainer"
22
export * from "./Logo"
3+
export * from "./NewsletterSignupForm"

src/pages/[slug].tsx

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@ import { gql } from "../__generated__/gql"
55
import client from "../apollo-client"
66
import { PageQuery } from "../__generated__/graphql"
77
import { Layout } from "../components/Layout"
8+
import { NewsletterSignupForm } from "../components"
89

910
interface Props {
11+
slug?: string
1012
page: PageQuery["page"]
1113
pages: PageQuery["pages"]
1214
}
@@ -53,20 +55,33 @@ export const getStaticProps: GetStaticProps<Props> = async ({ params }) => {
5355

5456
return {
5557
props: {
58+
slug,
5659
page: data.page,
5760
pages: data.pages,
5861
},
5962
}
6063
}
6164

62-
export default function Page({ page, pages }: Props) {
65+
export default function Page({ slug, page, pages }: Props) {
6366
if (!page) return null
6467

6568
return (
6669
<Layout pages={pages}>
6770
<div className="main-col text-styles text-page">
6871
<ReactMarkdown>{page.content || ""}</ReactMarkdown>
6972
</div>
73+
{slug === "amicaux" && (
74+
<NewsletterSignupForm
75+
id="100836031458183082"
76+
title="anmeldung"
77+
includeName
78+
description="Melde dich hier mit deinem Namen und deiner E-Mailadresse an, um mehr Informationen (inkl. Kontoangaben) zu den suppléments amicaux per E-Mail zu erhalten."
79+
submit="Anmelden"
80+
statusSubmitting="Speichern …"
81+
statusSuccess="Vielen Dank! Du wirst in Kürze ein E-Mail zur Bestätigung deiner Anmeldung erhalten."
82+
statusError="Die Anmeldung hat leider nicht geklappt! Melde dich bitte per E-Mail bei uns."
83+
/>
84+
)}
7085
</Layout>
7186
)
7287
}

src/pages/index.tsx

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import { Layout } from "../components/Layout"
99
import { gql } from "../__generated__/gql"
1010
import client from "../apollo-client"
1111
import { HomeQuery } from "../__generated__/graphql"
12-
import { EventContainer } from "../components"
12+
import { EventContainer, NewsletterSignupForm } from "../components"
1313
import { parse, formatList } from "../utils"
1414

1515
interface Props {
@@ -126,6 +126,16 @@ export default function Home({ events, pages, content }: Props) {
126126
<Link href="/archiv">Archiv</Link> an.
127127
</p>
128128
</div>
129+
130+
<NewsletterSignupForm
131+
id="100835912863188758"
132+
title="newsletter"
133+
description="Erhalte Infos über unsere Projekte und Konzerte."
134+
submit="Anmelden"
135+
statusSubmitting="Speichern …"
136+
statusSuccess="Vielen Dank! Du wirst in Kürze ein E-Mail zur Bestätigung deiner Anmeldung erhalten."
137+
statusError="Die Anmeldung hat leider nicht geklappt! Melde dich bitte per E-Mail bei uns."
138+
/>
129139
</Layout>
130140
)
131141
}

src/styles/globals.css

Lines changed: 75 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,16 @@
33
:root {
44
--text: #333;
55
--default-event-background: #444;
6-
--blue: #425FA6;
7-
--red: #F2505B;
6+
--blue: rgb(66, 95, 166);
7+
--blue-90: rgba(66, 95, 166, 0.9);
8+
--red: rgb(242, 80, 91);
89
--red-0: rgba(242, 80, 91, 0.00);
910
--white: #FFF;
11+
--white-20: rgba(255, 255, 255, 0.2);
1012
--white-80: rgba(255, 255, 255, 0.8);
11-
--white-20: rgba(0, 0, 0, 0.2);
1213
--black: #000;
13-
--black-10: rgba(0, 0, 0, 0.1)
14+
--black-10: rgba(0, 0, 0, 0.1);
15+
--black-20: rgba(0, 0, 0, 0.2);
1416
}
1517

1618
/* font */
@@ -148,7 +150,7 @@ a {
148150
letter-spacing: -0.01em;
149151
}
150152
.text-styles h4 {
151-
padding-bottom: 4px;
153+
padding-bottom: 6px;
152154

153155
font-size: 1.2rem;
154156
letter-spacing: 0em;
@@ -179,7 +181,7 @@ a {
179181
.text-styles strong {
180182
padding: 2px 4px;
181183

182-
background-color: var(--white-20);
184+
background-color: var(--black-20);
183185
opacity: 1;
184186
}
185187

@@ -325,3 +327,70 @@ a {
325327
padding-top: 32px;
326328
}
327329

330+
/* Newsletter signup form */
331+
332+
.newsletter-signup-form {
333+
margin-top: 48px;
334+
margin-bottom: 48px;
335+
}
336+
.newsletter-signup-form h4 {
337+
color: var(--blue);
338+
}
339+
.newsletter-signup-form .inner {
340+
padding: 16px 0;
341+
background-color: var(--blue);
342+
}
343+
344+
.text-styles.inverted p.loading,
345+
.text-styles.inverted p.success {
346+
color: var(--white);
347+
}
348+
.text-styles.inverted p.error {
349+
color: var(--red);
350+
}
351+
352+
.newsletter-signup-form form {
353+
max-width: 360px;
354+
margin-bottom: 8px;
355+
}
356+
.newsletter-signup-form form input {
357+
display: block;
358+
width: 100%;
359+
padding: 4px 8px;
360+
margin-bottom: 8px;
361+
362+
outline: none;
363+
border: none;
364+
}
365+
.newsletter-signup-form form button {
366+
display: block;
367+
padding: 4px 8px;
368+
369+
outline: none;
370+
border: none;
371+
372+
background-color: var(--blue);
373+
color: var(--white);
374+
border: 2px solid var(--white);
375+
}
376+
.newsletter-signup-form form button:hover {
377+
background-color: var(--white-20);
378+
cursor: pointer;
379+
}
380+
.newsletter-signup-form form button:active {
381+
color: var(--blue);
382+
background-color: var(--white);
383+
}
384+
385+
@media screen and (min-width: 520px) {
386+
.newsletter-signup-form form {
387+
display: flex;
388+
flex-direction: row;
389+
}
390+
.newsletter-signup-form form input {
391+
width: unset;
392+
flex: 1;
393+
margin-right: 8px;
394+
margin-bottom: 0;
395+
}
396+
}

0 commit comments

Comments
 (0)