@paroicms/contact-form-plugin 0.3.0

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/README.md ADDED
@@ -0,0 +1,9 @@
1
+ # @paroicms/contact-form-plugin
2
+
3
+ Contact form for ParoiCMS.
4
+
5
+ This package is part of [ParoiCMS](https://www.npmjs.com/package/@paroicms/server).
6
+
7
+ ## License
8
+
9
+ Released under the [MIT license](https://gitlab.com/paroi/opensource/paroicms/-/blob/main/LICENSE.md).
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.formatSendMailInput = void 0;
4
+ const data_formatters_lib_1 = require("@paroi/data-formatters-lib");
5
+ function formatSendMailInput(data) {
6
+ return {
7
+ language: (0, data_formatters_lib_1.strVal)(data.language),
8
+ email: (0, data_formatters_lib_1.strVal)(data.email),
9
+ name: (0, data_formatters_lib_1.strVal)(data.name),
10
+ subject: (0, data_formatters_lib_1.strValOrUndef)(data.subject),
11
+ message: (0, data_formatters_lib_1.strVal)(data.message),
12
+ gRecaptchaResponse: (0, data_formatters_lib_1.strValOrUndef)(data.gRecaptchaResponse),
13
+ };
14
+ }
15
+ exports.formatSendMailInput = formatSendMailInput;
@@ -0,0 +1,69 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.sendContactFormMail = void 0;
4
+ const data_formatters_lib_1 = require("@paroi/data-formatters-lib");
5
+ const public_server_lib_1 = require("@paroicms/public-server-lib");
6
+ const plugin_1 = require("../plugin");
7
+ async function sendContactFormMail(pluginSiteContext, input) {
8
+ const { email, name, message, subject, gRecaptchaResponse } = input;
9
+ let contactEmail;
10
+ try {
11
+ contactEmail = (0, data_formatters_lib_1.strValOrUndef)(await pluginSiteContext.getSiteFieldValue({
12
+ fieldName: "contactEmail",
13
+ language: input.language,
14
+ }));
15
+ if (!contactEmail)
16
+ throw new Error(`['${pluginSiteContext.fqdn}'] missing 'contactEmail' site field`);
17
+ if (!(await pluginSiteContext.validateRecaptchaResponse(gRecaptchaResponse))) {
18
+ throw new Error("invalid recaptcha response");
19
+ }
20
+ const noSubject = plugin_1.simpleI18n.translate({
21
+ key: "mail.noSubject",
22
+ language: input.language,
23
+ });
24
+ const contactFrom = plugin_1.simpleI18n.translate({
25
+ key: "mail.contactFrom",
26
+ language: input.language,
27
+ args: [pluginSiteContext.fqdn],
28
+ });
29
+ await pluginSiteContext.sendMail({
30
+ to: contactEmail,
31
+ replyTo: { email, name },
32
+ subject: `${subject ?? noSubject} ${contactFrom}`,
33
+ html: `<p>${plugin_1.simpleI18n.translate({
34
+ key: "mail.nameIs",
35
+ language: input.language,
36
+ args: [(0, public_server_lib_1.escapeHtml)(name)],
37
+ })}</p>
38
+ <p>${plugin_1.simpleI18n.translate({
39
+ key: "mail.emailIs",
40
+ language: input.language,
41
+ args: [(0, public_server_lib_1.escapeHtml)(email)],
42
+ })}</p>
43
+ <p>${(0, public_server_lib_1.escapeHtml)(message, { newLinesToBr: true })}</p>`,
44
+ }, { appLog: pluginSiteContext.siteLog });
45
+ return {
46
+ success: true,
47
+ };
48
+ }
49
+ catch (err) {
50
+ if (err)
51
+ throw err;
52
+ pluginSiteContext.siteLog.error(`fail to send mail: ${(0, data_formatters_lib_1.messageOf)(err)}`);
53
+ return {
54
+ success: false,
55
+ message: contactEmail
56
+ ? plugin_1.simpleI18n.translate({
57
+ key: "mail.sendUsAnEmailTo",
58
+ language: input.language,
59
+ args: [contactEmail],
60
+ })
61
+ : plugin_1.simpleI18n.translate({
62
+ key: "mail.sorryMessage",
63
+ language: input.language,
64
+ }),
65
+ senderEmail: email,
66
+ };
67
+ }
68
+ }
69
+ exports.sendContactFormMail = sendContactFormMail;
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.simpleI18n = void 0;
4
+ const public_server_lib_1 = require("@paroicms/public-server-lib");
5
+ const node_path_1 = require("node:path");
6
+ const data_format_1 = require("./helpers/data-format");
7
+ const contact_form_mail_1 = require("./mail/contact-form-mail");
8
+ const { version } = require("../package.json");
9
+ const localesDir = (0, node_path_1.join)(__dirname, "..", "locales");
10
+ const assetsBaseUrl = `/assets/plugin/contact-form/${version}`;
11
+ const plugin = {
12
+ boPluginDir: (0, node_path_1.join)(__dirname, "..", "dist-backend"),
13
+ version,
14
+ siteInit(api) {
15
+ api.setPublicAssetsDirectory((0, node_path_1.join)(__dirname, "..", "dist-frontend"));
16
+ api.addHeadTag(`<link rel="stylesheet" href="${(0, public_server_lib_1.escapeHtml)(`${assetsBaseUrl}/style.css`)}">`, `<script type="module" src="${(0, public_server_lib_1.escapeHtml)(`${assetsBaseUrl}/front-plugin.mjs`)}"></script>`);
17
+ api.setPublicApiHandler(async (pluginSiteContext, req, res, relativePath) => {
18
+ let input;
19
+ try {
20
+ input = (0, data_format_1.formatSendMailInput)(req.body);
21
+ }
22
+ catch (error) {
23
+ res.status(400).send({ status: 400, message: error.message });
24
+ return;
25
+ }
26
+ exports.simpleI18n = await (0, public_server_lib_1.createSimpleTranslator)({
27
+ l10nDir: localesDir,
28
+ languages: ["en", "fr"],
29
+ appLog: pluginSiteContext.siteLog,
30
+ });
31
+ const result = await (0, contact_form_mail_1.sendContactFormMail)(pluginSiteContext, input);
32
+ res.send(result);
33
+ });
34
+ },
35
+ };
36
+ module.exports = plugin;
@@ -0,0 +1,632 @@
1
+ const Pe = (e, t) => e === t, I = {
2
+ equals: Pe
3
+ };
4
+ let be = Fe;
5
+ const E = 1, B = 2, we = {
6
+ owned: null,
7
+ cleanups: null,
8
+ context: null,
9
+ owner: null
10
+ };
11
+ var u = null;
12
+ let z = null, Ne = null, a = null, d = null, v = null, k = 0;
13
+ function Le(e, t) {
14
+ const n = a, s = u, o = e.length === 0, r = t === void 0 ? s : t, i = o ? we : {
15
+ owned: null,
16
+ cleanups: null,
17
+ context: r ? r.context : null,
18
+ owner: r
19
+ }, l = o ? e : () => e(() => A(() => V(i)));
20
+ u = i, a = null;
21
+ try {
22
+ return P(l, !0);
23
+ } finally {
24
+ a = n, u = s;
25
+ }
26
+ }
27
+ function y(e, t) {
28
+ t = t ? Object.assign({}, I, t) : I;
29
+ const n = {
30
+ value: e,
31
+ observers: null,
32
+ observerSlots: null,
33
+ comparator: t.equals || void 0
34
+ }, s = (o) => (typeof o == "function" && (o = o(n.value)), ve(n, o));
35
+ return [ye.bind(n), s];
36
+ }
37
+ function S(e, t, n) {
38
+ const s = se(e, t, !1, E);
39
+ _(s);
40
+ }
41
+ function Ue(e, t, n) {
42
+ be = qe;
43
+ const s = se(e, t, !1, E);
44
+ s.user = !0, v ? v.push(s) : _(s);
45
+ }
46
+ function ee(e, t, n) {
47
+ n = n ? Object.assign({}, I, n) : I;
48
+ const s = se(e, t, !0, 0);
49
+ return s.observers = null, s.observerSlots = null, s.comparator = n.equals || void 0, _(s), ye.bind(s);
50
+ }
51
+ function A(e) {
52
+ if (a === null)
53
+ return e();
54
+ const t = a;
55
+ a = null;
56
+ try {
57
+ return e();
58
+ } finally {
59
+ a = t;
60
+ }
61
+ }
62
+ function Oe(e) {
63
+ Ue(() => A(e));
64
+ }
65
+ function Ie(e) {
66
+ return u === null || (u.cleanups === null ? u.cleanups = [e] : u.cleanups.push(e)), e;
67
+ }
68
+ function ye() {
69
+ if (this.sources && this.state)
70
+ if (this.state === E)
71
+ _(this);
72
+ else {
73
+ const e = d;
74
+ d = null, P(() => q(this), !1), d = e;
75
+ }
76
+ if (a) {
77
+ const e = this.observers ? this.observers.length : 0;
78
+ a.sources ? (a.sources.push(this), a.sourceSlots.push(e)) : (a.sources = [this], a.sourceSlots = [e]), this.observers ? (this.observers.push(a), this.observerSlots.push(a.sources.length - 1)) : (this.observers = [a], this.observerSlots = [a.sources.length - 1]);
79
+ }
80
+ return this.value;
81
+ }
82
+ function ve(e, t, n) {
83
+ let s = e.value;
84
+ return (!e.comparator || !e.comparator(s, t)) && (e.value = t, e.observers && e.observers.length && P(() => {
85
+ for (let o = 0; o < e.observers.length; o += 1) {
86
+ const r = e.observers[o], i = z && z.running;
87
+ i && z.disposed.has(r), (i ? !r.tState : !r.state) && (r.pure ? d.push(r) : v.push(r), r.observers && Se(r)), i || (r.state = E);
88
+ }
89
+ if (d.length > 1e6)
90
+ throw d = [], new Error();
91
+ }, !1)), t;
92
+ }
93
+ function _(e) {
94
+ if (!e.fn)
95
+ return;
96
+ V(e);
97
+ const t = k;
98
+ Be(
99
+ e,
100
+ e.value,
101
+ t
102
+ );
103
+ }
104
+ function Be(e, t, n) {
105
+ let s;
106
+ const o = u, r = a;
107
+ a = u = e;
108
+ try {
109
+ s = e.fn(t);
110
+ } catch (i) {
111
+ return e.pure && (e.state = E, e.owned && e.owned.forEach(V), e.owned = null), e.updatedAt = n + 1, Ee(i);
112
+ } finally {
113
+ a = r, u = o;
114
+ }
115
+ (!e.updatedAt || e.updatedAt <= n) && (e.updatedAt != null && "observers" in e ? ve(e, s) : e.value = s, e.updatedAt = n);
116
+ }
117
+ function se(e, t, n, s = E, o) {
118
+ const r = {
119
+ fn: e,
120
+ state: s,
121
+ updatedAt: null,
122
+ owned: null,
123
+ sources: null,
124
+ sourceSlots: null,
125
+ cleanups: null,
126
+ value: t,
127
+ owner: u,
128
+ context: u ? u.context : null,
129
+ pure: n
130
+ };
131
+ return u === null || u !== we && (u.owned ? u.owned.push(r) : u.owned = [r]), r;
132
+ }
133
+ function H(e) {
134
+ if (e.state === 0)
135
+ return;
136
+ if (e.state === B)
137
+ return q(e);
138
+ if (e.suspense && A(e.suspense.inFallback))
139
+ return e.suspense.effects.push(e);
140
+ const t = [e];
141
+ for (; (e = e.owner) && (!e.updatedAt || e.updatedAt < k); )
142
+ e.state && t.push(e);
143
+ for (let n = t.length - 1; n >= 0; n--)
144
+ if (e = t[n], e.state === E)
145
+ _(e);
146
+ else if (e.state === B) {
147
+ const s = d;
148
+ d = null, P(() => q(e, t[0]), !1), d = s;
149
+ }
150
+ }
151
+ function P(e, t) {
152
+ if (d)
153
+ return e();
154
+ let n = !1;
155
+ t || (d = []), v ? n = !0 : v = [], k++;
156
+ try {
157
+ const s = e();
158
+ return He(n), s;
159
+ } catch (s) {
160
+ n || (v = null), d = null, Ee(s);
161
+ }
162
+ }
163
+ function He(e) {
164
+ if (d && (Fe(d), d = null), e)
165
+ return;
166
+ const t = v;
167
+ v = null, t.length && P(() => be(t), !1);
168
+ }
169
+ function Fe(e) {
170
+ for (let t = 0; t < e.length; t++)
171
+ H(e[t]);
172
+ }
173
+ function qe(e) {
174
+ let t, n = 0;
175
+ for (t = 0; t < e.length; t++) {
176
+ const s = e[t];
177
+ s.user ? e[n++] = s : H(s);
178
+ }
179
+ for (t = 0; t < n; t++)
180
+ H(e[t]);
181
+ }
182
+ function q(e, t) {
183
+ e.state = 0;
184
+ for (let n = 0; n < e.sources.length; n += 1) {
185
+ const s = e.sources[n];
186
+ if (s.sources) {
187
+ const o = s.state;
188
+ o === E ? s !== t && (!s.updatedAt || s.updatedAt < k) && H(s) : o === B && q(s, t);
189
+ }
190
+ }
191
+ }
192
+ function Se(e) {
193
+ for (let t = 0; t < e.observers.length; t += 1) {
194
+ const n = e.observers[t];
195
+ n.state || (n.state = B, n.pure ? d.push(n) : v.push(n), n.observers && Se(n));
196
+ }
197
+ }
198
+ function V(e) {
199
+ let t;
200
+ if (e.sources)
201
+ for (; e.sources.length; ) {
202
+ const n = e.sources.pop(), s = e.sourceSlots.pop(), o = n.observers;
203
+ if (o && o.length) {
204
+ const r = o.pop(), i = n.observerSlots.pop();
205
+ s < o.length && (r.sourceSlots[i] = s, o[s] = r, n.observerSlots[s] = i);
206
+ }
207
+ }
208
+ if (e.owned) {
209
+ for (t = e.owned.length - 1; t >= 0; t--)
210
+ V(e.owned[t]);
211
+ e.owned = null;
212
+ }
213
+ if (e.cleanups) {
214
+ for (t = e.cleanups.length - 1; t >= 0; t--)
215
+ e.cleanups[t]();
216
+ e.cleanups = null;
217
+ }
218
+ e.state = 0;
219
+ }
220
+ function De(e) {
221
+ return e instanceof Error ? e : new Error(typeof e == "string" ? e : "Unknown error", {
222
+ cause: e
223
+ });
224
+ }
225
+ function Ee(e, t = u) {
226
+ throw De(e);
227
+ }
228
+ let ke = !1;
229
+ function te(e, t) {
230
+ return A(() => e(t || {}));
231
+ }
232
+ const Ve = (e) => `Stale read from <${e}>.`;
233
+ function me(e) {
234
+ const t = e.keyed, n = ee(() => e.when, void 0, {
235
+ equals: (s, o) => t ? s === o : !s == !o
236
+ });
237
+ return ee(
238
+ () => {
239
+ const s = n();
240
+ if (s) {
241
+ const o = e.children;
242
+ return typeof o == "function" && o.length > 0 ? A(
243
+ () => o(
244
+ t ? s : () => {
245
+ if (!A(n))
246
+ throw Ve("Show");
247
+ return e.when;
248
+ }
249
+ )
250
+ ) : o;
251
+ }
252
+ return e.fallback;
253
+ },
254
+ void 0,
255
+ void 0
256
+ );
257
+ }
258
+ function Ge(e, t, n) {
259
+ let s = n.length, o = t.length, r = s, i = 0, l = 0, f = t[o - 1].nextSibling, m = null;
260
+ for (; i < o || l < r; ) {
261
+ if (t[i] === n[l]) {
262
+ i++, l++;
263
+ continue;
264
+ }
265
+ for (; t[o - 1] === n[r - 1]; )
266
+ o--, r--;
267
+ if (o === i) {
268
+ const h = r < s ? l ? n[l - 1].nextSibling : n[r - l] : f;
269
+ for (; l < r; )
270
+ e.insertBefore(n[l++], h);
271
+ } else if (r === l)
272
+ for (; i < o; )
273
+ (!m || !m.has(t[i])) && t[i].remove(), i++;
274
+ else if (t[i] === n[r - 1] && n[l] === t[o - 1]) {
275
+ const h = t[--o].nextSibling;
276
+ e.insertBefore(n[l++], t[i++].nextSibling), e.insertBefore(n[--r], h), t[o] = n[r];
277
+ } else {
278
+ if (!m) {
279
+ m = /* @__PURE__ */ new Map();
280
+ let w = l;
281
+ for (; w < r; )
282
+ m.set(n[w], w++);
283
+ }
284
+ const h = m.get(t[i]);
285
+ if (h != null)
286
+ if (l < h && h < r) {
287
+ let w = i, j = 1, M;
288
+ for (; ++w < o && w < r && !((M = m.get(t[w])) == null || M !== h + j); )
289
+ j++;
290
+ if (j > h - l) {
291
+ const N = t[i];
292
+ for (; l < h; )
293
+ e.insertBefore(n[l++], N);
294
+ } else
295
+ e.replaceChild(n[l++], t[i++]);
296
+ } else
297
+ i++;
298
+ else
299
+ t[i++].remove();
300
+ }
301
+ }
302
+ }
303
+ function Ye(e, t, n, s = {}) {
304
+ let o;
305
+ return Le((r) => {
306
+ o = r, t === document ? e() : g(t, e(), t.firstChild ? null : void 0, n);
307
+ }, s.owner), () => {
308
+ o(), t.textContent = "";
309
+ };
310
+ }
311
+ function G(e, t, n) {
312
+ let s;
313
+ const o = () => {
314
+ const i = document.createElement("template");
315
+ return i.innerHTML = e, i.content.firstChild;
316
+ }, r = () => (s || (s = o())).cloneNode(!0);
317
+ return r.cloneNode = r, r;
318
+ }
319
+ function x(e, t, n) {
320
+ n == null ? e.removeAttribute(t) : e.setAttribute(t, n);
321
+ }
322
+ function g(e, t, n, s) {
323
+ if (n !== void 0 && !s && (s = []), typeof t != "function")
324
+ return D(e, t, s, n);
325
+ S((o) => D(e, t(), o, n), s);
326
+ }
327
+ function D(e, t, n, s, o) {
328
+ for (; typeof n == "function"; )
329
+ n = n();
330
+ if (t === n)
331
+ return n;
332
+ const r = typeof t, i = s !== void 0;
333
+ if (e = i && n[0] && n[0].parentNode || e, r === "string" || r === "number") {
334
+ if (r === "number" && (t = t.toString(), t === n))
335
+ return n;
336
+ if (i) {
337
+ let l = n[0];
338
+ l && l.nodeType === 3 ? l.data !== t && (l.data = t) : l = document.createTextNode(t), n = $(e, n, s, l);
339
+ } else
340
+ n !== "" && typeof n == "string" ? n = e.firstChild.data = t : n = e.textContent = t;
341
+ } else if (t == null || r === "boolean")
342
+ n = $(e, n, s);
343
+ else {
344
+ if (r === "function")
345
+ return S(() => {
346
+ let l = t();
347
+ for (; typeof l == "function"; )
348
+ l = l();
349
+ n = D(e, l, n, s);
350
+ }), () => n;
351
+ if (Array.isArray(t)) {
352
+ const l = [], f = n && Array.isArray(n);
353
+ if (ne(l, t, n, o))
354
+ return S(() => n = D(e, l, n, s, !0)), () => n;
355
+ if (l.length === 0) {
356
+ if (n = $(e, n, s), i)
357
+ return n;
358
+ } else
359
+ f ? n.length === 0 ? pe(e, l, s) : Ge(e, n, l) : (n && $(e), pe(e, l));
360
+ n = l;
361
+ } else if (t.nodeType) {
362
+ if (Array.isArray(n)) {
363
+ if (i)
364
+ return n = $(e, n, s, t);
365
+ $(e, n, null, t);
366
+ } else
367
+ n == null || n === "" || !e.firstChild ? e.appendChild(t) : e.replaceChild(t, e.firstChild);
368
+ n = t;
369
+ }
370
+ }
371
+ return n;
372
+ }
373
+ function ne(e, t, n, s) {
374
+ let o = !1;
375
+ for (let r = 0, i = t.length; r < i; r++) {
376
+ let l = t[r], f = n && n[e.length], m;
377
+ if (!(l == null || l === !0 || l === !1))
378
+ if ((m = typeof l) == "object" && l.nodeType)
379
+ e.push(l);
380
+ else if (Array.isArray(l))
381
+ o = ne(e, l, f) || o;
382
+ else if (m === "function")
383
+ if (s) {
384
+ for (; typeof l == "function"; )
385
+ l = l();
386
+ o = ne(
387
+ e,
388
+ Array.isArray(l) ? l : [l],
389
+ Array.isArray(f) ? f : [f]
390
+ ) || o;
391
+ } else
392
+ e.push(l), o = !0;
393
+ else {
394
+ const h = String(l);
395
+ f && f.nodeType === 3 && f.data === h ? e.push(f) : e.push(document.createTextNode(h));
396
+ }
397
+ }
398
+ return o;
399
+ }
400
+ function pe(e, t, n = null) {
401
+ for (let s = 0, o = t.length; s < o; s++)
402
+ e.insertBefore(t[s], n);
403
+ }
404
+ function $(e, t, n, s) {
405
+ if (n === void 0)
406
+ return e.textContent = "";
407
+ const o = s || document.createTextNode("");
408
+ if (t.length) {
409
+ let r = !1;
410
+ for (let i = t.length - 1; i >= 0; i--) {
411
+ const l = t[i];
412
+ if (o !== l) {
413
+ const f = l.parentNode === e;
414
+ !r && !i ? f ? e.replaceChild(o, l) : e.insertBefore(o, n) : f && l.remove();
415
+ } else
416
+ r = !0;
417
+ }
418
+ } else
419
+ e.insertBefore(o, n);
420
+ return [o];
421
+ }
422
+ function Je(e) {
423
+ return e.varName ? ` for '${e.varName}'` : "";
424
+ }
425
+ function Qe(e, t = {}) {
426
+ if (e == null || e === "" && !t.allowEmpty)
427
+ throw new Error(`Missing string value${Je(t)}`);
428
+ return typeof e == "string" ? e : e.toString();
429
+ }
430
+ var Ce = (e) => e != null && (e = Object.getPrototypeOf(e), e === Array.prototype || e === Object.prototype);
431
+ function xe(e, t, n) {
432
+ for (const [s, o] of Object.entries(t)) {
433
+ const r = `${n}.${s}`;
434
+ e[r] = o, Ce(o) && xe(e, o, r);
435
+ }
436
+ }
437
+ function We(e) {
438
+ const t = { ...e };
439
+ for (const [n, s] of Object.entries(e))
440
+ Ce(s) && xe(t, s, n);
441
+ return t;
442
+ }
443
+ var Xe = (e, t) => {
444
+ if (t)
445
+ for (const [n, s] of Object.entries(t))
446
+ e = e.replace(new RegExp(`{{\\s*${n}\\s*}}`, "g"), s);
447
+ return e;
448
+ }, Ze = (e) => e;
449
+ function Ke(e, t = Ze) {
450
+ return (n, ...s) => {
451
+ n[0] === "." && (n = n.slice(1));
452
+ const o = e()?.[n];
453
+ switch (typeof o) {
454
+ case "function":
455
+ return o(...s);
456
+ case "string":
457
+ return t(o, s[0]);
458
+ default:
459
+ return o;
460
+ }
461
+ };
462
+ }
463
+ const ze = {
464
+ noSubject: "-no subject-",
465
+ contactFrom: "(contact from $1)",
466
+ nameIs: "<b>Name:</b> $1",
467
+ emailIs: "<b>E-mail:</b> $1",
468
+ sendUsAnEmailTo: "send us an e-mail to: $1",
469
+ sorryMessage: "sorry, the website is incorrectly configured"
470
+ }, et = {
471
+ name: "Name",
472
+ email: "Email",
473
+ subject: "Subject",
474
+ message: "Message",
475
+ send: "Send",
476
+ emailPlaceholder: "The e-mail address on which we can reply to you",
477
+ namePlaceholder: "Your name",
478
+ subjectPlaceholder: "The subject of your message",
479
+ messagePlaceholder: "Enter your message here...",
480
+ unexpectedErrorMessage: "Unexpected error, the message could not be sent.",
481
+ returnHome: "Return Home",
482
+ successMessage: "Your message has been sent. If there is a response, it will be sent to the address"
483
+ }, tt = {
484
+ mail: ze,
485
+ contactForm: et
486
+ }, nt = {
487
+ noSubject: "-sans sujet-",
488
+ contactFrom: "(contact via $1)",
489
+ nameIs: "<b>Nom :</b> $1",
490
+ emailIs: "<b>E-mail :</b> $1",
491
+ sendUsAnEmailTo: "envoyez-nous un e-mail directement à : $1",
492
+ sorryMessage: "désolé, le site est mal configuré"
493
+ }, st = {
494
+ name: "Nom",
495
+ email: "E-mail",
496
+ subject: "Sujet",
497
+ message: "Message",
498
+ send: "Envoyer",
499
+ emailPlaceholder: "L'adresse e-mail sur laquelle nous pourrons vous répondre",
500
+ namePlaceholder: "Votre nom",
501
+ subjectPlaceholder: "Le sujet de votre message",
502
+ messagePlaceholder: "Saisissez votre message",
503
+ unexpectedErrorMessage: "Erreur inattendue, le message n'a pas pu être envoyé.",
504
+ returnHome: "Retourner à l'accueil",
505
+ successMessage: "Votre message a été envoyé. S'il y a une réponse, elle sera envoyée à l'adresse"
506
+ }, ot = {
507
+ mail: nt,
508
+ contactForm: st
509
+ }, ge = { en: tt, fr: ot };
510
+ function lt(e) {
511
+ const t = ee(() => {
512
+ const s = e in ge ? e : "en";
513
+ return We(ge[s]);
514
+ });
515
+ return { t: Ke(t, Xe) };
516
+ }
517
+ async function rt(e, t, n) {
518
+ n(!0);
519
+ try {
520
+ const s = await it(e);
521
+ return t.reset(), s;
522
+ } finally {
523
+ n(!1);
524
+ }
525
+ }
526
+ async function it(e) {
527
+ const t = await fetch("/api/plugin/contact-form", {
528
+ headers: {
529
+ "Content-Type": "application/json"
530
+ },
531
+ body: JSON.stringify(e),
532
+ method: "POST"
533
+ });
534
+ if (t.status !== 200) {
535
+ const s = await t.text();
536
+ throw new Error(`Unexpected error: ${s}`);
537
+ }
538
+ return await t.json();
539
+ }
540
+ var ct = /* @__PURE__ */ G("<div class=ContactForm-error>"), at = /* @__PURE__ */ G('<div class="ContactForm-done ContactForm-ended"><div class=ContactForm-endedMessage><p></p><p></p></div><div class=ContactForm-endedActions><a class=BigBtn>'), ut = /* @__PURE__ */ G("<form class=ContactForm><div class=ContactForm-fieldGroup><label class=ContactFormField><span class=ContactFormField-label></span><input class=ContactFormField-input type=email name=email required></label><label class=ContactFormField><span class=ContactFormField-label></span><input class=ContactFormField-input type=text name=name required></label><label class=ContactFormField><span class=ContactFormField-label></span><input class=ContactFormField-input type=text name=subject></label><label class=ContactFormField><span class=ContactFormField-label></span><textarea class=ContactFormField-textarea rows=5 name=message required></textarea></label></div><div class=ContactForm-action><button type=submit class=ContactForm-btn>"), ft = /* @__PURE__ */ G("<div class=ContactForm-captcha><div class=g-recaptcha data-callback=onRecaptchaSubmitted data-expired-callback=onRecaptchaExpired>");
541
+ function dt({
542
+ recaptchaKey: e,
543
+ language: t,
544
+ homeUrl: n
545
+ }) {
546
+ const [s, o] = y(""), [r, i] = y(""), [l, f] = y(), [m, h] = y(""), [w, j] = y(), [M, N] = y(!e), [oe, Y] = y(), [$e, le] = y(""), [Ae, je] = y(!1), {
547
+ t: p
548
+ } = lt(t), Me = async (b) => {
549
+ try {
550
+ if (b.preventDefault(), !M() || !L)
551
+ throw new Error("Erreur de recaptcha");
552
+ const F = await rt({
553
+ language: t,
554
+ name: s(),
555
+ subject: l(),
556
+ message: m(),
557
+ email: r(),
558
+ gRecaptchaResponse: w()
559
+ }, L, je);
560
+ F.success ? Y(!0) : (Y(!1), le(F.message ?? p("contactForm.unexpectedErrorMessage")));
561
+ } catch {
562
+ Y(!1), le(p("contactForm.unexpectedErrorMessage"));
563
+ }
564
+ }, L = (() => {
565
+ var b = ut(), F = b.firstChild, re = F.firstChild, ie = re.firstChild, J = ie.nextSibling, ce = re.nextSibling, ae = ce.firstChild, Q = ae.nextSibling, ue = ce.nextSibling, fe = ue.firstChild, W = fe.nextSibling, _e = ue.nextSibling, de = _e.firstChild, X = de.nextSibling, Z = F.nextSibling, K = Z.firstChild;
566
+ return b.addEventListener("submit", Me), g(ie, () => p("contactForm.email")), J.addEventListener("change", (c) => {
567
+ i(c.currentTarget.value);
568
+ }), g(ae, () => p("contactForm.name")), Q.addEventListener("change", (c) => o(c.currentTarget.value)), g(fe, () => p("contactForm.subject")), W.addEventListener("change", (c) => f(c.currentTarget.value)), g(de, () => p("contactForm.message")), X.addEventListener("change", (c) => h(c.currentTarget.value)), g(b, e && (() => {
569
+ var c = ft(), C = c.firstChild;
570
+ return x(C, "data-sitekey", e), c;
571
+ })(), Z), g(b, te(me, {
572
+ get when() {
573
+ return oe() === !1;
574
+ },
575
+ get children() {
576
+ var c = ct();
577
+ return g(c, $e), c;
578
+ }
579
+ }), Z), g(K, () => p("contactForm.send")), g(b, te(me, {
580
+ get when() {
581
+ return oe() === !0;
582
+ },
583
+ get children() {
584
+ var c = at(), C = c.firstChild, R = C.firstChild, U = R.nextSibling, O = C.nextSibling, T = O.firstChild;
585
+ return g(R, () => p("contactForm.successMessage")), g(U, r), x(T, "href", n), g(T, () => p("contactForm.returnHome")), c;
586
+ }
587
+ }), null), S((c) => {
588
+ var C = p("contactForm.emailPlaceholder"), R = p("contactForm.namePlaceholder"), U = p("contactForm.subjectPlaceholder"), O = p("contactForm.messagePlaceholder"), T = !!Ae(), he = !M();
589
+ return C !== c.e && x(J, "placeholder", c.e = C), R !== c.t && x(Q, "placeholder", c.t = R), U !== c.a && x(W, "placeholder", c.a = U), O !== c.o && x(X, "placeholder", c.o = O), T !== c.i && K.classList.toggle("inProgress", c.i = T), he !== c.n && (K.disabled = c.n = he), c;
590
+ }, {
591
+ e: void 0,
592
+ t: void 0,
593
+ a: void 0,
594
+ o: void 0,
595
+ i: void 0,
596
+ n: void 0
597
+ }), S(() => J.value = r()), S(() => Q.value = s()), S(() => W.value = l() ?? ""), S(() => X.value = m()), b;
598
+ })();
599
+ return Oe(() => {
600
+ e && (window.onRecaptchaSubmitted = Re, window.onRecaptchaExpired = Te);
601
+ }), Ie(() => {
602
+ e && (window.onRecaptchaSubmitted = void 0, window.onRecaptchaExpired = void 0);
603
+ }), L;
604
+ function Re(b) {
605
+ if (!b)
606
+ return;
607
+ N(!0);
608
+ const F = L?.elements.namedItem("g-recaptcha-response");
609
+ j(F.value);
610
+ }
611
+ function Te() {
612
+ N(!1);
613
+ }
614
+ }
615
+ function ht(e, {
616
+ language: t
617
+ }) {
618
+ if (!t)
619
+ throw new Error("Missing language");
620
+ const n = e.dataset.recaptchaKey, s = Qe(e.dataset.homeUrl), o = document.createElement("script");
621
+ o.setAttribute("src", "https://www.google.com/recaptcha/api.js"), document.head.appendChild(o), Ye(() => te(dt, {
622
+ recaptchaKey: n,
623
+ language: t,
624
+ homeUrl: s
625
+ }), e);
626
+ }
627
+ document.addEventListener("DOMContentLoaded", () => {
628
+ const e = document.documentElement.lang, t = document.querySelector("[data-effect='contactForm']");
629
+ t && ht(t, {
630
+ language: e
631
+ });
632
+ });
@@ -0,0 +1 @@
1
+ .ContactForm{margin-bottom:30px;margin-left:auto;margin-right:auto;position:relative}.ContactForm-error{margin:50px 50px 0;padding:20px}.ContactForm-done{display:flex;inset:0;position:absolute}.ContactForm-action{display:flex;justify-content:center;margin-top:50px}@media (max-width: 800px){.ContactForm-action{margin-top:30px}}.ContactForm-ended{align-content:center;align-items:center;flex-direction:column;justify-content:center;padding:20px;text-align:center;transition:opacity .4s;width:100%}.ContactForm-endedMessage{max-width:500px;font-size:18px;line-height:1.5}.ContactForm-endedActions{display:flex;gap:10px;margin-top:50px}.ContactForm-fieldGroup>*{margin-bottom:20px}.ContactFormField{display:block}.ContactFormField-label{display:block;font-size:16px;margin-bottom:5px}.ContactFormField-input,.ContactFormField-textarea{font-size:16px;display:block;padding:8px;width:100%}.ContactForm-btn{border:2px solid #ddbe8b;display:inline-block;font-size:20px;padding:12px 40px;position:relative;text-align:center}.ContactForm-btn:disabled{cursor:not-allowed}.ContactForm-btn.inProgress{pointer-events:none}.ContactForm-btn.inProgress:before{animation:contactFormSpin 2s linear infinite;border-radius:50%;box-sizing:border-box;content:"";display:block;height:26px;position:absolute;right:6px;top:calc(50% - 13px);width:26px}@keyframes contactFormSpin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}
@@ -0,0 +1,24 @@
1
+ {
2
+ "mail": {
3
+ "noSubject": "-no subject-",
4
+ "contactFrom": "(contact from $1)",
5
+ "nameIs": "<b>Name:</b> $1",
6
+ "emailIs": "<b>E-mail:</b> $1",
7
+ "sendUsAnEmailTo": "send us an e-mail to: $1",
8
+ "sorryMessage": "sorry, the website is incorrectly configured"
9
+ },
10
+ "contactForm": {
11
+ "name": "Name",
12
+ "email": "Email",
13
+ "subject": "Subject",
14
+ "message": "Message",
15
+ "send": "Send",
16
+ "emailPlaceholder": "The e-mail address on which we can reply to you",
17
+ "namePlaceholder": "Your name",
18
+ "subjectPlaceholder": "The subject of your message",
19
+ "messagePlaceholder": "Enter your message here...",
20
+ "unexpectedErrorMessage": "Unexpected error, the message could not be sent.",
21
+ "returnHome": "Return Home",
22
+ "successMessage": "Your message has been sent. If there is a response, it will be sent to the address"
23
+ }
24
+ }
@@ -0,0 +1,24 @@
1
+ {
2
+ "mail": {
3
+ "noSubject": "-sans sujet-",
4
+ "contactFrom": "(contact via $1)",
5
+ "nameIs": "<b>Nom :</b> $1",
6
+ "emailIs": "<b>E-mail :</b> $1",
7
+ "sendUsAnEmailTo": "envoyez-nous un e-mail directement à : $1",
8
+ "sorryMessage": "désolé, le site est mal configuré"
9
+ },
10
+ "contactForm": {
11
+ "name": "Nom",
12
+ "email": "E-mail",
13
+ "subject": "Sujet",
14
+ "message": "Message",
15
+ "send": "Envoyer",
16
+ "emailPlaceholder": "L'adresse e-mail sur laquelle nous pourrons vous répondre",
17
+ "namePlaceholder": "Votre nom",
18
+ "subjectPlaceholder": "Le sujet de votre message",
19
+ "messagePlaceholder": "Saisissez votre message",
20
+ "unexpectedErrorMessage": "Erreur inattendue, le message n'a pas pu être envoyé.",
21
+ "returnHome": "Retourner à l'accueil",
22
+ "successMessage": "Votre message a été envoyé. S'il y a une réponse, elle sera envoyée à l'adresse"
23
+ }
24
+ }
package/package.json ADDED
@@ -0,0 +1,52 @@
1
+ {
2
+ "name": "@paroicms/contact-form-plugin",
3
+ "version": "0.3.0",
4
+ "description": "Contact form for ParoiCMS",
5
+ "keywords": [
6
+ "paroicms",
7
+ "plugin",
8
+ "contact",
9
+ "form"
10
+ ],
11
+ "repository": {
12
+ "type": "git",
13
+ "url": "https://gitlab.com/paroi/opensource/paroicms.git",
14
+ "directory": "plugins/contact-form"
15
+ },
16
+ "author": "Paroi Team",
17
+ "license": "MIT",
18
+ "scripts": {
19
+ "dev": "vite",
20
+ "build": "npm run build:backend && npm run build:frontend",
21
+ "build:backend": "tsc --project tsconfig.backend.json",
22
+ "build:frontend": "tsc && vite build",
23
+ "clear": "rimraf bo-dist/*",
24
+ "preview": "vite preview"
25
+ },
26
+ "dependencies": {
27
+ "@paroi/data-formatters-lib": "~0.4.0"
28
+ },
29
+ "peerDependencies": {
30
+ "@paroicms/internal-anywhere-lib": "1",
31
+ "@paroicms/public-server-lib": "0"
32
+ },
33
+ "devDependencies": {
34
+ "@paroicms/public-anywhere-lib": "0.2.0",
35
+ "@paroicms/public-server-lib": "0.6.0",
36
+ "@solid-primitives/i18n": "~2.1.1",
37
+ "@types/node": "~20.12.8",
38
+ "rimraf": "~5.0.5",
39
+ "sass": "~1.76.0",
40
+ "solid-devtools": "~0.30.1",
41
+ "solid-js": "~1.8.17",
42
+ "typescript": "~5.4.5",
43
+ "vite": "~5.2.11",
44
+ "vite-plugin-solid": "~2.10.2"
45
+ },
46
+ "main": "dist-backend/plugin.js",
47
+ "files": [
48
+ "dist-frontend",
49
+ "dist-backend",
50
+ "locales"
51
+ ]
52
+ }