payload-plugin-newsletter 0.3.2 → 0.4.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +44 -1
- package/CLAUDE.md +31 -19
- package/dist/client.cjs +899 -0
- package/dist/client.cjs.map +1 -0
- package/dist/client.d.cts +52 -0
- package/dist/client.d.ts +52 -0
- package/dist/client.js +867 -0
- package/dist/client.js.map +1 -0
- package/dist/components.cjs +899 -0
- package/dist/components.cjs.map +1 -0
- package/dist/components.d.cts +4 -0
- package/dist/components.d.ts +4 -0
- package/dist/components.js +867 -0
- package/dist/components.js.map +1 -0
- package/dist/index.cjs +2004 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +11 -0
- package/dist/index.d.ts +6 -5
- package/dist/index.js +1967 -0
- package/dist/index.js.map +1 -0
- package/dist/types.cjs +19 -0
- package/dist/types.cjs.map +1 -0
- package/dist/{types/index.d.ts → types.d.cts} +19 -17
- package/dist/types.d.ts +350 -0
- package/dist/types.js +1 -0
- package/dist/types.js.map +1 -0
- package/package.json +48 -25
- package/dist/.tsbuildinfo +0 -1
- package/dist/collections/NewsletterSettings.d.ts +0 -4
- package/dist/collections/NewsletterSettings.d.ts.map +0 -1
- package/dist/collections/Subscribers.d.ts +0 -4
- package/dist/collections/Subscribers.d.ts.map +0 -1
- package/dist/components/MagicLinkVerify.d.ts +0 -27
- package/dist/components/MagicLinkVerify.d.ts.map +0 -1
- package/dist/components/NewsletterForm.d.ts +0 -5
- package/dist/components/NewsletterForm.d.ts.map +0 -1
- package/dist/components/PreferencesForm.d.ts +0 -5
- package/dist/components/PreferencesForm.d.ts.map +0 -1
- package/dist/components/index.d.ts +0 -5
- package/dist/components/index.d.ts.map +0 -1
- package/dist/endpoints/index.d.ts +0 -4
- package/dist/endpoints/index.d.ts.map +0 -1
- package/dist/endpoints/preferences.d.ts +0 -5
- package/dist/endpoints/preferences.d.ts.map +0 -1
- package/dist/endpoints/subscribe.d.ts +0 -4
- package/dist/endpoints/subscribe.d.ts.map +0 -1
- package/dist/endpoints/unsubscribe.d.ts +0 -4
- package/dist/endpoints/unsubscribe.d.ts.map +0 -1
- package/dist/endpoints/verify-magic-link.d.ts +0 -4
- package/dist/endpoints/verify-magic-link.d.ts.map +0 -1
- package/dist/exports/client.d.ts +0 -6
- package/dist/exports/client.d.ts.map +0 -1
- package/dist/exports/components.d.ts +0 -2
- package/dist/exports/components.d.ts.map +0 -1
- package/dist/exports/types.d.ts +0 -2
- package/dist/exports/types.d.ts.map +0 -1
- package/dist/fields/newsletterScheduling.d.ts +0 -4
- package/dist/fields/newsletterScheduling.d.ts.map +0 -1
- package/dist/hooks/useNewsletterAuth.d.ts +0 -16
- package/dist/hooks/useNewsletterAuth.d.ts.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/providers/broadcast.d.ts +0 -19
- package/dist/providers/broadcast.d.ts.map +0 -1
- package/dist/providers/index.d.ts +0 -23
- package/dist/providers/index.d.ts.map +0 -1
- package/dist/providers/resend.d.ts +0 -20
- package/dist/providers/resend.d.ts.map +0 -1
- package/dist/providers/types.d.ts +0 -46
- package/dist/providers/types.d.ts.map +0 -1
- package/dist/src/__tests__/fixtures/newsletter-settings.js +0 -41
- package/dist/src/__tests__/fixtures/newsletter-settings.js.map +0 -1
- package/dist/src/__tests__/fixtures/subscribers.js +0 -70
- package/dist/src/__tests__/fixtures/subscribers.js.map +0 -1
- package/dist/src/__tests__/integration/collections/subscriber-hooks.test.js +0 -356
- package/dist/src/__tests__/integration/collections/subscriber-hooks.test.js.map +0 -1
- package/dist/src/__tests__/integration/endpoints/preferences.test.js +0 -266
- package/dist/src/__tests__/integration/endpoints/preferences.test.js.map +0 -1
- package/dist/src/__tests__/integration/endpoints/subscribe.test.js +0 -280
- package/dist/src/__tests__/integration/endpoints/subscribe.test.js.map +0 -1
- package/dist/src/__tests__/integration/endpoints/unsubscribe.test.js +0 -187
- package/dist/src/__tests__/integration/endpoints/unsubscribe.test.js.map +0 -1
- package/dist/src/__tests__/integration/endpoints/verify-magic-link.test.js +0 -188
- package/dist/src/__tests__/integration/endpoints/verify-magic-link.test.js.map +0 -1
- package/dist/src/__tests__/mocks/email-providers.js +0 -153
- package/dist/src/__tests__/mocks/email-providers.js.map +0 -1
- package/dist/src/__tests__/mocks/payload.js +0 -244
- package/dist/src/__tests__/mocks/payload.js.map +0 -1
- package/dist/src/__tests__/security/csrf-protection.test.js +0 -309
- package/dist/src/__tests__/security/csrf-protection.test.js.map +0 -1
- package/dist/src/__tests__/security/settings-access.test.js +0 -204
- package/dist/src/__tests__/security/settings-access.test.js.map +0 -1
- package/dist/src/__tests__/security/subscriber-access.test.js +0 -210
- package/dist/src/__tests__/security/subscriber-access.test.js.map +0 -1
- package/dist/src/__tests__/security/xss-prevention.test.js +0 -305
- package/dist/src/__tests__/security/xss-prevention.test.js.map +0 -1
- package/dist/src/__tests__/setup/integration.setup.js +0 -38
- package/dist/src/__tests__/setup/integration.setup.js.map +0 -1
- package/dist/src/__tests__/setup/unit.setup.js +0 -41
- package/dist/src/__tests__/setup/unit.setup.js.map +0 -1
- package/dist/src/__tests__/unit/utils/access.test.js +0 -116
- package/dist/src/__tests__/unit/utils/access.test.js.map +0 -1
- package/dist/src/__tests__/unit/utils/jwt.test.js +0 -238
- package/dist/src/__tests__/unit/utils/jwt.test.js.map +0 -1
- package/dist/src/collections/NewsletterSettings.js +0 -390
- package/dist/src/collections/NewsletterSettings.js.map +0 -1
- package/dist/src/collections/Subscribers.js +0 -309
- package/dist/src/collections/Subscribers.js.map +0 -1
- package/dist/src/components/MagicLinkVerify.js +0 -180
- package/dist/src/components/MagicLinkVerify.js.map +0 -1
- package/dist/src/components/NewsletterForm.js +0 -326
- package/dist/src/components/NewsletterForm.js.map +0 -1
- package/dist/src/components/PreferencesForm.js +0 -524
- package/dist/src/components/PreferencesForm.js.map +0 -1
- package/dist/src/components/index.js +0 -5
- package/dist/src/components/index.js.map +0 -1
- package/dist/src/endpoints/index.js +0 -17
- package/dist/src/endpoints/index.js.map +0 -1
- package/dist/src/endpoints/preferences.js +0 -136
- package/dist/src/endpoints/preferences.js.map +0 -1
- package/dist/src/endpoints/subscribe.js +0 -151
- package/dist/src/endpoints/subscribe.js.map +0 -1
- package/dist/src/endpoints/unsubscribe.js +0 -105
- package/dist/src/endpoints/unsubscribe.js.map +0 -1
- package/dist/src/endpoints/verify-magic-link.js +0 -103
- package/dist/src/endpoints/verify-magic-link.js.map +0 -1
- package/dist/src/exports/client.js +0 -7
- package/dist/src/exports/client.js.map +0 -1
- package/dist/src/exports/components.js +0 -6
- package/dist/src/exports/components.js.map +0 -1
- package/dist/src/exports/types.js +0 -3
- package/dist/src/exports/types.js.map +0 -1
- package/dist/src/fields/newsletterScheduling.js +0 -195
- package/dist/src/fields/newsletterScheduling.js.map +0 -1
- package/dist/src/hooks/useNewsletterAuth.js +0 -112
- package/dist/src/hooks/useNewsletterAuth.js.map +0 -1
- package/dist/src/index.js +0 -130
- package/dist/src/index.js.map +0 -1
- package/dist/src/providers/broadcast.js +0 -158
- package/dist/src/providers/broadcast.js.map +0 -1
- package/dist/src/providers/index.js +0 -63
- package/dist/src/providers/index.js.map +0 -1
- package/dist/src/providers/resend.js +0 -122
- package/dist/src/providers/resend.js.map +0 -1
- package/dist/src/providers/types.js +0 -12
- package/dist/src/providers/types.js.map +0 -1
- package/dist/src/templates/BaseTemplate.js +0 -105
- package/dist/src/templates/BaseTemplate.js.map +0 -1
- package/dist/src/templates/MagicLinkTemplate.js +0 -178
- package/dist/src/templates/MagicLinkTemplate.js.map +0 -1
- package/dist/src/templates/NewsletterTemplate.js +0 -150
- package/dist/src/templates/NewsletterTemplate.js.map +0 -1
- package/dist/src/templates/WelcomeTemplate.js +0 -192
- package/dist/src/templates/WelcomeTemplate.js.map +0 -1
- package/dist/src/templates/index.js +0 -6
- package/dist/src/templates/index.js.map +0 -1
- package/dist/src/types/index.js +0 -3
- package/dist/src/types/index.js.map +0 -1
- package/dist/src/utils/access.js +0 -80
- package/dist/src/utils/access.js.map +0 -1
- package/dist/src/utils/jwt.js +0 -91
- package/dist/src/utils/jwt.js.map +0 -1
- package/dist/src/utils/validation.js +0 -74
- package/dist/src/utils/validation.js.map +0 -1
- package/dist/templates/BaseTemplate.d.ts +0 -45
- package/dist/templates/BaseTemplate.d.ts.map +0 -1
- package/dist/templates/MagicLinkTemplate.d.ts +0 -67
- package/dist/templates/MagicLinkTemplate.d.ts.map +0 -1
- package/dist/templates/NewsletterTemplate.d.ts +0 -112
- package/dist/templates/NewsletterTemplate.d.ts.map +0 -1
- package/dist/templates/WelcomeTemplate.d.ts +0 -55
- package/dist/templates/WelcomeTemplate.d.ts.map +0 -1
- package/dist/templates/index.d.ts +0 -7
- package/dist/templates/index.d.ts.map +0 -1
- package/dist/types/index.d.ts.map +0 -1
- package/dist/utils/access.d.ts +0 -15
- package/dist/utils/access.d.ts.map +0 -1
- package/dist/utils/jwt.d.ts +0 -32
- package/dist/utils/jwt.d.ts.map +0 -1
- package/dist/utils/validation.d.ts +0 -25
- package/dist/utils/validation.d.ts.map +0 -1
|
@@ -1,326 +0,0 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
import React, { useState } from 'react';
|
|
4
|
-
const defaultStyles = {
|
|
5
|
-
form: {
|
|
6
|
-
display: 'flex',
|
|
7
|
-
flexDirection: 'column',
|
|
8
|
-
gap: '1rem',
|
|
9
|
-
maxWidth: '400px',
|
|
10
|
-
margin: '0 auto'
|
|
11
|
-
},
|
|
12
|
-
inputGroup: {
|
|
13
|
-
display: 'flex',
|
|
14
|
-
flexDirection: 'column',
|
|
15
|
-
gap: '0.5rem'
|
|
16
|
-
},
|
|
17
|
-
label: {
|
|
18
|
-
fontSize: '0.875rem',
|
|
19
|
-
fontWeight: '500',
|
|
20
|
-
color: '#374151'
|
|
21
|
-
},
|
|
22
|
-
input: {
|
|
23
|
-
padding: '0.5rem 0.75rem',
|
|
24
|
-
fontSize: '1rem',
|
|
25
|
-
border: '1px solid #e5e7eb',
|
|
26
|
-
borderRadius: '0.375rem',
|
|
27
|
-
outline: 'none',
|
|
28
|
-
transition: 'border-color 0.2s'
|
|
29
|
-
},
|
|
30
|
-
button: {
|
|
31
|
-
padding: '0.75rem 1.5rem',
|
|
32
|
-
fontSize: '1rem',
|
|
33
|
-
fontWeight: '500',
|
|
34
|
-
color: '#ffffff',
|
|
35
|
-
backgroundColor: '#3b82f6',
|
|
36
|
-
border: 'none',
|
|
37
|
-
borderRadius: '0.375rem',
|
|
38
|
-
cursor: 'pointer',
|
|
39
|
-
transition: 'background-color 0.2s'
|
|
40
|
-
},
|
|
41
|
-
buttonDisabled: {
|
|
42
|
-
opacity: 0.5,
|
|
43
|
-
cursor: 'not-allowed'
|
|
44
|
-
},
|
|
45
|
-
error: {
|
|
46
|
-
fontSize: '0.875rem',
|
|
47
|
-
color: '#ef4444',
|
|
48
|
-
marginTop: '0.25rem'
|
|
49
|
-
},
|
|
50
|
-
success: {
|
|
51
|
-
fontSize: '0.875rem',
|
|
52
|
-
color: '#10b981',
|
|
53
|
-
marginTop: '0.25rem'
|
|
54
|
-
},
|
|
55
|
-
checkbox: {
|
|
56
|
-
display: 'flex',
|
|
57
|
-
alignItems: 'center',
|
|
58
|
-
gap: '0.5rem'
|
|
59
|
-
},
|
|
60
|
-
checkboxInput: {
|
|
61
|
-
width: '1rem',
|
|
62
|
-
height: '1rem'
|
|
63
|
-
},
|
|
64
|
-
checkboxLabel: {
|
|
65
|
-
fontSize: '0.875rem',
|
|
66
|
-
color: '#374151'
|
|
67
|
-
}
|
|
68
|
-
};
|
|
69
|
-
export const NewsletterForm = ({ onSuccess, onError, showName = false, showPreferences = false, leadMagnet, className, styles: customStyles = {}, apiEndpoint = '/api/newsletter/subscribe', buttonText = 'Subscribe', loadingText = 'Subscribing...', successMessage = 'Successfully subscribed!', placeholders = {
|
|
70
|
-
email: 'Enter your email',
|
|
71
|
-
name: 'Enter your name'
|
|
72
|
-
}, labels = {
|
|
73
|
-
email: 'Email',
|
|
74
|
-
name: 'Name',
|
|
75
|
-
newsletter: 'Newsletter updates',
|
|
76
|
-
announcements: 'Product announcements'
|
|
77
|
-
} })=>{
|
|
78
|
-
const [email, setEmail] = useState('');
|
|
79
|
-
const [name, setName] = useState('');
|
|
80
|
-
const [preferences, setPreferences] = useState({
|
|
81
|
-
newsletter: true,
|
|
82
|
-
announcements: true
|
|
83
|
-
});
|
|
84
|
-
const [loading, setLoading] = useState(false);
|
|
85
|
-
const [error, setError] = useState(null);
|
|
86
|
-
const [success, setSuccess] = useState(false);
|
|
87
|
-
const styles = {
|
|
88
|
-
form: {
|
|
89
|
-
...defaultStyles.form,
|
|
90
|
-
...customStyles.form
|
|
91
|
-
},
|
|
92
|
-
inputGroup: {
|
|
93
|
-
...defaultStyles.inputGroup,
|
|
94
|
-
...customStyles.inputGroup
|
|
95
|
-
},
|
|
96
|
-
label: {
|
|
97
|
-
...defaultStyles.label,
|
|
98
|
-
...customStyles.label
|
|
99
|
-
},
|
|
100
|
-
input: {
|
|
101
|
-
...defaultStyles.input,
|
|
102
|
-
...customStyles.input
|
|
103
|
-
},
|
|
104
|
-
button: {
|
|
105
|
-
...defaultStyles.button,
|
|
106
|
-
...customStyles.button
|
|
107
|
-
},
|
|
108
|
-
buttonDisabled: {
|
|
109
|
-
...defaultStyles.buttonDisabled,
|
|
110
|
-
...customStyles.buttonDisabled
|
|
111
|
-
},
|
|
112
|
-
error: {
|
|
113
|
-
...defaultStyles.error,
|
|
114
|
-
...customStyles.error
|
|
115
|
-
},
|
|
116
|
-
success: {
|
|
117
|
-
...defaultStyles.success,
|
|
118
|
-
...customStyles.success
|
|
119
|
-
},
|
|
120
|
-
checkbox: {
|
|
121
|
-
...defaultStyles.checkbox,
|
|
122
|
-
...customStyles.checkbox
|
|
123
|
-
},
|
|
124
|
-
checkboxInput: {
|
|
125
|
-
...defaultStyles.checkboxInput,
|
|
126
|
-
...customStyles.checkboxInput
|
|
127
|
-
},
|
|
128
|
-
checkboxLabel: {
|
|
129
|
-
...defaultStyles.checkboxLabel,
|
|
130
|
-
...customStyles.checkboxLabel
|
|
131
|
-
}
|
|
132
|
-
};
|
|
133
|
-
const handleSubmit = async (e)=>{
|
|
134
|
-
e.preventDefault();
|
|
135
|
-
setError(null);
|
|
136
|
-
setLoading(true);
|
|
137
|
-
try {
|
|
138
|
-
const payload = {
|
|
139
|
-
email,
|
|
140
|
-
...showName && name && {
|
|
141
|
-
name
|
|
142
|
-
},
|
|
143
|
-
...showPreferences && {
|
|
144
|
-
preferences
|
|
145
|
-
},
|
|
146
|
-
...leadMagnet && {
|
|
147
|
-
leadMagnet: leadMagnet.id
|
|
148
|
-
},
|
|
149
|
-
metadata: {
|
|
150
|
-
signupPage: window.location.href,
|
|
151
|
-
...typeof window !== 'undefined' && window.location.search && {
|
|
152
|
-
utmParams: Object.fromEntries(new URLSearchParams(window.location.search))
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
};
|
|
156
|
-
const response = await fetch(apiEndpoint, {
|
|
157
|
-
method: 'POST',
|
|
158
|
-
headers: {
|
|
159
|
-
'Content-Type': 'application/json'
|
|
160
|
-
},
|
|
161
|
-
body: JSON.stringify(payload)
|
|
162
|
-
});
|
|
163
|
-
const data = await response.json();
|
|
164
|
-
if (!response.ok) {
|
|
165
|
-
throw new Error(data.error || data.errors?.join(', ') || 'Subscription failed');
|
|
166
|
-
}
|
|
167
|
-
setSuccess(true);
|
|
168
|
-
setEmail('');
|
|
169
|
-
setName('');
|
|
170
|
-
if (onSuccess) {
|
|
171
|
-
onSuccess(data.subscriber);
|
|
172
|
-
}
|
|
173
|
-
} catch (err) {
|
|
174
|
-
const errorMessage = err instanceof Error ? err.message : 'An error occurred';
|
|
175
|
-
setError(errorMessage);
|
|
176
|
-
if (onError) {
|
|
177
|
-
onError(new Error(errorMessage));
|
|
178
|
-
}
|
|
179
|
-
} finally{
|
|
180
|
-
setLoading(false);
|
|
181
|
-
}
|
|
182
|
-
};
|
|
183
|
-
if (success && !showPreferences) {
|
|
184
|
-
return /*#__PURE__*/ _jsx("div", {
|
|
185
|
-
className: className,
|
|
186
|
-
style: styles.form,
|
|
187
|
-
children: /*#__PURE__*/ _jsx("p", {
|
|
188
|
-
style: styles.success,
|
|
189
|
-
children: successMessage
|
|
190
|
-
})
|
|
191
|
-
});
|
|
192
|
-
}
|
|
193
|
-
return /*#__PURE__*/ _jsxs("form", {
|
|
194
|
-
onSubmit: handleSubmit,
|
|
195
|
-
className: className,
|
|
196
|
-
style: styles.form,
|
|
197
|
-
children: [
|
|
198
|
-
/*#__PURE__*/ _jsxs("div", {
|
|
199
|
-
style: styles.inputGroup,
|
|
200
|
-
children: [
|
|
201
|
-
/*#__PURE__*/ _jsx("label", {
|
|
202
|
-
htmlFor: "email",
|
|
203
|
-
style: styles.label,
|
|
204
|
-
children: labels.email
|
|
205
|
-
}),
|
|
206
|
-
/*#__PURE__*/ _jsx("input", {
|
|
207
|
-
id: "email",
|
|
208
|
-
type: "email",
|
|
209
|
-
value: email,
|
|
210
|
-
onChange: (e)=>setEmail(e.target.value),
|
|
211
|
-
placeholder: placeholders.email,
|
|
212
|
-
required: true,
|
|
213
|
-
disabled: loading,
|
|
214
|
-
style: {
|
|
215
|
-
...styles.input,
|
|
216
|
-
...loading && {
|
|
217
|
-
opacity: 0.5
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
})
|
|
221
|
-
]
|
|
222
|
-
}),
|
|
223
|
-
showName && /*#__PURE__*/ _jsxs("div", {
|
|
224
|
-
style: styles.inputGroup,
|
|
225
|
-
children: [
|
|
226
|
-
/*#__PURE__*/ _jsx("label", {
|
|
227
|
-
htmlFor: "name",
|
|
228
|
-
style: styles.label,
|
|
229
|
-
children: labels.name
|
|
230
|
-
}),
|
|
231
|
-
/*#__PURE__*/ _jsx("input", {
|
|
232
|
-
id: "name",
|
|
233
|
-
type: "text",
|
|
234
|
-
value: name,
|
|
235
|
-
onChange: (e)=>setName(e.target.value),
|
|
236
|
-
placeholder: placeholders.name,
|
|
237
|
-
disabled: loading,
|
|
238
|
-
style: {
|
|
239
|
-
...styles.input,
|
|
240
|
-
...loading && {
|
|
241
|
-
opacity: 0.5
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
})
|
|
245
|
-
]
|
|
246
|
-
}),
|
|
247
|
-
showPreferences && /*#__PURE__*/ _jsxs("div", {
|
|
248
|
-
style: styles.inputGroup,
|
|
249
|
-
children: [
|
|
250
|
-
/*#__PURE__*/ _jsx("label", {
|
|
251
|
-
style: styles.label,
|
|
252
|
-
children: "Email Preferences"
|
|
253
|
-
}),
|
|
254
|
-
/*#__PURE__*/ _jsxs("div", {
|
|
255
|
-
style: styles.checkbox,
|
|
256
|
-
children: [
|
|
257
|
-
/*#__PURE__*/ _jsx("input", {
|
|
258
|
-
id: "newsletter",
|
|
259
|
-
type: "checkbox",
|
|
260
|
-
checked: preferences.newsletter,
|
|
261
|
-
onChange: (e)=>setPreferences({
|
|
262
|
-
...preferences,
|
|
263
|
-
newsletter: e.target.checked
|
|
264
|
-
}),
|
|
265
|
-
disabled: loading,
|
|
266
|
-
style: styles.checkboxInput
|
|
267
|
-
}),
|
|
268
|
-
/*#__PURE__*/ _jsx("label", {
|
|
269
|
-
htmlFor: "newsletter",
|
|
270
|
-
style: styles.checkboxLabel,
|
|
271
|
-
children: labels.newsletter
|
|
272
|
-
})
|
|
273
|
-
]
|
|
274
|
-
}),
|
|
275
|
-
/*#__PURE__*/ _jsxs("div", {
|
|
276
|
-
style: styles.checkbox,
|
|
277
|
-
children: [
|
|
278
|
-
/*#__PURE__*/ _jsx("input", {
|
|
279
|
-
id: "announcements",
|
|
280
|
-
type: "checkbox",
|
|
281
|
-
checked: preferences.announcements,
|
|
282
|
-
onChange: (e)=>setPreferences({
|
|
283
|
-
...preferences,
|
|
284
|
-
announcements: e.target.checked
|
|
285
|
-
}),
|
|
286
|
-
disabled: loading,
|
|
287
|
-
style: styles.checkboxInput
|
|
288
|
-
}),
|
|
289
|
-
/*#__PURE__*/ _jsx("label", {
|
|
290
|
-
htmlFor: "announcements",
|
|
291
|
-
style: styles.checkboxLabel,
|
|
292
|
-
children: labels.announcements
|
|
293
|
-
})
|
|
294
|
-
]
|
|
295
|
-
})
|
|
296
|
-
]
|
|
297
|
-
}),
|
|
298
|
-
/*#__PURE__*/ _jsx("button", {
|
|
299
|
-
type: "submit",
|
|
300
|
-
disabled: loading,
|
|
301
|
-
style: {
|
|
302
|
-
...styles.button,
|
|
303
|
-
...loading && styles.buttonDisabled
|
|
304
|
-
},
|
|
305
|
-
children: loading ? loadingText : buttonText
|
|
306
|
-
}),
|
|
307
|
-
error && /*#__PURE__*/ _jsx("p", {
|
|
308
|
-
style: styles.error,
|
|
309
|
-
children: error
|
|
310
|
-
}),
|
|
311
|
-
success && /*#__PURE__*/ _jsx("p", {
|
|
312
|
-
style: styles.success,
|
|
313
|
-
children: successMessage
|
|
314
|
-
})
|
|
315
|
-
]
|
|
316
|
-
});
|
|
317
|
-
};
|
|
318
|
-
// Factory function for creating custom newsletter forms
|
|
319
|
-
export function createNewsletterForm(defaultProps) {
|
|
320
|
-
return (props)=>/*#__PURE__*/ _jsx(NewsletterForm, {
|
|
321
|
-
...defaultProps,
|
|
322
|
-
...props
|
|
323
|
-
});
|
|
324
|
-
}
|
|
325
|
-
|
|
326
|
-
//# sourceMappingURL=NewsletterForm.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/NewsletterForm.tsx"],"sourcesContent":["'use client'\n\nimport React, { useState, FormEvent } from 'react'\nimport type { SignupFormProps } from '../types'\n\nconst defaultStyles = {\n form: {\n display: 'flex',\n flexDirection: 'column' as const,\n gap: '1rem',\n maxWidth: '400px',\n margin: '0 auto',\n },\n inputGroup: {\n display: 'flex',\n flexDirection: 'column' as const,\n gap: '0.5rem',\n },\n label: {\n fontSize: '0.875rem',\n fontWeight: '500',\n color: '#374151',\n },\n input: {\n padding: '0.5rem 0.75rem',\n fontSize: '1rem',\n border: '1px solid #e5e7eb',\n borderRadius: '0.375rem',\n outline: 'none',\n transition: 'border-color 0.2s',\n },\n button: {\n padding: '0.75rem 1.5rem',\n fontSize: '1rem',\n fontWeight: '500',\n color: '#ffffff',\n backgroundColor: '#3b82f6',\n border: 'none',\n borderRadius: '0.375rem',\n cursor: 'pointer',\n transition: 'background-color 0.2s',\n },\n buttonDisabled: {\n opacity: 0.5,\n cursor: 'not-allowed',\n },\n error: {\n fontSize: '0.875rem',\n color: '#ef4444',\n marginTop: '0.25rem',\n },\n success: {\n fontSize: '0.875rem',\n color: '#10b981',\n marginTop: '0.25rem',\n },\n checkbox: {\n display: 'flex',\n alignItems: 'center',\n gap: '0.5rem',\n },\n checkboxInput: {\n width: '1rem',\n height: '1rem',\n },\n checkboxLabel: {\n fontSize: '0.875rem',\n color: '#374151',\n },\n}\n\nexport const NewsletterForm: React.FC<SignupFormProps> = ({\n onSuccess,\n onError,\n showName = false,\n showPreferences = false,\n leadMagnet,\n className,\n styles: customStyles = {},\n apiEndpoint = '/api/newsletter/subscribe',\n buttonText = 'Subscribe',\n loadingText = 'Subscribing...',\n successMessage = 'Successfully subscribed!',\n placeholders = {\n email: 'Enter your email',\n name: 'Enter your name',\n },\n labels = {\n email: 'Email',\n name: 'Name',\n newsletter: 'Newsletter updates',\n announcements: 'Product announcements',\n },\n}) => {\n const [email, setEmail] = useState('')\n const [name, setName] = useState('')\n const [preferences, setPreferences] = useState({\n newsletter: true,\n announcements: true,\n })\n const [loading, setLoading] = useState(false)\n const [error, setError] = useState<string | null>(null)\n const [success, setSuccess] = useState(false)\n\n const styles = {\n form: { ...defaultStyles.form, ...customStyles.form },\n inputGroup: { ...defaultStyles.inputGroup, ...customStyles.inputGroup },\n label: { ...defaultStyles.label, ...customStyles.label },\n input: { ...defaultStyles.input, ...customStyles.input },\n button: { ...defaultStyles.button, ...customStyles.button },\n buttonDisabled: { ...defaultStyles.buttonDisabled, ...customStyles.buttonDisabled },\n error: { ...defaultStyles.error, ...customStyles.error },\n success: { ...defaultStyles.success, ...customStyles.success },\n checkbox: { ...defaultStyles.checkbox, ...customStyles.checkbox },\n checkboxInput: { ...defaultStyles.checkboxInput, ...customStyles.checkboxInput },\n checkboxLabel: { ...defaultStyles.checkboxLabel, ...customStyles.checkboxLabel },\n }\n\n const handleSubmit = async (e: FormEvent) => {\n e.preventDefault()\n setError(null)\n setLoading(true)\n\n try {\n const payload: any = {\n email,\n ...(showName && name && { name }),\n ...(showPreferences && { preferences }),\n ...(leadMagnet && { leadMagnet: leadMagnet.id }),\n metadata: {\n signupPage: window.location.href,\n ...(typeof window !== 'undefined' && window.location.search && {\n utmParams: Object.fromEntries(new URLSearchParams(window.location.search)),\n }),\n },\n }\n\n const response = await fetch(apiEndpoint, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(payload),\n })\n\n const data = await response.json()\n\n if (!response.ok) {\n throw new Error(data.error || data.errors?.join(', ') || 'Subscription failed')\n }\n\n setSuccess(true)\n setEmail('')\n setName('')\n if (onSuccess) {\n onSuccess(data.subscriber)\n }\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : 'An error occurred'\n setError(errorMessage)\n if (onError) {\n onError(new Error(errorMessage))\n }\n } finally {\n setLoading(false)\n }\n }\n\n if (success && !showPreferences) {\n return (\n <div className={className} style={styles.form}>\n <p style={styles.success}>{successMessage}</p>\n </div>\n )\n }\n\n return (\n <form onSubmit={handleSubmit} className={className} style={styles.form}>\n <div style={styles.inputGroup}>\n <label htmlFor=\"email\" style={styles.label}>\n {labels.email}\n </label>\n <input\n id=\"email\"\n type=\"email\"\n value={email}\n onChange={(e) => setEmail(e.target.value)}\n placeholder={placeholders.email}\n required\n disabled={loading}\n style={{\n ...styles.input,\n ...(loading && { opacity: 0.5 }),\n }}\n />\n </div>\n\n {showName && (\n <div style={styles.inputGroup}>\n <label htmlFor=\"name\" style={styles.label}>\n {labels.name}\n </label>\n <input\n id=\"name\"\n type=\"text\"\n value={name}\n onChange={(e) => setName(e.target.value)}\n placeholder={placeholders.name}\n disabled={loading}\n style={{\n ...styles.input,\n ...(loading && { opacity: 0.5 }),\n }}\n />\n </div>\n )}\n\n {showPreferences && (\n <div style={styles.inputGroup}>\n <label style={styles.label}>Email Preferences</label>\n <div style={styles.checkbox}>\n <input\n id=\"newsletter\"\n type=\"checkbox\"\n checked={preferences.newsletter}\n onChange={(e) =>\n setPreferences({ ...preferences, newsletter: e.target.checked })\n }\n disabled={loading}\n style={styles.checkboxInput}\n />\n <label htmlFor=\"newsletter\" style={styles.checkboxLabel}>\n {labels.newsletter}\n </label>\n </div>\n <div style={styles.checkbox}>\n <input\n id=\"announcements\"\n type=\"checkbox\"\n checked={preferences.announcements}\n onChange={(e) =>\n setPreferences({ ...preferences, announcements: e.target.checked })\n }\n disabled={loading}\n style={styles.checkboxInput}\n />\n <label htmlFor=\"announcements\" style={styles.checkboxLabel}>\n {labels.announcements}\n </label>\n </div>\n </div>\n )}\n\n <button\n type=\"submit\"\n disabled={loading}\n style={{\n ...styles.button,\n ...(loading && styles.buttonDisabled),\n }}\n >\n {loading ? loadingText : buttonText}\n </button>\n\n {error && <p style={styles.error}>{error}</p>}\n {success && <p style={styles.success}>{successMessage}</p>}\n </form>\n )\n}\n\n// Factory function for creating custom newsletter forms\nexport function createNewsletterForm(\n defaultProps: Partial<SignupFormProps>\n): React.FC<SignupFormProps> {\n return (props: SignupFormProps) => (\n <NewsletterForm {...defaultProps} {...props} />\n )\n}"],"names":["React","useState","defaultStyles","form","display","flexDirection","gap","maxWidth","margin","inputGroup","label","fontSize","fontWeight","color","input","padding","border","borderRadius","outline","transition","button","backgroundColor","cursor","buttonDisabled","opacity","error","marginTop","success","checkbox","alignItems","checkboxInput","width","height","checkboxLabel","NewsletterForm","onSuccess","onError","showName","showPreferences","leadMagnet","className","styles","customStyles","apiEndpoint","buttonText","loadingText","successMessage","placeholders","email","name","labels","newsletter","announcements","setEmail","setName","preferences","setPreferences","loading","setLoading","setError","setSuccess","handleSubmit","e","preventDefault","payload","id","metadata","signupPage","window","location","href","search","utmParams","Object","fromEntries","URLSearchParams","response","fetch","method","headers","body","JSON","stringify","data","json","ok","Error","errors","join","subscriber","err","errorMessage","message","div","style","p","onSubmit","htmlFor","type","value","onChange","target","placeholder","required","disabled","checked","createNewsletterForm","defaultProps","props"],"mappings":"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"}
|