nodebb-plugin-onekite-calendar 1.0.3 → 1.0.4

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/public/admin.js CHANGED
@@ -1,5 +1,5 @@
1
1
 
2
- define('admin/plugins/calendar-onekite', ['alerts', 'bootbox'], function (alerts, bootbox) {
2
+ define('admin/plugins/onekite-calendar', ['alerts', 'bootbox'], function (alerts, bootbox) {
3
3
  'use strict';
4
4
 
5
5
  // Cache of pending reservations keyed by rid so delegated click handlers
@@ -11,11 +11,11 @@ define('admin/plugins/calendar-onekite', ['alerts', 'bootbox'], function (alerts
11
11
  // by NodeBB ACP save buttons/hooks across ajaxify navigations.
12
12
  try {
13
13
  const now = Date.now();
14
- const last = window.oneKiteCalendarLastAlert;
14
+ const last = window.onekiteCalendarLastAlert;
15
15
  if (last && last.type === type && last.msg === msg && (now - last.ts) < 1200) {
16
16
  return;
17
17
  }
18
- window.oneKiteCalendarLastAlert = { type, msg, ts: now };
18
+ window.onekiteCalendarLastAlert = { type, msg, ts: now };
19
19
  } catch (e) {}
20
20
  try {
21
21
  if (alerts && typeof alerts[type] === 'function') {
@@ -46,30 +46,7 @@ define('admin/plugins/calendar-onekite', ['alerts', 'bootbox'], function (alerts
46
46
 
47
47
 
48
48
  if (!res.ok) {
49
- // NodeBB versions differ: some expose admin APIs under /api/admin instead of /api/v3/admin
50
- if (res.status === 404 && typeof url === 'string' && url.includes('/api/v3/admin/')) {
51
- const altUrl = url.replace('/api/v3/admin/', '/api/admin/');
52
- const res2 = await fetch(altUrl, {
53
- credentials: 'same-origin',
54
- headers: (() => {
55
- const headers = { 'Content-Type': 'application/json' };
56
- const token =
57
- (window.config && (window.config.csrf_token || window.config.csrfToken)) ||
58
- (window.ajaxify && window.ajaxify.data && window.ajaxify.data.csrf_token) ||
59
- (document.querySelector('meta[name="csrf-token"]') && document.querySelector('meta[name="csrf-token"]').getAttribute('content')) ||
60
- (document.querySelector('meta[name="csrf_token"]') && document.querySelector('meta[name="csrf_token"]').getAttribute('content')) ||
61
- (typeof app !== 'undefined' && app && app.csrfToken) ||
62
- null;
63
- if (token) headers['x-csrf-token'] = token;
64
- return headers;
65
- })(),
66
- ...opts,
67
- });
68
- if (res2.ok) {
69
- return await res2.json();
70
- }
71
- }
72
- const text = await res.text().catch(() => '');
49
+ const text = await res.text().catch(() => '');
73
50
  throw new Error(`${res.status} ${text}`);
74
51
  }
75
52
  return await res.json();
@@ -267,36 +244,36 @@ define('admin/plugins/calendar-onekite', ['alerts', 'bootbox'], function (alerts
267
244
  }
268
245
 
269
246
  async function loadSettings() {
270
- return await fetchJson('/api/v3/admin/plugins/calendar-onekite/settings');
247
+ return await fetchJson('/api/v3/admin/plugins/onekite-calendar/settings');
271
248
  }
272
249
 
273
250
  async function saveSettings(payload) {
274
- return await fetchJson('/api/v3/admin/plugins/calendar-onekite/settings', {
251
+ return await fetchJson('/api/v3/admin/plugins/onekite-calendar/settings', {
275
252
  method: 'PUT',
276
253
  body: JSON.stringify(payload),
277
254
  });
278
255
  }
279
256
 
280
257
  async function loadPending() {
281
- return await fetchJson('/api/v3/admin/plugins/calendar-onekite/pending');
258
+ return await fetchJson('/api/v3/admin/plugins/onekite-calendar/pending');
282
259
  }
283
260
 
284
261
  async function approve(rid, payload) {
285
- return await fetchJson(`/api/v3/admin/plugins/calendar-onekite/reservations/${rid}/approve`, {
262
+ return await fetchJson(`/api/v3/admin/plugins/onekite-calendar/reservations/${rid}/approve`, {
286
263
  method: 'PUT',
287
264
  body: JSON.stringify(payload || {}),
288
265
  });
289
266
  }
290
267
 
291
268
  async function refuse(rid, payload) {
292
- return await fetchJson(`/api/v3/admin/plugins/calendar-onekite/reservations/${rid}/refuse`, {
269
+ return await fetchJson(`/api/v3/admin/plugins/onekite-calendar/reservations/${rid}/refuse`, {
293
270
  method: 'PUT',
294
271
  body: JSON.stringify(payload || {}),
295
272
  });
296
273
  }
297
274
 
298
275
  async function purge(year) {
299
- return await fetchJson('/api/v3/admin/plugins/calendar-onekite/purge', {
276
+ return await fetchJson('/api/v3/admin/plugins/onekite-calendar/purge', {
300
277
  method: 'POST',
301
278
  body: JSON.stringify({ year }),
302
279
  });
@@ -304,55 +281,30 @@ define('admin/plugins/calendar-onekite', ['alerts', 'bootbox'], function (alerts
304
281
 
305
282
  async function purgeSpecialEvents(year) {
306
283
  try {
307
- return await fetchJson('/api/v3/admin/plugins/calendar-onekite/special-events/purge', {
284
+ return await fetchJson('/api/v3/admin/plugins/onekite-calendar/special-events/purge', {
308
285
  method: 'POST',
309
286
  body: JSON.stringify({ year }),
310
287
  });
311
288
  } catch (e) {
312
- return await fetchJson('/api/v3/admin/plugins/calendar-onekite/special-events/purge', {
289
+ return await fetchJson('/api/v3/admin/plugins/onekite-calendar/special-events/purge', {
313
290
  method: 'POST',
314
291
  body: JSON.stringify({ year }),
315
292
  });
316
293
  }
317
294
  }
318
295
 
319
- async function debugHelloAsso() {
320
- try {
321
- return await fetchJson('/api/v3/admin/plugins/calendar-onekite/debug');
322
- } catch (e) {
323
- return await fetchJson('/api/v3/admin/plugins/calendar-onekite/debug');
324
- }
325
- }
326
-
327
296
  async function loadAccounting(from, to) {
328
297
  const params = new URLSearchParams();
329
298
  if (from) params.set('from', from);
330
299
  if (to) params.set('to', to);
331
300
  const qs = params.toString();
332
- return await fetchJson(`/api/v3/admin/plugins/calendar-onekite/accounting${qs ? `?${qs}` : ''}`);
301
+ return await fetchJson(`/api/v3/admin/plugins/onekite-calendar/accounting${qs ? `?${qs}` : ''}`);
333
302
  }
334
303
 
335
304
  async function init() {
336
305
  const form = document.getElementById('onekite-settings-form');
337
306
  if (!form) return;
338
307
 
339
- // Make the HelloAsso debug output readable in both light and dark ACP themes.
340
- // NodeBB 4.x uses Bootstrap variables, so we can rely on CSS variables here.
341
- (function injectAdminCss() {
342
- const id = 'onekite-admin-css';
343
- if (document.getElementById(id)) return;
344
- const style = document.createElement('style');
345
- style.id = id;
346
- style.textContent = `
347
- #onekite-debug-output.onekite-debug-output {
348
- background: var(--bs-body-bg) !important;
349
- color: var(--bs-body-color) !important;
350
- border: 1px solid var(--bs-border-color) !important;
351
- }
352
- `;
353
- document.head.appendChild(style);
354
- })();
355
-
356
308
  // Load settings
357
309
  try {
358
310
  const s = await loadSettings();
@@ -409,19 +361,19 @@ define('admin/plugins/calendar-onekite', ['alerts', 'bootbox'], function (alerts
409
361
 
410
362
  // Expose the latest save handler so the global delegated listener (bound once)
411
363
  // can always call the current instance tied to the current form.
412
- window.oneKiteCalendarAdminDoSave = doSave;
364
+ window.onekiteCalendarAdminDoSave = doSave;
413
365
 
414
366
  // Save buttons (NodeBB header/footer "Enregistrer" + floppy icon)
415
367
  // Bind a SINGLE delegated listener for the entire admin session.
416
368
  const SAVE_SELECTOR = '#save, .save, [data-action="save"], .settings-save, .floating-save, .btn[data-action="save"]';
417
- if (!window.oneKiteCalendarAdminBound) {
418
- window.oneKiteCalendarAdminBound = true;
369
+ if (!window.onekiteCalendarAdminBound) {
370
+ window.onekiteCalendarAdminBound = true;
419
371
  document.addEventListener('click', (ev) => {
420
372
  const btn = ev.target && ev.target.closest && ev.target.closest(SAVE_SELECTOR);
421
373
  if (!btn) return;
422
374
  // Only handle clicks while we're on this plugin page
423
375
  if (!document.getElementById('onekite-settings-form')) return;
424
- const fn = window.oneKiteCalendarAdminDoSave;
376
+ const fn = window.onekiteCalendarAdminDoSave;
425
377
  if (typeof fn === 'function') fn(ev);
426
378
  });
427
379
  }
@@ -674,30 +626,6 @@ define('admin/plugins/calendar-onekite', ['alerts', 'bootbox'], function (alerts
674
626
  });
675
627
  }
676
628
 
677
- // Debug
678
- const debugBtn = document.getElementById('onekite-debug-run');
679
- if (debugBtn) {
680
- debugBtn.addEventListener('click', async () => {
681
- const out = document.getElementById('onekite-debug-output');
682
- if (out) out.textContent = 'Chargement...';
683
- try {
684
- const result = await debugHelloAsso();
685
- if (out) out.textContent = JSON.stringify(result, null, 2);
686
- const catalogCount = result && result.catalog ? parseInt(result.catalog.count, 10) || 0 : 0;
687
- const catalogOk = !!(result && result.catalog && result.catalog.ok);
688
- // Accept "count > 0" even if ok flag is false (some proxies can strip fields, etc.)
689
- if (catalogOk || catalogCount > 0) {
690
- showAlert('success', `Catalogue HelloAsso: ${catalogCount} item(s)`);
691
- } else {
692
- showAlert('error', 'HelloAsso: impossible de récupérer le catalogue.');
693
- }
694
- } catch (e) {
695
- if (out) out.textContent = String(e && e.message ? e.message : e);
696
- showAlert('error', 'Debug impossible.');
697
- }
698
- });
699
- }
700
-
701
629
  // Accounting (paid reservations)
702
630
  const accFrom = document.getElementById('onekite-acc-from');
703
631
  const accTo = document.getElementById('onekite-acc-to');
@@ -769,7 +697,7 @@ define('admin/plugins/calendar-onekite', ['alerts', 'bootbox'], function (alerts
769
697
  if (accFrom && accFrom.value) params.set('from', accFrom.value);
770
698
  if (accTo && accTo.value) params.set('to', accTo.value);
771
699
  const qs = params.toString();
772
- const url = `/api/v3/admin/plugins/calendar-onekite/accounting.csv${qs ? `?${qs}` : ''}`;
700
+ const url = `/api/v3/admin/plugins/onekite-calendar/accounting.csv${qs ? `?${qs}` : ''}`;
773
701
  window.open(url, '_blank');
774
702
  });
775
703
 
@@ -782,7 +710,7 @@ define('admin/plugins/calendar-onekite', ['alerts', 'bootbox'], function (alerts
782
710
  if (accFrom && accFrom.value) params.set('from', accFrom.value);
783
711
  if (accTo && accTo.value) params.set('to', accTo.value);
784
712
  const qs = params.toString();
785
- const url = `/api/v3/admin/plugins/calendar-onekite/accounting/purge${qs ? `?${qs}` : ''}`;
713
+ const url = `/api/v3/admin/plugins/onekite-calendar/accounting/purge${qs ? `?${qs}` : ''}`;
786
714
  const res = await fetchJson(url, { method: 'POST' });
787
715
  if (res && res.ok) {
788
716
  showAlert('success', `Compta purgée : ${res.purged || 0} réservation(s).`);
package/public/client.js CHANGED
@@ -1,10 +1,10 @@
1
1
  /* global FullCalendar, ajaxify */
2
2
 
3
- define('forum/calendar-onekite', ['alerts', 'bootbox', 'hooks'], function (alerts, bootbox, hooks) {
3
+ define('forum/onekite-calendar', ['alerts', 'bootbox', 'hooks'], function (alerts, bootbox, hooks) {
4
4
  'use strict';
5
5
 
6
6
  // Ensure small UI tweaks are applied even when themes override bootstrap defaults.
7
- (function ensureOneKiteStyles() {
7
+ (function ensureOnekiteStyles() {
8
8
  try {
9
9
  if (document.getElementById('onekite-inline-styles')) return;
10
10
  const style = document.createElement('style');
@@ -498,7 +498,7 @@ define('forum/calendar-onekite', ['alerts', 'bootbox', 'hooks'], function (alert
498
498
  }
499
499
 
500
500
  async function loadCapabilities() {
501
- return await fetchJson('/api/v3/plugins/calendar-onekite/capabilities');
501
+ return await fetchJson('/api/v3/plugins/onekite-calendar/capabilities');
502
502
  }
503
503
 
504
504
  // Leaflet (OpenStreetMap) helpers - loaded lazily only when needed.
@@ -706,34 +706,34 @@ function attachAddressAutocomplete(inputEl, onPick) {
706
706
 
707
707
  async function loadItems() {
708
708
  try {
709
- return await fetchJson('/api/v3/plugins/calendar-onekite/items');
709
+ return await fetchJson('/api/v3/plugins/onekite-calendar/items');
710
710
  } catch (e) {
711
711
  return [];
712
712
  }
713
713
  }
714
714
 
715
715
  async function requestReservation(payload) {
716
- return await fetchJson('/api/v3/plugins/calendar-onekite/reservations', {
716
+ return await fetchJson('/api/v3/plugins/onekite-calendar/reservations', {
717
717
  method: 'POST',
718
718
  body: JSON.stringify(payload),
719
719
  });
720
720
  }
721
721
 
722
722
  async function approveReservation(rid, payload) {
723
- return await fetchJson(`/api/v3/plugins/calendar-onekite/reservations/${rid}/approve`, {
723
+ return await fetchJson(`/api/v3/plugins/onekite-calendar/reservations/${rid}/approve`, {
724
724
  method: 'PUT',
725
725
  body: JSON.stringify(payload || {}),
726
726
  });
727
727
  }
728
728
 
729
729
  async function cancelReservation(rid) {
730
- return await fetchJson(`/api/v3/plugins/calendar-onekite/reservations/${rid}/cancel`, {
730
+ return await fetchJson(`/api/v3/plugins/onekite-calendar/reservations/${rid}/cancel`, {
731
731
  method: 'PUT',
732
732
  });
733
733
  }
734
734
 
735
735
  async function refuseReservation(rid, payload) {
736
- return await fetchJson(`/api/v3/plugins/calendar-onekite/reservations/${rid}/refuse`, {
736
+ return await fetchJson(`/api/v3/plugins/onekite-calendar/reservations/${rid}/refuse`, {
737
737
  method: 'PUT',
738
738
  body: JSON.stringify(payload || {}),
739
739
  });
@@ -783,7 +783,7 @@ function toDatetimeLocalValue(date) {
783
783
  let blocked = new Set();
784
784
  try {
785
785
  const qs = new URLSearchParams({ start: selectionInfo.startStr, end: selectionInfo.endStr });
786
- const evs = await fetchJson(`/api/v3/plugins/calendar-onekite/events?${qs.toString()}`);
786
+ const evs = await fetchJson(`/api/v3/plugins/onekite-calendar/events?${qs.toString()}`);
787
787
  (evs || []).forEach((ev) => {
788
788
  const st = (ev.extendedProps && ev.extendedProps.status) || '';
789
789
  if (!['pending', 'awaiting_payment', 'approved', 'paid'].includes(st)) return;
@@ -1094,7 +1094,7 @@ function toDatetimeLocalValue(date) {
1094
1094
  window.__onekiteEventsAbort = abort;
1095
1095
 
1096
1096
  const qs = new URLSearchParams({ start: info.startStr, end: info.endStr });
1097
- const url = `/api/v3/plugins/calendar-onekite/events?${qs.toString()}`;
1097
+ const url = `/api/v3/plugins/onekite-calendar/events?${qs.toString()}`;
1098
1098
  const data = await fetchJsonCached(url, { signal: abort.signal });
1099
1099
 
1100
1100
  // Prefetch adjacent range (previous/next) for snappier navigation.
@@ -1108,8 +1108,8 @@ function toDatetimeLocalValue(date) {
1108
1108
  const toStr = (d) => new Date(d.getTime()).toISOString();
1109
1109
  const qPrev = new URLSearchParams({ start: toStr(prevStart), end: toStr(prevEnd) });
1110
1110
  const qNext = new URLSearchParams({ start: toStr(nextStart), end: toStr(nextEnd) });
1111
- fetchJsonCached(`/api/v3/plugins/calendar-onekite/events?${qPrev.toString()}`).catch(() => {});
1112
- fetchJsonCached(`/api/v3/plugins/calendar-onekite/events?${qNext.toString()}`).catch(() => {});
1111
+ fetchJsonCached(`/api/v3/plugins/onekite-calendar/events?${qPrev.toString()}`).catch(() => {});
1112
+ fetchJsonCached(`/api/v3/plugins/onekite-calendar/events?${qNext.toString()}`).catch(() => {});
1113
1113
  }
1114
1114
  } catch (e) {}
1115
1115
 
@@ -1171,11 +1171,11 @@ function toDatetimeLocalValue(date) {
1171
1171
  isDialogOpen = false;
1172
1172
  return;
1173
1173
  }
1174
- await fetchJson('/api/v3/plugins/calendar-onekite/special-events', {
1174
+ await fetchJson('/api/v3/plugins/onekite-calendar/special-events', {
1175
1175
  method: 'POST',
1176
1176
  body: JSON.stringify(payload),
1177
1177
  }).catch(async () => {
1178
- return await fetchJson('/api/v3/plugins/calendar-onekite/special-events', {
1178
+ return await fetchJson('/api/v3/plugins/onekite-calendar/special-events', {
1179
1179
  method: 'POST',
1180
1180
  body: JSON.stringify(payload),
1181
1181
  });
@@ -1265,11 +1265,11 @@ function toDatetimeLocalValue(date) {
1265
1265
  isDialogOpen = false;
1266
1266
  return;
1267
1267
  }
1268
- await fetchJson('/api/v3/plugins/calendar-onekite/special-events', {
1268
+ await fetchJson('/api/v3/plugins/onekite-calendar/special-events', {
1269
1269
  method: 'POST',
1270
1270
  body: JSON.stringify(payload),
1271
1271
  }).catch(async () => {
1272
- return await fetchJson('/api/v3/plugins/calendar-onekite/special-events', {
1272
+ return await fetchJson('/api/v3/plugins/onekite-calendar/special-events', {
1273
1273
  method: 'POST',
1274
1274
  body: JSON.stringify(payload),
1275
1275
  });
@@ -1296,10 +1296,10 @@ function toDatetimeLocalValue(date) {
1296
1296
  let p = p0;
1297
1297
  try {
1298
1298
  if (p0.type === 'reservation' && p0.rid) {
1299
- const details = await fetchJson(`/api/v3/plugins/calendar-onekite/reservations/${encodeURIComponent(String(p0.rid))}`);
1299
+ const details = await fetchJson(`/api/v3/plugins/onekite-calendar/reservations/${encodeURIComponent(String(p0.rid))}`);
1300
1300
  p = Object.assign({}, p0, details);
1301
1301
  } else if (p0.type === 'special' && p0.eid) {
1302
- const details = await fetchJson(`/api/v3/plugins/calendar-onekite/special-events/${encodeURIComponent(String(p0.eid))}`);
1302
+ const details = await fetchJson(`/api/v3/plugins/onekite-calendar/special-events/${encodeURIComponent(String(p0.eid))}`);
1303
1303
  p = Object.assign({}, p0, details, {
1304
1304
  // keep backward compat with older field names used by templates below
1305
1305
  pickupAddress: details.address || details.pickupAddress || p0.pickupAddress,
@@ -1348,7 +1348,7 @@ function toDatetimeLocalValue(date) {
1348
1348
  callback: async () => {
1349
1349
  try {
1350
1350
  const eid = String(p.eid || ev.id).replace(/^special:/, '');
1351
- await fetchJson(`/api/v3/plugins/calendar-onekite/special-events/${encodeURIComponent(eid)}`, { method: 'DELETE' });
1351
+ await fetchJson(`/api/v3/plugins/onekite-calendar/special-events/${encodeURIComponent(eid)}`, { method: 'DELETE' });
1352
1352
  showAlert('success', 'Évènement supprimé.');
1353
1353
  calendar.refetchEvents();
1354
1354
  } catch (e) {
@@ -1667,7 +1667,7 @@ function toDatetimeLocalValue(date) {
1667
1667
  });
1668
1668
 
1669
1669
  // Expose for live updates
1670
- try { window.oneKiteCalendar = calendar; } catch (e) {}
1670
+ try { window.onekiteCalendar = calendar; } catch (e) {}
1671
1671
 
1672
1672
  calendar.render();
1673
1673
 
@@ -1766,7 +1766,7 @@ function toDatetimeLocalValue(date) {
1766
1766
  function autoInit(data) {
1767
1767
  try {
1768
1768
  const tpl = data && data.template ? data.template.name : (ajaxify && ajaxify.data && ajaxify.data.template ? ajaxify.data.template.name : '');
1769
- if (tpl === 'calendar-onekite') {
1769
+ if (tpl === 'onekite-calendar') {
1770
1770
  init('#onekite-calendar');
1771
1771
  }
1772
1772
  } catch (e) {}
@@ -1786,9 +1786,9 @@ function toDatetimeLocalValue(date) {
1786
1786
  try {
1787
1787
  if (!window.__oneKiteSocketBound && typeof socket !== 'undefined' && socket && typeof socket.on === 'function') {
1788
1788
  window.__oneKiteSocketBound = true;
1789
- socket.on('event:calendar-onekite.reservationUpdated', function () {
1789
+ socket.on('event:onekite-calendar.reservationUpdated', function () {
1790
1790
  try {
1791
- const cal = window.oneKiteCalendar;
1791
+ const cal = window.onekiteCalendar;
1792
1792
  scheduleRefetch(cal);
1793
1793
  } catch (e) {}
1794
1794
  });
@@ -2,22 +2,10 @@
2
2
 
3
3
  <div class="row">
4
4
  <div class="col-lg-9">
5
- <h1>Calendar OneKite</h1>
5
+ <h1>Calendar Onekite</h1>
6
6
 
7
7
  <ul class="nav nav-tabs mt-3" role="tablist">
8
- <li class="nav-item" role="presentation">
9
- <button class="nav-link active" data-bs-toggle="tab" data-bs-target="#onekite-tab-settings" type="button" role="tab">Locations</button>
10
- </li>
11
- <li class="nav-item" role="presentation">
12
- <button class="nav-link" data-bs-toggle="tab" data-bs-target="#onekite-tab-events" type="button" role="tab">Évènements</button>
13
- </li>
14
- <li class="nav-item" role="presentation">
15
- <button class="nav-link" data-bs-toggle="tab" data-bs-target="#onekite-tab-pending" type="button" role="tab">Demandes en attente</button>
16
- </li>
17
- <li class="nav-item" role="presentation">
18
- <button class="nav-link" data-bs-toggle="tab" data-bs-target="#onekite-tab-debug" type="button" role="tab">Debug HelloAsso</button>
19
- </li>
20
- <li class="nav-item" role="presentation">
8
+ <li class="nav-item" role="presentation">
21
9
  <button class="nav-link" data-bs-toggle="tab" data-bs-target="#onekite-tab-accounting" type="button" role="tab">Comptabilisation</button>
22
10
  </li>
23
11
  </ul>
@@ -154,14 +142,7 @@
154
142
  <h4>Demandes en attente</h4>
155
143
  <div id="onekite-pending" class="list-group"></div>
156
144
  </div>
157
-
158
- <div class="tab-pane fade" id="onekite-tab-debug" role="tabpanel">
159
- <p class="text-muted">Teste la récupération du token et la liste du matériel (catalogue).</p>
160
- <button type="button" class="btn btn-secondary me-2" id="onekite-debug-run">Tester le chargement du matériel</button>
161
- <pre id="onekite-debug-output" class="mt-3 p-3 border rounded onekite-debug-output" style="max-height: 360px; overflow: auto;"></pre>
162
- </div>
163
-
164
- <div class="tab-pane fade" id="onekite-tab-accounting" role="tabpanel">
145
+ <div class="tab-pane fade" id="onekite-tab-accounting" role="tabpanel">
165
146
  <h4>Comptabilisation des locations (payées)</h4>
166
147
  <div class="d-flex flex-wrap gap-2 align-items-end mb-3">
167
148
  <div>
@@ -205,7 +186,7 @@
205
186
  </div>
206
187
 
207
188
  <script>
208
- require(['admin/plugins/calendar-onekite'], function (mod) {
189
+ require(['admin/plugins/onekite-calendar'], function (mod) {
209
190
  if (mod && mod.init) {
210
191
  mod.init();
211
192
  }
@@ -21,6 +21,17 @@
21
21
  The plugin's forum script auto-initialises on the calendar page via ajaxify.
22
22
  -->
23
23
 
24
+ <script>
25
+ // Ultra-perf: load the forum JS only on the calendar page.
26
+ require(['forum/onekite-calendar'], function (mod) {
27
+ try {
28
+ if (mod && typeof mod.init === 'function') {
29
+ mod.init('#onekite-calendar');
30
+ }
31
+ } catch (e) {}
32
+ });
33
+ </script>
34
+
24
35
 
25
36
  <style>
26
37
  /* Make the custom "Évènement" button distinct from view buttons */