@arquimedes.co/eureka-forms 3.0.71 → 3.0.72-test

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 (45) hide show
  1. package/dist/@Types/BookingFormStep.d.ts +70 -18
  2. package/dist/@Types/BookingFormStep.js +21 -0
  3. package/dist/App/App.submitError.test.d.ts +1 -0
  4. package/dist/App/App.submitError.test.js +53 -0
  5. package/dist/BookingManage/AppointmentText.d.ts +5 -0
  6. package/dist/BookingManage/AppointmentText.js +20 -0
  7. package/dist/BookingManage/BookingManagePage.d.ts +17 -0
  8. package/dist/BookingManage/BookingManagePage.js +177 -0
  9. package/dist/BookingManage/BookingManagePage.module.css +115 -0
  10. package/dist/BookingManage/BookingManagePage.test.d.ts +1 -0
  11. package/dist/BookingManage/BookingManagePage.test.js +149 -0
  12. package/dist/Form/ConfirmationDialog/ConfirmationDialog.d.ts +14 -5
  13. package/dist/Form/ConfirmationDialog/ConfirmationDialog.js +8 -1
  14. package/dist/Form/ConfirmationDialog/ConfirmationDialog.module.css +12 -0
  15. package/dist/Form/ConfirmationDialog/ConfirmationDialog.test.d.ts +1 -0
  16. package/dist/Form/ConfirmationDialog/ConfirmationDialog.test.js +21 -0
  17. package/dist/Form/Form.d.ts +3 -0
  18. package/dist/Form/Form.js +9 -2
  19. package/dist/Form/FormTypes/ColumnForm/ColumnForm.d.ts +1 -1
  20. package/dist/Form/FormTypes/ColumnForm/ColumnForm.js +3 -2
  21. package/dist/Form/FormTypes/StepperForm/StepperForm.d.ts +1 -1
  22. package/dist/Form/FormTypes/StepperForm/StepperForm.js +3 -2
  23. package/dist/Form/SubmitError/SubmitError.d.ts +11 -0
  24. package/dist/Form/SubmitError/SubmitError.js +9 -0
  25. package/dist/Form/SubmitError/SubmitError.module.css +25 -0
  26. package/dist/Form/SubmitError/SubmitError.test.d.ts +1 -0
  27. package/dist/Form/SubmitError/SubmitError.test.js +34 -0
  28. package/dist/Form/SubmitError/SubmitErrorReason.d.ts +13 -0
  29. package/dist/Form/SubmitError/SubmitErrorReason.js +20 -0
  30. package/dist/FormSteps/BookingStep/MaterialBookingStep/MaterialBookingStep.d.ts +8 -1
  31. package/dist/FormSteps/BookingStep/MaterialBookingStep/MaterialBookingStep.js +197 -41
  32. package/dist/FormSteps/BookingStep/MaterialBookingStep/MaterialBookingStep.test.d.ts +1 -0
  33. package/dist/FormSteps/BookingStep/MaterialBookingStep/MaterialBookingStep.test.js +275 -0
  34. package/dist/Services/BookingService.d.ts +159 -12
  35. package/dist/Services/BookingService.js +210 -12
  36. package/dist/Services/BookingService.test.js +130 -9
  37. package/dist/Shared/ErkBookingPicker/ErkBookingPicker.d.ts +63 -12
  38. package/dist/Shared/ErkBookingPicker/ErkBookingPicker.js +141 -36
  39. package/dist/Shared/ErkBookingPicker/ErkBookingPicker.module.css +41 -3
  40. package/dist/Shared/ErkBookingPicker/ErkBookingPicker.stories.d.ts +11 -3
  41. package/dist/Shared/ErkBookingPicker/ErkBookingPicker.stories.js +69 -9
  42. package/dist/Shared/ErkBookingPicker/ErkBookingPicker.stories.test.js +13 -15
  43. package/dist/Shared/ErkBookingPicker/ErkBookingPicker.test.js +331 -62
  44. package/dist/main.js +4 -1
  45. package/package.json +1 -1
@@ -5,10 +5,8 @@ import { withFormStepProviders } from '../../FormSteps/@StoryDecorators/FormStep
5
5
  import { BookingMode, PersonSelectionMode } from '../../@Types/BookingFormStep';
6
6
  const SLOTS = [
7
7
  { id: 's-1', startTime: '09:00', endTime: '09:50', available: true },
8
- { id: 's-2', startTime: '10:00', endTime: '10:50', available: false },
9
8
  { id: 's-3', startTime: '11:00', endTime: '11:50', available: true },
10
9
  { id: 's-4', startTime: '14:00', endTime: '14:50', available: true },
11
- { id: 's-5', startTime: '15:00', endTime: '15:50', available: false },
12
10
  { id: 's-6', startTime: '16:00', endTime: '16:50', available: true },
13
11
  ];
14
12
  function mockFetchSlots() {
@@ -69,32 +67,43 @@ export const NoPerson = {
69
67
  fetchSlots: mockFetchSlots,
70
68
  },
71
69
  };
72
- /** Extra contact step (collectContact). */
73
- export const WithContact = {
70
+ /** The email comes from an earlier step of the form: the picker only asks for the name. */
71
+ export const EmailFromStep = {
74
72
  args: {
75
73
  value: null,
76
74
  label: 'Agendar cita',
77
- description: 'Elige y déjanos tus datos.',
75
+ description: 'Elige y déjanos tu nombre.',
78
76
  durationMinutes: 45,
79
77
  personSelectionMode: PersonSelectionMode.OPTIONAL,
80
78
  persons: PERSONS,
81
- collectContact: true,
79
+ knownContact: { email: 'juan@correo.com' },
82
80
  fetchSlots: mockFetchSlots,
83
81
  },
84
82
  };
85
- /** Full config: contact data, buffer, lock notice and in-person mode. */
83
+ /** Full config: name and email asked in the picker, lock notice, in-person mode and the organization clock. */
86
84
  export const Complete = {
87
85
  args: {
88
86
  value: null,
89
87
  label: 'Agendar cita',
90
88
  description: 'Soporte postventa',
91
89
  durationMinutes: 60,
92
- bufferMinutes: 10,
93
90
  bookingMode: BookingMode.IN_PERSON,
94
91
  temporaryLockMinutes: 15,
95
92
  personSelectionMode: PersonSelectionMode.OPTIONAL,
96
93
  persons: PERSONS,
97
- collectContact: true,
94
+ askEmail: true,
95
+ timeZone: 'America/Bogota',
96
+ fetchSlots: mockFetchSlots,
97
+ },
98
+ };
99
+ /** A hold that lapsed after it was made: the requester is sent back to the hours with the reason. */
100
+ export const Lapsed = {
101
+ args: {
102
+ value: null,
103
+ label: 'Agendar cita',
104
+ durationMinutes: 30,
105
+ personSelectionMode: PersonSelectionMode.NONE,
106
+ lapsed: 'Tu reserva venció; elige la hora de nuevo.',
98
107
  fetchSlots: mockFetchSlots,
99
108
  },
100
109
  };
@@ -115,3 +124,54 @@ export const ReadOnly = {
115
124
  },
116
125
  },
117
126
  };
127
+ /** Several event templates: the requester picks what they need first, and its duration rules the hours. */
128
+ export const PickEventTemplate = {
129
+ args: {
130
+ value: null,
131
+ label: 'Agendar cita',
132
+ description: 'Elige qué necesitas, el día y la hora.',
133
+ durationMinutes: 30,
134
+ bookingMode: BookingMode.VIRTUAL,
135
+ personSelectionMode: PersonSelectionMode.OPTIONAL,
136
+ persons: PERSONS,
137
+ eventTemplates: [
138
+ { id: 't-1', name: 'Valoración', description: 'Primera visita, sin costo.', durationMinutes: 30 },
139
+ {
140
+ id: 't-2',
141
+ name: 'Asesoría de crédito',
142
+ description: 'Revisamos tu caso con un asesor.',
143
+ durationMinutes: 45,
144
+ },
145
+ { id: 't-3', name: 'Firma de documentos', durationMinutes: 60, bookingMode: BookingMode.IN_PERSON },
146
+ ],
147
+ timeZone: 'America/Bogota',
148
+ fetchSlots: mockFetchSlots,
149
+ },
150
+ };
151
+ /** Booked with an event template: the summary names it with its duration. */
152
+ export const BookedWithEventTemplate = {
153
+ args: {
154
+ label: 'Agendar cita',
155
+ durationMinutes: 45,
156
+ value: {
157
+ type: 'BOOKING_VALUE',
158
+ date: '2026-07-02',
159
+ startTime: '11:00',
160
+ endTime: '11:45',
161
+ personName: 'María González',
162
+ status: 'PENDING',
163
+ eventTemplate: { name: 'Asesoría de crédito', durationMinutes: 45 },
164
+ },
165
+ },
166
+ };
167
+ /** The offer did not load: the entry card stays disabled and offers "Reintentar". */
168
+ export const OfferFailed = {
169
+ args: {
170
+ value: null,
171
+ label: 'Agendar cita',
172
+ durationMinutes: 30,
173
+ disabled: true,
174
+ loadError: 'No pudimos cargar los horarios.',
175
+ onRetryLoad: () => undefined,
176
+ },
177
+ };
@@ -5,18 +5,14 @@ import { composeStories } from '@storybook/react-vite';
5
5
  import { describe, expect, it } from 'vitest';
6
6
  import '@testing-library/jest-dom';
7
7
  import { format } from 'date-fns';
8
+ import { es } from 'date-fns/locale';
8
9
  import * as stories from './ErkBookingPicker.stories';
9
10
  const { Complete } = composeStories(stories);
10
11
  function clickableToday() {
11
- // El número de hoy puede aparecer también como día de un mes adyacente (deshabilitado).
12
- const candidates = screen.getAllByRole('button', { name: format(new Date(), 'd') });
13
- const enabled = candidates.find((b) => !b.disabled);
14
- if (!enabled)
15
- throw new Error('No selectable day found for today');
16
- return enabled;
12
+ return screen.getByRole('button', { name: format(new Date(), "EEEE d 'de' MMMM 'de' yyyy", { locale: es }) });
17
13
  }
18
14
  describe('ErkBookingPicker Complete story', () => {
19
- it('opens the wizard in a modal, completes it, and confirming closes the modal leaving the summary', async () => {
15
+ it('opens the wizard in a modal, completes it, and reserving closes the modal leaving the summary', async () => {
20
16
  const user = userEvent.setup();
21
17
  render(_jsx(Complete, {}));
22
18
  // Trigger → modal con el wizard
@@ -31,16 +27,18 @@ describe('ErkBookingPicker Complete story', () => {
31
27
  await user.click(screen.getByRole('button', { name: 'Siguiente' }));
32
28
  // Hora (los slots del mock llegan con delay)
33
29
  await screen.findByRole('heading', { name: 'Elige una hora' });
34
- await user.click(await screen.findByRole('button', { name: '09:00' }));
30
+ expect(screen.getByText(/^Horas en hora de Bogotá/)).toBeInTheDocument();
31
+ await user.click(await screen.findByRole('button', { name: /^09:00/ }));
35
32
  await user.click(screen.getByRole('button', { name: 'Siguiente' }));
36
- // Confirmar
37
- await screen.findByRole('heading', { name: 'Revisa y confirma tu cita' });
38
- await user.type(screen.getByLabelText('Nombre'), 'Juan Pérez');
39
- await user.type(screen.getByLabelText('Correo'), 'juan@correo.com');
40
- await user.click(screen.getByRole('button', { name: 'Confirmar cita' }));
33
+ // Reservar
34
+ await screen.findByRole('heading', { name: 'Revisa y reserva tu horario' });
35
+ await user.type(screen.getByLabelText(/Nombre/), 'Juan Pérez');
36
+ await user.type(screen.getByLabelText(/Correo/), 'juan@correo.com');
37
+ await user.click(screen.getByRole('button', { name: 'Reservar' }));
41
38
  // El modal se cierra y queda el resumen compacto con opción de cambiar
42
- await waitFor(() => expect(screen.queryByRole('heading', { name: 'Revisa y confirma tu cita' })).not.toBeInTheDocument());
43
- expect(screen.getByText(/María González .* 09:00–09:50/)).toBeInTheDocument();
39
+ await waitFor(() => expect(screen.queryByRole('heading', { name: 'Revisa y reserva tu horario' })).not.toBeInTheDocument());
40
+ expect(screen.getByText(/09:00–09:50 · con María González/)).toBeInTheDocument();
41
+ expect(screen.getByText(/Envía el formulario para confirmar la cita/)).toBeInTheDocument();
44
42
  expect(screen.getByRole('button', { name: 'Cambiar' })).toBeInTheDocument();
45
43
  // "Cambiar" limpia el valor y vuelve al botón de agendar
46
44
  await user.click(screen.getByRole('button', { name: 'Cambiar' }));