@saltcorn/reservable 0.1.4 → 0.2.0

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.
Files changed (2) hide show
  1. package/index.js +91 -52
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -105,6 +105,12 @@ const configuration_workflow = () =>
105
105
  options: show_view_opts,
106
106
  },
107
107
  },
108
+ {
109
+ name: "btn_columns",
110
+ label: "Button columns",
111
+ type: "Integer",
112
+ default: 1,
113
+ },
108
114
  new FieldRepeat({
109
115
  name: "availability",
110
116
  fields: [
@@ -254,7 +260,7 @@ const get_available_slots = async ({
254
260
  available_slots[i] = false;
255
261
  }
256
262
  });
257
- return { available_slots, from, durGCD };
263
+ return { available_slots, from, durGCD, taken_slots };
258
264
  };
259
265
 
260
266
  const run = async (
@@ -266,6 +272,7 @@ const run = async (
266
272
  duration_field,
267
273
  availability,
268
274
  services,
275
+ btn_columns,
269
276
  },
270
277
  state,
271
278
  { req, res }
@@ -280,37 +287,44 @@ const run = async (
280
287
  }
281
288
 
282
289
  const date = state.day ? new Date(state.day) : new Date(); //todo from state
283
- const { available_slots, from, durGCD } = await get_available_slots({
284
- table,
285
- availability,
286
- date,
287
- entity_wanted,
288
- reservable_entity_key,
289
- services,
290
- start_field,
291
- duration_field,
292
- });
290
+ const { available_slots, from, durGCD, taken_slots } =
291
+ await get_available_slots({
292
+ table,
293
+ availability,
294
+ date,
295
+ entity_wanted,
296
+ reservable_entity_key,
297
+ services,
298
+ start_field,
299
+ duration_field,
300
+ });
293
301
  const minSlot = Math.min(...Object.keys(available_slots));
294
302
  const maxSlot = Math.max(...Object.keys(available_slots));
295
303
  const service_availabilities = services.map((service, serviceIx) => {
296
304
  const nslots = service.duration / durGCD;
297
305
  const availabilities = [];
298
306
  for (let i = minSlot; i <= maxSlot; i++) {
299
- if (range(nslots, i).every((j) => available_slots[j])) {
300
- const mins_since_midnight = i * durGCD;
301
- const hour = Math.floor(mins_since_midnight / 60);
307
+ const mins_since_midnight = i * durGCD;
308
+ const hour = Math.floor(mins_since_midnight / 60);
302
309
 
303
- const minute = mins_since_midnight - hour * 60;
304
- const date1 = new Date(date);
305
- date1.setHours(hour);
306
- date1.setMinutes(minute);
307
- date1.setSeconds(0);
308
- date1.setMilliseconds(0);
309
- if (date1 > new Date())
310
+ const minute = mins_since_midnight - hour * 60;
311
+ const date1 = new Date(date);
312
+ date1.setHours(hour);
313
+ date1.setMinutes(minute);
314
+ date1.setSeconds(0);
315
+ date1.setMilliseconds(0);
316
+ if (date1 > new Date())
317
+ if (range(nslots, i).every((j) => available_slots[j])) {
310
318
  availabilities.push({
311
319
  date: date1,
320
+ available: true,
312
321
  });
313
- }
322
+ } else {
323
+ availabilities.push({
324
+ date: date1,
325
+ available: false,
326
+ });
327
+ }
314
328
  }
315
329
  //console.log({ availabilities, service });
316
330
  return { availabilities, service, serviceIx };
@@ -368,19 +382,22 @@ const run = async (
368
382
  )
369
383
  ),
370
384
  service_availabilities.map(({ availabilities, service, serviceIx }) =>
371
- div(
385
+ ul(
372
386
  h3(service.title || `${service.duration} minutes`),
373
- ul(
374
- availabilities.map(({ date }) =>
375
- reserve_btn({
376
- viewname,
377
- service,
378
- date,
379
- serviceIx,
380
- req,
381
- entity_wanted,
382
- reservable_entity_key,
383
- })
387
+ groupArray(availabilities, btn_columns || 1).map((gavail) =>
388
+ div(
389
+ gavail.map(({ date, available }) =>
390
+ reserve_btn({
391
+ viewname,
392
+ service,
393
+ date,
394
+ serviceIx,
395
+ req,
396
+ entity_wanted,
397
+ reservable_entity_key,
398
+ available,
399
+ })
400
+ )
384
401
  )
385
402
  )
386
403
  )
@@ -388,6 +405,17 @@ const run = async (
388
405
  );
389
406
  };
390
407
 
408
+ //https://stackoverflow.com/a/74206554
409
+ function groupArray(array, num) {
410
+ const group = [];
411
+
412
+ for (let i = 0; i < array.length; i += num) {
413
+ group.push(array.slice(i, i + num));
414
+ }
415
+
416
+ return group;
417
+ }
418
+
391
419
  const reserve_btn = ({
392
420
  viewname,
393
421
  date,
@@ -396,26 +424,37 @@ const reserve_btn = ({
396
424
  req,
397
425
  reservable_entity_key,
398
426
  entity_wanted,
427
+ available,
399
428
  }) =>
400
- form(
401
- { action: `/view/${viewname}`, method: "post" },
402
- input({ type: "hidden", name: "_csrf", value: req.csrfToken() }),
403
- input({ type: "hidden", name: "date", value: date.toISOString() }),
404
- input({ type: "hidden", name: "serviceIx", value: serviceIx }),
405
- entity_wanted &&
406
- input({
407
- type: "hidden",
408
- name: reservable_entity_key,
409
- value: entity_wanted,
410
- }),
411
- input({ type: "hidden", name: "step", value: "getReservationForm" }),
429
+ available
430
+ ? form(
431
+ { action: `/view/${viewname}`, method: "post", class: "d-inline" },
432
+ input({ type: "hidden", name: "_csrf", value: req.csrfToken() }),
433
+ input({ type: "hidden", name: "date", value: date.toISOString() }),
434
+ input({ type: "hidden", name: "serviceIx", value: serviceIx }),
435
+ entity_wanted &&
436
+ input({
437
+ type: "hidden",
438
+ name: reservable_entity_key,
439
+ value: entity_wanted,
440
+ }),
441
+ input({ type: "hidden", name: "step", value: "getReservationForm" }),
412
442
 
413
- button(
414
- { type: "submit", class: "btn btn-primary mt-2" },
415
- localeTime(date)
416
- // `${hour}:${String(minute).padStart(2, "0")}`
417
- )
418
- );
443
+ button(
444
+ { type: "submit", class: "btn btn-primary mt-2 me-2" },
445
+ localeTime(date)
446
+ // `${hour}:${String(minute).padStart(2, "0")}`
447
+ )
448
+ )
449
+ : button(
450
+ {
451
+ type: "button",
452
+ disabled: true,
453
+ class: "btn btn-secondary mt-2 me-2",
454
+ },
455
+ localeTime(date)
456
+ // `${hour}:${String(minute).padStart(2, "0")}`
457
+ );
419
458
  const getReservationForm = async ({ table, viewname, config, body, req }) => {
420
459
  const {
421
460
  view_to_create,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@saltcorn/reservable",
3
- "version": "0.1.4",
3
+ "version": "0.2.0",
4
4
  "description": "Reservable resources",
5
5
  "main": "index.js",
6
6
  "dependencies": {