nodebb-plugin-calendar-onekite 11.2.23 → 11.2.25

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 ADDED
@@ -0,0 +1,21 @@
1
+ # Changelog
2
+
3
+ ## 1.0.0
4
+
5
+ ### ACP
6
+ - Locations en attente : validation/refus avec les **mêmes modales** que côté calendrier (adresse + carte + notes + heure / raison de refus) et **suppression de la ligne** après action.
7
+ - Réglages : correction de l’enregistrement des **groupes** dans l’onglet Évènements (form + payload), et correction du décalage d’affichage des onglets.
8
+
9
+ ### Calendrier (front)
10
+ - Évènements : suppression de l’icône « pin-it ».
11
+ - Évènements : alignement de l’horloge identique aux icônes des réservations (rendu sans colonne de temps FullCalendar).
12
+ - Création d’évènement : clic sur un jour = valeur par défaut **07:00 → 07:00** (gestion robuste de l’`end` exclusif FullCalendar).
13
+ - Modales : correction d’un cas où, après annulation (ESC/clic extérieur), les modales ne réapparaissaient plus.
14
+ - **Nouveau** : conservation du dernier mode sélectionné (**Location** / **Évènement**) même après création/annulation/refetch (persisté par utilisateur via `localStorage`).
15
+
16
+ ### Emails
17
+ - Template relance : ajout du même bloc de paiement que dans pending (bouton + lien de secours).
18
+
19
+ ### Maintenance
20
+ - Nettoyage des CSS/handlers devenus inutiles suite aux corrections d’alignement.
21
+ - Harmonisation des versions (`package.json` + `plugin.json`) en `1.0.0`.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nodebb-plugin-calendar-onekite",
3
- "version": "11.2.23",
3
+ "version": "11.2.25",
4
4
  "description": "FullCalendar-based equipment reservation workflow with admin approval & HelloAsso payment for NodeBB",
5
5
  "main": "library.js",
6
6
  "license": "MIT",
@@ -11,4 +11,4 @@
11
11
  "nbbpm": {
12
12
  "compatibility": "^4.0.0"
13
13
  }
14
- }
14
+ }
package/plugin.json CHANGED
@@ -31,5 +31,5 @@
31
31
  "acpScripts": [
32
32
  "public/admin.js"
33
33
  ],
34
- "version": "1.0.61"
34
+ "version": "1.0.0"
35
35
  }
package/public/client.js CHANGED
@@ -838,51 +838,83 @@ function toDatetimeLocalValue(date) {
838
838
  const canCreateSpecial = !!caps.canCreateSpecial;
839
839
  const canDeleteSpecial = !!caps.canDeleteSpecial;
840
840
 
841
- // Current creation mode: reservation (location) or special (event)
842
- let mode = 'reservation';
841
+ // Current creation mode: reservation (location) or special (event).
842
+ // Persist the user's last choice so actions (create/approve/refuse/refetch) don't reset it.
843
+ const modeStorageKey = (() => {
844
+ try {
845
+ const uid = (typeof app !== 'undefined' && app && app.user && (app.user.uid || app.user.uid === 0)) ? String(app.user.uid)
846
+ : (window.ajaxify && window.ajaxify.data && (window.ajaxify.data.uid || window.ajaxify.data.uid === 0)) ? String(window.ajaxify.data.uid)
847
+ : '0';
848
+ return `onekiteCalendarMode:${uid}`;
849
+ } catch (e) {
850
+ return 'onekiteCalendarMode:0';
851
+ }
852
+ })();
853
+
854
+ function loadSavedMode() {
855
+ try {
856
+ const v = (window.localStorage && window.localStorage.getItem(modeStorageKey)) || '';
857
+ return (v === 'special' || v === 'reservation') ? v : 'reservation';
858
+ } catch (e) {
859
+ return 'reservation';
860
+ }
861
+ }
862
+
863
+ function saveMode(v) {
864
+ try {
865
+ if (!window.localStorage) return;
866
+ window.localStorage.setItem(modeStorageKey, v);
867
+ } catch (e) {
868
+ // ignore
869
+ }
870
+ }
871
+
872
+ let mode = loadSavedMode();
843
873
  // Avoid showing the "mode évènement" hint multiple times (desktop + mobile handlers)
844
874
  let lastModeHintAt = 0;
845
- function refreshDesktopModeButton() {
846
- try {
847
- const btn = document.querySelector('#onekite-calendar .fc-newSpecial-button');
848
- if (!btn) return;
849
- const isSpecial = mode === 'special';
850
- const label = isSpecial ? 'Évènement ✓' : 'Évènement';
851
- // FullCalendar wraps text in a span.fc-button-text. Replacing the entire
852
- // button textContent can confuse its rerendering and lead to duplicated
853
- // labels ("EvenementEvenement").
854
- const span = btn.querySelector('.fc-button-text');
855
- if (span) {
856
- span.textContent = label;
857
- } else {
858
- btn.textContent = label;
859
- }
860
- btn.classList.toggle('onekite-active', isSpecial);
861
- } catch (e) {}
875
+
876
+ function refreshDesktopModeButton() {
877
+ try {
878
+ const btn = document.querySelector('#onekite-calendar .fc-newSpecial-button');
879
+ if (!btn) return;
880
+ const isSpecial = mode === 'special';
881
+ const label = isSpecial ? 'Évènement ✓' : 'Évènement';
882
+ const span = btn.querySelector('.fc-button-text');
883
+ if (span) {
884
+ span.textContent = label;
885
+ } else {
886
+ btn.textContent = label;
862
887
  }
888
+ btn.classList.toggle('onekite-active', isSpecial);
889
+ } catch (e) {}
890
+ }
863
891
 
864
- function setMode(next) {
865
- mode = next;
866
- // Reset any pending selection/dialog state when switching modes
867
- try { if (mode === 'reservation') { calendar.unselect(); isDialogOpen = false; } } catch (e) {}
868
- if (mode === 'special') {
869
- const now = Date.now();
870
- if (now - lastModeHintAt > 1200) {
871
- lastModeHintAt = now;
872
- showAlert('success', 'Mode évènement : sélectionnez une date ou une plage');
873
- }
874
- }
875
- refreshDesktopModeButton();
876
- try {
877
- const mb = document.querySelector('#onekite-mobile-controls .onekite-mode-btn');
878
- if (mb) {
879
- const isSpecial = mode === 'special';
880
- mb.textContent = isSpecial ? 'Mode évènement ✓' : 'Mode évènement';
881
- mb.classList.toggle('onekite-active', isSpecial);
882
- }
883
- } catch (e) {}
892
+ function setMode(next, opts) {
893
+ if (next !== 'reservation' && next !== 'special') return;
894
+ mode = next;
895
+ saveMode(mode);
896
+
897
+ // Reset any pending selection/dialog state when switching modes
898
+ try { if (mode === 'reservation') { calendar.unselect(); isDialogOpen = false; } } catch (e) {}
899
+
900
+ const silent = !!(opts && opts.silent);
901
+ if (!silent && mode === 'special') {
902
+ const now = Date.now();
903
+ if (now - lastModeHintAt > 1200) {
904
+ lastModeHintAt = now;
905
+ showAlert('success', 'Mode évènement : sélectionnez une date ou une plage');
884
906
  }
885
- // or 'special'
907
+ }
908
+ refreshDesktopModeButton();
909
+ try {
910
+ const mb = document.querySelector('#onekite-mobile-controls .onekite-mode-btn');
911
+ if (mb) {
912
+ const isSpecial = mode === 'special';
913
+ mb.textContent = isSpecial ? 'Mode évènement ✓' : 'Mode évènement';
914
+ mb.classList.toggle('onekite-active', isSpecial);
915
+ }
916
+ } catch (e) {}
917
+ }
886
918
 
887
919
  // Inject lightweight responsive CSS once.
888
920
  try {
@@ -1048,7 +1080,6 @@ function toDatetimeLocalValue(date) {
1048
1080
  });
1049
1081
  });
1050
1082
  showAlert('success', 'Évènement créé.');
1051
- setMode('reservation');
1052
1083
  calendar.refetchEvents();
1053
1084
  calendar.unselect();
1054
1085
  isDialogOpen = false;
@@ -1142,7 +1173,6 @@ function toDatetimeLocalValue(date) {
1142
1173
  body: JSON.stringify(payload),
1143
1174
  });
1144
1175
  });
1145
- setMode('reservation');
1146
1176
  showAlert('success', 'Évènement créé.');
1147
1177
  calendar.refetchEvents();
1148
1178
  } finally {
@@ -22,9 +22,8 @@
22
22
  </li>
23
23
  </ul>
24
24
 
25
+ <form id="onekite-settings-form">
25
26
  <div class="tab-content pt-3">
26
- <form id="onekite-settings-form" class="mt-1">
27
-
28
27
  <div class="tab-pane fade show active" id="onekite-tab-settings" role="tabpanel">
29
28
  <h4>Groupes</h4>
30
29
  <div class="mb-3">
@@ -126,10 +125,6 @@
126
125
  <div class="form-text mt-2">Supprime définitivement tous les évènements dont la date de début est dans l'année sélectionnée.</div>
127
126
  </div>
128
127
 
129
- </form>
130
-
131
-
132
-
133
128
  <div class="tab-pane fade" id="onekite-tab-pending" role="tabpanel">
134
129
  <h4>Demandes en attente</h4>
135
130
  <div id="onekite-pending" class="list-group"></div>
@@ -180,6 +175,7 @@
180
175
  </div>
181
176
  </div>
182
177
  </div>
178
+ </form>
183
179
  </div>
184
180
  </div>
185
181