@arquimedes.co/eureka-forms 3.0.48-test → 3.0.49-new-steps

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 (140) hide show
  1. package/dist/@Types/AvailabilityFormStep.d.ts +48 -0
  2. package/dist/@Types/AvailabilityFormStep.js +24 -0
  3. package/dist/@Types/BankAccountFormStep.d.ts +67 -0
  4. package/dist/@Types/BankAccountFormStep.js +14 -0
  5. package/dist/@Types/BookingFormStep.d.ts +156 -0
  6. package/dist/@Types/BookingFormStep.js +44 -0
  7. package/dist/@Types/CalendarFormStep.d.ts +192 -0
  8. package/dist/@Types/CalendarFormStep.js +48 -0
  9. package/dist/@Types/CommunicationChannelFormStep.d.ts +51 -0
  10. package/dist/@Types/CommunicationChannelFormStep.js +15 -0
  11. package/dist/@Types/Condition.d.ts +4 -6
  12. package/dist/@Types/ConsentFormStep.d.ts +36 -0
  13. package/dist/@Types/ConsentFormStep.js +8 -0
  14. package/dist/@Types/EntityFormFormStep.d.ts +66 -0
  15. package/dist/@Types/EntityFormFormStep.js +20 -0
  16. package/dist/@Types/EventFormStep.d.ts +52 -0
  17. package/dist/@Types/EventFormStep.js +13 -0
  18. package/dist/@Types/ExternalReferenceFormStep.d.ts +74 -0
  19. package/dist/@Types/ExternalReferenceFormStep.js +20 -0
  20. package/dist/@Types/Form.d.ts +0 -1
  21. package/dist/@Types/FormStep.d.ts +8 -10
  22. package/dist/@Types/FormStep.js +2 -1
  23. package/dist/@Types/LocationFormStep.d.ts +159 -0
  24. package/dist/@Types/LocationFormStep.js +46 -0
  25. package/dist/@Types/NumericFormSteps.d.ts +108 -0
  26. package/dist/@Types/NumericFormSteps.js +20 -0
  27. package/dist/@Types/PredefinedSelectorFormStep.d.ts +51 -0
  28. package/dist/@Types/PredefinedSelectorFormStep.js +39 -0
  29. package/dist/@Types/StepRef.d.ts +135 -0
  30. package/dist/@Types/StepRef.js +49 -0
  31. package/dist/App/App.js +1 -1
  32. package/dist/App/AppFunctions.js +3 -8
  33. package/dist/App/AppHooks.js +1 -20
  34. package/dist/Form/Form.js +2 -6
  35. package/dist/Form/Form.module.css +39 -48
  36. package/dist/FormSteps/ApiSelectorStep/MaterialApiSelectorStep/MaterialApiSelectorStep.js +4 -8
  37. package/dist/FormSteps/BookingStep/BookingStep.d.ts +17 -0
  38. package/dist/FormSteps/BookingStep/BookingStep.js +14 -0
  39. package/dist/FormSteps/BookingStep/MaterialBookingStep/MaterialBookingStep.d.ts +3 -0
  40. package/dist/FormSteps/BookingStep/MaterialBookingStep/MaterialBookingStep.js +362 -0
  41. package/dist/FormSteps/BookingStep/MaterialBookingStep/MaterialBookingStep.module.css +174 -0
  42. package/dist/FormSteps/CBRStepMapper.js +1 -1
  43. package/dist/FormSteps/CalendarStep/CalendarStep.d.ts +7 -0
  44. package/dist/FormSteps/CalendarStep/CalendarStep.js +14 -0
  45. package/dist/FormSteps/CalendarStep/MaterialCalendarStep/MaterialCalendarStep.d.ts +3 -0
  46. package/dist/FormSteps/CalendarStep/MaterialCalendarStep/MaterialCalendarStep.js +269 -0
  47. package/dist/FormSteps/CalendarStep/MaterialCalendarStep/MaterialCalendarStep.module.css +531 -0
  48. package/dist/FormSteps/ClassifierSelectorStep/MaterialClassifierSelectorStep/MaterialClassifierSelectorStep.js +2 -2
  49. package/dist/FormSteps/EntityValueStep/MaterialEntityValuePickerStep/MaterialEntityValuePickerStep.js +4 -52
  50. package/dist/FormSteps/LocationStep/LocationStep.d.ts +10 -0
  51. package/dist/FormSteps/LocationStep/LocationStep.js +14 -0
  52. package/dist/FormSteps/LocationStep/MaterialLocationStep/MaterialLocationStep.d.ts +3 -0
  53. package/dist/FormSteps/LocationStep/MaterialLocationStep/MaterialLocationStep.js +47 -0
  54. package/dist/FormSteps/LocationStep/MaterialLocationStep/MaterialLocationStep.module.css +18 -0
  55. package/dist/FormSteps/NumberStep/MaterialNumberStep/MaterialNumberStep.d.ts +3 -0
  56. package/dist/FormSteps/NumberStep/MaterialNumberStep/MaterialNumberStep.js +168 -0
  57. package/dist/FormSteps/NumberStep/MaterialNumberStep/MaterialNumberStep.module.css +94 -0
  58. package/dist/FormSteps/NumberStep/NumberStep.d.ts +10 -0
  59. package/dist/FormSteps/NumberStep/NumberStep.js +14 -0
  60. package/dist/FormSteps/Step.js +16 -0
  61. package/dist/FormSteps/StepFunctions.js +23 -6
  62. package/dist/FormSteps/StepFunctions.test.js +57 -3
  63. package/dist/FormSteps/TitleStep/MaterialTitleStep/MaterialTitleStep.js +1 -2
  64. package/dist/Icons/@ErkIcon.d.ts +2 -2
  65. package/dist/Icons/@ErkIcon.js +2 -2
  66. package/dist/Icons/AddIcon.d.ts +3 -0
  67. package/dist/Icons/AddIcon.js +7 -0
  68. package/dist/Icons/EditIcon.d.ts +3 -0
  69. package/dist/Icons/{EmailIcon.js → EditIcon.js} +3 -3
  70. package/dist/Icons/RemoveIcon.d.ts +3 -0
  71. package/dist/Icons/RemoveIcon.js +7 -0
  72. package/dist/Icons/ViewDayIcon.d.ts +3 -0
  73. package/dist/Icons/ViewDayIcon.js +7 -0
  74. package/dist/Icons/ViewWeekIcon.d.ts +3 -0
  75. package/dist/Icons/ViewWeekIcon.js +7 -0
  76. package/dist/Services/DraftService.js +1 -4
  77. package/dist/Shared/ErkAddressAutocomplete/ErkAddressAutocomplete.d.ts +19 -0
  78. package/dist/Shared/ErkAddressAutocomplete/ErkAddressAutocomplete.js +80 -0
  79. package/dist/Shared/ErkAddressAutocomplete/ErkAddressAutocomplete.module.css +82 -0
  80. package/dist/Shared/ErkAddressAutocomplete/googlePlaces.d.ts +29 -0
  81. package/dist/Shared/ErkAddressAutocomplete/googlePlaces.js +139 -0
  82. package/dist/Shared/ErkDatePicker/ErkDatePicker.js +1 -3
  83. package/dist/Shared/ErkDateRangePicker/ErkDateRangePicker.d.ts +2 -3
  84. package/dist/Shared/ErkDateRangePicker/ErkDateRangePicker.js +1 -2
  85. package/dist/Shared/ErkLocationField/ErkLocationField.d.ts +23 -0
  86. package/dist/Shared/ErkLocationField/ErkLocationField.js +73 -0
  87. package/dist/Shared/ErkLocationField/ErkLocationField.module.css +29 -0
  88. package/dist/Shared/ErkLocationField/addressFields.d.ts +12 -0
  89. package/dist/Shared/ErkLocationField/addressFields.js +34 -0
  90. package/dist/Shared/ErkLocationField/locationRestrictions.d.ts +6 -0
  91. package/dist/Shared/ErkLocationField/locationRestrictions.js +51 -0
  92. package/dist/Shared/ErkLocationInput/ErkLocationInput.d.ts +15 -0
  93. package/dist/Shared/ErkLocationInput/ErkLocationInput.js +499 -0
  94. package/dist/Shared/ErkLocationInput/ErkLocationInput.module.css +115 -0
  95. package/dist/Shared/ErkNumberField/ErkNumberField.d.ts +42 -0
  96. package/dist/Shared/ErkNumberField/ErkNumberField.js +170 -0
  97. package/dist/Shared/ErkSelect/ErkSelect.d.ts +2 -2
  98. package/dist/Shared/InputIcon/InputIcon.js +0 -6
  99. package/dist/Shared/Navbar/Navbar.d.ts +1 -2
  100. package/dist/Shared/Navbar/Navbar.js +3 -22
  101. package/dist/Shared/Navbar/Navbar.module.css +8 -22
  102. package/dist/Shared/SmartDraftRenderer/SmartDraftRenderer.js +2 -8
  103. package/dist/States/GlobalSlice.d.ts +1 -4
  104. package/dist/States/GlobalSlice.js +1 -8
  105. package/dist/constants/ErkIconTypes.d.ts +1 -3
  106. package/dist/constants/ErkIconTypes.js +0 -2
  107. package/dist/constants/FormStepTypes.d.ts +6 -3
  108. package/dist/constants/FormStepTypes.js +4 -1
  109. package/dist/hooks.d.ts +0 -3
  110. package/dist/hooks.js +1 -17
  111. package/package.json +3 -9
  112. package/dist/@Types/ErkValue.d.ts +0 -16
  113. package/dist/@Types/ErkValue.js +0 -1
  114. package/dist/@Types/User.d.ts +0 -13
  115. package/dist/@Types/User.js +0 -1
  116. package/dist/Icons/EmailIcon.d.ts +0 -3
  117. package/dist/Icons/Entities/SchoolIcon.d.ts +0 -3
  118. package/dist/Icons/Entities/SchoolIcon.js +0 -7
  119. package/dist/Icons/GroupIcon.d.ts +0 -3
  120. package/dist/Icons/GroupIcon.js +0 -7
  121. package/dist/Icons/LockedIcon.d.ts +0 -3
  122. package/dist/Icons/LockedIcon.js +0 -7
  123. package/dist/Login/Login.module.css +0 -135
  124. package/dist/Login/LoginLayout.module.css +0 -68
  125. package/dist/Login/LoginPage.d.ts +0 -10
  126. package/dist/Login/LoginPage.js +0 -101
  127. package/dist/Login/LoginTextField.d.ts +0 -14
  128. package/dist/Login/LoginTextField.js +0 -29
  129. package/dist/Services/ApiSelectorService.d.ts +0 -366
  130. package/dist/Services/ApiSelectorService.js +0 -173
  131. package/dist/Services/ApiSelectorService.test.d.ts +0 -1
  132. package/dist/Services/ApiSelectorService.test.js +0 -87
  133. package/dist/Services/IntegrationService.d.ts +0 -21
  134. package/dist/Services/IntegrationService.js +0 -22
  135. package/dist/Services/UserService.d.ts +0 -10
  136. package/dist/Services/UserService.js +0 -21
  137. package/dist/Shared/SmartDraftRenderer/LinkDecorator.d.ts +0 -14
  138. package/dist/Shared/SmartDraftRenderer/LinkDecorator.js +0 -48
  139. package/dist/constants/ErkValueTypes.d.ts +0 -6
  140. package/dist/constants/ErkValueTypes.js +0 -7
@@ -0,0 +1,269 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { useContext, useState, useCallback, useRef, useMemo } from 'react';
3
+ import { startOfWeek, endOfWeek, addWeeks, addDays, addMonths, startOfMonth, endOfMonth, isSameMonth, isSameDay, isToday, format, parse, startOfDay, } from 'date-fns';
4
+ import { es } from 'date-fns/locale';
5
+ import { Popover } from '@mui/material';
6
+ import ArrowLeftIcon from '../../../Icons/ArrowLeftIcon';
7
+ import ArrowRightIcon from '../../../Icons/ArrowRightIcon';
8
+ import ViewWeekIcon from '../../../Icons/ViewWeekIcon';
9
+ import ViewDayIcon from '../../../Icons/ViewDayIcon';
10
+ import CalendarIcon from '../../../Icons/CalendarIcon';
11
+ import AddIcon from '../../../Icons/AddIcon';
12
+ import CloseIcon from '../../../Icons/CloseIcon';
13
+ import DeleteIcon from '../../../Icons/DeleteIcon';
14
+ import { CalendarEventCategory, CalendarDefaultView, } from '../../../@Types/CalendarFormStep';
15
+ import { useFormStep } from '../../StepHooks';
16
+ import FormContext from '../../../Contexts/FormContext';
17
+ import { selectBreakPoint, useAppSelector } from '../../../hooks';
18
+ import { calcStepWidth } from '../../StepFunctions';
19
+ import styles from './MaterialCalendarStep.module.css';
20
+ // ---------------------------------------------------------------------------
21
+ // Constants
22
+ // ---------------------------------------------------------------------------
23
+ const CELL_HEIGHT = 48; // px per hour
24
+ const WEEK_START = 1; // Monday
25
+ const CATEGORY_COLORS = {
26
+ [CalendarEventCategory.WORKING]: '#4CAF50',
27
+ [CalendarEventCategory.PHYSICAL]: '#2196F3',
28
+ [CalendarEventCategory.VIRTUAL]: '#9C27B0',
29
+ [CalendarEventCategory.SPECIFIC]: '#FF9800',
30
+ [CalendarEventCategory.MEETING]: '#E91E63',
31
+ [CalendarEventCategory.BUSY]: '#607D8B',
32
+ [CalendarEventCategory.CUSTOM]: '#795548',
33
+ };
34
+ const CATEGORY_LABELS = {
35
+ [CalendarEventCategory.WORKING]: 'Trabajo',
36
+ [CalendarEventCategory.PHYSICAL]: 'Presencial',
37
+ [CalendarEventCategory.VIRTUAL]: 'Virtual',
38
+ [CalendarEventCategory.SPECIFIC]: 'Específico',
39
+ [CalendarEventCategory.MEETING]: 'Reunión',
40
+ [CalendarEventCategory.BUSY]: 'Ocupado',
41
+ [CalendarEventCategory.CUSTOM]: 'Personalizado',
42
+ };
43
+ // ---------------------------------------------------------------------------
44
+ // Helpers
45
+ // ---------------------------------------------------------------------------
46
+ function parseTime(hhmm) {
47
+ const [h, m] = hhmm.split(':').map(Number);
48
+ return { h: h ?? 0, m: m ?? 0 };
49
+ }
50
+ function toMinutes(hhmm) {
51
+ const { h, m } = parseTime(hhmm);
52
+ return h * 60 + m;
53
+ }
54
+ function minutesToHHMM(mins) {
55
+ const h = Math.floor(mins / 60);
56
+ const m = mins % 60;
57
+ return `${String(h).padStart(2, '0')}:${String(m).padStart(2, '0')}`;
58
+ }
59
+ function isoToHHMM(iso) {
60
+ // "2024-06-19T09:30:00" → "09:30"
61
+ return iso.slice(11, 16);
62
+ }
63
+ function dateAndTimeToISO(date, hhmm) {
64
+ const { h, m } = parseTime(hhmm);
65
+ const d = new Date(date);
66
+ d.setHours(h, m, 0, 0);
67
+ return d.toISOString().slice(0, 19);
68
+ }
69
+ function isoToDate(iso) {
70
+ // Treat as local time (no timezone shift)
71
+ return parse(iso.slice(0, 19), 'yyyy-MM-dd\'T\'HH:mm:ss', new Date());
72
+ }
73
+ function newEventId() {
74
+ return `evt-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`;
75
+ }
76
+ function EventBlock({ event, minHour, template, onDelete, readOnly }) {
77
+ const startMins = toMinutes(isoToHHMM(event.start));
78
+ const endMins = toMinutes(isoToHHMM(event.end));
79
+ const top = (startMins - minHour * 60) * (CELL_HEIGHT / 60);
80
+ const height = Math.max((endMins - startMins) * (CELL_HEIGHT / 60), 18);
81
+ const color = template?.color ?? CATEGORY_COLORS[event.category] ?? '#607D8B';
82
+ const label = event.title ?? template?.name ?? CATEGORY_LABELS[event.category];
83
+ return (_jsxs("div", { className: styles.eventBlock, style: { top, height, backgroundColor: color }, title: `${label} ${isoToHHMM(event.start)}–${isoToHHMM(event.end)}`, children: [_jsx("span", { className: styles.eventLabel, children: label }), _jsxs("span", { className: styles.eventTime, children: [isoToHHMM(event.start), "\u2013", isoToHHMM(event.end)] }), !readOnly && (_jsx("button", { type: "button", className: styles.eventDeleteBtn, onClick: (e) => { e.stopPropagation(); onDelete(event.id); }, "aria-label": "Eliminar", children: _jsx(DeleteIcon, { size: 13 }) }))] }));
84
+ }
85
+ // ---------------------------------------------------------------------------
86
+ // Main component
87
+ // ---------------------------------------------------------------------------
88
+ function MaterialCalendarStep({ step, editable }) {
89
+ const currentBreakPoint = useAppSelector(selectBreakPoint);
90
+ const { postview } = useAppSelector((state) => state.global);
91
+ const form = useContext(FormContext);
92
+ const isReadOnly = !editable || postview;
93
+ const widthStyle = currentBreakPoint <= step.size ? '100%' : calcStepWidth(step.size, form.size);
94
+ // ------------------------------------------------------------------
95
+ // Resolve config
96
+ // ------------------------------------------------------------------
97
+ const minTimeStr = step.minTime ?? '00:00';
98
+ const maxTimeStr = step.maxTime ?? '23:00';
99
+ const minHour = parseTime(minTimeStr).h;
100
+ const maxHour = parseTime(maxTimeStr).h + 1;
101
+ const totalHours = maxHour - minHour;
102
+ const showWeekends = step.showWeekends ?? true;
103
+ const allowedCategories = (step.allowedCategories?.length ? step.allowedCategories : Object.values(CalendarEventCategory));
104
+ const defaultViewMode = (step.defaultView ?? CalendarDefaultView.WEEK);
105
+ // ------------------------------------------------------------------
106
+ // Form value
107
+ // ------------------------------------------------------------------
108
+ const { value, onChange } = useFormStep(step, {
109
+ defaultValue: null,
110
+ rules: {
111
+ required: step.required ? 'Este campo es obligatorio' : undefined,
112
+ },
113
+ });
114
+ const events = useMemo(() => value?.events ?? [], [value?.events]);
115
+ const setEvents = useCallback((updater) => {
116
+ onChange({
117
+ type: 'CALENDAR_VALUE',
118
+ events: updater(events),
119
+ timezone: value?.timezone,
120
+ });
121
+ }, [events, value?.timezone, onChange]);
122
+ const deleteEvent = useCallback((id) => setEvents((prev) => prev.filter((e) => e.id !== id)), [setEvents]);
123
+ // ------------------------------------------------------------------
124
+ // Navigation state
125
+ // ------------------------------------------------------------------
126
+ const [viewMode, setViewMode] = useState(defaultViewMode);
127
+ const [current, setCurrent] = useState(() => startOfDay(new Date()));
128
+ const [createState, setCreate] = useState(null);
129
+ // Create form
130
+ const [newCategory, setNewCategory] = useState(allowedCategories[0] ?? CalendarEventCategory.WORKING);
131
+ const [newTitle, setNewTitle] = useState('');
132
+ const [newStart, setNewStart] = useState('09:00');
133
+ const [newEnd, setNewEnd] = useState('10:00');
134
+ const gridRef = useRef(null);
135
+ // ------------------------------------------------------------------
136
+ // Derived view dates
137
+ // ------------------------------------------------------------------
138
+ const weekStart = startOfWeek(current, { weekStartsOn: WEEK_START });
139
+ const weekEnd = endOfWeek(current, { weekStartsOn: WEEK_START });
140
+ const visibleDays = (() => {
141
+ if (viewMode === 'day')
142
+ return [current];
143
+ const days = Array.from({ length: 7 }, (_, i) => addDays(weekStart, i));
144
+ return showWeekends ? days : days.filter((d) => d.getDay() !== 0 && d.getDay() !== 6);
145
+ })();
146
+ // ------------------------------------------------------------------
147
+ // Navigate
148
+ // ------------------------------------------------------------------
149
+ const prev = () => {
150
+ if (viewMode === 'month')
151
+ setCurrent((d) => addMonths(d, -1));
152
+ else if (viewMode === 'week')
153
+ setCurrent((d) => addWeeks(d, -1));
154
+ else
155
+ setCurrent((d) => addDays(d, -1));
156
+ };
157
+ const next = () => {
158
+ if (viewMode === 'month')
159
+ setCurrent((d) => addMonths(d, 1));
160
+ else if (viewMode === 'week')
161
+ setCurrent((d) => addWeeks(d, 1));
162
+ else
163
+ setCurrent((d) => addDays(d, 1));
164
+ };
165
+ const navLabel = () => {
166
+ if (viewMode === 'month')
167
+ return format(current, 'MMMM yyyy', { locale: es });
168
+ if (viewMode === 'week') {
169
+ const s = format(weekStart, 'd MMM', { locale: es });
170
+ const e = format(weekEnd, 'd MMM yyyy', { locale: es });
171
+ return `${s} – ${e}`;
172
+ }
173
+ return format(current, 'EEEE d \'de\' MMMM yyyy', { locale: es });
174
+ };
175
+ // ------------------------------------------------------------------
176
+ // Events per day (for time-grid views)
177
+ // ------------------------------------------------------------------
178
+ const eventsForDay = (day) => events.filter((e) => isSameDay(isoToDate(e.start), day));
179
+ // ------------------------------------------------------------------
180
+ // Create flow
181
+ // ------------------------------------------------------------------
182
+ const handleGridClick = (e, day) => {
183
+ if (isReadOnly)
184
+ return;
185
+ const rect = (e.currentTarget).getBoundingClientRect();
186
+ const relY = e.clientY - rect.top;
187
+ const clickedMins = Math.round((relY / CELL_HEIGHT) * 60) * 30; // snap to 30min
188
+ const startMins = minHour * 60 + clickedMins;
189
+ const startHHMM = minutesToHHMM(Math.min(startMins, (maxHour - 1) * 60));
190
+ const endHHMM = minutesToHHMM(Math.min(startMins + 60, maxHour * 60));
191
+ setNewStart(startHHMM);
192
+ setNewEnd(endHHMM);
193
+ setNewCategory(allowedCategories[0] ?? CalendarEventCategory.WORKING);
194
+ setNewTitle('');
195
+ setCreate({ anchorEl: e.currentTarget, date: day, startMins });
196
+ };
197
+ const handleMonthDayClick = (day) => {
198
+ setCurrent(day);
199
+ setViewMode('day');
200
+ };
201
+ const handleCreate = () => {
202
+ if (!createState)
203
+ return;
204
+ const startISO = dateAndTimeToISO(createState.date, newStart);
205
+ const endISO = dateAndTimeToISO(createState.date, newEnd);
206
+ const template = step.eventTemplates?.find((t) => t.category === newCategory);
207
+ const evt = {
208
+ id: newEventId(),
209
+ category: newCategory,
210
+ start: startISO,
211
+ end: endISO,
212
+ title: newTitle || undefined,
213
+ eventTemplateId: template?.id,
214
+ };
215
+ setEvents((prev) => [...prev, evt]);
216
+ setCreate(null);
217
+ };
218
+ // ------------------------------------------------------------------
219
+ // Hour labels column
220
+ // ------------------------------------------------------------------
221
+ const hourLabels = Array.from({ length: totalHours }, (_, i) => minHour + i);
222
+ // ------------------------------------------------------------------
223
+ // Time-grid view (week / day)
224
+ // ------------------------------------------------------------------
225
+ const renderTimeGrid = () => (_jsxs("div", { className: styles.gridWrapper, children: [_jsxs("div", { className: styles.gridHeader, style: { gridTemplateColumns: `48px repeat(${visibleDays.length}, 1fr)` }, children: [_jsx("div", { className: styles.cornerCell }), visibleDays.map((day) => (_jsxs("div", { className: `${styles.dayHeader} ${isToday(day) ? styles.dayHeaderToday : ''}`, onClick: () => { setCurrent(day); setViewMode('day'); }, children: [_jsx("span", { className: styles.dayHeaderDow, children: format(day, 'EEE', { locale: es }) }), _jsx("span", { className: `${styles.dayHeaderNum} ${isToday(day) ? styles.todayCircle : ''}`, children: format(day, 'd') })] }, day.toISOString())))] }), _jsx("div", { className: styles.gridBody, ref: gridRef, children: _jsxs("div", { className: styles.gridInner, style: { gridTemplateColumns: `48px repeat(${visibleDays.length}, 1fr)` }, children: [_jsx("div", { className: styles.hourLabels, children: hourLabels.map((h) => (_jsx("div", { className: styles.hourLabel, style: { height: CELL_HEIGHT }, children: h > 0 && `${String(h).padStart(2, '0')}:00` }, h))) }), visibleDays.map((day) => (_jsxs("div", { className: styles.dayColumn, style: { height: totalHours * CELL_HEIGHT }, onClick: (e) => handleGridClick(e, day), children: [hourLabels.map((h) => (_jsx("div", { className: styles.hourLine, style: { top: (h - minHour) * CELL_HEIGHT } }, h))), eventsForDay(day).map((evt) => (_jsx(EventBlock, { event: evt, minHour: minHour, template: step.eventTemplates?.find((t) => t.category === evt.category), onDelete: deleteEvent, readOnly: isReadOnly }, evt.id)))] }, day.toISOString())))] }) })] }));
226
+ // ------------------------------------------------------------------
227
+ // Month view
228
+ // ------------------------------------------------------------------
229
+ const renderMonth = () => {
230
+ const mStart = startOfMonth(current);
231
+ const mEnd = endOfMonth(current);
232
+ const gridStart = startOfWeek(mStart, { weekStartsOn: WEEK_START });
233
+ const gridEnd = endOfWeek(mEnd, { weekStartsOn: WEEK_START });
234
+ const days = [];
235
+ let d = gridStart;
236
+ while (d <= gridEnd) {
237
+ days.push(d);
238
+ d = addDays(d, 1);
239
+ }
240
+ const DOW_LABELS = ['Lun', 'Mar', 'Mié', 'Jue', 'Vie', 'Sáb', 'Dom'];
241
+ return (_jsxs("div", { className: styles.monthGrid, children: [DOW_LABELS.map((lbl) => (_jsx("div", { className: styles.monthDowHeader, children: lbl }, lbl))), days.map((day) => {
242
+ const dayEvts = eventsForDay(day);
243
+ const outside = !isSameMonth(day, current);
244
+ return (_jsxs("div", { className: [
245
+ styles.monthCell,
246
+ outside ? styles.monthCellOutside : '',
247
+ isToday(day) ? styles.monthCellToday : '',
248
+ ].filter(Boolean).join(' '), onClick: () => handleMonthDayClick(day), children: [_jsx("span", { className: `${styles.monthCellNum} ${isToday(day) ? styles.todayCircle : ''}`, children: format(day, 'd') }), dayEvts.slice(0, 3).map((evt) => {
249
+ const color = CATEGORY_COLORS[evt.category] ?? '#607D8B';
250
+ return (_jsx("div", { className: styles.monthEventDot, style: { backgroundColor: color }, children: evt.title ?? CATEGORY_LABELS[evt.category] }, evt.id));
251
+ }), dayEvts.length > 3 && (_jsxs("div", { className: styles.monthMoreLabel, children: ["+", dayEvts.length - 3, " m\u00E1s"] }))] }, day.toISOString()));
252
+ })] }));
253
+ };
254
+ // ------------------------------------------------------------------
255
+ // Create popover
256
+ // ------------------------------------------------------------------
257
+ const needsTitle = newCategory === CalendarEventCategory.MEETING ||
258
+ newCategory === CalendarEventCategory.CUSTOM;
259
+ const renderCreatePopover = () => {
260
+ if (!createState)
261
+ return null;
262
+ return (_jsxs(Popover, { open: true, anchorEl: createState.anchorEl, onClose: () => setCreate(null), anchorOrigin: { vertical: 'top', horizontal: 'right' }, transformOrigin: { vertical: 'top', horizontal: 'left' }, slotProps: { paper: { className: styles.popoverPaper } }, children: [_jsxs("div", { className: styles.popoverHeader, children: [_jsx("span", { className: styles.popoverTitle, children: "Nuevo evento" }), _jsx("button", { type: "button", className: styles.popoverClose, onClick: () => setCreate(null), children: _jsx(CloseIcon, { size: 16 }) })] }), _jsxs("div", { className: styles.popoverBody, children: [_jsx("div", { className: styles.popoverLabel, children: "Tipo" }), _jsx("div", { className: styles.categoryGrid, children: allowedCategories.map((cat) => (_jsxs("button", { type: "button", className: `${styles.categoryChip} ${newCategory === cat ? styles.categoryChipActive : ''}`, style: newCategory === cat ? { backgroundColor: CATEGORY_COLORS[cat], color: '#fff' } : {}, onClick: () => setNewCategory(cat), children: [_jsx("span", { className: styles.categoryDot, style: { backgroundColor: CATEGORY_COLORS[cat] } }), CATEGORY_LABELS[cat]] }, cat))) }), needsTitle && (_jsxs(_Fragment, { children: [_jsx("div", { className: styles.popoverLabel, children: "Nombre" }), _jsx("input", { className: styles.popoverInput, value: newTitle, onChange: (e) => setNewTitle(e.target.value), placeholder: "Ej: Standup, Visita cliente\u2026", autoFocus: true })] })), _jsxs("div", { className: styles.timeRow, children: [_jsxs("div", { children: [_jsx("div", { className: styles.popoverLabel, children: "Inicio" }), _jsx("input", { type: "time", className: styles.popoverInput, value: newStart, onChange: (e) => setNewStart(e.target.value) })] }), _jsx("span", { className: styles.timeDash, children: "\u2013" }), _jsxs("div", { children: [_jsx("div", { className: styles.popoverLabel, children: "Fin" }), _jsx("input", { type: "time", className: styles.popoverInput, value: newEnd, onChange: (e) => setNewEnd(e.target.value) })] })] }), _jsxs("button", { type: "button", className: styles.createBtn, style: { backgroundColor: CATEGORY_COLORS[newCategory] }, onClick: handleCreate, children: [_jsx(AddIcon, { size: 16 }), "Agregar bloque"] })] })] }));
263
+ };
264
+ // ------------------------------------------------------------------
265
+ // Render
266
+ // ------------------------------------------------------------------
267
+ return (_jsxs("div", { className: styles.container, style: { width: widthStyle }, children: [_jsxs("div", { className: styles.toolbar, children: [_jsxs("div", { className: styles.viewSwitcher, children: [_jsx("button", { type: "button", className: `${styles.viewBtn} ${viewMode === 'day' ? styles.viewBtnActive : ''}`, onClick: () => setViewMode('day'), title: "D\u00EDa", children: _jsx(ViewDayIcon, { size: 18 }) }), _jsx("button", { type: "button", className: `${styles.viewBtn} ${viewMode === 'week' ? styles.viewBtnActive : ''}`, onClick: () => setViewMode('week'), title: "Semana", children: _jsx(ViewWeekIcon, { size: 18 }) }), _jsx("button", { type: "button", className: `${styles.viewBtn} ${viewMode === 'month' ? styles.viewBtnActive : ''}`, onClick: () => setViewMode('month'), title: "Mes", children: _jsx(CalendarIcon, { size: 18 }) })] }), _jsxs("div", { className: styles.navGroup, children: [_jsx("button", { type: "button", className: styles.navBtn, onClick: prev, children: _jsx(ArrowLeftIcon, { size: 20 }) }), _jsx("span", { className: styles.navLabel, children: navLabel() }), _jsx("button", { type: "button", className: styles.navBtn, onClick: next, children: _jsx(ArrowRightIcon, { size: 20 }) })] }), events.length > 0 && (_jsxs("span", { className: styles.eventBadge, children: [events.length, " evento", events.length !== 1 ? 's' : ''] })), !isReadOnly && viewMode !== 'month' && (_jsx("span", { className: styles.hintText, children: "Clic en el grid para agregar" }))] }), _jsx("div", { className: styles.calendarCard, children: viewMode === 'month' ? renderMonth() : renderTimeGrid() }), !isReadOnly && renderCreatePopover()] }));
268
+ }
269
+ export default MaterialCalendarStep;