domma-cms 0.2.1 → 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.
Files changed (70) hide show
  1. package/admin/css/admin.css +1 -1200
  2. package/admin/js/api.js +1 -242
  3. package/admin/js/app.js +5 -279
  4. package/admin/js/config/sidebar-config.js +1 -115
  5. package/admin/js/lib/card.js +1 -63
  6. package/admin/js/lib/image-editor.js +1 -869
  7. package/admin/js/lib/markdown-toolbar.js +46 -421
  8. package/admin/js/templates/layouts.html +44 -7
  9. package/admin/js/templates/page-editor.html +9 -0
  10. package/admin/js/templates/settings.html +18 -1
  11. package/admin/js/templates/users.html +29 -4
  12. package/admin/js/views/collection-editor.js +3 -487
  13. package/admin/js/views/collection-entries.js +1 -484
  14. package/admin/js/views/collections.js +1 -153
  15. package/admin/js/views/dashboard.js +1 -56
  16. package/admin/js/views/documentation.js +1 -12
  17. package/admin/js/views/index.js +1 -39
  18. package/admin/js/views/layouts.js +9 -42
  19. package/admin/js/views/login.js +7 -251
  20. package/admin/js/views/media.js +1 -240
  21. package/admin/js/views/navigation.js +14 -212
  22. package/admin/js/views/page-editor.js +53 -661
  23. package/admin/js/views/pages.js +5 -72
  24. package/admin/js/views/plugins.js +13 -90
  25. package/admin/js/views/settings.js +1 -199
  26. package/admin/js/views/tutorials.js +1 -12
  27. package/admin/js/views/user-editor.js +1 -88
  28. package/admin/js/views/users.js +7 -76
  29. package/config/auth.json +1 -17
  30. package/config/navigation.json +15 -0
  31. package/config/site.json +5 -4
  32. package/package.json +1 -1
  33. package/plugins/domma-effects/public/celebrations/core/canvas.js +2 -104
  34. package/plugins/domma-effects/public/celebrations/core/particles.js +1 -144
  35. package/plugins/domma-effects/public/celebrations/core/physics.js +1 -166
  36. package/plugins/domma-effects/public/celebrations/index.js +1 -535
  37. package/plugins/domma-effects/public/celebrations/themes/christmas.js +1 -1805
  38. package/plugins/domma-effects/public/celebrations/themes/guy-fawkes.js +1 -1477
  39. package/plugins/domma-effects/public/celebrations/themes/halloween.js +1 -1837
  40. package/plugins/domma-effects/public/celebrations/themes/st-andrews.js +1 -1175
  41. package/plugins/domma-effects/public/celebrations/themes/st-davids.js +1 -1258
  42. package/plugins/domma-effects/public/celebrations/themes/st-georges.js +1 -1754
  43. package/plugins/domma-effects/public/celebrations/themes/st-patricks.js +1 -1290
  44. package/plugins/domma-effects/public/celebrations/themes/valentines.js +1 -1361
  45. package/plugins/example-analytics/stats.json +16 -12
  46. package/plugins/form-builder/admin/templates/form-editor.html +158 -130
  47. package/plugins/form-builder/admin/views/form-editor.js +3 -1
  48. package/plugins/form-builder/data/forms/contact-details.json +71 -35
  49. package/plugins/form-builder/data/forms/feedback.json +130 -0
  50. package/plugins/form-builder/data/submissions/feedback.json +1 -0
  51. package/plugins/form-builder/public/form-logic-engine.js +1 -568
  52. package/public/css/site.css +1 -302
  53. package/public/js/btt.js +1 -90
  54. package/public/js/cookie-consent.js +1 -61
  55. package/public/js/site.js +1 -204
  56. package/scripts/setup.js +4 -4
  57. package/server/middleware/auth.js +44 -21
  58. package/server/routes/api/auth.js +38 -8
  59. package/server/routes/api/collections.js +18 -5
  60. package/server/routes/api/layouts.js +18 -4
  61. package/server/routes/api/media.js +2 -3
  62. package/server/routes/api/navigation.js +2 -3
  63. package/server/routes/api/pages.js +3 -3
  64. package/server/routes/api/settings.js +2 -3
  65. package/server/routes/api/users.js +4 -6
  66. package/server/routes/public.js +3 -3
  67. package/server/server.js +8 -0
  68. package/server/services/markdown.js +102 -3
  69. package/server/services/userTypes.js +167 -0
  70. package/plugins/form-builder/email.js +0 -103
@@ -1,15 +1,19 @@
1
1
  {
2
- "/": 31,
3
- "/about": 28,
4
- "/blog": 11,
5
- "/contact": 10,
6
- "/resources/typography": 3,
7
- "/resources": 2,
8
- "/resources/shortcodes": 5,
9
- "/resources/cards": 1,
10
- "/resources/interactive": 12,
11
- "/resources/grid": 4,
2
+ "/": 64,
3
+ "/about": 50,
4
+ "/blog": 21,
5
+ "/contact": 22,
6
+ "/resources/typography": 4,
7
+ "/resources": 4,
8
+ "/resources/shortcodes": 6,
9
+ "/resources/cards": 3,
10
+ "/resources/interactive": 13,
11
+ "/resources/grid": 5,
12
12
  "/forms": 14,
13
- "/resources/effects": 3,
14
- "/blog/hello-world": 14
13
+ "/resources/effects": 6,
14
+ "/blog/hello-world": 19,
15
+ "/feedback": 10,
16
+ "/resources/dependencies": 1,
17
+ "/resources/components": 1,
18
+ "/gdpr": 1
15
19
  }
@@ -13,159 +13,187 @@
13
13
  </div>
14
14
  </div>
15
15
 
16
- <div class="row">
17
- <!-- Left column: metadata + fields -->
18
- <div class="col-8">
19
- <div class="card mb-4">
20
- <div class="card-header"><h2>Form Details</h2></div>
21
- <div class="card-body">
22
- <div class="row mb-3">
23
- <div class="col-7">
24
- <label class="form-label">Title</label>
25
- <input id="field-title" type="text" class="form-input" placeholder="My Form">
26
- </div>
27
- <div class="col-5">
28
- <label class="form-label">Slug</label>
29
- <input id="field-slug" type="text" class="form-input" placeholder="my-form">
30
- <p class="form-hint text-muted" style="margin-top:.3rem;font-size:.8rem;">Used in embed: <code>data-form="slug"</code></p>
31
- </div>
32
- </div>
33
- <div class="row">
34
- <div class="col">
35
- <label class="form-label">Description</label>
36
- <textarea id="field-description" class="form-input" rows="2" placeholder="Optional form description..."></textarea>
37
- </div>
38
- </div>
16
+ <div class="tabs" id="editor-tabs">
17
+ <div class="tab-list">
18
+ <button class="tab-item active">Fields</button>
19
+ <button class="tab-item">Form Details</button>
20
+ <button class="tab-item">Settings</button>
21
+ <button class="tab-item">Actions</button>
22
+ </div>
23
+ <div class="tab-content">
24
+
25
+ <!-- Tab 1: Fields -->
26
+ <div class="tab-panel active">
27
+ <div class="card mb-4">
28
+ <div class="card-header" style="display:flex;justify-content:space-between;align-items:center;">
29
+ <h2>Fields</h2>
30
+ <div id="add-element-dropdown" style="position:relative;">
31
+ <button id="add-element-btn" class="btn btn-ghost btn-sm" type="button">
32
+ <span data-icon="plus"></span> Add <span
33
+ style="font-size:.65rem;opacity:.6;margin-left:.1rem;">▾</span>
34
+ </button>
35
+ <div id="add-element-menu"
36
+ style="display:none;position:absolute;right:0;top:calc(100% + .2rem);background:var(--card-bg,#1e1e2e);border:1px solid var(--border-color,#333);border-radius:6px;min-width:140px;z-index:100;box-shadow:0 4px 16px rgba(0,0,0,.3);overflow:hidden;">
37
+ <button id="add-field-btn" type="button"
38
+ style="display:block;width:100%;text-align:left;padding:.5rem .85rem;background:none;border:none;color:inherit;cursor:pointer;font-size:.875rem;border-bottom:1px solid var(--border-color,#333);">
39
+ Field
40
+ </button>
41
+ <button id="add-spacer-btn" type="button"
42
+ style="display:block;width:100%;text-align:left;padding:.5rem .85rem;background:none;border:none;color:inherit;cursor:pointer;font-size:.875rem;border-bottom:1px solid var(--border-color,#333);">
43
+ Spacer
44
+ </button>
45
+ <button id="add-page-break-btn" type="button"
46
+ style="display:block;width:100%;text-align:left;padding:.5rem .85rem;background:none;border:none;color:inherit;cursor:pointer;font-size:.875rem;">
47
+ Page Break
48
+ </button>
39
49
  </div>
50
+ </div>
40
51
  </div>
52
+ <div class="card-body" style="padding:0;">
53
+ <div id="fields-list" style="padding:1rem;">
54
+ <p class="text-muted" id="fields-empty-msg" style="text-align:center;padding:2rem 0;">No fields yet. Click
55
+ "Add Field" to get started.</p>
56
+ </div>
57
+ </div>
58
+ </div>
41
59
 
42
- <div class="card mb-4">
43
- <div class="card-header" style="display:flex;justify-content:space-between;align-items:center;">
44
- <h2>Fields</h2>
45
- <div id="add-element-dropdown" style="position:relative;">
46
- <button id="add-element-btn" class="btn btn-ghost btn-sm" type="button">
47
- <span data-icon="plus"></span> Add <span
48
- style="font-size:.65rem;opacity:.6;margin-left:.1rem;">▾</span>
49
- </button>
50
- <div id="add-element-menu"
51
- style="display:none;position:absolute;right:0;top:calc(100% + .2rem);background:var(--card-bg,#1e1e2e);border:1px solid var(--border-color,#333);border-radius:6px;min-width:140px;z-index:100;box-shadow:0 4px 16px rgba(0,0,0,.3);overflow:hidden;">
52
- <button id="add-field-btn" type="button"
53
- style="display:block;width:100%;text-align:left;padding:.5rem .85rem;background:none;border:none;color:inherit;cursor:pointer;font-size:.875rem;border-bottom:1px solid var(--border-color,#333);">
54
- Field
55
- </button>
56
- <button id="add-spacer-btn" type="button"
57
- style="display:block;width:100%;text-align:left;padding:.5rem .85rem;background:none;border:none;color:inherit;cursor:pointer;font-size:.875rem;border-bottom:1px solid var(--border-color,#333);">
58
- Spacer
59
- </button>
60
- <button id="add-page-break-btn" type="button"
61
- style="display:block;width:100%;text-align:left;padding:.5rem .85rem;background:none;border:none;color:inherit;cursor:pointer;font-size:.875rem;">
62
- Page Break
63
- </button>
64
- </div>
65
- </div>
66
- </div>
67
- <div class="card-body" style="padding:0;">
68
- <div id="fields-list" style="padding:1rem;">
69
- <p class="text-muted" id="fields-empty-msg" style="text-align:center;padding:2rem 0;">No fields yet. Click "Add Field" to get started.</p>
70
- </div>
71
- </div>
60
+ <div class="card mb-4" id="preview-card" style="display:none;">
61
+ <div class="card-header" style="display:flex;justify-content:space-between;align-items:center;">
62
+ <h2><span data-icon="eye"></span> Preview</h2>
63
+ <span id="preview-test-badge"
64
+ style="display:none;font-size:.75rem;padding:.2rem .6rem;border-radius:999px;background:rgba(99,102,241,.15);color:var(--primary,#6366f1);">Test Mode submissions are stored</span>
65
+ </div>
66
+ <div class="card-body">
67
+ <div id="preview-container"></div>
68
+ <div id="preview-test-result"
69
+ style="display:none;margin-top:.75rem;padding:.6rem .9rem;border-radius:6px;font-size:.9rem;"></div>
72
70
  </div>
71
+ </div>
72
+ </div>
73
73
 
74
- <div class="card mb-4" id="preview-card" style="display:none;">
75
- <div class="card-header" style="display:flex;justify-content:space-between;align-items:center;">
76
- <h2><span data-icon="eye"></span> Preview</h2>
77
- <span id="preview-test-badge"
78
- style="display:none;font-size:.75rem;padding:.2rem .6rem;border-radius:999px;background:rgba(99,102,241,.15);color:var(--primary,#6366f1);">Test Mode — submissions are stored</span>
74
+ <!-- Tab 2: Form Details -->
75
+ <div class="tab-panel">
76
+ <div class="card mb-4">
77
+ <div class="card-header"><h2>Form Details</h2></div>
78
+ <div class="card-body">
79
+ <div class="row mb-3">
80
+ <div class="col-7">
81
+ <label class="form-label">Title</label>
82
+ <input id="field-title" type="text" class="form-input" placeholder="My Form">
83
+ </div>
84
+ <div class="col-5">
85
+ <label class="form-label">Slug</label>
86
+ <input id="field-slug" type="text" class="form-input" placeholder="my-form">
87
+ <p class="form-hint text-muted" style="margin-top:.3rem;font-size:.8rem;">Used in embed: <code>data-form="slug"</code>
88
+ </p>
89
+ </div>
79
90
  </div>
80
- <div class="card-body">
81
- <div id="preview-container"></div>
82
- <div id="preview-test-result"
83
- style="display:none;margin-top:.75rem;padding:.6rem .9rem;border-radius:6px;font-size:.9rem;"></div>
91
+ <div class="row">
92
+ <div class="col">
93
+ <label class="form-label">Description</label>
94
+ <textarea id="field-description" class="form-input" rows="2"
95
+ placeholder="Optional form description..."></textarea>
84
96
  </div>
97
+ </div>
85
98
  </div>
99
+ </div>
86
100
  </div>
87
101
 
88
- <!-- Right column: settings + actions -->
89
- <div class="col-4">
90
- <div class="card mb-4">
91
- <div class="card-header"><h2>Settings</h2></div>
92
- <div class="card-body">
93
- <div class="mb-3">
94
- <label class="form-label">Submit Button Text</label>
95
- <input id="setting-submit-text" type="text" class="form-input" placeholder="Submit" value="Submit">
96
- </div>
97
- <div class="mb-3">
98
- <label class="form-label">Success Message</label>
99
- <textarea id="setting-success-message" class="form-input" rows="3" placeholder="Thank you for your submission."></textarea>
100
- </div>
101
- <div>
102
- <label class="form-label">Layout</label>
103
- <select id="setting-layout" class="form-input">
104
- <option value="stacked">Stacked</option>
105
- <option value="inline">Inline</option>
106
- </select>
102
+ <!-- Tab 3: Settings -->
103
+ <div class="tab-panel">
104
+ <div class="card mb-4">
105
+ <div class="card-header"><h2>Settings</h2></div>
106
+ <div class="card-body">
107
+ <div class="mb-3">
108
+ <label class="form-label">Submit Button Text</label>
109
+ <input id="setting-submit-text" type="text" class="form-input" placeholder="Submit" value="Submit">
110
+ </div>
111
+ <div class="mb-3">
112
+ <label class="form-label">Success Message</label>
113
+ <textarea id="setting-success-message" class="form-input" rows="3"
114
+ placeholder="Thank you for your submission."></textarea>
115
+ </div>
116
+ <div>
117
+ <label class="form-label">Layout</label>
118
+ <select id="setting-layout" class="form-input">
119
+ <option value="stacked">Stacked</option>
120
+ <option value="inline">Inline</option>
121
+ </select>
122
+ </div>
107
123
  </div>
108
124
  </div>
109
125
  </div>
110
126
 
111
- <div class="card mb-4">
127
+ <!-- Tab 4: Actions -->
128
+ <div class="tab-panel">
129
+ <div class="row">
130
+ <div class="col-6">
131
+ <div class="card mb-4">
112
132
  <div class="card-header"><h2>Email Action</h2></div>
113
133
  <div class="card-body">
114
- <div class="mb-3">
115
- <label class="form-label" style="display:flex;align-items:center;gap:.5rem;cursor:pointer;">
116
- <input id="action-email-enabled" type="checkbox"> Send email on submit
117
- </label>
118
- </div>
119
- <div class="mb-3">
120
- <label class="form-label">Recipients</label>
121
- <input id="action-email-recipients" type="text" class="form-input" placeholder="admin@example.com">
122
- <p class="form-hint text-muted" style="margin-top:.3rem;font-size:.8rem;">Comma-separated. Uses global SMTP settings.</p>
123
- </div>
124
- <div>
125
- <label class="form-label">Subject Prefix</label>
126
- <input id="action-email-subject-prefix" type="text" class="form-input" placeholder="[Form]">
127
- </div>
134
+ <div class="mb-3">
135
+ <label class="form-label" style="display:flex;align-items:center;gap:.5rem;cursor:pointer;">
136
+ <input id="action-email-enabled" type="checkbox"> Send email on submit
137
+ </label>
138
+ </div>
139
+ <div class="mb-3">
140
+ <label class="form-label">Recipients</label>
141
+ <input id="action-email-recipients" type="text" class="form-input" placeholder="admin@example.com">
142
+ <p class="form-hint text-muted" style="margin-top:.3rem;font-size:.8rem;">Comma-separated. Uses global
143
+ SMTP settings.</p>
144
+ </div>
145
+ <div>
146
+ <label class="form-label">Subject Prefix</label>
147
+ <input id="action-email-subject-prefix" type="text" class="form-input" placeholder="[Form]">
148
+ </div>
128
149
  </div>
150
+ </div>
129
151
  </div>
130
-
131
- <div class="card mb-4">
152
+ <div class="col-6">
153
+ <div class="card mb-4">
132
154
  <div class="card-header"><h2>Webhook Action</h2></div>
133
155
  <div class="card-body">
134
- <div class="mb-3">
135
- <label class="form-label" style="display:flex;align-items:center;gap:.5rem;cursor:pointer;">
136
- <input id="action-webhook-enabled" type="checkbox"> POST to webhook on submit
137
- </label>
138
- </div>
139
- <div class="mb-3">
140
- <label class="form-label">URL</label>
141
- <input id="action-webhook-url" type="url" class="form-input" placeholder="https://hooks.example.com/form">
142
- </div>
143
- <div>
144
- <label class="form-label">Method</label>
145
- <select id="action-webhook-method" class="form-input">
146
- <option value="POST">POST</option>
147
- <option value="PUT">PUT</option>
148
- </select>
149
- </div>
156
+ <div class="mb-3">
157
+ <label class="form-label" style="display:flex;align-items:center;gap:.5rem;cursor:pointer;">
158
+ <input id="action-webhook-enabled" type="checkbox"> POST to webhook on submit
159
+ </label>
160
+ </div>
161
+ <div class="mb-3">
162
+ <label class="form-label">URL</label>
163
+ <input id="action-webhook-url" type="url" class="form-input"
164
+ placeholder="https://hooks.example.com/form">
165
+ </div>
166
+ <div>
167
+ <label class="form-label">Method</label>
168
+ <select id="action-webhook-method" class="form-input">
169
+ <option value="POST">POST</option>
170
+ <option value="PUT">PUT</option>
171
+ </select>
172
+ </div>
150
173
  </div>
174
+ </div>
151
175
  </div>
176
+ </div>
152
177
 
153
- <div class="card mb-4">
154
- <div class="card-header"><h2>Spam Protection</h2></div>
155
- <div class="card-body">
156
- <div class="mb-3">
157
- <label class="form-label" style="display:flex;align-items:center;gap:.5rem;cursor:pointer;">
158
- <input id="setting-honeypot" type="checkbox" checked> Enable honeypot field
159
- </label>
160
- <p class="form-hint text-muted" style="margin-top:.3rem;font-size:.8rem;">Silently discards bot submissions that fill a hidden field.</p>
161
- </div>
162
- <div>
163
- <label class="form-label">Rate Limit (per minute)</label>
164
- <input id="setting-rate-limit" type="number" class="form-input" min="1" max="60" value="3">
165
- <p class="form-hint text-muted" style="margin-top:.3rem;font-size:.8rem;">Max submissions per IP per minute.</p>
166
- </div>
167
- </div>
178
+ <div class="card mb-4">
179
+ <div class="card-header"><h2>Spam Protection</h2></div>
180
+ <div class="card-body">
181
+ <div class="mb-3">
182
+ <label class="form-label" style="display:flex;align-items:center;gap:.5rem;cursor:pointer;">
183
+ <input id="setting-honeypot" type="checkbox" checked> Enable honeypot field
184
+ </label>
185
+ <p class="form-hint text-muted" style="margin-top:.3rem;font-size:.8rem;">Silently discards bot submissions
186
+ that fill a hidden field.</p>
187
+ </div>
188
+ <div>
189
+ <label class="form-label">Rate Limit (per minute)</label>
190
+ <input id="setting-rate-limit" type="number" class="form-input" min="1" max="60" value="3">
191
+ <p class="form-hint text-muted" style="margin-top:.3rem;font-size:.8rem;">Max submissions per IP per
192
+ minute.</p>
193
+ </div>
168
194
  </div>
195
+ </div>
169
196
  </div>
170
- </div>
171
197
 
198
+ </div>
199
+ </div>
@@ -948,7 +948,7 @@ function buildCascadeSection(cascade, idx, otherFields) {
948
948
 
949
949
  function buildFieldLogic(field, idx) {
950
950
  const logic = field.logic || {};
951
- const otherFields = fields.filter((f, i) => i !== idx && f.type !== 'page-break');
951
+ const otherFields = fields.filter((f, i) => i !== idx && f.type !== 'page-break' && f.type !== 'spacer');
952
952
 
953
953
  const section = document.createElement('div');
954
954
  section.className = 'fb-field-logic';
@@ -1262,6 +1262,8 @@ export const formEditorView = {
1262
1262
  });
1263
1263
  }
1264
1264
 
1265
+ E.tabs($container.find('#editor-tabs').get(0));
1266
+
1265
1267
  renderFieldList($container);
1266
1268
 
1267
1269
  // --- Add dropdown toggle ---
@@ -1,54 +1,90 @@
1
1
  {
2
2
  "slug": "contact-details",
3
- "title": "Contact Details",
4
- "description": "",
3
+ "title": "Contact Us",
4
+ "description": "Get in touch with us",
5
5
  "fields": [
6
6
  {
7
- "name": "are_you_going",
8
- "type": "checkbox-group",
9
- "label": "Are you going?",
7
+ "name": "full_name",
8
+ "type": "string",
9
+ "label": "Full Name",
10
+ "required": true,
11
+ "placeholder": "Your full name",
12
+ "helper": "",
13
+ "validation": {
14
+ "min": 2,
15
+ "max": 100
16
+ }
17
+ },
18
+ {
19
+ "name": "email",
20
+ "type": "email",
21
+ "label": "Email Address",
22
+ "required": true,
23
+ "placeholder": "your@email.com",
24
+ "helper": ""
25
+ },
26
+ {
27
+ "name": "phone",
28
+ "type": "tel",
29
+ "label": "Phone Number",
10
30
  "required": false,
11
- "placeholder": "",
31
+ "placeholder": "+44 7700 000000",
32
+ "helper": "Optional"
33
+ },
34
+ {
35
+ "name": "subject",
36
+ "type": "select",
37
+ "label": "Subject",
38
+ "required": true,
39
+ "placeholder": "Please select a subject",
12
40
  "helper": "",
13
41
  "options": [
14
- {
15
- "value": "yes",
16
- "label": "Yes"
17
- },
18
- {
19
- "value": "no",
20
- "label": "No"
21
- },
22
- {
23
- "value": "maybe",
24
- "label": "Maybe"
25
- }
42
+ {
43
+ "value": "general",
44
+ "label": "General Enquiry"
45
+ },
46
+ {
47
+ "value": "support",
48
+ "label": "Support"
49
+ },
50
+ {
51
+ "value": "sales",
52
+ "label": "Sales"
53
+ },
54
+ {
55
+ "value": "partnership",
56
+ "label": "Partnership"
57
+ },
58
+ {
59
+ "value": "other",
60
+ "label": "Other"
61
+ }
26
62
  ]
27
- },
28
- {
29
- "type": "page-break",
30
- "label": "Email",
31
- "description": "Personal Details"
32
- },
33
- {
34
- "name": "name",
35
- "type": "string",
36
- "label": "Name",
37
- "required": false,
38
- "placeholder": "Name",
39
- "helper": "Enter your email address"
63
+ },
64
+ {
65
+ "name": "message",
66
+ "type": "textarea",
67
+ "label": "Message",
68
+ "required": true,
69
+ "placeholder": "How can we help you?",
70
+ "helper": "",
71
+ "rows": 4,
72
+ "validation": {
73
+ "min": 10,
74
+ "max": 2000
75
+ }
40
76
  }
41
77
  ],
42
78
  "settings": {
43
- "submitText": "Submit",
44
- "successMessage": "Thank you for your submission.",
79
+ "submitText": "Send Message",
80
+ "successMessage": "Thanks for reaching out! We'll get back to you shortly.",
45
81
  "layout": "stacked",
46
82
  "honeypot": true,
47
83
  "rateLimitPerMinute": 3
48
84
  },
49
85
  "actions": {
50
86
  "email": {
51
- "enabled": false,
87
+ "enabled": true,
52
88
  "recipients": "",
53
89
  "subjectPrefix": "[contact-details]"
54
90
  },
@@ -59,5 +95,5 @@
59
95
  }
60
96
  },
61
97
  "createdAt": "2026-03-03T11:05:45.630Z",
62
- "updatedAt": "2026-03-03T12:31:49.644Z"
98
+ "updatedAt": "2026-03-05T00:00:00.000Z"
63
99
  }
@@ -0,0 +1,130 @@
1
+ {
2
+ "slug": "feedback",
3
+ "title": "Feedback",
4
+ "description": "Share your feedback with us",
5
+ "fields": [
6
+ {
7
+ "name": "name",
8
+ "type": "string",
9
+ "label": "Your Name",
10
+ "required": true,
11
+ "placeholder": "Your name",
12
+ "helper": "",
13
+ "validation": {
14
+ "min": 2,
15
+ "max": 100
16
+ }
17
+ },
18
+ {
19
+ "name": "email",
20
+ "type": "email",
21
+ "label": "Email Address",
22
+ "required": true,
23
+ "placeholder": "your@email.com",
24
+ "helper": ""
25
+ },
26
+ {
27
+ "name": "rating",
28
+ "type": "radio",
29
+ "label": "Overall Rating",
30
+ "required": true,
31
+ "helper": "",
32
+ "options": [
33
+ {
34
+ "value": "excellent",
35
+ "label": "Excellent"
36
+ },
37
+ {
38
+ "value": "good",
39
+ "label": "Good"
40
+ },
41
+ {
42
+ "value": "average",
43
+ "label": "Average"
44
+ },
45
+ {
46
+ "value": "poor",
47
+ "label": "Poor"
48
+ }
49
+ ]
50
+ },
51
+ {
52
+ "name": "category",
53
+ "type": "select",
54
+ "label": "Category",
55
+ "required": true,
56
+ "placeholder": "Please select a category",
57
+ "helper": "",
58
+ "options": [
59
+ {
60
+ "value": "general",
61
+ "label": "General"
62
+ },
63
+ {
64
+ "value": "bug-report",
65
+ "label": "Bug Report"
66
+ },
67
+ {
68
+ "value": "feature-request",
69
+ "label": "Feature Request"
70
+ },
71
+ {
72
+ "value": "praise",
73
+ "label": "Praise"
74
+ }
75
+ ]
76
+ },
77
+ {
78
+ "name": "subject",
79
+ "type": "string",
80
+ "label": "Subject",
81
+ "required": true,
82
+ "placeholder": "Brief summary of your feedback",
83
+ "helper": "",
84
+ "validation": {
85
+ "max": 200
86
+ }
87
+ },
88
+ {
89
+ "name": "message",
90
+ "type": "textarea",
91
+ "label": "Your Feedback",
92
+ "required": true,
93
+ "placeholder": "Please share your thoughts in detail...",
94
+ "helper": "",
95
+ "rows": 4,
96
+ "validation": {
97
+ "min": 10,
98
+ "max": 2000
99
+ }
100
+ },
101
+ {
102
+ "name": "recommend",
103
+ "type": "checkbox",
104
+ "label": "I would recommend you to others",
105
+ "required": false,
106
+ "helper": ""
107
+ }
108
+ ],
109
+ "settings": {
110
+ "submitText": "Submit Feedback",
111
+ "successMessage": "Thank you for your feedback! We appreciate you taking the time.",
112
+ "layout": "stacked",
113
+ "honeypot": true,
114
+ "rateLimitPerMinute": 3
115
+ },
116
+ "actions": {
117
+ "email": {
118
+ "enabled": true,
119
+ "recipients": "",
120
+ "subjectPrefix": "[feedback]"
121
+ },
122
+ "webhook": {
123
+ "enabled": false,
124
+ "url": "",
125
+ "method": "POST"
126
+ }
127
+ },
128
+ "createdAt": "2026-03-05T00:00:00.000Z",
129
+ "updatedAt": "2026-03-05T00:00:00.000Z"
130
+ }