domma-cms 0.6.5 → 0.6.7
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/CLAUDE.md +159 -0
- package/README.md +1 -1
- package/bin/cli.js +2 -1
- package/config/plugins.json +19 -19
- package/package.json +5 -2
- package/plugins/{example-analytics → analytics}/plugin.js +5 -5
- package/plugins/{example-analytics → analytics}/plugin.json +2 -2
- package/plugins/{example-analytics → analytics}/public/inject-body.html +2 -2
- package/plugins/analytics/public/inject-head.html +1 -0
- package/plugins/{example-analytics → analytics}/stats.json +2 -2
- package/scripts/build.js +1 -0
- package/plugins/example-analytics/public/inject-head.html +0 -1
- package/plugins/form-builder/data/forms/contacts.json +0 -66
- package/plugins/form-builder/data/forms/enquiries.json +0 -103
- package/plugins/form-builder/data/forms/feedback.json +0 -131
- package/plugins/form-builder/data/forms/notes.json +0 -79
- package/plugins/form-builder/data/forms/to-do.json +0 -100
- package/plugins/form-builder/data/submissions/contacts.json +0 -1
- package/plugins/form-builder/data/submissions/enquiries.json +0 -1
- package/plugins/form-builder/data/submissions/feedback.json +0 -1
- package/plugins/form-builder/data/submissions/notes.json +0 -1
- package/plugins/form-builder/data/submissions/to-do.json +0 -1
- /package/plugins/{example-analytics → analytics}/admin/templates/analytics.html +0 -0
- /package/plugins/{example-analytics → analytics}/admin/views/analytics.js +0 -0
- /package/plugins/{example-analytics → analytics}/config.js +0 -0
package/CLAUDE.md
ADDED
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
# Domma CMS — AI Assistant Guide
|
|
2
|
+
|
|
3
|
+
## Project Overview
|
|
4
|
+
|
|
5
|
+
This is a **Domma CMS** project. Stack: Fastify 5 (ESM) backend, Domma SPA admin, SSR public site.
|
|
6
|
+
Content is Markdown + YAML frontmatter in `content/pages/`. Config is JSON in `config/`.
|
|
7
|
+
Server runs on port **4096** by default (`config/server.json`).
|
|
8
|
+
|
|
9
|
+
## Domma Framework — Use These, Not Vanilla JS
|
|
10
|
+
|
|
11
|
+
Domma provides built-in solutions. Never use vanilla JS equivalents.
|
|
12
|
+
|
|
13
|
+
| Alias | Purpose | NOT this |
|
|
14
|
+
|--------------------------------------------------|------------------------------------------|------------------------------------|
|
|
15
|
+
| `$('#el')` | DOM selection + manipulation | `document.querySelector()` |
|
|
16
|
+
| `S.set/get` | Storage | `localStorage.setItem/getItem` |
|
|
17
|
+
| `H.get/post/put/delete` | HTTP | `fetch()`, `XMLHttpRequest` |
|
|
18
|
+
| `D()` | Date manipulation (Moment-style) | Manual `Date` arithmetic |
|
|
19
|
+
| `_` | Array/object utils (`_.map`, `_.filter`) | Always evaluate if native suffices |
|
|
20
|
+
| `M.create(blueprint)` | Reactive data models | Manual state management |
|
|
21
|
+
| `F.create(selector, {blueprint})` | Form generation | Manual `<form>` HTML |
|
|
22
|
+
| `E.toast/confirm/modal/tabs/accordion/slideover` | UI components | Manual HTML/CSS/JS components |
|
|
23
|
+
| `I.scan()` / `<span data-icon="name">` | Icons | Manual SVG or icon fonts |
|
|
24
|
+
| `T.create(selector, {data, columns})` | Tables | Manual `<table>` generation |
|
|
25
|
+
|
|
26
|
+
## Architecture
|
|
27
|
+
|
|
28
|
+
```
|
|
29
|
+
server/ Fastify 5 API + SSR (DO NOT modify — upstream-replaced on update)
|
|
30
|
+
admin/ Domma SPA admin panel (DO NOT modify — upstream-replaced on update)
|
|
31
|
+
public/js/ Public site JS (site.js + component init)
|
|
32
|
+
public/css/ Site stylesheet (site.css is yours to edit)
|
|
33
|
+
content/pages/ Markdown pages (URL → file mapping below)
|
|
34
|
+
content/media/ Uploaded media
|
|
35
|
+
content/users/ User accounts (JSON)
|
|
36
|
+
content/collections/ Collection entries
|
|
37
|
+
config/ All configuration JSON (see Config section)
|
|
38
|
+
plugins/ CMS plugins (yours to create/modify)
|
|
39
|
+
docs/ Reference documentation
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
**URL → file mapping:**
|
|
43
|
+
|
|
44
|
+
- `/` → `content/pages/index.md`
|
|
45
|
+
- `/about` → `content/pages/about.md`
|
|
46
|
+
- `/services` → `content/pages/services/index.md`
|
|
47
|
+
|
|
48
|
+
## Content Pages
|
|
49
|
+
|
|
50
|
+
Pages are Markdown files with YAML frontmatter:
|
|
51
|
+
|
|
52
|
+
```markdown
|
|
53
|
+
---
|
|
54
|
+
title: Page Title
|
|
55
|
+
layout: default # default | landing | blank
|
|
56
|
+
description: SEO desc
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
Page content here. Shortcodes work anywhere in the body.
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### Shortcodes (18 types — full syntax in `docs/markdown-shortcodes.md`)
|
|
63
|
+
|
|
64
|
+
| Shortcode | Purpose |
|
|
65
|
+
|-----------------------------------------|----------------------------------------------------|
|
|
66
|
+
| `[card]` | Card container (optional title, collapsible, icon) |
|
|
67
|
+
| `[grid cols="N"]` / `[col]` | CSS Grid layout (Domma Grid — NOT `.col` class) |
|
|
68
|
+
| `[row]` / `[col]` | Row/column layout |
|
|
69
|
+
| `[slideover trigger="..." title="..."]` | Slide-over panel |
|
|
70
|
+
| `[dconfig]{...}[/dconfig]` | Declarative page config (JSON) |
|
|
71
|
+
| `[tabs]` / `[tab title="..."]` | Tab panels |
|
|
72
|
+
| `[accordion]` / `[item title="..."]` | Accordion sections |
|
|
73
|
+
| `[carousel]` / `[slide]` | Image/content carousel |
|
|
74
|
+
| `[hero title="..." tagline="..."]` | Hero section |
|
|
75
|
+
| `[table]` | Data table (Markdown table inside) |
|
|
76
|
+
| `[badge variant="..."]` | Badge/label |
|
|
77
|
+
| `[countdown to="..." /]` | Countdown timer |
|
|
78
|
+
| `[timeline]` / `[event]` | Timeline component |
|
|
79
|
+
| `[spacer /]` | Vertical spacer |
|
|
80
|
+
| `[center]` | Centre-align content |
|
|
81
|
+
| `[icon name="..." /]` | Inline icon |
|
|
82
|
+
| `[cta action="..."]` | Collection action trigger (admin) |
|
|
83
|
+
|
|
84
|
+
### Shortcode Nesting Rules
|
|
85
|
+
|
|
86
|
+
Processing order (innermost first):
|
|
87
|
+
|
|
88
|
+
1. `[dconfig]` — always first
|
|
89
|
+
2. `[grid]` / `[row]` / `[col]`
|
|
90
|
+
3. `[card]`
|
|
91
|
+
4. `[tabs]`, `[accordion]`, `[carousel]`, `[hero]`, `[table]`, `[badge]`, `[countdown]`, `[timeline]`, `[spacer]`,
|
|
92
|
+
`[center]`, `[icon]`, `[cta]`
|
|
93
|
+
5. `[slideover]` — always last (can contain anything above)
|
|
94
|
+
|
|
95
|
+
Safe nesting: `[card]` inside `[slideover]`, `[grid]` inside `[slideover]`, `[col]` inside `[grid]`.
|
|
96
|
+
Do NOT nest `[slideover]` inside another `[slideover]`.
|
|
97
|
+
|
|
98
|
+
## Public Site Patterns
|
|
99
|
+
|
|
100
|
+
The server injects these globals on every public page:
|
|
101
|
+
|
|
102
|
+
```js
|
|
103
|
+
window.__CMS_NAV__ // Navigation config (brand, items)
|
|
104
|
+
window.__CMS_SITE__ // Site config (title, theme, footer, smtp, etc.)
|
|
105
|
+
window.__CMS_DCONFIG__ // Page-level declarative config (merged with inline [dconfig])
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
`public/js/site.js` reads these to initialise the Domma navbar, footer, and page components.
|
|
109
|
+
Domma components (tabs, accordion, carousel, etc.) in `.page-body` are auto-initialised by `site.js`.
|
|
110
|
+
Add custom public-site JS to `public/js/site.js` or new files loaded from `public/js/`.
|
|
111
|
+
|
|
112
|
+
## Plugin Development
|
|
113
|
+
|
|
114
|
+
Each plugin needs exactly 3 files:
|
|
115
|
+
|
|
116
|
+
```
|
|
117
|
+
plugins/my-plugin/
|
|
118
|
+
plugin.json Required manifest (name, displayName, version, description, author, date, icon)
|
|
119
|
+
plugin.js Default export: Fastify plugin function
|
|
120
|
+
config.js Default export: plain object of config defaults
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
See `docs/plugin-development.md` for full plugin API, hooks, and injection points.
|
|
124
|
+
|
|
125
|
+
## Config Reference
|
|
126
|
+
|
|
127
|
+
| File | Owner | Purpose |
|
|
128
|
+
|--------------------------|-----------------------|------------------------------------|
|
|
129
|
+
| `config/server.json` | CMS (merge on update) | Port, host, CORS, uploads |
|
|
130
|
+
| `config/auth.json` | CMS (merge on update) | JWT expiry, bcrypt rounds |
|
|
131
|
+
| `config/content.json` | CMS (merge on update) | Content dirs, page defaults |
|
|
132
|
+
| `config/presets.json` | CMS (merge on update) | Preset collection schemas |
|
|
133
|
+
| `config/site.json` | Yours | Site title, theme, footer, SMTP |
|
|
134
|
+
| `config/navigation.json` | Yours | Navbar brand + items |
|
|
135
|
+
| `config/plugins.json` | Yours | Plugin enabled/disabled + settings |
|
|
136
|
+
|
|
137
|
+
See `docs/configuration.md` for full schema reference.
|
|
138
|
+
|
|
139
|
+
## Key Gotchas
|
|
140
|
+
|
|
141
|
+
1. **Navigation sub-items**: use `items` key, NOT `children` — Domma navbar reads `items`.
|
|
142
|
+
2. **Domma collections**: use `.get(0)` NOT `[0]` to get native DOM elements.
|
|
143
|
+
3. **`.html()` strips interactive elements**: `E.modal().setContent(x)` also strips HTML — use light DOM slot
|
|
144
|
+
projection (`modal.element.appendChild(myDomElement)`) for buttons/inputs.
|
|
145
|
+
4. **Landing layout**: `layout: landing` removes the standard page wrapper — add your own container CSS.
|
|
146
|
+
5. **Grid shortcode**: uses Domma Grid (`grid`, `grid-cols-N`) — NOT the `.col` compatibility class.
|
|
147
|
+
6. **Event delegation namespaces**: `$(doc).on('click.ns', '.sel', cb)` silently fails — use direct `addEventListener`
|
|
148
|
+
or unnamespaced `$(el).on('click', cb)`.
|
|
149
|
+
7. **Tabs component classes**: wrapper `.tabs`, list `.tab-list`, trigger `button.tab-item`, panel `.tab-panel` (not
|
|
150
|
+
`.tabs-nav`, `.tabs-content`, `.tabs-pane`).
|
|
151
|
+
|
|
152
|
+
## Docs
|
|
153
|
+
|
|
154
|
+
- `docs/getting-started.md` — Installation, first run, setup wizard
|
|
155
|
+
- `docs/markdown-shortcodes.md` — Full shortcode syntax and examples
|
|
156
|
+
- `docs/configuration.md` — Complete config schema for all JSON files
|
|
157
|
+
- `docs/plugin-development.md` — Plugin API, lifecycle hooks, injection points
|
|
158
|
+
- `docs/theming.md` — Available themes, CSS variables, customisation
|
|
159
|
+
- `docs/api-reference.md` — REST API endpoints (for headless / external integrations)
|
package/README.md
CHANGED
package/bin/cli.js
CHANGED
|
@@ -237,7 +237,8 @@ const DEFAULT_NAV = {
|
|
|
237
237
|
// Plugins enabled by default in a fresh project
|
|
238
238
|
const ENABLED_BY_DEFAULT = new Set([
|
|
239
239
|
'domma-effects',
|
|
240
|
-
'
|
|
240
|
+
'analytics',
|
|
241
|
+
'theme-roller',
|
|
241
242
|
]);
|
|
242
243
|
|
|
243
244
|
// Discover all plugins and set enabled state accordingly
|
package/config/plugins.json
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
{
|
|
2
|
-
"
|
|
3
|
-
"enabled": true,
|
|
4
|
-
"settings": {}
|
|
5
|
-
},
|
|
6
|
-
"theme-roller": {
|
|
7
|
-
"enabled": true,
|
|
8
|
-
"settings": {}
|
|
9
|
-
},
|
|
10
|
-
"domma-effects": {
|
|
11
|
-
"enabled": true,
|
|
12
|
-
"settings": {
|
|
13
|
-
"respectMotion": false,
|
|
14
|
-
"defaultDuration": 600,
|
|
15
|
-
"defaultAnimation": "fade",
|
|
16
|
-
"defaultThreshold": 0.1
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"analytics": {
|
|
3
|
+
"enabled": true,
|
|
4
|
+
"settings": {}
|
|
5
|
+
},
|
|
6
|
+
"theme-roller": {
|
|
7
|
+
"enabled": true,
|
|
8
|
+
"settings": {}
|
|
9
|
+
},
|
|
10
|
+
"domma-effects": {
|
|
11
|
+
"enabled": true,
|
|
12
|
+
"settings": {
|
|
13
|
+
"respectMotion": false,
|
|
14
|
+
"defaultDuration": 600,
|
|
15
|
+
"defaultAnimation": "fade",
|
|
16
|
+
"defaultThreshold": 0.1
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "domma-cms",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.7",
|
|
4
4
|
"description": "File-based CMS powered by Domma and Fastify. Run npx domma-cms my-site to create a new project.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "server/server.js",
|
|
@@ -29,7 +29,10 @@
|
|
|
29
29
|
"build": "node scripts/build.js",
|
|
30
30
|
"delete-users": "node -e \"import('fs').then(({readdirSync,rmSync})=>{const d='content/users';readdirSync(d).filter(f=>f.endsWith('.json')).forEach(f=>{rmSync(d+'/'+f);console.log('deleted',f)})})\"",
|
|
31
31
|
"start": "node server/server.js",
|
|
32
|
-
"start
|
|
32
|
+
"pm2:start": "pm2 start ecosystem.config.cjs --env production",
|
|
33
|
+
"pm2:stop": "pm2 stop ecosystem.config.cjs",
|
|
34
|
+
"pm2:restart": "pm2 reload ecosystem.config.cjs",
|
|
35
|
+
"pm2:logs": "pm2 logs domma-cms",
|
|
33
36
|
"dev": "node --watch server/server.js",
|
|
34
37
|
"prod": "node server/server.js",
|
|
35
38
|
"setup": "node scripts/setup.js",
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Analytics Plugin — Server
|
|
3
3
|
* Tracks page hits in a JSON file alongside the plugin.
|
|
4
4
|
* Endpoints:
|
|
5
|
-
* POST /api/plugins/
|
|
6
|
-
* GET /api/plugins/
|
|
7
|
-
* DELETE /api/plugins/
|
|
5
|
+
* POST /api/plugins/analytics/hit - public: record a hit { url }
|
|
6
|
+
* GET /api/plugins/analytics/stats - admin: return all hit counts
|
|
7
|
+
* DELETE /api/plugins/analytics/stats - admin: reset all stats
|
|
8
8
|
*/
|
|
9
9
|
import fs from 'fs/promises';
|
|
10
10
|
import path from 'path';
|
|
11
|
-
import {
|
|
11
|
+
import {fileURLToPath} from 'url';
|
|
12
12
|
|
|
13
13
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
14
14
|
const STATS_FILE = path.join(__dirname, 'stats.json');
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
2
|
+
"name": "analytics",
|
|
3
3
|
"displayName": "Analytics",
|
|
4
4
|
"version": "1.0.0",
|
|
5
5
|
"description": "Basic page view analytics. Tracks hits per page using a simple JSON store.",
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
],
|
|
16
16
|
"views": {
|
|
17
17
|
"plugin-analytics": {
|
|
18
|
-
|
|
18
|
+
"entry": "analytics/admin/views/analytics.js",
|
|
19
19
|
"exportName": "analyticsView"
|
|
20
20
|
}
|
|
21
21
|
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
<!--
|
|
1
|
+
<!-- analytics: page view tracker -->
|
|
2
2
|
<script>
|
|
3
3
|
(function () {
|
|
4
4
|
var url = window.location.pathname;
|
|
5
5
|
if (typeof fetch === 'function') {
|
|
6
|
-
|
|
6
|
+
fetch('/api/plugins/analytics/hit', {
|
|
7
7
|
method: 'POST',
|
|
8
8
|
headers: { 'Content-Type': 'application/json' },
|
|
9
9
|
body: JSON.stringify({ url: url })
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<!-- analytics: head injection (empty — tracking is done via body script) -->
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
|
-
"/":
|
|
2
|
+
"/": 139,
|
|
3
3
|
"/about": 71,
|
|
4
4
|
"/blog": 30,
|
|
5
5
|
"/contact": 30,
|
|
6
6
|
"/resources/typography": 4,
|
|
7
7
|
"/resources": 13,
|
|
8
8
|
"/resources/shortcodes": 14,
|
|
9
|
-
"/resources/cards":
|
|
9
|
+
"/resources/cards": 16,
|
|
10
10
|
"/resources/interactive": 13,
|
|
11
11
|
"/resources/grid": 6,
|
|
12
12
|
"/forms": 14,
|
package/scripts/build.js
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
<!-- example-analytics: head injection (empty — tracking is done via body script) -->
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"slug": "contacts",
|
|
3
|
-
"title": "Contacts",
|
|
4
|
-
"description": "Contact Information",
|
|
5
|
-
"fields": [
|
|
6
|
-
{
|
|
7
|
-
"name": "full_name",
|
|
8
|
-
"type": "string",
|
|
9
|
-
"label": "Full Name",
|
|
10
|
-
"required": false,
|
|
11
|
-
"placeholder": "Full Name",
|
|
12
|
-
"helper": "Full Name",
|
|
13
|
-
"minLength": 8,
|
|
14
|
-
"maxLength": 255
|
|
15
|
-
},
|
|
16
|
-
{
|
|
17
|
-
"type": "spacer"
|
|
18
|
-
},
|
|
19
|
-
{
|
|
20
|
-
"name": "phone_number",
|
|
21
|
-
"type": "tel",
|
|
22
|
-
"label": "Phone Number",
|
|
23
|
-
"required": false,
|
|
24
|
-
"placeholder": "Phone Number",
|
|
25
|
-
"helper": "Primary Phone Number"
|
|
26
|
-
},
|
|
27
|
-
{
|
|
28
|
-
"type": "spacer"
|
|
29
|
-
},
|
|
30
|
-
{
|
|
31
|
-
"name": "email_address",
|
|
32
|
-
"type": "string",
|
|
33
|
-
"label": "Email Address",
|
|
34
|
-
"required": false,
|
|
35
|
-
"placeholder": "Email Address",
|
|
36
|
-
"helper": "Email Address",
|
|
37
|
-
"minLength": 8,
|
|
38
|
-
"maxLength": 255
|
|
39
|
-
}
|
|
40
|
-
],
|
|
41
|
-
"settings": {
|
|
42
|
-
"submitText": "Submit",
|
|
43
|
-
"successMessage": "Thank you for your submission.",
|
|
44
|
-
"layout": "stacked",
|
|
45
|
-
"honeypot": true,
|
|
46
|
-
"rateLimitPerMinute": 3
|
|
47
|
-
},
|
|
48
|
-
"actions": {
|
|
49
|
-
"email": {
|
|
50
|
-
"enabled": false,
|
|
51
|
-
"recipients": "",
|
|
52
|
-
"subjectPrefix": "[Contacts]"
|
|
53
|
-
},
|
|
54
|
-
"webhook": {
|
|
55
|
-
"enabled": false,
|
|
56
|
-
"url": "",
|
|
57
|
-
"method": "POST"
|
|
58
|
-
},
|
|
59
|
-
"collection": {
|
|
60
|
-
"enabled": true,
|
|
61
|
-
"slug": "contacts"
|
|
62
|
-
}
|
|
63
|
-
},
|
|
64
|
-
"createdAt": "2026-03-17T12:35:44.569Z",
|
|
65
|
-
"updatedAt": "2026-03-17T12:35:44.569Z"
|
|
66
|
-
}
|
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"slug": "enquiries",
|
|
3
|
-
"title": "Enquiries",
|
|
4
|
-
"description": "Get in touch with us",
|
|
5
|
-
"fields": [
|
|
6
|
-
{
|
|
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",
|
|
30
|
-
"required": false,
|
|
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",
|
|
40
|
-
"helper": "",
|
|
41
|
-
"options": [
|
|
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
|
-
}
|
|
62
|
-
]
|
|
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
|
-
}
|
|
76
|
-
}
|
|
77
|
-
],
|
|
78
|
-
"settings": {
|
|
79
|
-
"submitText": "Send Message",
|
|
80
|
-
"successMessage": "Thanks for reaching out! We'll get back to you shortly.",
|
|
81
|
-
"layout": "stacked",
|
|
82
|
-
"honeypot": true,
|
|
83
|
-
"rateLimitPerMinute": 3
|
|
84
|
-
},
|
|
85
|
-
"actions": {
|
|
86
|
-
"email": {
|
|
87
|
-
"enabled": false,
|
|
88
|
-
"recipients": "",
|
|
89
|
-
"subjectPrefix": "[enquiries]"
|
|
90
|
-
},
|
|
91
|
-
"webhook": {
|
|
92
|
-
"enabled": false,
|
|
93
|
-
"url": "",
|
|
94
|
-
"method": "POST"
|
|
95
|
-
},
|
|
96
|
-
"collection": {
|
|
97
|
-
"enabled": true,
|
|
98
|
-
"slug": "enquiries"
|
|
99
|
-
}
|
|
100
|
-
},
|
|
101
|
-
"createdAt": "2026-03-17T12:35:44.569Z",
|
|
102
|
-
"updatedAt": "2026-03-17T12:35:44.569Z"
|
|
103
|
-
}
|
|
@@ -1,131 +0,0 @@
|
|
|
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": "Please enter your full name",
|
|
12
|
-
"helper": "Please enter your full name",
|
|
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": "Please enter your email address"
|
|
25
|
-
},
|
|
26
|
-
{
|
|
27
|
-
"name": "rating",
|
|
28
|
-
"type": "select",
|
|
29
|
-
"label": "Overall Rating",
|
|
30
|
-
"required": true,
|
|
31
|
-
"helper": "Tell us how we are doing!",
|
|
32
|
-
"options": [
|
|
33
|
-
{
|
|
34
|
-
"value": "none",
|
|
35
|
-
"label": "Please Choose"
|
|
36
|
-
},
|
|
37
|
-
{
|
|
38
|
-
"value": "excellent",
|
|
39
|
-
"label": "Excellent"
|
|
40
|
-
},
|
|
41
|
-
{
|
|
42
|
-
"value": "good",
|
|
43
|
-
"label": "Good"
|
|
44
|
-
},
|
|
45
|
-
{
|
|
46
|
-
"value": "average",
|
|
47
|
-
"label": "Average"
|
|
48
|
-
},
|
|
49
|
-
{
|
|
50
|
-
"value": "poor",
|
|
51
|
-
"label": "Poor"
|
|
52
|
-
}
|
|
53
|
-
]
|
|
54
|
-
},
|
|
55
|
-
{
|
|
56
|
-
"name": "category",
|
|
57
|
-
"type": "select",
|
|
58
|
-
"label": "Category",
|
|
59
|
-
"required": true,
|
|
60
|
-
"placeholder": "Please select a category",
|
|
61
|
-
"helper": "",
|
|
62
|
-
"options": [
|
|
63
|
-
{
|
|
64
|
-
"value": "general",
|
|
65
|
-
"label": "General"
|
|
66
|
-
},
|
|
67
|
-
{
|
|
68
|
-
"value": "bug-report",
|
|
69
|
-
"label": "Bug Report"
|
|
70
|
-
},
|
|
71
|
-
{
|
|
72
|
-
"value": "feature-request",
|
|
73
|
-
"label": "Feature Request"
|
|
74
|
-
},
|
|
75
|
-
{
|
|
76
|
-
"value": "praise",
|
|
77
|
-
"label": "Praise"
|
|
78
|
-
}
|
|
79
|
-
]
|
|
80
|
-
},
|
|
81
|
-
{
|
|
82
|
-
"name": "subject",
|
|
83
|
-
"type": "string",
|
|
84
|
-
"label": "Subject",
|
|
85
|
-
"required": true,
|
|
86
|
-
"placeholder": "Brief summary of your feedback",
|
|
87
|
-
"helper": "",
|
|
88
|
-
"validation": {
|
|
89
|
-
"max": 200
|
|
90
|
-
}
|
|
91
|
-
},
|
|
92
|
-
{
|
|
93
|
-
"name": "message",
|
|
94
|
-
"type": "textarea",
|
|
95
|
-
"label": "Your Feedback",
|
|
96
|
-
"required": true,
|
|
97
|
-
"placeholder": "Please share your thoughts in detail…",
|
|
98
|
-
"helper": "Please share your thoughts in detail…",
|
|
99
|
-
"rows": 4,
|
|
100
|
-
"validation": {
|
|
101
|
-
"min": 10,
|
|
102
|
-
"max": 2000
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
],
|
|
106
|
-
"settings": {
|
|
107
|
-
"submitText": "Submit Feedback",
|
|
108
|
-
"successMessage": "Thank you for your feedback! We appreciate you taking the time.",
|
|
109
|
-
"layout": "stacked",
|
|
110
|
-
"honeypot": true,
|
|
111
|
-
"rateLimitPerMinute": 3
|
|
112
|
-
},
|
|
113
|
-
"actions": {
|
|
114
|
-
"email": {
|
|
115
|
-
"enabled": true,
|
|
116
|
-
"recipients": "",
|
|
117
|
-
"subjectPrefix": "[feedback]"
|
|
118
|
-
},
|
|
119
|
-
"webhook": {
|
|
120
|
-
"enabled": false,
|
|
121
|
-
"url": "",
|
|
122
|
-
"method": "POST"
|
|
123
|
-
},
|
|
124
|
-
"collection": {
|
|
125
|
-
"enabled": true,
|
|
126
|
-
"slug": "feedback"
|
|
127
|
-
}
|
|
128
|
-
},
|
|
129
|
-
"createdAt": "2026-03-17T12:35:44.569Z",
|
|
130
|
-
"updatedAt": "2026-03-17T12:35:44.569Z"
|
|
131
|
-
}
|
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"slug": "notes",
|
|
3
|
-
"title": "Notes",
|
|
4
|
-
"description": "Free-form notes with categories and tags.",
|
|
5
|
-
"fields": [
|
|
6
|
-
{
|
|
7
|
-
"name": "title",
|
|
8
|
-
"type": "string",
|
|
9
|
-
"label": "Title",
|
|
10
|
-
"required": true,
|
|
11
|
-
"placeholder": "Note title"
|
|
12
|
-
},
|
|
13
|
-
{
|
|
14
|
-
"name": "content",
|
|
15
|
-
"type": "textarea",
|
|
16
|
-
"label": "Content",
|
|
17
|
-
"required": true,
|
|
18
|
-
"placeholder": "Write your note here…",
|
|
19
|
-
"rows": 5
|
|
20
|
-
},
|
|
21
|
-
{
|
|
22
|
-
"name": "category",
|
|
23
|
-
"type": "select",
|
|
24
|
-
"label": "Category",
|
|
25
|
-
"required": false,
|
|
26
|
-
"options": [
|
|
27
|
-
{
|
|
28
|
-
"value": "general",
|
|
29
|
-
"label": "General"
|
|
30
|
-
},
|
|
31
|
-
{
|
|
32
|
-
"value": "idea",
|
|
33
|
-
"label": "Idea"
|
|
34
|
-
},
|
|
35
|
-
{
|
|
36
|
-
"value": "reminder",
|
|
37
|
-
"label": "Reminder"
|
|
38
|
-
},
|
|
39
|
-
{
|
|
40
|
-
"value": "reference",
|
|
41
|
-
"label": "Reference"
|
|
42
|
-
}
|
|
43
|
-
]
|
|
44
|
-
},
|
|
45
|
-
{
|
|
46
|
-
"name": "tags",
|
|
47
|
-
"type": "string",
|
|
48
|
-
"label": "Tags",
|
|
49
|
-
"required": false,
|
|
50
|
-
"placeholder": "Comma-separated tags",
|
|
51
|
-
"helper": "Separate tags with commas"
|
|
52
|
-
}
|
|
53
|
-
],
|
|
54
|
-
"settings": {
|
|
55
|
-
"submitText": "Save Note",
|
|
56
|
-
"successMessage": "Note saved successfully.",
|
|
57
|
-
"layout": "stacked",
|
|
58
|
-
"honeypot": true,
|
|
59
|
-
"rateLimitPerMinute": 3
|
|
60
|
-
},
|
|
61
|
-
"actions": {
|
|
62
|
-
"email": {
|
|
63
|
-
"enabled": false,
|
|
64
|
-
"recipients": "",
|
|
65
|
-
"subjectPrefix": "[notes]"
|
|
66
|
-
},
|
|
67
|
-
"webhook": {
|
|
68
|
-
"enabled": false,
|
|
69
|
-
"url": "",
|
|
70
|
-
"method": "POST"
|
|
71
|
-
},
|
|
72
|
-
"collection": {
|
|
73
|
-
"enabled": true,
|
|
74
|
-
"slug": "notes"
|
|
75
|
-
}
|
|
76
|
-
},
|
|
77
|
-
"createdAt": "2026-03-17T12:35:44.569Z",
|
|
78
|
-
"updatedAt": "2026-03-17T12:35:44.569Z"
|
|
79
|
-
}
|
|
@@ -1,100 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"slug": "to-do",
|
|
3
|
-
"title": "To-Do",
|
|
4
|
-
"description": "Task tracking with status, priority, and due dates.",
|
|
5
|
-
"fields": [
|
|
6
|
-
{
|
|
7
|
-
"name": "title",
|
|
8
|
-
"type": "string",
|
|
9
|
-
"label": "Title",
|
|
10
|
-
"required": true,
|
|
11
|
-
"placeholder": "Task title"
|
|
12
|
-
},
|
|
13
|
-
{
|
|
14
|
-
"name": "description",
|
|
15
|
-
"type": "textarea",
|
|
16
|
-
"label": "Description",
|
|
17
|
-
"required": false,
|
|
18
|
-
"placeholder": "Task details…",
|
|
19
|
-
"rows": 3
|
|
20
|
-
},
|
|
21
|
-
{
|
|
22
|
-
"name": "status",
|
|
23
|
-
"type": "select",
|
|
24
|
-
"label": "Status",
|
|
25
|
-
"required": true,
|
|
26
|
-
"options": [
|
|
27
|
-
{
|
|
28
|
-
"value": "pending",
|
|
29
|
-
"label": "Pending"
|
|
30
|
-
},
|
|
31
|
-
{
|
|
32
|
-
"value": "in-progress",
|
|
33
|
-
"label": "In Progress"
|
|
34
|
-
},
|
|
35
|
-
{
|
|
36
|
-
"value": "done",
|
|
37
|
-
"label": "Done"
|
|
38
|
-
}
|
|
39
|
-
]
|
|
40
|
-
},
|
|
41
|
-
{
|
|
42
|
-
"name": "priority",
|
|
43
|
-
"type": "select",
|
|
44
|
-
"label": "Priority",
|
|
45
|
-
"required": false,
|
|
46
|
-
"options": [
|
|
47
|
-
{
|
|
48
|
-
"value": "low",
|
|
49
|
-
"label": "Low"
|
|
50
|
-
},
|
|
51
|
-
{
|
|
52
|
-
"value": "medium",
|
|
53
|
-
"label": "Medium"
|
|
54
|
-
},
|
|
55
|
-
{
|
|
56
|
-
"value": "high",
|
|
57
|
-
"label": "High"
|
|
58
|
-
}
|
|
59
|
-
]
|
|
60
|
-
},
|
|
61
|
-
{
|
|
62
|
-
"name": "due_date",
|
|
63
|
-
"type": "date",
|
|
64
|
-
"label": "Due Date",
|
|
65
|
-
"required": false
|
|
66
|
-
},
|
|
67
|
-
{
|
|
68
|
-
"name": "assigned_to",
|
|
69
|
-
"type": "string",
|
|
70
|
-
"label": "Assigned To",
|
|
71
|
-
"required": false,
|
|
72
|
-
"placeholder": "Name or email"
|
|
73
|
-
}
|
|
74
|
-
],
|
|
75
|
-
"settings": {
|
|
76
|
-
"submitText": "Add Task",
|
|
77
|
-
"successMessage": "Task added successfully.",
|
|
78
|
-
"layout": "stacked",
|
|
79
|
-
"honeypot": true,
|
|
80
|
-
"rateLimitPerMinute": 3
|
|
81
|
-
},
|
|
82
|
-
"actions": {
|
|
83
|
-
"email": {
|
|
84
|
-
"enabled": false,
|
|
85
|
-
"recipients": "",
|
|
86
|
-
"subjectPrefix": "[to-do]"
|
|
87
|
-
},
|
|
88
|
-
"webhook": {
|
|
89
|
-
"enabled": false,
|
|
90
|
-
"url": "",
|
|
91
|
-
"method": "POST"
|
|
92
|
-
},
|
|
93
|
-
"collection": {
|
|
94
|
-
"enabled": true,
|
|
95
|
-
"slug": "to-do"
|
|
96
|
-
}
|
|
97
|
-
},
|
|
98
|
-
"createdAt": "2026-03-17T12:35:44.569Z",
|
|
99
|
-
"updatedAt": "2026-03-17T12:35:44.569Z"
|
|
100
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
[]
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
[]
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
[]
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
[]
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
[]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|