nodebb-plugin-onekite-calendar 2.0.15 → 2.0.16

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/CHANGELOG.md CHANGED
@@ -114,3 +114,7 @@
114
114
  - Mobile: ajout d’un bouton flottant (FAB) sur la page calendrier uniquement.
115
115
  - Le FAB ouvre une mini-modale de sélection de dates (dd/mm/yyyy) puis ouvre la modale standard de réservation.
116
116
  - Le FAB est automatiquement retiré quand on navigue hors de la page calendrier.
117
+
118
+ ## 1.3.10
119
+ - Widget : ne pas afficher le statut « Payée » pour les sorties gratuites (validateurs).
120
+ - Modale réservation : affichage de la période corrigé (fin affichée inclusive, fin stockée exclusive).
package/lib/widgets.js CHANGED
@@ -319,7 +319,15 @@ dateClick: function() { window.location.href = calUrl; },
319
319
  const k = String(s || '');
320
320
  return map[k] || '';
321
321
  });
322
- const status = (String(ep.type || '') === 'reservation') ? statusLabel(ep.status) : '';
322
+ let status = (String(ep.type || '') === 'reservation') ? statusLabel(ep.status) : '';
323
+ // Do not display "Payée" for free validator rentals.
324
+ // Free rentals are marked with extendedProps.isFree === true.
325
+ try {
326
+ const isFree = !!(ep && (ep.isFree === true || String(ep.isFree) === 'true'));
327
+ if (isFree && String(ep.status) === 'paid') {
328
+ status = '';
329
+ }
330
+ } catch (e) {}
323
331
  const reservedBy = (String(ep.type || '') === 'reservation') ? String(ep.reservedByUsername || '') : '';
324
332
  const html = '' +
325
333
  '<div style="font-weight:600; margin-bottom:2px;">' + escapeHtml(title) + '</div>' +
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nodebb-plugin-onekite-calendar",
3
- "version": "2.0.15",
3
+ "version": "2.0.16",
4
4
  "description": "FullCalendar-based equipment reservation workflow with admin approval & HelloAsso payment for NodeBB",
5
5
  "main": "library.js",
6
6
  "license": "MIT",
@@ -110,3 +110,7 @@
110
110
  - Mobile: ajout d’un bouton flottant (FAB) sur la page calendrier uniquement.
111
111
  - Le FAB ouvre une mini-modale de sélection de dates (dd/mm/yyyy) puis ouvre la modale standard de réservation.
112
112
  - Le FAB est automatiquement retiré quand on navigue hors de la page calendrier.
113
+
114
+ ## 1.3.10
115
+ - Widget : ne pas afficher le statut « Payée » pour les sorties gratuites (validateurs).
116
+ - Modale réservation : affichage de la période corrigé (fin affichée inclusive, fin stockée exclusive).
@@ -319,7 +319,15 @@ dateClick: function() { window.location.href = calUrl; },
319
319
  const k = String(s || '');
320
320
  return map[k] || '';
321
321
  });
322
- const status = (String(ep.type || '') === 'reservation') ? statusLabel(ep.status) : '';
322
+ let status = (String(ep.type || '') === 'reservation') ? statusLabel(ep.status) : '';
323
+ // Do not display "Payée" for free validator rentals.
324
+ // Free rentals are marked with extendedProps.isFree === true.
325
+ try {
326
+ const isFree = !!(ep && (ep.isFree === true || String(ep.isFree) === 'true'));
327
+ if (isFree && String(ep.status) === 'paid') {
328
+ status = '';
329
+ }
330
+ } catch (e) {}
323
331
  const reservedBy = (String(ep.type || '') === 'reservation') ? String(ep.reservedByUsername || '') : '';
324
332
  const html = '' +
325
333
  '<div style="font-weight:600; margin-bottom:2px;">' + escapeHtml(title) + '</div>' +
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nodebb-plugin-onekite-calendar",
3
- "version": "1.3.9",
3
+ "version": "1.3.10",
4
4
  "description": "FullCalendar-based equipment reservation workflow with admin approval & HelloAsso payment for NodeBB",
5
5
  "main": "library.js",
6
6
  "license": "MIT",
@@ -967,8 +967,26 @@ function toDatetimeLocalValue(date) {
967
967
  `;
968
968
  })();
969
969
 
970
+ // UI display: end is stored/processed as EXCLUSIVE, but humans expect an inclusive end date.
971
+ function endInclusiveForDisplay(startDate, endExclusive) {
972
+ try {
973
+ const e = new Date(endExclusive);
974
+ // Subtract one day to display the last included day.
975
+ e.setDate(e.getDate() - 1);
976
+ // Guard: never display an end before start.
977
+ if (e < startDate) {
978
+ return new Date(startDate);
979
+ }
980
+ return e;
981
+ } catch (e) {
982
+ return new Date(startDate);
983
+ }
984
+ }
985
+
986
+ const endDisplay = endInclusiveForDisplay(start, end);
987
+
970
988
  const messageHtml = `
971
- <div class="mb-2" id="onekite-period"><strong>Période</strong><br>${formatDt(start)} → ${formatDt(end)} <span class="text-muted" id="onekite-days">(${days} jour${days > 1 ? 's' : ''})</span></div>
989
+ <div class="mb-2" id="onekite-period"><strong>Période</strong><br>${formatDt(start)} → ${formatDt(endDisplay)} <span class="text-muted" id="onekite-days">(${days} jour${days > 1 ? 's' : ''})</span></div>
972
990
  ${shortcutsHtml}
973
991
  <div class="mb-2"><strong>Matériel</strong></div>
974
992
  <div id="onekite-items" class="mb-2" style="max-height: 320px; overflow: auto; border: 1px solid var(--bs-border-color, #ddd); border-radius: 6px; padding: 6px;">
@@ -1098,7 +1116,8 @@ function toDatetimeLocalValue(date) {
1098
1116
  daysEl.textContent = `(${days} jour${days > 1 ? 's' : ''})`;
1099
1117
  }
1100
1118
  if (periodEl) {
1101
- periodEl.innerHTML = `<strong>Période</strong><br>${formatDt(start)} → ${formatDt(end)} <span class="text-muted" id="onekite-days">(${days} jour${days > 1 ? 's' : ''})</span>`;
1119
+ const endDisp = endInclusiveForDisplay(start, end);
1120
+ periodEl.innerHTML = `<strong>Période</strong><br>${formatDt(start)} → ${formatDt(endDisp)} <span class="text-muted" id="onekite-days">(${days} jour${days > 1 ? 's' : ''})</span>`;
1102
1121
  }
1103
1122
  // Toggle active button
1104
1123
  shortcutsWrap.querySelectorAll('button[data-days]').forEach((b) => b.classList.toggle('active', b === btn));
package/plugin.json CHANGED
@@ -39,5 +39,5 @@
39
39
  "acpScripts": [
40
40
  "public/admin.js"
41
41
  ],
42
- "version": "2.0.15"
42
+ "version": "2.0.16"
43
43
  }
package/public/client.js CHANGED
@@ -967,8 +967,26 @@ function toDatetimeLocalValue(date) {
967
967
  `;
968
968
  })();
969
969
 
970
+ // UI display: end is stored/processed as EXCLUSIVE, but humans expect an inclusive end date.
971
+ function endInclusiveForDisplay(startDate, endExclusive) {
972
+ try {
973
+ const e = new Date(endExclusive);
974
+ // Subtract one day to display the last included day.
975
+ e.setDate(e.getDate() - 1);
976
+ // Guard: if something goes weird, never display an end before start.
977
+ if (e < startDate) {
978
+ return new Date(startDate);
979
+ }
980
+ return e;
981
+ } catch (e) {
982
+ return new Date(startDate);
983
+ }
984
+ }
985
+
986
+ const endDisplay = endInclusiveForDisplay(start, end);
987
+
970
988
  const messageHtml = `
971
- <div class="mb-2" id="onekite-period"><strong>Période</strong><br>${formatDt(start)} → ${formatDt(end)} <span class="text-muted" id="onekite-days">(${days} jour${days > 1 ? 's' : ''})</span></div>
989
+ <div class="mb-2" id="onekite-period"><strong>Période</strong><br>${formatDt(start)} → ${formatDt(endDisplay)} <span class="text-muted" id="onekite-days">(${days} jour${days > 1 ? 's' : ''})</span></div>
972
990
  ${shortcutsHtml}
973
991
  <div class="mb-2"><strong>Matériel</strong></div>
974
992
  <div id="onekite-items" class="mb-2" style="max-height: 320px; overflow: auto; border: 1px solid var(--bs-border-color, #ddd); border-radius: 6px; padding: 6px;">
@@ -1098,7 +1116,8 @@ function toDatetimeLocalValue(date) {
1098
1116
  daysEl.textContent = `(${days} jour${days > 1 ? 's' : ''})`;
1099
1117
  }
1100
1118
  if (periodEl) {
1101
- periodEl.innerHTML = `<strong>Période</strong><br>${formatDt(start)} → ${formatDt(end)} <span class="text-muted" id="onekite-days">(${days} jour${days > 1 ? 's' : ''})</span>`;
1119
+ const endDisp = endInclusiveForDisplay(start, end);
1120
+ periodEl.innerHTML = `<strong>Période</strong><br>${formatDt(start)} → ${formatDt(endDisp)} <span class="text-muted" id="onekite-days">(${days} jour${days > 1 ? 's' : ''})</span>`;
1102
1121
  }
1103
1122
  // Toggle active button
1104
1123
  shortcutsWrap.querySelectorAll('button[data-days]').forEach((b) => b.classList.toggle('active', b === btn));