nodebb-plugin-equipment-calendar 0.1.2 → 0.2.3

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 CHANGED
@@ -35,3 +35,9 @@ Le plugin vérifie la signature si `webhookSecret` est renseigné (exemple basiq
35
35
  - Ce plugin est un squelette complet mais générique : adapte la logique de paiement HelloAsso selon ton besoin exact
36
36
  (type de checkout, itemization, montant, etc.).
37
37
  - Pour un contrôle d'overlap strict : le plugin empêche les réservations qui chevauchent (même item) pour les statuts bloquants.
38
+
39
+
40
+ ## URLs
41
+ - Calendrier: `/equipment/calendar` (alias `/calendar`)
42
+ - Validations: `/equipment/approvals`
43
+ - ACP: `/admin/plugins/equipment-calendar`
package/library.js CHANGED
@@ -306,7 +306,18 @@ function clampRange(startStr, endStr, tz) {
306
306
 
307
307
  // --- Routes ---
308
308
  plugin.init = async function (params) {
309
- const { router } = params;
309
+ const { router } = params;
310
+ const mid = params.middleware;
311
+
312
+ // Admin (ACP) routes
313
+ if (mid && mid.admin) {
314
+ router.get('/admin/plugins/equipment-calendar', mid.admin.buildHeader, renderAdminPage);
315
+ router.get('/api/admin/plugins/equipment-calendar', renderAdminPage);
316
+ }
317
+
318
+ // Convenience alias (optional): /calendar -> /equipment/calendar
319
+ router.get('/calendar', (req, res) => res.redirect('/equipment/calendar'));
320
+
310
321
 
311
322
  // To verify webhook signature we need raw body; add a rawBody collector for this route only
312
323
  router.post('/equipment/webhook/helloasso',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nodebb-plugin-equipment-calendar",
3
- "version": "0.1.2",
3
+ "version": "0.2.3",
4
4
  "description": "Equipment reservation calendar for NodeBB (FullCalendar, approvals, HelloAsso payments)",
5
5
  "main": "library.js",
6
6
  "scripts": {
package/plugin.json CHANGED
@@ -18,8 +18,15 @@
18
18
  "method": "addPageRoutes"
19
19
  }
20
20
  ],
21
+ "templates": "./public/templates",
21
22
  "staticDirs": {
22
- "public": "./public"
23
+ "js": "public/js",
24
+ "css": "public/css"
23
25
  },
24
- "templates": "./public/templates"
26
+ "scripts": [
27
+ "public/js/client.js"
28
+ ],
29
+ "acpScripts": [
30
+ "public/js/admin.js"
31
+ ]
25
32
  }
@@ -0,0 +1,2 @@
1
+ .equipment-calendar-page {}
2
+ .ec-status-pending {}
@@ -0,0 +1,32 @@
1
+ 'use strict';
2
+ /* global $, app */
3
+
4
+ define('admin/plugins/equipment-calendar', function () {
5
+ const EquipmentCalendar = {};
6
+
7
+ EquipmentCalendar.init = function () {
8
+ $('#save').on('click', function () {
9
+ const payload = {
10
+ creatorGroups: $('#creatorGroups').val(),
11
+ approverGroup: $('#approverGroup').val(),
12
+ notifyGroup: $('#notifyGroup').val(),
13
+ itemsJson: $('#itemsJson').val(),
14
+ ha_clientId: $('#ha_clientId').val(),
15
+ ha_clientSecret: $('#ha_clientSecret').val(),
16
+ ha_organizationSlug: $('#ha_organizationSlug').val(),
17
+ ha_returnUrl: $('#ha_returnUrl').val(),
18
+ ha_webhookSecret: $('#ha_webhookSecret').val(),
19
+ defaultView: $('#defaultView').val(),
20
+ timezone: $('#timezone').val(),
21
+ showRequesterToAll: $('#showRequesterToAll').is(':checked') ? '1' : '0',
22
+ };
23
+
24
+ socket.emit('admin.settings.save', { hash: 'equipmentCalendar', values: payload }, function (err) {
25
+ if (err) return app.alertError(err.message || err);
26
+ app.alertSuccess('Sauvegardé');
27
+ });
28
+ });
29
+ };
30
+
31
+ return EquipmentCalendar;
32
+ });
@@ -0,0 +1,50 @@
1
+ 'use strict';
2
+ /* global $, window, document, FullCalendar */
3
+
4
+ (function () {
5
+ function submitCreate(startISO, endISO) {
6
+ const form = document.getElementById('ec-create-form');
7
+ if (!form) return;
8
+ form.querySelector('input[name="start"]').value = startISO;
9
+ form.querySelector('input[name="end"]').value = endISO;
10
+ form.submit();
11
+ }
12
+
13
+ $(document).ready(function () {
14
+ const el = document.getElementById('equipment-calendar');
15
+ if (!el) return;
16
+
17
+ const events = window.EC_EVENTS || [];
18
+ const initialDate = window.EC_INITIAL_DATE;
19
+ const initialView = window.EC_INITIAL_VIEW || 'dayGridMonth';
20
+
21
+ const calendar = new FullCalendar.Calendar(el, {
22
+ initialView: initialView,
23
+ initialDate: initialDate,
24
+ timeZone: window.EC_TZ || 'local',
25
+ selectable: window.EC_CAN_CREATE === true,
26
+ selectMirror: true,
27
+ events: events,
28
+ select: function (info) {
29
+ // FullCalendar provides end exclusive for all-day; for timed selections it's fine.
30
+ submitCreate(info.startStr, info.endStr);
31
+ },
32
+ dateClick: function (info) {
33
+ // Create 1-hour slot by default
34
+ const start = info.date;
35
+ const end = new Date(start.getTime() + 60 * 60 * 1000);
36
+ submitCreate(start.toISOString(), end.toISOString());
37
+ },
38
+ eventClick: function (info) {
39
+ // optionally show details
40
+ },
41
+ headerToolbar: {
42
+ left: 'prev,next today',
43
+ center: 'title',
44
+ right: 'dayGridMonth,timeGridWeek,timeGridDay'
45
+ },
46
+ });
47
+
48
+ calendar.render();
49
+ });
50
+ }());
@@ -52,7 +52,7 @@
52
52
 
53
53
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/fullcalendar@6.1.19/index.global.min.css">
54
54
  <script src="https://cdn.jsdelivr.net/npm/fullcalendar@6.1.19/index.global.min.js"></script>
55
- <script src="/plugins/nodebb-plugin-equipment-calendar/lib/client.js"></script>
55
+ <script src="/plugins/nodebb-plugin-equipment-calendar/js/client.js"></script>
56
56
 
57
57
  <script>
58
58
  // eventsJson is already JSON, we output it unescaped by using data attribute trick