domma-cms 0.2.0 → 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 (72) hide show
  1. package/README.md +2 -3
  2. package/admin/css/admin.css +1 -1200
  3. package/admin/js/api.js +1 -242
  4. package/admin/js/app.js +5 -279
  5. package/admin/js/config/sidebar-config.js +1 -115
  6. package/admin/js/lib/card.js +1 -63
  7. package/admin/js/lib/image-editor.js +1 -869
  8. package/admin/js/lib/markdown-toolbar.js +46 -421
  9. package/admin/js/templates/layouts.html +44 -7
  10. package/admin/js/templates/page-editor.html +9 -0
  11. package/admin/js/templates/settings.html +18 -1
  12. package/admin/js/templates/users.html +29 -4
  13. package/admin/js/views/collection-editor.js +3 -487
  14. package/admin/js/views/collection-entries.js +1 -484
  15. package/admin/js/views/collections.js +1 -153
  16. package/admin/js/views/dashboard.js +1 -56
  17. package/admin/js/views/documentation.js +1 -12
  18. package/admin/js/views/index.js +1 -39
  19. package/admin/js/views/layouts.js +9 -42
  20. package/admin/js/views/login.js +7 -251
  21. package/admin/js/views/media.js +1 -240
  22. package/admin/js/views/navigation.js +14 -212
  23. package/admin/js/views/page-editor.js +53 -661
  24. package/admin/js/views/pages.js +5 -72
  25. package/admin/js/views/plugins.js +13 -90
  26. package/admin/js/views/settings.js +1 -199
  27. package/admin/js/views/tutorials.js +1 -12
  28. package/admin/js/views/user-editor.js +1 -88
  29. package/admin/js/views/users.js +7 -76
  30. package/bin/cli.js +18 -9
  31. package/config/auth.json +1 -17
  32. package/config/navigation.json +15 -0
  33. package/config/site.json +5 -4
  34. package/package.json +1 -1
  35. package/plugins/domma-effects/public/celebrations/core/canvas.js +2 -104
  36. package/plugins/domma-effects/public/celebrations/core/particles.js +1 -144
  37. package/plugins/domma-effects/public/celebrations/core/physics.js +1 -166
  38. package/plugins/domma-effects/public/celebrations/index.js +1 -535
  39. package/plugins/domma-effects/public/celebrations/themes/christmas.js +1 -1805
  40. package/plugins/domma-effects/public/celebrations/themes/guy-fawkes.js +1 -1477
  41. package/plugins/domma-effects/public/celebrations/themes/halloween.js +1 -1837
  42. package/plugins/domma-effects/public/celebrations/themes/st-andrews.js +1 -1175
  43. package/plugins/domma-effects/public/celebrations/themes/st-davids.js +1 -1258
  44. package/plugins/domma-effects/public/celebrations/themes/st-georges.js +1 -1754
  45. package/plugins/domma-effects/public/celebrations/themes/st-patricks.js +1 -1290
  46. package/plugins/domma-effects/public/celebrations/themes/valentines.js +1 -1361
  47. package/plugins/example-analytics/stats.json +16 -12
  48. package/plugins/form-builder/admin/templates/form-editor.html +158 -130
  49. package/plugins/form-builder/admin/views/form-editor.js +3 -1
  50. package/plugins/form-builder/data/forms/contact-details.json +71 -35
  51. package/plugins/form-builder/data/forms/feedback.json +130 -0
  52. package/plugins/form-builder/data/submissions/feedback.json +1 -0
  53. package/plugins/form-builder/public/form-logic-engine.js +1 -568
  54. package/public/css/site.css +1 -302
  55. package/public/js/btt.js +1 -90
  56. package/public/js/cookie-consent.js +1 -61
  57. package/public/js/site.js +1 -204
  58. package/scripts/setup.js +12 -9
  59. package/server/middleware/auth.js +44 -21
  60. package/server/routes/api/auth.js +38 -8
  61. package/server/routes/api/collections.js +18 -5
  62. package/server/routes/api/layouts.js +18 -4
  63. package/server/routes/api/media.js +2 -3
  64. package/server/routes/api/navigation.js +2 -3
  65. package/server/routes/api/pages.js +3 -3
  66. package/server/routes/api/settings.js +2 -3
  67. package/server/routes/api/users.js +4 -6
  68. package/server/routes/public.js +3 -3
  69. package/server/server.js +8 -0
  70. package/server/services/markdown.js +102 -3
  71. package/server/services/userTypes.js +167 -0
  72. package/plugins/form-builder/email.js +0 -103
@@ -1,115 +1 @@
1
- /**
2
- * Admin Sidebar Configuration
3
- * Role-aware — certain sections are only visible to privileged roles.
4
- *
5
- * @param {string|null} role - Current user role: 'admin' | 'manager' | 'editor' | null
6
- * @param {object} counts - Optional badge counts: { pages, media, users }
7
- * @param pluginItems
8
- * @returns {object[]}
9
- */
10
- export function getSidebarConfig(role, counts = {}, pluginItems = []) {
11
- const isAdmin = role === 'admin';
12
- const isManager = role === 'manager';
13
- const canStructure = isAdmin || isManager;
14
-
15
- const badge = (n) => (n != null && n > 0) ? String(n) : null;
16
-
17
- const items = [];
18
-
19
- items.push(
20
- {heading: 'Overview'},
21
- {id: 'dashboard', text: 'Dashboard', icon: 'home', url: '#/', section: '#/'},
22
- {divider: true}
23
- );
24
-
25
- if (canStructure) {
26
- items.push(
27
- {heading: 'Structure'},
28
- {id: 'navigation', text: 'Navigation', icon: 'menu', url: '#/navigation', section: '#/navigation'},
29
- {id: 'layouts', text: 'Layouts', icon: 'layout', url: '#/layouts', section: '#/layouts'},
30
- {divider: true}
31
- )
32
- ;
33
- }
34
-
35
- items.push(
36
- {heading: 'Content'},
37
- {id: 'pages', text: 'Pages', icon: 'file-text', url: '#/pages', section: '#/pages', badge: badge(counts.pages)},
38
- {id: 'media', text: 'Media', icon: 'image', url: '#/media', section: '#/media', badge: badge(counts.media)}
39
- );
40
-
41
- if (canStructure) {
42
- items.push(
43
- {divider: true},
44
- {heading: 'Data'},
45
- {id: 'collections', text: 'Collections', icon: 'database', url: '#/collections', section: '#/collections', badge: badge(counts.collections)}
46
- );
47
- }
48
-
49
- items.push(
50
- {divider: true},
51
- {heading: 'Configuration'}
52
- );
53
-
54
- if (canStructure) {
55
- items.push(
56
- {id: 'users', text: 'Users', icon: 'users', url: '#/users', section: '#/users', badge: badge(counts.users)},
57
- {id: 'settings', text: 'Site Settings', icon: 'settings', url: '#/settings', section: '#/settings'}
58
- );
59
- }
60
-
61
- items.push(
62
- {divider: true},
63
- {heading: 'Plugins'}
64
- );
65
-
66
- if (isAdmin) {
67
- items.push(
68
- {
69
- id: 'plugins',
70
- text: 'Plugins',
71
- icon: 'package',
72
- url: '#/plugins',
73
- section: '#/plugins',
74
- badge: badge(counts.plugins)
75
- }
76
- );
77
- items.push(...pluginItems);
78
- }
79
-
80
- items.push(
81
- {divider: true},
82
- {heading: 'View Site'}
83
- );
84
-
85
- items.push(
86
- {id: 'view-site', text: 'View Site', icon: 'external-link', url: '/', section: '/'}
87
- );
88
-
89
- items.push(
90
- {divider: true},
91
- {heading: 'Documentation'}
92
- );
93
-
94
- items.push(
95
- {
96
- id: 'documentation',
97
- text: 'Usage',
98
- icon: 'book',
99
- url: '#/documentation',
100
- section: '#/documentation',
101
- badge: badge(counts.documents)
102
- },
103
- {
104
- id: 'tutorials',
105
- text: 'Tutorials',
106
- icon: 'document',
107
- url: '#/tutorials',
108
- section: '#/documentation',
109
- badge: badge(counts.tutorials)
110
- }
111
- );
112
- // items.push(...pluginItems);
113
-
114
- return items;
115
- }
1
+ export function getSidebarConfig(a,e={},u=[]){const o=a==="admin",n=o||a==="manager",t=s=>s!=null&&s>0?String(s):null,i=[];return i.push({heading:"Overview"},{id:"dashboard",text:"Dashboard",icon:"home",url:"#/",section:"#/"},{divider:!0}),n&&i.push({heading:"Structure"},{id:"navigation",text:"Navigation",icon:"menu",url:"#/navigation",section:"#/navigation"},{id:"layouts",text:"Layouts",icon:"layout",url:"#/layouts",section:"#/layouts"},{divider:!0}),i.push({heading:"Content"},{id:"pages",text:"Pages",icon:"file-text",url:"#/pages",section:"#/pages",badge:t(e.pages)},{id:"media",text:"Media",icon:"image",url:"#/media",section:"#/media",badge:t(e.media)}),n&&i.push({divider:!0},{heading:"Data"},{id:"collections",text:"Collections",icon:"database",url:"#/collections",section:"#/collections",badge:t(e.collections)}),i.push({divider:!0},{heading:"Configuration"}),n&&i.push({id:"users",text:"Users",icon:"users",url:"#/users",section:"#/users",badge:t(e.users)},{id:"settings",text:"Site Settings",icon:"settings",url:"#/settings",section:"#/settings"}),i.push({divider:!0},{heading:"Plugins"}),o&&(i.push({id:"plugins",text:"Plugins",icon:"package",url:"#/plugins",section:"#/plugins",badge:t(e.plugins)}),i.push(...u)),i.push({divider:!0},{heading:"View Site"}),i.push({id:"view-site",text:"View Site",icon:"external-link",url:"/",section:"/"}),i.push({divider:!0},{heading:"Documentation"}),i.push({id:"documentation",text:"Usage",icon:"book",url:"#/documentation",section:"#/documentation",badge:t(e.documents)},{id:"tutorials",text:"Tutorials",icon:"document",url:"#/tutorials",section:"#/documentation",badge:t(e.tutorials)}),i}
@@ -1,63 +1 @@
1
- /**
2
- * Card Builder — admin utility for creating Domma-styled card elements.
3
- *
4
- * Usage:
5
- * import { buildCard, wrapInCard } from '/admin/js/lib/card.js';
6
- *
7
- * const card = buildCard({ title: 'My Card', content: '<p>Body</p>' });
8
- * document.getElementById('container').appendChild(card);
9
- *
10
- * // Or wrap an existing element
11
- * wrapInCard(document.getElementById('my-table'), { title: 'Results' });
12
- */
13
-
14
- /**
15
- * Build a card element.
16
- *
17
- * @param {object} [opts]
18
- * @param {string} [opts.title] - Card header title (omit for no header)
19
- * @param {string|HTMLElement} [opts.content] - Body: HTML string (sanitised via Domma) or DOM element
20
- * @param {string} [opts.className] - Extra classes on the outer card div (default: 'mb-4')
21
- * @param {string} [opts.id] - ID attribute on the outer card div
22
- * @returns {HTMLElement}
23
- */
24
- export function buildCard({ title = '', content = '', className = 'mb-4', id = '' } = {}) {
25
- const card = document.createElement('div');
26
- card.className = `card ${className}`.trim();
27
- if (id) card.id = id;
28
-
29
- if (title) {
30
- const header = document.createElement('div');
31
- header.className = 'card-header';
32
- const h2 = document.createElement('h2');
33
- h2.textContent = title;
34
- header.appendChild(h2);
35
- card.appendChild(header);
36
- }
37
-
38
- const body = document.createElement('div');
39
- body.className = 'card-body';
40
- if (content instanceof Node) {
41
- body.appendChild(content);
42
- } else if (typeof content === 'string' && content) {
43
- // Use Domma's $(…).html() which passes content through DOMPurify
44
- $(body).html(content);
45
- }
46
- card.appendChild(body);
47
-
48
- return card;
49
- }
50
-
51
- /**
52
- * Wrap an existing DOM element in a card, replacing it in the DOM.
53
- *
54
- * @param {HTMLElement} element
55
- * @param {object} [opts] - Same options as buildCard (excluding `content`)
56
- * @returns {HTMLElement} the card element
57
- */
58
- export function wrapInCard(element, opts = {}) {
59
- const card = buildCard(opts);
60
- element.parentNode?.insertBefore(card, element);
61
- card.querySelector('.card-body').appendChild(element);
62
- return card;
63
- }
1
+ export function buildCard({title:d="",content:e="",className:a="mb-4",id:n=""}={}){const r=document.createElement("div");if(r.className=`card ${a}`.trim(),n&&(r.id=n),d){const c=document.createElement("div");c.className="card-header";const o=document.createElement("h2");o.textContent=d,c.appendChild(o),r.appendChild(c)}const t=document.createElement("div");return t.className="card-body",e instanceof Node?t.appendChild(e):typeof e=="string"&&e&&$(t).html(e),r.appendChild(t),r}export function wrapInCard(d,e={}){const a=buildCard(e);return d.parentNode?.insertBefore(a,d),a.querySelector(".card-body").appendChild(d),a}