nodebb-plugin-onekite-calendar 1.0.8 → 1.0.10

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/lib/api.js CHANGED
@@ -134,12 +134,14 @@ function formatFR(tsOrIso) {
134
134
  }
135
135
 
136
136
  function buildHelloAssoItemName(baseLabel, itemNames, start, end) {
137
- const base = String(baseLabel || 'Réservation matériel Onekite').trim();
137
+ const base = String(baseLabel || '').trim();
138
138
  const items = Array.isArray(itemNames) ? itemNames.map((s) => String(s || '').trim()).filter(Boolean) : [];
139
- const range = (start && end) ? `Du ${formatFR(start)} au ${formatFR(end)}` : '';
140
- const lines = [base];
141
- items.forEach((it) => lines.push(`• ${it}`));
139
+ const range = (start && end) ? ('Du ' + formatFR(start) + ' au ' + formatFR(end)) : '';
140
+ const lines = [];
141
+ if (base) lines.push(base);
142
+ items.forEach((it) => lines.push('• ' + it));
142
143
  if (range) lines.push(range);
144
+ if (!lines.length) lines.push('Réservation matériel');
143
145
  let out = lines.join('\n').trim();
144
146
  // HelloAsso constraint: itemName max 250 chars
145
147
  if (out.length > 250) {
@@ -812,7 +814,7 @@ api.approveReservation = async function (req, res) {
812
814
  // Can be overridden via ACP setting `helloassoCallbackUrl`.
813
815
  callbackUrl: normalizeReturnUrl(meta),
814
816
  webhookUrl: normalizeCallbackUrl(settings2.helloassoCallbackUrl, meta),
815
- itemName: buildHelloAssoItemName('Réservation matériel Onekite', r.itemNames || (r.itemName ? [r.itemName] : []), r.start, r.end),
817
+ itemName: buildHelloAssoItemName('', r.itemNames || (r.itemName ? [r.itemName] : []), r.start, r.end),
816
818
  containsDonation: false,
817
819
  metadata: {
818
820
  reservationId: String(rid),
package/lib/widgets.js CHANGED
@@ -164,10 +164,51 @@ widgets.renderTwoWeeksWidget = async function (data) {
164
164
  },
165
165
  navLinks: false,
166
166
  eventTimeFormat: { hour: '2-digit', minute: '2-digit', hour12: false },
167
- // Render as a colored dot (like FullCalendar list dots)
167
+ // Force day number to be numeric only (avoid '1 janvier' style labels)
168
+ dayCellContent: function(arg) {
169
+ try {
170
+ const t = String(arg.dayNumberText || '');
171
+ const m = t.match(/^\d+/);
172
+ return { html: m ? m[0] : t };
173
+ } catch (e) {
174
+ return { html: String(arg.dayNumberText || '') };
175
+ }
176
+ },
177
+ eventClassNames: function(arg) {
178
+ try {
179
+ const ev = arg && arg.event;
180
+ if (!ev) return ['onekite-singleday'];
181
+ if (ev.extendedProps && (ev.extendedProps.multiDay === true || ev.extendedProps.days > 1)) return ['onekite-multiday'];
182
+ if (ev.start && ev.end) {
183
+ const diff = (new Date(ev.end)).getTime() - (new Date(ev.start)).getTime();
184
+ return [diff > 86400000 ? 'onekite-multiday' : 'onekite-singleday'];
185
+ }
186
+ } catch (e) {}
187
+ return ['onekite-singleday'];
188
+ },
189
+ // Render: dot for single-day, pill for multi-day
168
190
  eventContent: function(arg) {
169
- const bg = (arg.event.backgroundColor || (arg.event.extendedProps && arg.event.extendedProps.backgroundColor) || '').trim();
170
- const border = (arg.event.borderColor || '').trim();
191
+ const ev = arg && arg.event;
192
+ const isMulti = (function(){
193
+ try {
194
+ if (!ev || !ev.start || !ev.end) return false;
195
+ if (ev.extendedProps && (ev.extendedProps.multiDay === true || ev.extendedProps.days > 1)) return true;
196
+ const s = new Date(ev.start);
197
+ const e = new Date(ev.end);
198
+ const diff = e.getTime() - s.getTime();
199
+ return diff > 86400000; // strictly more than 1 day
200
+ } catch (e) { return false; }
201
+ })();
202
+
203
+ if (isMulti) {
204
+ const spacer = document.createElement('span');
205
+ spacer.className = 'onekite-pill-spacer';
206
+ spacer.appendChild(document.createTextNode('\u00A0'));
207
+ return { domNodes: [spacer] };
208
+ }
209
+
210
+ const bg = (ev.backgroundColor || (ev.extendedProps && ev.extendedProps.backgroundColor) || '').trim();
211
+ const border = (ev.borderColor || '').trim();
171
212
  const color = bg || border || '#3788d8';
172
213
  const wrap = document.createElement('span');
173
214
  wrap.className = 'onekite-dot-wrap';
@@ -194,13 +235,12 @@ widgets.renderTwoWeeksWidget = async function (data) {
194
235
  const start = ev.start ? new Date(ev.start) : null;
195
236
  const end = ev.end ? new Date(ev.end) : null;
196
237
  const pad2 = (n) => String(n).padStart(2, '0');
197
- const fmt = (d) => d ? `${pad2(d.getDate())}/${pad2(d.getMonth() + 1)}/${String(d.getFullYear()).slice(-2)}` : '';
198
- const range = (start && end) ? `Du ${fmt(start)} au ${fmt(end)}` : '';
199
- const html = `
200
- <div style="font-weight:600; margin-bottom:2px;">${escapeHtml(title)}</div>
201
- ${range ? `<div style=\"opacity:.85\">${escapeHtml(range)}</div>` : ''}
202
- ${status ? `<div style=\"opacity:.75; margin-top:2px; font-size:.85em;\">${escapeHtml(status)}</div>` : ''}
203
- `;
238
+ const fmt = (d) => d ? (pad2(d.getDate()) + '/' + pad2(d.getMonth() + 1) + '/' + String(d.getFullYear()).slice(-2)) : '';
239
+ const range = (start && end) ? ('Du ' + fmt(start) + ' au ' + fmt(end)) : '';
240
+ const html = '' +
241
+ '<div style="font-weight:600; margin-bottom:2px;">' + escapeHtml(title) + '</div>' +
242
+ (range ? ('<div style="opacity:.85">' + escapeHtml(range) + '</div>') : '') +
243
+ (status ? ('<div style="opacity:.75; margin-top:2px; font-size:.85em;">' + escapeHtml(status) + '</div>') : '');
204
244
 
205
245
  // Hover (desktop)
206
246
  info.el.addEventListener('mouseenter', (e) => {
@@ -262,11 +302,38 @@ widgets.renderTwoWeeksWidget = async function (data) {
262
302
  .onekite-twoweeks .fc .fc-button { padding: .2rem .35rem; font-size: .75rem; }
263
303
  .onekite-twoweeks .fc .fc-daygrid-day-number { font-size: .75rem; padding: 2px; }
264
304
  .onekite-twoweeks .fc .fc-col-header-cell-cushion { font-size: .75rem; }
265
- .onekite-twoweeks .fc .fc-event { background: transparent; border: none; }
305
+
306
+ /* Single-day: show only a dot */
307
+ .onekite-twoweeks .fc .fc-event.onekite-singleday { background: transparent !important; border: none !important; }
308
+ .onekite-twoweeks .fc .fc-daygrid-event.onekite-singleday,
309
+ .onekite-twoweeks .fc .fc-daygrid-block-event.onekite-singleday {
310
+ background: transparent !important;
311
+ border: none !important;
312
+ box-shadow: none !important;
313
+ }
314
+ .onekite-twoweeks .fc .fc-daygrid-block-event.onekite-singleday .fc-event-main { padding: 0 !important; }
315
+
316
+ /* Multi-day: keep FullCalendar bar, but hide text and make it a pill */
317
+ .onekite-twoweeks .fc .fc-event.onekite-multiday {
318
+ border-radius: 999px !important;
319
+ overflow: hidden;
320
+ }
321
+ .onekite-twoweeks .fc .fc-daygrid-event.onekite-multiday,
322
+ .onekite-twoweeks .fc .fc-daygrid-block-event.onekite-multiday {
323
+ border-radius: 999px !important;
324
+ box-shadow: none !important;
325
+ }
326
+ .onekite-twoweeks .fc .fc-event.onekite-multiday .fc-event-main { padding: 0 !important; }
327
+ .onekite-twoweeks .fc .fc-event.onekite-multiday .fc-event-title,
328
+ .onekite-twoweeks .fc .fc-event.onekite-multiday .fc-event-time { display:none !important; }
329
+
330
+ .onekite-twoweeks .fc .fc-daygrid-event-harness { margin-top: 2px; }
331
+ .onekite-twoweeks .fc .fc-daygrid-event { padding: 0 !important; }
266
332
  .onekite-twoweeks .fc .fc-event-main { color: inherit; }
267
333
  .onekite-twoweeks .fc .fc-event-title { display:none; }
268
- .onekite-dot-wrap { display:flex; align-items:center; justify-content:center; width: 100%; }
334
+ .onekite-dot-wrap { display:flex; align-items:center; justify-content:center; width: auto; }
269
335
  .onekite-dot { width: 10px; height: 10px; border-radius: 999px; display:inline-block; }
336
+ .onekite-pill-spacer { display:block; height: 10px; line-height: 10px; }
270
337
  .onekite-cal-tooltip {
271
338
  position: absolute;
272
339
  z-index: 99999;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nodebb-plugin-onekite-calendar",
3
- "version": "1.0.8",
3
+ "version": "1.0.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",
package/plugin.json CHANGED
@@ -39,5 +39,5 @@
39
39
  "acpScripts": [
40
40
  "public/admin.js"
41
41
  ],
42
- "version": "1.0.3"
42
+ "version": "1.0.10"
43
43
  }